From 9f00b16f799090abaa74bccade60305c5a683797 Mon Sep 17 00:00:00 2001 From: Matthew Witkowski Date: Fri, 9 Feb 2024 12:02:59 -0500 Subject: [PATCH] Add tests for asset storage. --- contracts/nav/src/storage/asset.rs | 235 +++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/contracts/nav/src/storage/asset.rs b/contracts/nav/src/storage/asset.rs index 8a3b1e4a..e381dde8 100644 --- a/contracts/nav/src/storage/asset.rs +++ b/contracts/nav/src/storage/asset.rs @@ -64,6 +64,7 @@ pub fn has_tag(storage: &dyn Storage, tag: &str) -> bool { /// Attempts to set the asset's tag in the contract's storage. /// An entry will be put into ASSET_TO_TAG and TAG_TO_ASSET. +/// The previous entry in TAG_TO_ASSET will also be removed. /// /// # Arguments /// @@ -81,6 +82,7 @@ pub fn set_tag( asset_addr: &Addr, tag: &str, ) -> Result<(), ContractError> { + remove_tag(storage, asset_addr); ASSET_TO_TAG.save(storage, asset_addr, &tag.to_string())?; Ok(TAG_TO_ASSET.save(storage, (tag.to_string(), asset_addr), &())?) } @@ -105,3 +107,236 @@ pub fn remove_tag(storage: &mut dyn Storage, asset_addr: &Addr) { TAG_TO_ASSET.remove(storage, (tag_to_remove, asset_addr)); } } + +#[cfg(test)] +mod tests { + use cosmwasm_std::Addr; + use provwasm_mocks::mock_provenance_dependencies; + + use crate::storage::asset::{get_tag, ASSET_TO_TAG, TAG_TO_ASSET}; + + use super::{has_tag, remove_tag, set_tag, with_tag}; + + #[test] + fn test_get_tag_empty() { + let deps = mock_provenance_dependencies(); + let asset_addr = Addr::unchecked("test"); + let tag = get_tag(&deps.storage, &asset_addr); + tag.expect_err("should throw an error when asset is missing"); + } + + #[test] + fn test_has_tag_missing() { + let mut deps = mock_provenance_dependencies(); + let asset_addr = Addr::unchecked("test"); + let tag = "tag1"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + let value = has_tag(&deps.storage, "tag2"); + let expected = false; + assert_eq!(expected, value); + } + + #[test] + fn test_has_tag_success() { + let mut deps = mock_provenance_dependencies(); + let asset_addr = Addr::unchecked("test"); + let tag = "tag1"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + let value = has_tag(&deps.storage, "tag1"); + let expected = true; + assert_eq!(expected, value); + } + + #[test] + fn test_set_tag_single() { + let mut deps = mock_provenance_dependencies(); + let asset_addr = Addr::unchecked("test"); + let tag = "tag1"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + let loaded_tag = ASSET_TO_TAG + .load(&deps.storage, &asset_addr) + .expect("should have entry in ASSET_TO_TAG"); + assert_eq!(loaded_tag, tag.to_string()); + TAG_TO_ASSET + .load(&deps.storage, (tag.to_string(), &asset_addr)) + .expect("should have entry in TAG_TO_ASSET") + } + + #[test] + fn test_set_tag_duplicate() { + let mut deps = mock_provenance_dependencies(); + let asset_addr = Addr::unchecked("test"); + let tag = "tag1"; + let tag2 = "tag2"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + set_tag(deps.as_mut().storage, &asset_addr, tag2).expect("should be successful"); + + let loaded_tag = ASSET_TO_TAG + .load(&deps.storage, &asset_addr) + .expect("should have entry in ASSET_TO_TAG"); + assert_eq!(loaded_tag, tag2.to_string()); + + TAG_TO_ASSET + .load(&deps.storage, (tag.to_string(), &asset_addr)) + .expect_err("should remove original entry in TAG_TO_ASSET"); + TAG_TO_ASSET + .load(&deps.storage, (tag2.to_string(), &asset_addr)) + .expect("should have latest entry in TAG_TO_ASSET"); + } + + #[test] + fn test_set_tag_multiple() { + let mut deps = mock_provenance_dependencies(); + let asset_addr = Addr::unchecked("test"); + let asset_addr2 = Addr::unchecked("test2"); + let tag = "tag1"; + let tag2 = "tag2"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + set_tag(deps.as_mut().storage, &asset_addr2, tag2).expect("should be successful"); + + let loaded_tag = ASSET_TO_TAG + .load(&deps.storage, &asset_addr) + .expect("should have entry in ASSET_TO_TAG"); + assert_eq!(loaded_tag, tag.to_string()); + + let loaded_tag2 = ASSET_TO_TAG + .load(&deps.storage, &asset_addr2) + .expect("should have both entries in ASSET_TO_TAG"); + assert_eq!(loaded_tag2, tag2.to_string()); + + TAG_TO_ASSET + .load(&deps.storage, (tag.to_string(), &asset_addr)) + .expect("should have entry in TAG_TO_ASSET"); + TAG_TO_ASSET + .load(&deps.storage, (tag2.to_string(), &asset_addr2)) + .expect("should have both entries in TAG_TO_ASSET"); + } + + #[test] + fn test_remove_invalid() { + let mut deps = mock_provenance_dependencies(); + let asset_addr = Addr::unchecked("test"); + let asset_addr2 = Addr::unchecked("test2"); + let tag = "tag1"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + remove_tag(deps.as_mut().storage, &asset_addr2); + + let loaded_tag = ASSET_TO_TAG + .load(&deps.storage, &asset_addr) + .expect("should have entry in ASSET_TO_TAG"); + assert_eq!(loaded_tag, tag.to_string()); + TAG_TO_ASSET + .load(&deps.storage, (tag.to_string(), &asset_addr)) + .expect("should have entry in TAG_TO_ASSET"); + } + + #[test] + fn test_remove_single() { + let mut deps = mock_provenance_dependencies(); + let asset_addr = Addr::unchecked("test"); + let tag = "tag1"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + remove_tag(deps.as_mut().storage, &asset_addr); + + ASSET_TO_TAG + .load(&deps.storage, &asset_addr) + .expect_err("should have no entry in ASSET_TO_TAG"); + TAG_TO_ASSET + .load(&deps.storage, (tag.to_string(), &asset_addr)) + .expect_err("should have no entry in TAG_TO_ASSET"); + } + + #[test] + fn test_remove_multiple() { + let mut deps = mock_provenance_dependencies(); + let asset_addr = Addr::unchecked("test"); + let asset_addr2 = Addr::unchecked("test2"); + let tag = "tag1"; + let tag2 = "tag2"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + set_tag(deps.as_mut().storage, &asset_addr2, tag2).expect("should be successful"); + remove_tag(deps.as_mut().storage, &asset_addr); + remove_tag(deps.as_mut().storage, &asset_addr2); + + ASSET_TO_TAG + .load(&deps.storage, &asset_addr) + .expect_err("should not have entry in ASSET_TO_TAG"); + ASSET_TO_TAG + .load(&deps.storage, &asset_addr2) + .expect_err("should remove both entries from ASSET_TO_TAG"); + + TAG_TO_ASSET + .load(&deps.storage, (tag.to_string(), &asset_addr)) + .expect_err("should not have entry in TAG_TO_ASSET"); + TAG_TO_ASSET + .load(&deps.storage, (tag2.to_string(), &asset_addr2)) + .expect_err("should remove both entries frrom TAG_TO_ASSET"); + } + + #[test] + fn test_with_tag_empty() { + let deps = mock_provenance_dependencies(); + let expected: Vec = vec![]; + let tags = with_tag(&deps.storage, "tag1").expect("should successfully obtain tags"); + assert_eq!(expected, tags); + } + + #[test] + fn test_with_tag_one_tag() { + let mut deps = mock_provenance_dependencies(); + let expected = vec![Addr::unchecked("test")]; + + let asset_addr = Addr::unchecked("test"); + let tag = "tag1"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + + let tags = with_tag(&deps.storage, "tag1").expect("should successfully obtain tags"); + assert_eq!(expected, tags); + } + + #[test] + fn test_with_tag_multi_asset_same_tag() { + let mut deps = mock_provenance_dependencies(); + let expected = vec![Addr::unchecked("test"), Addr::unchecked("test2")]; + + let asset_addr = Addr::unchecked("test"); + let asset_addr2 = Addr::unchecked("test2"); + let tag = "tag1"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + set_tag(deps.as_mut().storage, &asset_addr2, tag).expect("should be successful"); + + let tags = with_tag(&deps.storage, tag).expect("should successfully obtain tags"); + assert_eq!(expected, tags); + } + + #[test] + fn test_with_tag_multi_asset_different_tag() { + let mut deps = mock_provenance_dependencies(); + let expected1 = vec![Addr::unchecked("test")]; + let expected2 = vec![Addr::unchecked("test2")]; + + let asset_addr = Addr::unchecked("test"); + let asset_addr2 = Addr::unchecked("test2"); + let tag = "tag1"; + let tag2 = "tag2"; + + set_tag(deps.as_mut().storage, &asset_addr, tag).expect("should be successful"); + set_tag(deps.as_mut().storage, &asset_addr2, tag2).expect("should be successful"); + + let tags = with_tag(&deps.storage, tag).expect("should successfully obtain tags"); + assert_eq!(expected1, tags); + + let tags = with_tag(&deps.storage, tag2).expect("should successfully obtain tags"); + assert_eq!(expected2, tags); + } +}