From b00d7fa487e68f95cf5f461f23a5f831e01c25a0 Mon Sep 17 00:00:00 2001 From: Shashank Goyal Date: Tue, 26 Oct 2021 16:33:52 -0700 Subject: [PATCH 1/2] Add tests for the claims controller --- packages/controllers/src/claim.rs | 394 +++++++++++++++++++++++++++++- 1 file changed, 393 insertions(+), 1 deletion(-) diff --git a/packages/controllers/src/claim.rs b/packages/controllers/src/claim.rs index d5b1104ea..c7de8b77a 100644 --- a/packages/controllers/src/claim.rs +++ b/packages/controllers/src/claim.rs @@ -92,4 +92,396 @@ impl<'a> Claims<'a> { } } -// TODO: add test coverage +#[cfg(test)] +mod test { + use cosmwasm_std::{ + testing::{mock_dependencies, mock_env}, + Order, + }; + + use super::*; + const TEST_AMOUNT: u128 = 1000u128; + const TEST_EXPIRATION: Expiration = Expiration::AtHeight(10); + + #[test] + fn can_create_claim() { + let claim = Claim::new(TEST_AMOUNT, TEST_EXPIRATION); + assert_eq!(claim.amount, TEST_AMOUNT.into()); + assert_eq!(claim.release_at, TEST_EXPIRATION); + } + + #[test] + fn can_create_claims() { + let deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + // Assert that claims creates a map and there are no keys in the map. + assert_eq!( + claims + .0 + .range(&deps.storage, None, None, Order::Ascending) + .collect::>>() + .unwrap() + .len(), + 0 + ); + } + + #[test] + fn check_create_claim_updates_map() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + TEST_AMOUNT.into(), + TEST_EXPIRATION, + ) + .unwrap(); + + // Assert that claims creates a map and there is one claim for the address. + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(saved_claims.len(), 1); + assert_eq!(saved_claims[0].amount, TEST_AMOUNT.into()); + assert_eq!(saved_claims[0].release_at, TEST_EXPIRATION); + + // Adding another claim to same address, make sure that both claims are saved. + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + TEST_EXPIRATION, + ) + .unwrap(); + + // Assert that both claims exist for the address. + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(saved_claims.len(), 2); + assert_eq!(saved_claims[0].amount, TEST_AMOUNT.into()); + assert_eq!(saved_claims[0].release_at, TEST_EXPIRATION); + assert_eq!(saved_claims[1].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[1].release_at, TEST_EXPIRATION); + + // Adding another claim to different address, make sure that other address only has one claim. + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr2"), + (TEST_AMOUNT + 100).into(), + TEST_EXPIRATION, + ) + .unwrap(); + + // Assert that both claims exist for the address. + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + + let saved_claims_addr2 = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr2")) + .unwrap(); + assert_eq!(saved_claims.len(), 2); + assert_eq!(saved_claims_addr2.len(), 1); + } + + #[test] + fn test_claim_tokens_with_no_claims() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + let amount = claims + .claim_tokens( + deps.as_mut().storage, + &Addr::unchecked("addr"), + &mock_env().block, + None, + ) + .unwrap(); + assert_eq!(amount, Uint128::zero()); + } + + #[test] + fn test_claim_tokens_with_no_released_claims() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(10), + ) + .unwrap(); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(100), + ) + .unwrap(); + + let mut env = mock_env(); + env.block.height = 0; + // the address has two claims however they are both not expired + let amount = claims + .claim_tokens( + deps.as_mut().storage, + &Addr::unchecked("addr"), + &env.block, + None, + ) + .unwrap(); + assert_eq!(amount, Uint128::zero()); + } + + #[test] + fn test_claim_tokens_with_one_released_claims() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + TEST_AMOUNT.into(), + Expiration::AtHeight(10), + ) + .unwrap(); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(100), + ) + .unwrap(); + + let mut env = mock_env(); + env.block.height = 20; + // the address has two claims and the first one can be released + let amount = claims + .claim_tokens( + deps.as_mut().storage, + &Addr::unchecked("addr"), + &env.block, + None, + ) + .unwrap(); + assert_eq!(amount, TEST_AMOUNT.into()); + } + + #[test] + fn test_claim_tokens_with_all_released_claims() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + TEST_AMOUNT.into(), + Expiration::AtHeight(10), + ) + .unwrap(); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(100), + ) + .unwrap(); + + let mut env = mock_env(); + env.block.height = 1000; + // the address has two claims and the first one can be released + let amount = claims + .claim_tokens( + deps.as_mut().storage, + &Addr::unchecked("addr"), + &env.block, + None, + ) + .unwrap(); + assert_eq!(amount, (TEST_AMOUNT + TEST_AMOUNT + 100).into()); + } + + #[test] + fn test_claim_tokens_with_zero_cap() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + TEST_AMOUNT.into(), + Expiration::AtHeight(10), + ) + .unwrap(); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(100), + ) + .unwrap(); + + let mut env = mock_env(); + env.block.height = 1000; + // the address has two claims and the first one can be released + let amount = claims + .claim_tokens( + deps.as_mut().storage, + &Addr::unchecked("addr"), + &env.block, + Some(Uint128::zero()), + ) + .unwrap(); + assert_eq!(amount, Uint128::zero()); + } + + #[test] + fn test_claim_tokens_with_cap_greater_than_pending_claims() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + TEST_AMOUNT.into(), + Expiration::AtHeight(10), + ) + .unwrap(); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(100), + ) + .unwrap(); + + let mut env = mock_env(); + env.block.height = 1000; + // the address has two claims and the first one can be released + let amount = claims + .claim_tokens( + deps.as_mut().storage, + &Addr::unchecked("addr"), + &env.block, + Some(Uint128::from(2100u128)), + ) + .unwrap(); + assert_eq!(amount, (TEST_AMOUNT + TEST_AMOUNT + 100).into()); + } + + #[test] + fn test_claim_tokens_with_cap_only_one_claim_released() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(10), + ) + .unwrap(); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + TEST_AMOUNT.into(), + Expiration::AtHeight(5), + ) + .unwrap(); + + let mut env = mock_env(); + env.block.height = 1000; + // the address has two claims and the first one can be released + let amount = claims + .claim_tokens( + deps.as_mut().storage, + &Addr::unchecked("addr"), + &env.block, + Some((TEST_AMOUNT + 50).into()), + ) + .unwrap(); + assert_eq!(amount, (TEST_AMOUNT).into()); + + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(saved_claims.len(), 1); + assert_eq!(saved_claims[0].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); + } + + #[test] + fn test_query_claims_returns_correct_claims() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(10), + ) + .unwrap(); + + let queried_claims = claims + .query_claims(deps.as_ref(), &Addr::unchecked("addr")) + .unwrap(); + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(queried_claims.claims, saved_claims); + } + + #[test] + fn test_query_claims_returns_empty_for_non_existent_user() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(10), + ) + .unwrap(); + + let queried_claims = claims + .query_claims(deps.as_ref(), &Addr::unchecked("addr2")) + .unwrap(); + + assert_eq!(queried_claims.claims.len(), 0); + } +} From 84728a4dbe021fc61b502ccd54cc7aa76ce3e08f Mon Sep 17 00:00:00 2001 From: Shashank Goyal Date: Thu, 28 Oct 2021 12:45:43 -0700 Subject: [PATCH 2/2] Update tests to make sure saved claims are properly checked after all operations. --- packages/controllers/src/claim.rs | 106 ++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 4 deletions(-) diff --git a/packages/controllers/src/claim.rs b/packages/controllers/src/claim.rs index c7de8b77a..bcc8d8304 100644 --- a/packages/controllers/src/claim.rs +++ b/packages/controllers/src/claim.rs @@ -207,7 +207,13 @@ mod test { None, ) .unwrap(); + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(amount, Uint128::zero()); + assert_eq!(saved_claims.len(), 0); } #[test] @@ -244,11 +250,22 @@ mod test { None, ) .unwrap(); + + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(amount, Uint128::zero()); + assert_eq!(saved_claims.len(), 2); + assert_eq!(saved_claims[0].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); + assert_eq!(saved_claims[1].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[1].release_at, Expiration::AtHeight(100)); } #[test] - fn test_claim_tokens_with_one_released_claims() { + fn test_claim_tokens_with_one_released_claim() { let mut deps = mock_dependencies(&[]); let claims = Claims::new("claims"); @@ -281,7 +298,16 @@ mod test { None, ) .unwrap(); + + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(amount, TEST_AMOUNT.into()); + assert_eq!(saved_claims.len(), 1); + assert_eq!(saved_claims[0].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(100)); } #[test] @@ -309,7 +335,7 @@ mod test { let mut env = mock_env(); env.block.height = 1000; - // the address has two claims and the first one can be released + // the address has two claims and both can be released let amount = claims .claim_tokens( deps.as_mut().storage, @@ -318,7 +344,14 @@ mod test { None, ) .unwrap(); + + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(amount, (TEST_AMOUNT + TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims.len(), 0); } #[test] @@ -346,7 +379,7 @@ mod test { let mut env = mock_env(); env.block.height = 1000; - // the address has two claims and the first one can be released + let amount = claims .claim_tokens( deps.as_mut().storage, @@ -355,7 +388,18 @@ mod test { Some(Uint128::zero()), ) .unwrap(); + + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(amount, Uint128::zero()); + assert_eq!(saved_claims.len(), 2); + assert_eq!(saved_claims[0].amount, (TEST_AMOUNT).into()); + assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); + assert_eq!(saved_claims[1].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[1].release_at, Expiration::AtHeight(100)); } #[test] @@ -383,7 +427,7 @@ mod test { let mut env = mock_env(); env.block.height = 1000; - // the address has two claims and the first one can be released + let amount = claims .claim_tokens( deps.as_mut().storage, @@ -392,7 +436,14 @@ mod test { Some(Uint128::from(2100u128)), ) .unwrap(); + + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(amount, (TEST_AMOUNT + TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims.len(), 0); } #[test] @@ -440,6 +491,53 @@ mod test { assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); } + #[test] + fn test_claim_tokens_with_cap_too_low_no_claims_released() { + let mut deps = mock_dependencies(&[]); + let claims = Claims::new("claims"); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + (TEST_AMOUNT + 100).into(), + Expiration::AtHeight(10), + ) + .unwrap(); + + claims + .create_claim( + deps.as_mut().storage, + &Addr::unchecked("addr"), + TEST_AMOUNT.into(), + Expiration::AtHeight(5), + ) + .unwrap(); + + let mut env = mock_env(); + env.block.height = 1000; + // the address has two claims and the first one can be released + let amount = claims + .claim_tokens( + deps.as_mut().storage, + &Addr::unchecked("addr"), + &env.block, + Some((TEST_AMOUNT - 50).into()), + ) + .unwrap(); + assert_eq!(amount, Uint128::zero()); + + let saved_claims = claims + .0 + .load(deps.as_mut().storage, &Addr::unchecked("addr")) + .unwrap(); + assert_eq!(saved_claims.len(), 2); + assert_eq!(saved_claims[0].amount, (TEST_AMOUNT + 100).into()); + assert_eq!(saved_claims[0].release_at, Expiration::AtHeight(10)); + assert_eq!(saved_claims[1].amount, (TEST_AMOUNT).into()); + assert_eq!(saved_claims[1].release_at, Expiration::AtHeight(5)); + } + #[test] fn test_query_claims_returns_correct_claims() { let mut deps = mock_dependencies(&[]);