123456789101112131415161718use crate::{Test, TestCrossAccountId, CollectionCreationPrice, RuntimeOrigin, Unique, new_test_ext};19use up_data_structs::{20 COLLECTION_NUMBER_LIMIT, CollectionId, CreateItemData, CreateFungibleData, CreateNftData,21 CreateReFungibleData, MAX_DECIMAL_POINTS, COLLECTION_ADMINS_LIMIT, TokenId,22 MAX_TOKEN_OWNERSHIP, CreateCollectionData, CollectionMode, AccessMode, CollectionPermissions,23 PropertyKeyPermission, PropertyPermission, Property, CollectionPropertiesVec,24 CollectionPropertiesPermissionsVec,25};26use frame_support::{assert_noop, assert_ok, assert_err};27use sp_std::convert::TryInto;28use pallet_evm::account::CrossAccountId;29use pallet_common::Error as CommonError;30use pallet_unique::Error as UniqueError;3132fn add_balance(user: u64, value: u64) {33 const DONOR_USER: u64 = 999;34 assert_ok!(<pallet_balances::Pallet<Test>>::force_set_balance(35 RuntimeOrigin::root(),36 DONOR_USER,37 value,38 ));39 assert_ok!(<pallet_balances::Pallet<Test>>::force_transfer(40 RuntimeOrigin::root(),41 DONOR_USER,42 user,43 value44 ));45}4647fn default_nft_data() -> CreateNftData {48 CreateNftData {49 properties: vec![Property {50 key: b"test-prop".to_vec().try_into().unwrap(),51 value: b"test-nft-prop".to_vec().try_into().unwrap(),52 }]53 .try_into()54 .unwrap(),55 }56}5758fn default_fungible_data() -> CreateFungibleData {59 CreateFungibleData { value: 5 }60}6162fn default_re_fungible_data() -> CreateReFungibleData {63 CreateReFungibleData {64 pieces: 1023,65 properties: vec![Property {66 key: b"test-prop".to_vec().try_into().unwrap(),67 value: b"test-nft-prop".to_vec().try_into().unwrap(),68 }]69 .try_into()70 .unwrap(),71 }72}7374fn create_test_collection_for_owner(75 mode: &CollectionMode,76 owner: u64,77 id: CollectionId,78) -> CollectionId {79 add_balance(owner, CollectionCreationPrice::get() as u64 + 1);8081 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();82 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();83 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();84 let token_property_permissions: CollectionPropertiesPermissionsVec =85 vec![PropertyKeyPermission {86 key: b"test-prop".to_vec().try_into().unwrap(),87 permission: PropertyPermission {88 mutable: true,89 collection_admin: false,90 token_owner: true,91 },92 }]93 .try_into()94 .unwrap();95 let properties: CollectionPropertiesVec = vec![Property {96 key: b"test-collection-prop".to_vec().try_into().unwrap(),97 value: b"test-collection-value".to_vec().try_into().unwrap(),98 }]99 .try_into()100 .unwrap();101102 let data = CreateCollectionData {103 name: col_name1.try_into().unwrap(),104 description: col_desc1.try_into().unwrap(),105 token_prefix: token_prefix1.try_into().unwrap(),106 mode: mode.clone(),107 token_property_permissions: token_property_permissions.clone(),108 properties: properties.clone(),109 ..Default::default()110 };111112 let origin1 = RuntimeOrigin::signed(owner);113 assert_ok!(Unique::create_collection_ex(origin1, data));114115 let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();116 let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();117 let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();118 assert_eq!(119 <pallet_common::CollectionById<Test>>::get(id)120 .unwrap()121 .owner,122 owner123 );124 assert_eq!(125 <pallet_common::CollectionById<Test>>::get(id).unwrap().name,126 saved_col_name127 );128 assert_eq!(129 <pallet_common::CollectionById<Test>>::get(id).unwrap().mode,130 *mode131 );132 assert_eq!(133 <pallet_common::CollectionById<Test>>::get(id)134 .unwrap()135 .description,136 saved_description137 );138 assert_eq!(139 <pallet_common::CollectionById<Test>>::get(id)140 .unwrap()141 .token_prefix,142 saved_prefix143 );144 assert_eq!(145 get_collection_property_permissions(id).as_slice(),146 token_property_permissions.as_slice()147 );148 assert_eq!(149 get_collection_properties(id).as_slice(),150 properties.as_slice()151 );152 id153}154155fn get_collection_property_permissions(collection_id: CollectionId) -> Vec<PropertyKeyPermission> {156 <pallet_common::Pallet<Test>>::property_permissions(collection_id)157 .into_iter()158 .map(|(key, permission)| PropertyKeyPermission { key, permission })159 .collect()160}161162fn get_collection_properties(collection_id: CollectionId) -> Vec<Property> {163 <pallet_common::Pallet<Test>>::collection_properties(collection_id)164 .into_iter()165 .map(|(key, value)| Property { key, value })166 .collect()167}168169fn get_token_properties(collection_id: CollectionId, token_id: TokenId) -> Vec<Property> {170 <pallet_nonfungible::Pallet<Test>>::token_properties((collection_id, token_id))171 .into_iter()172 .map(|(key, value)| Property { key, value })173 .collect()174}175176fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {177 create_test_collection_for_owner(&mode, 1, id)178}179180fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {181 let origin1 = RuntimeOrigin::signed(1);182 assert_ok!(Unique::create_item(183 origin1,184 collection_id,185 account(1),186 data.clone()187 ));188}189190fn account(sub: u64) -> TestCrossAccountId {191 TestCrossAccountId::from_sub(sub)192}193194195196197#[test]198fn check_not_sufficient_founds() {199 new_test_ext().execute_with(|| {200 let acc: u64 = 1;201 <pallet_balances::Pallet<Test>>::force_set_balance(RuntimeOrigin::root(), acc, 0).unwrap();202203 let name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();204 let description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();205 let token_prefix: Vec<u8> = b"token_prefix1\0".to_vec();206207 let data = CreateCollectionData {208 name: name.try_into().unwrap(),209 description: description.try_into().unwrap(),210 token_prefix: token_prefix.try_into().unwrap(),211 mode: CollectionMode::NFT,212 ..Default::default()213 };214215 let result = Unique::create_collection_ex(RuntimeOrigin::signed(acc), data);216 assert_err!(result, <CommonError<Test>>::NotSufficientFounds);217 });218}219220#[test]221fn create_fungible_collection_fails_with_large_decimal_numbers() {222 new_test_ext().execute_with(|| {223 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();224 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();225 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();226227 let data = CreateCollectionData {228 name: col_name1.try_into().unwrap(),229 description: col_desc1.try_into().unwrap(),230 token_prefix: token_prefix1.try_into().unwrap(),231 mode: CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1),232 ..Default::default()233 };234235 let origin1 = RuntimeOrigin::signed(1);236 assert_noop!(237 Unique::create_collection_ex(origin1, data),238 UniqueError::<Test>::CollectionDecimalPointLimitExceeded239 );240 });241}242243#[test]244fn create_nft_item() {245 new_test_ext().execute_with(|| {246 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));247248 let data = default_nft_data();249 create_test_item(collection_id, &data.clone().into());250251 assert_eq!(252 get_token_properties(collection_id, TokenId(1)).as_slice(),253 data.properties.as_slice(),254 );255 });256}257258259260#[test]261fn create_nft_multiple_items() {262 new_test_ext().execute_with(|| {263 create_test_collection(&CollectionMode::NFT, CollectionId(1));264265 let origin1 = RuntimeOrigin::signed(1);266267 let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];268269 assert_ok!(Unique::create_multiple_items(270 origin1,271 CollectionId(1),272 account(1),273 items_data274 .clone()275 .into_iter()276 .map(|d| { d.into() })277 .collect()278 ));279 for (index, data) in items_data.into_iter().enumerate() {280 assert_eq!(281 get_token_properties(CollectionId(1), TokenId(index as u32 + 1)).as_slice(),282 data.properties.as_slice()283 );284 }285 });286}287288#[test]289fn create_refungible_item() {290 new_test_ext().execute_with(|| {291 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));292293 let data = default_re_fungible_data();294 create_test_item(collection_id, &data.clone().into());295 let balance =296 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));297 assert_eq!(balance, 1023);298 });299}300301#[test]302fn create_multiple_refungible_items() {303 new_test_ext().execute_with(|| {304 create_test_collection(&CollectionMode::ReFungible, CollectionId(1));305306 let origin1 = RuntimeOrigin::signed(1);307308 let items_data = vec![309 default_re_fungible_data(),310 default_re_fungible_data(),311 default_re_fungible_data(),312 ];313314 assert_ok!(Unique::create_multiple_items(315 origin1,316 CollectionId(1),317 account(1),318 items_data319 .clone()320 .into_iter()321 .map(|d| { d.into() })322 .collect()323 ));324 for (index, _data) in items_data.into_iter().enumerate() {325 let balance = <pallet_refungible::Balance<Test>>::get((326 CollectionId(1),327 TokenId((index + 1) as u32),328 account(1),329 ));330 assert_eq!(balance, 1023);331 }332 });333}334335#[test]336fn create_fungible_item() {337 new_test_ext().execute_with(|| {338 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));339340 let data = default_fungible_data();341 create_test_item(collection_id, &data.into());342343 assert_eq!(344 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),345 5346 );347 });348}349350351352353354355356357358359360361362363364365366367368369370371372373374375376#[test]377fn transfer_fungible_item() {378 new_test_ext().execute_with(|| {379 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));380381 let origin1 = RuntimeOrigin::signed(1);382 let origin2 = RuntimeOrigin::signed(2);383384 let data = default_fungible_data();385 create_test_item(collection_id, &data.into());386387 assert_eq!(388 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),389 5390 );391392 393 assert_ok!(Unique::transfer(394 origin1,395 account(2),396 CollectionId(1),397 TokenId(0),398 5399 ));400 assert_eq!(401 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),402 0403 );404405 406 assert_ok!(Unique::transfer(407 origin2.clone(),408 account(3),409 CollectionId(1),410 TokenId(0),411 3412 ));413414 415 assert_ok!(Unique::transfer(416 origin2,417 account(3),418 CollectionId(1),419 TokenId(0),420 1421 ));422 assert_eq!(423 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(2))),424 1425 );426 assert_eq!(427 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(3))),428 4429 );430 });431}432433#[test]434fn transfer_refungible_item() {435 new_test_ext().execute_with(|| {436 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));437438 439 let data = default_re_fungible_data();440 create_test_item(collection_id, &data.clone().into());441 assert_eq!(442 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),443 1444 );445 assert_eq!(446 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),447 1023448 );449 assert_eq!(450 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),451 true452 );453454 455 let origin1 = RuntimeOrigin::signed(1);456 let origin2 = RuntimeOrigin::signed(2);457 assert_ok!(Unique::transfer(458 origin1,459 account(2),460 CollectionId(1),461 TokenId(1),462 1023463 ));464 assert_eq!(465 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),466 1023467 );468 assert_eq!(469 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),470 0471 );472 assert_eq!(473 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),474 1475 );476 assert_eq!(477 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),478 false479 );480 assert_eq!(481 <pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),482 true483 );484485 486 assert_ok!(Unique::transfer(487 origin2.clone(),488 account(3),489 CollectionId(1),490 TokenId(1),491 500492 ));493 assert_eq!(494 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),495 523496 );497 assert_eq!(498 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),499 500500 );501 assert_eq!(502 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),503 1504 );505 assert_eq!(506 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),507 1508 );509 assert_eq!(510 <pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),511 true512 );513 assert_eq!(514 <pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),515 true516 );517518 519 assert_ok!(Unique::transfer(520 origin2,521 account(3),522 CollectionId(1),523 TokenId(1),524 200525 ));526 assert_eq!(527 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),528 323529 );530 assert_eq!(531 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),532 700533 );534 assert_eq!(535 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),536 1537 );538 assert_eq!(539 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),540 1541 );542 assert_eq!(543 <pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),544 true545 );546 assert_eq!(547 <pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),548 true549 );550 });551}552553#[test]554fn transfer_nft_item() {555 new_test_ext().execute_with(|| {556 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));557558 let data = default_nft_data();559 create_test_item(collection_id, &data.into());560 assert_eq!(561 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),562 1563 );564 assert_eq!(565 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),566 true567 );568569 let origin1 = RuntimeOrigin::signed(1);570 571 assert_ok!(Unique::transfer(572 origin1,573 account(2),574 CollectionId(1),575 TokenId(1),576 1577 ));578 assert_eq!(579 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),580 0581 );582 assert_eq!(583 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),584 1585 );586 assert_eq!(587 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),588 false589 );590 assert_eq!(591 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),592 true593 );594 });595}596597#[test]598fn transfer_nft_item_wrong_value() {599 new_test_ext().execute_with(|| {600 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));601602 let data = default_nft_data();603 create_test_item(collection_id, &data.into());604 assert_eq!(605 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),606 1607 );608 assert_eq!(609 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),610 true611 );612613 let origin1 = RuntimeOrigin::signed(1);614615 assert_noop!(616 Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 2)617 .map_err(|e| e.error),618 <pallet_nonfungible::Error::<Test>>::NonfungibleItemsHaveNoAmount619 );620 });621}622623#[test]624fn transfer_nft_item_zero_value() {625 new_test_ext().execute_with(|| {626 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));627628 let data = default_nft_data();629 create_test_item(collection_id, &data.into());630 assert_eq!(631 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),632 1633 );634 assert_eq!(635 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),636 true637 );638639 let origin1 = RuntimeOrigin::signed(1);640641 642 assert_ok!(Unique::transfer(643 origin1,644 account(2),645 CollectionId(1),646 TokenId(1),647 0648 ));649 650 assert_eq!(651 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),652 1653 );654 assert_eq!(655 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),656 true657 );658 });659}660661#[test]662fn nft_approve_and_transfer_from() {663 new_test_ext().execute_with(|| {664 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));665666 let data = default_nft_data();667 create_test_item(collection_id, &data.into());668669 let origin1 = RuntimeOrigin::signed(1);670 let origin2 = RuntimeOrigin::signed(2);671672 assert_eq!(673 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),674 1675 );676 assert_eq!(677 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),678 true679 );680681 682 assert_noop!(683 Unique::transfer_from(684 origin2.clone(),685 account(1),686 account(2),687 CollectionId(1),688 TokenId(1),689 1690 )691 .map_err(|e| e.error),692 CommonError::<Test>::ApprovedValueTooLow693 );694695 696 assert_ok!(Unique::approve(697 origin1,698 account(2),699 CollectionId(1),700 TokenId(1),701 1702 ));703 assert_eq!(704 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),705 account(2)706 );707708 assert_ok!(Unique::transfer_from(709 origin2,710 account(1),711 account(3),712 CollectionId(1),713 TokenId(1),714 1715 ));716 assert!(717 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()718 );719 });720}721722#[test]723fn nft_approve_and_transfer_from_allow_list() {724 new_test_ext().execute_with(|| {725 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));726727 let origin1 = RuntimeOrigin::signed(1);728 let origin2 = RuntimeOrigin::signed(2);729730 731 let data = default_nft_data();732 create_test_item(collection_id, &data.clone().into());733 assert_eq!(734 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),735 1736 );737 assert_eq!(738 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),739 true740 );741742 743 assert_ok!(Unique::set_collection_permissions(744 origin1.clone(),745 CollectionId(1),746 CollectionPermissions {747 mint_mode: Some(true),748 access: Some(AccessMode::AllowList),749 nesting: None,750 }751 ));752 assert_ok!(Unique::add_to_allow_list(753 origin1.clone(),754 CollectionId(1),755 account(1)756 ));757 assert_ok!(Unique::add_to_allow_list(758 origin1.clone(),759 CollectionId(1),760 account(2)761 ));762 assert_ok!(Unique::add_to_allow_list(763 origin1.clone(),764 CollectionId(1),765 account(3)766 ));767768 769 assert_ok!(Unique::approve(770 origin1.clone(),771 account(2),772 CollectionId(1),773 TokenId(1),774 1775 ));776 assert_eq!(777 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),778 account(2)779 );780781 782 assert_ok!(Unique::transfer_from(783 origin2,784 account(1),785 account(3),786 CollectionId(1),787 TokenId(1),788 1789 ));790 assert!(791 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()792 );793 });794}795796#[test]797fn refungible_approve_and_transfer_from() {798 new_test_ext().execute_with(|| {799 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));800801 let origin1 = RuntimeOrigin::signed(1);802 let origin2 = RuntimeOrigin::signed(2);803804 805 let data = default_re_fungible_data();806 create_test_item(collection_id, &data.into());807808 assert_eq!(809 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),810 1811 );812 assert_eq!(813 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),814 1023815 );816 assert_eq!(817 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),818 true819 );820821 822 assert_ok!(Unique::set_collection_permissions(823 origin1.clone(),824 CollectionId(1),825 CollectionPermissions {826 mint_mode: Some(true),827 access: Some(AccessMode::AllowList),828 nesting: None,829 }830 ));831 assert_ok!(Unique::add_to_allow_list(832 origin1.clone(),833 CollectionId(1),834 account(1)835 ));836 assert_ok!(Unique::add_to_allow_list(837 origin1.clone(),838 CollectionId(1),839 account(2)840 ));841 assert_ok!(Unique::add_to_allow_list(842 origin1.clone(),843 CollectionId(1),844 account(3)845 ));846847 848 assert_ok!(Unique::approve(849 origin1,850 account(2),851 CollectionId(1),852 TokenId(1),853 1023854 ));855 assert_eq!(856 <pallet_refungible::Allowance<Test>>::get((857 CollectionId(1),858 TokenId(1),859 account(1),860 account(2)861 )),862 1023863 );864865 866 assert_ok!(Unique::transfer_from(867 origin2,868 account(1),869 account(3),870 CollectionId(1),871 TokenId(1),872 100873 ));874 assert_eq!(875 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),876 1877 );878 assert_eq!(879 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),880 1881 );882 assert_eq!(883 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),884 923885 );886 assert_eq!(887 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),888 100889 );890 assert_eq!(891 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),892 true893 );894 assert_eq!(895 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),896 true897 );898 assert_eq!(899 <pallet_refungible::Allowance<Test>>::get((900 CollectionId(1),901 TokenId(1),902 account(1),903 account(2)904 )),905 923906 );907 });908}909910#[test]911fn fungible_approve_and_transfer_from() {912 new_test_ext().execute_with(|| {913 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));914915 let data = default_fungible_data();916 create_test_item(collection_id, &data.into());917918 let origin1 = RuntimeOrigin::signed(1);919 let origin2 = RuntimeOrigin::signed(2);920921 assert_ok!(Unique::set_collection_permissions(922 origin1.clone(),923 CollectionId(1),924 CollectionPermissions {925 mint_mode: Some(true),926 access: Some(AccessMode::AllowList),927 nesting: None,928 }929 ));930 assert_ok!(Unique::add_to_allow_list(931 origin1.clone(),932 CollectionId(1),933 account(1)934 ));935 assert_ok!(Unique::add_to_allow_list(936 origin1.clone(),937 CollectionId(1),938 account(2)939 ));940 assert_ok!(Unique::add_to_allow_list(941 origin1.clone(),942 CollectionId(1),943 account(3)944 ));945946 947 assert_ok!(Unique::approve(948 origin1.clone(),949 account(2),950 CollectionId(1),951 TokenId(0),952 5953 ));954 assert_eq!(955 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),956 5957 );958 assert_ok!(Unique::approve(959 origin1,960 account(3),961 CollectionId(1),962 TokenId(0),963 5964 ));965 assert_eq!(966 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),967 5968 );969 assert_eq!(970 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(3))),971 5972 );973974 assert_ok!(Unique::transfer_from(975 origin2.clone(),976 account(1),977 account(3),978 CollectionId(1),979 TokenId(0),980 4981 ));982983 assert_eq!(984 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),985 1986 );987988 assert_noop!(989 Unique::transfer_from(990 origin2,991 account(1),992 account(3),993 CollectionId(1),994 TokenId(0),995 4996 )997 .map_err(|e| e.error),998 CommonError::<Test>::ApprovedValueTooLow999 );1000 });1001}10021003#[test]1004fn change_collection_owner() {1005 new_test_ext().execute_with(|| {1006 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10071008 let origin1 = RuntimeOrigin::signed(1);1009 assert_ok!(Unique::change_collection_owner(origin1, collection_id, 2));1010 assert_eq!(1011 <pallet_common::CollectionById<Test>>::get(collection_id)1012 .unwrap()1013 .owner,1014 21015 );1016 });1017}10181019#[test]1020fn destroy_collection() {1021 new_test_ext().execute_with(|| {1022 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10231024 let origin1 = RuntimeOrigin::signed(1);1025 assert_ok!(Unique::destroy_collection(origin1, collection_id));1026 });1027}10281029#[test]1030fn burn_nft_item() {1031 new_test_ext().execute_with(|| {1032 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10331034 let origin1 = RuntimeOrigin::signed(1);10351036 let data = default_nft_data();1037 create_test_item(collection_id, &data.into());10381039 1040 assert_eq!(1041 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1042 11043 );10441045 1046 assert_ok!(Unique::burn_item(1047 origin1.clone(),1048 collection_id,1049 TokenId(1),1050 11051 ));1052 assert_eq!(1053 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1054 01055 );1056 });1057}10581059#[test]1060fn burn_same_nft_item_twice() {1061 new_test_ext().execute_with(|| {1062 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10631064 let origin1 = RuntimeOrigin::signed(1);10651066 let data = default_nft_data();1067 create_test_item(collection_id, &data.into());10681069 1070 assert_eq!(1071 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1072 11073 );10741075 1076 assert_ok!(Unique::burn_item(1077 origin1.clone(),1078 collection_id,1079 TokenId(1),1080 11081 ));10821083 1084 assert_noop!(1085 Unique::burn_item(origin1, collection_id, TokenId(1), 1).map_err(|e| e.error),1086 CommonError::<Test>::TokenNotFound1087 );10881089 assert_eq!(1090 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1091 01092 );1093 });1094}10951096#[test]1097fn burn_fungible_item() {1098 new_test_ext().execute_with(|| {1099 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11001101 let origin1 = RuntimeOrigin::signed(1);1102 assert_ok!(Unique::add_collection_admin(1103 origin1.clone(),1104 collection_id,1105 account(2)1106 ));11071108 let data = default_fungible_data();1109 create_test_item(collection_id, &data.into());11101111 1112 assert_eq!(1113 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1114 51115 );11161117 1118 assert_ok!(Unique::burn_item(1119 origin1.clone(),1120 CollectionId(1),1121 TokenId(0),1122 51123 ));1124 assert_noop!(1125 Unique::burn_item(origin1, CollectionId(1), TokenId(0), 5).map_err(|e| e.error),1126 CommonError::<Test>::TokenValueTooLow1127 );11281129 assert_eq!(1130 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1131 01132 );1133 });1134}11351136#[test]1137fn burn_fungible_item_with_token_id() {1138 new_test_ext().execute_with(|| {1139 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11401141 let origin1 = RuntimeOrigin::signed(1);1142 assert_ok!(Unique::add_collection_admin(1143 origin1.clone(),1144 collection_id,1145 account(2)1146 ));11471148 let data = default_fungible_data();1149 create_test_item(collection_id, &data.into());11501151 1152 assert_eq!(1153 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1154 51155 );11561157 1158 assert_noop!(1159 Unique::burn_item(origin1, CollectionId(1), TokenId(1), 5).map_err(|e| e.error),1160 <pallet_fungible::Error::<Test>>::FungibleItemsHaveNoId1161 );1162 });1163}1164#[test]1165fn burn_refungible_item() {1166 new_test_ext().execute_with(|| {1167 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));1168 let origin1 = RuntimeOrigin::signed(1);11691170 assert_ok!(Unique::set_collection_permissions(1171 origin1.clone(),1172 collection_id,1173 CollectionPermissions {1174 mint_mode: Some(true),1175 access: Some(AccessMode::AllowList),1176 nesting: None,1177 }1178 ));1179 assert_ok!(Unique::add_to_allow_list(1180 origin1.clone(),1181 collection_id,1182 account(1)1183 ));11841185 assert_ok!(Unique::add_collection_admin(1186 origin1.clone(),1187 collection_id,1188 account(2)1189 ));11901191 let data = default_re_fungible_data();1192 create_test_item(collection_id, &data.into());11931194 1195 assert_eq!(1196 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),1197 11198 );1199 assert_eq!(1200 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1201 10231202 );12031204 1205 assert_ok!(Unique::burn_item(1206 origin1.clone(),1207 collection_id,1208 TokenId(1),1209 10231210 ));1211 assert_noop!(1212 Unique::burn_item(origin1, collection_id, TokenId(1), 1023).map_err(|e| e.error),1213 CommonError::<Test>::TokenValueTooLow1214 );12151216 assert_eq!(1217 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1218 01219 );1220 });1221}12221223#[test]1224fn add_collection_admin() {1225 new_test_ext().execute_with(|| {1226 let collection1_id =1227 create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1228 let origin1 = RuntimeOrigin::signed(1);12291230 1231 assert_ok!(Unique::add_collection_admin(1232 origin1.clone(),1233 collection1_id,1234 account(2)1235 ));1236 assert_ok!(Unique::add_collection_admin(1237 origin1,1238 collection1_id,1239 account(3)1240 ));12411242 1243 assert_eq!(1244 <pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(1))),1245 false1246 );1247 assert!(<pallet_common::IsAdmin<Test>>::get((1248 CollectionId(1),1249 account(2)1250 )));1251 assert!(<pallet_common::IsAdmin<Test>>::get((1252 CollectionId(1),1253 account(3)1254 )));1255 });1256}12571258#[test]1259fn remove_collection_admin() {1260 new_test_ext().execute_with(|| {1261 let collection1_id =1262 create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1263 let origin1 = RuntimeOrigin::signed(1);12641265 1266 assert_ok!(Unique::add_collection_admin(1267 origin1.clone(),1268 collection1_id,1269 account(2)1270 ));1271 assert_ok!(Unique::add_collection_admin(1272 origin1.clone(),1273 collection1_id,1274 account(3)1275 ));12761277 assert!(<pallet_common::IsAdmin<Test>>::get((1278 CollectionId(1),1279 account(2)1280 )));1281 assert!(<pallet_common::IsAdmin<Test>>::get((1282 CollectionId(1),1283 account(3)1284 )));12851286 1287 assert_ok!(Unique::remove_collection_admin(1288 origin1,1289 CollectionId(1),1290 account(3)1291 ));12921293 1294 assert!(<pallet_common::IsAdmin<Test>>::get((1295 CollectionId(1),1296 account(2)1297 )));1298 assert_eq!(1299 <pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))),1300 false1301 );1302 });1303}13041305#[test]1306fn balance_of() {1307 new_test_ext().execute_with(|| {1308 let nft_collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1309 let fungible_collection_id =1310 create_test_collection(&CollectionMode::Fungible(3), CollectionId(2));1311 let re_fungible_collection_id =1312 create_test_collection(&CollectionMode::ReFungible, CollectionId(3));13131314 1315 assert_eq!(1316 <pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1317 01318 );1319 assert_eq!(1320 <pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1321 01322 );1323 assert_eq!(1324 <pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1325 01326 );13271328 let nft_data = default_nft_data();1329 create_test_item(nft_collection_id, &nft_data.into());13301331 let fungible_data = default_fungible_data();1332 create_test_item(fungible_collection_id, &fungible_data.into());13331334 let re_fungible_data = default_re_fungible_data();1335 create_test_item(re_fungible_collection_id, &re_fungible_data.into());13361337 1338 assert_eq!(1339 <pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1340 11341 );1342 assert_eq!(1343 <pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1344 51345 );1346 assert_eq!(1347 <pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1348 11349 );13501351 assert_eq!(1352 <pallet_nonfungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))),1353 true1354 );1355 assert_eq!(1356 <pallet_refungible::Owned<Test>>::get((1357 re_fungible_collection_id,1358 account(1),1359 TokenId(1)1360 )),1361 true1362 );1363 });1364}13651366#[test]1367fn approve() {1368 new_test_ext().execute_with(|| {1369 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));13701371 let data = default_nft_data();1372 create_test_item(collection_id, &data.into());13731374 let origin1 = RuntimeOrigin::signed(1);13751376 1377 assert_ok!(Unique::approve(1378 origin1,1379 account(2),1380 CollectionId(1),1381 TokenId(1),1382 11383 ));1384 assert_eq!(1385 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1386 account(2)1387 );1388 });1389}13901391#[test]1392fn transfer_from() {1393 new_test_ext().execute_with(|| {1394 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1395 let origin1 = RuntimeOrigin::signed(1);1396 let origin2 = RuntimeOrigin::signed(2);13971398 let data = default_nft_data();1399 create_test_item(collection_id, &data.into());14001401 1402 assert_ok!(Unique::approve(1403 origin1.clone(),1404 account(2),1405 CollectionId(1),1406 TokenId(1),1407 11408 ));1409 assert_eq!(1410 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1411 account(2)1412 );14131414 assert_ok!(Unique::set_collection_permissions(1415 origin1.clone(),1416 CollectionId(1),1417 CollectionPermissions {1418 mint_mode: Some(true),1419 access: Some(AccessMode::AllowList),1420 nesting: None,1421 }1422 ));1423 assert_ok!(Unique::add_to_allow_list(1424 origin1.clone(),1425 CollectionId(1),1426 account(1)1427 ));1428 assert_ok!(Unique::add_to_allow_list(1429 origin1.clone(),1430 CollectionId(1),1431 account(2)1432 ));1433 assert_ok!(Unique::add_to_allow_list(1434 origin1,1435 CollectionId(1),1436 account(3)1437 ));14381439 assert_ok!(Unique::transfer_from(1440 origin2,1441 account(1),1442 account(2),1443 CollectionId(1),1444 TokenId(1),1445 11446 ));14471448 1449 assert_eq!(1450 <pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(1))),1451 01452 );1453 assert_eq!(1454 <pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(2))),1455 11456 );1457 });1458}1459146014611462146314641465#[test]1466fn owner_can_add_address_to_allow_list() {1467 new_test_ext().execute_with(|| {1468 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));14691470 let origin1 = RuntimeOrigin::signed(1);1471 assert_ok!(Unique::add_to_allow_list(1472 origin1,1473 collection_id,1474 account(2)1475 ));1476 assert!(<pallet_common::Allowlist<Test>>::get((1477 collection_id,1478 account(2)1479 )));1480 });1481}14821483#[test]1484fn admin_can_add_address_to_allow_list() {1485 new_test_ext().execute_with(|| {1486 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1487 let origin1 = RuntimeOrigin::signed(1);1488 let origin2 = RuntimeOrigin::signed(2);14891490 assert_ok!(Unique::add_collection_admin(1491 origin1,1492 collection_id,1493 account(2)1494 ));1495 assert_ok!(Unique::add_to_allow_list(1496 origin2,1497 collection_id,1498 account(3)1499 ));1500 assert!(<pallet_common::Allowlist<Test>>::get((1501 collection_id,1502 account(3)1503 )));1504 });1505}15061507#[test]1508fn nonprivileged_user_cannot_add_address_to_allow_list() {1509 new_test_ext().execute_with(|| {1510 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15111512 let origin2 = RuntimeOrigin::signed(2);1513 assert_noop!(1514 Unique::add_to_allow_list(origin2, collection_id, account(3)),1515 CommonError::<Test>::NoPermission1516 );1517 });1518}15191520#[test]1521fn nobody_can_add_address_to_allow_list_of_nonexisting_collection() {1522 new_test_ext().execute_with(|| {1523 let origin1 = RuntimeOrigin::signed(1);15241525 assert_noop!(1526 Unique::add_to_allow_list(origin1, CollectionId(1), account(2)),1527 CommonError::<Test>::CollectionNotFound1528 );1529 });1530}15311532#[test]1533fn nobody_can_add_address_to_allow_list_of_deleted_collection() {1534 new_test_ext().execute_with(|| {1535 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15361537 let origin1 = RuntimeOrigin::signed(1);1538 assert_ok!(Unique::destroy_collection(origin1.clone(), collection_id));1539 assert_noop!(1540 Unique::add_to_allow_list(origin1, collection_id, account(2)),1541 CommonError::<Test>::CollectionNotFound1542 );1543 });1544}154515461547#[test]1548fn address_is_already_added_to_allow_list() {1549 new_test_ext().execute_with(|| {1550 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1551 let origin1 = RuntimeOrigin::signed(1);15521553 assert_ok!(Unique::add_to_allow_list(1554 origin1.clone(),1555 collection_id,1556 account(2)1557 ));1558 assert_ok!(Unique::add_to_allow_list(1559 origin1,1560 collection_id,1561 account(2)1562 ));1563 assert!(<pallet_common::Allowlist<Test>>::get((1564 collection_id,1565 account(2)1566 )));1567 });1568}15691570#[test]1571fn owner_can_remove_address_from_allow_list() {1572 new_test_ext().execute_with(|| {1573 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15741575 let origin1 = RuntimeOrigin::signed(1);1576 assert_ok!(Unique::add_to_allow_list(1577 origin1.clone(),1578 collection_id,1579 account(2)1580 ));1581 assert_ok!(Unique::remove_from_allow_list(1582 origin1,1583 collection_id,1584 account(2)1585 ));1586 assert_eq!(1587 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1588 false1589 );1590 });1591}15921593#[test]1594fn admin_can_remove_address_from_allow_list() {1595 new_test_ext().execute_with(|| {1596 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1597 let origin1 = RuntimeOrigin::signed(1);1598 let origin2 = RuntimeOrigin::signed(2);15991600 1601 assert_ok!(Unique::add_collection_admin(1602 origin1.clone(),1603 collection_id,1604 account(2)1605 ));16061607 1608 assert_ok!(Unique::add_to_allow_list(1609 origin1,1610 collection_id,1611 account(3)1612 ));16131614 1615 assert_ok!(Unique::remove_from_allow_list(1616 origin2,1617 collection_id,1618 account(3)1619 ));1620 assert_eq!(1621 <pallet_common::Allowlist<Test>>::get((collection_id, account(3))),1622 false1623 );1624 });1625}16261627#[test]1628fn nonprivileged_user_cannot_remove_address_from_allow_list() {1629 new_test_ext().execute_with(|| {1630 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1631 let origin1 = RuntimeOrigin::signed(1);1632 let origin2 = RuntimeOrigin::signed(2);16331634 assert_ok!(Unique::add_to_allow_list(1635 origin1,1636 collection_id,1637 account(2)1638 ));1639 assert_noop!(1640 Unique::remove_from_allow_list(origin2, collection_id, account(2)),1641 CommonError::<Test>::NoPermission1642 );1643 assert!(<pallet_common::Allowlist<Test>>::get((1644 collection_id,1645 account(2)1646 )));1647 });1648}16491650#[test]1651fn nobody_can_remove_address_from_allow_list_of_nonexisting_collection() {1652 new_test_ext().execute_with(|| {1653 let origin1 = RuntimeOrigin::signed(1);16541655 assert_noop!(1656 Unique::remove_from_allow_list(origin1, CollectionId(1), account(2)),1657 CommonError::<Test>::CollectionNotFound1658 );1659 });1660}16611662#[test]1663fn nobody_can_remove_address_from_allow_list_of_deleted_collection() {1664 new_test_ext().execute_with(|| {1665 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1666 let origin1 = RuntimeOrigin::signed(1);1667 let origin2 = RuntimeOrigin::signed(2);16681669 1670 assert_ok!(Unique::add_to_allow_list(1671 origin1.clone(),1672 collection_id,1673 account(2)1674 ));16751676 1677 assert!(<pallet_common::Allowlist<Test>>::get((1678 collection_id,1679 account(2)1680 )));16811682 1683 assert_ok!(Unique::destroy_collection(origin1, collection_id));16841685 1686 assert_noop!(1687 Unique::remove_from_allow_list(origin2, collection_id, account(2)),1688 CommonError::<Test>::CollectionNotFound1689 );16901691 1692 assert_eq!(1693 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1694 false1695 );1696 });1697}169816991700#[test]1701fn address_is_already_removed_from_allow_list() {1702 new_test_ext().execute_with(|| {1703 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1704 let origin1 = RuntimeOrigin::signed(1);17051706 assert_ok!(Unique::add_to_allow_list(1707 origin1.clone(),1708 collection_id,1709 account(2)1710 ));1711 assert_ok!(Unique::remove_from_allow_list(1712 origin1.clone(),1713 collection_id,1714 account(2)1715 ));1716 assert_eq!(1717 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1718 false1719 );1720 assert_ok!(Unique::remove_from_allow_list(1721 origin1,1722 collection_id,1723 account(2)1724 ));1725 assert_eq!(1726 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1727 false1728 );1729 });1730}173117321733#[test]1734fn allow_list_test_1() {1735 new_test_ext().execute_with(|| {1736 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));17371738 let origin1 = RuntimeOrigin::signed(1);1739 assert_ok!(Unique::add_collection_admin(1740 origin1.clone(),1741 collection_id,1742 account(1)1743 ));17441745 let data = default_nft_data();1746 create_test_item(collection_id, &data.into());17471748 assert_ok!(Unique::set_collection_permissions(1749 origin1.clone(),1750 collection_id,1751 CollectionPermissions {1752 mint_mode: None,1753 access: Some(AccessMode::AllowList),1754 nesting: None,1755 }1756 ));1757 assert_ok!(Unique::add_to_allow_list(1758 origin1.clone(),1759 collection_id,1760 account(2)1761 ));17621763 assert_noop!(1764 Unique::transfer(origin1, account(3), CollectionId(1), TokenId(1), 1)1765 .map_err(|e| e.error),1766 CommonError::<Test>::AddressNotInAllowlist1767 );1768 });1769}17701771#[test]1772fn allow_list_test_2() {1773 new_test_ext().execute_with(|| {1774 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1775 let origin1 = RuntimeOrigin::signed(1);17761777 let data = default_nft_data();1778 create_test_item(collection_id, &data.into());17791780 assert_ok!(Unique::set_collection_permissions(1781 origin1.clone(),1782 collection_id,1783 CollectionPermissions {1784 mint_mode: None,1785 access: Some(AccessMode::AllowList),1786 nesting: None,1787 }1788 ));1789 assert_ok!(Unique::add_to_allow_list(1790 origin1.clone(),1791 collection_id,1792 account(1)1793 ));1794 assert_ok!(Unique::add_to_allow_list(1795 origin1.clone(),1796 collection_id,1797 account(2)1798 ));17991800 1801 assert_ok!(Unique::approve(1802 origin1.clone(),1803 account(1),1804 collection_id,1805 TokenId(1),1806 11807 ));1808 assert_eq!(1809 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1810 account(1)1811 );18121813 assert_ok!(Unique::remove_from_allow_list(1814 origin1.clone(),1815 collection_id,1816 account(1)1817 ));18181819 assert_noop!(1820 Unique::transfer_from(1821 origin1,1822 account(1),1823 account(3),1824 CollectionId(1),1825 TokenId(1),1826 11827 )1828 .map_err(|e| e.error),1829 CommonError::<Test>::AddressNotInAllowlist1830 );1831 });1832}183318341835#[test]1836fn allow_list_test_3() {1837 new_test_ext().execute_with(|| {1838 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18391840 let origin1 = RuntimeOrigin::signed(1);18411842 let data = default_nft_data();1843 create_test_item(collection_id, &data.into());18441845 assert_ok!(Unique::set_collection_permissions(1846 origin1.clone(),1847 collection_id,1848 CollectionPermissions {1849 mint_mode: None,1850 access: Some(AccessMode::AllowList),1851 nesting: None,1852 }1853 ));1854 assert_ok!(Unique::add_to_allow_list(1855 origin1.clone(),1856 collection_id,1857 account(1)1858 ));18591860 assert_noop!(1861 Unique::transfer(origin1, account(3), collection_id, TokenId(1), 1)1862 .map_err(|e| e.error),1863 CommonError::<Test>::AddressNotInAllowlist1864 );1865 });1866}18671868#[test]1869fn allow_list_test_4() {1870 new_test_ext().execute_with(|| {1871 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18721873 let origin1 = RuntimeOrigin::signed(1);18741875 let data = default_nft_data();1876 create_test_item(collection_id, &data.into());18771878 assert_ok!(Unique::set_collection_permissions(1879 origin1.clone(),1880 collection_id,1881 CollectionPermissions {1882 mint_mode: None,1883 access: Some(AccessMode::AllowList),1884 nesting: None,1885 }1886 ));1887 assert_ok!(Unique::add_to_allow_list(1888 origin1.clone(),1889 collection_id,1890 account(1)1891 ));1892 assert_ok!(Unique::add_to_allow_list(1893 origin1.clone(),1894 collection_id,1895 account(2)1896 ));18971898 1899 assert_ok!(Unique::approve(1900 origin1.clone(),1901 account(1),1902 collection_id,1903 TokenId(1),1904 11905 ));1906 assert_eq!(1907 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1908 account(1)1909 );19101911 assert_ok!(Unique::remove_from_allow_list(1912 origin1.clone(),1913 collection_id,1914 account(2)1915 ));19161917 assert_noop!(1918 Unique::transfer_from(1919 origin1,1920 account(1),1921 account(3),1922 collection_id,1923 TokenId(1),1924 11925 )1926 .map_err(|e| e.error),1927 CommonError::<Test>::AddressNotInAllowlist1928 );1929 });1930}193119321933#[test]1934fn allow_list_test_5() {1935 new_test_ext().execute_with(|| {1936 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19371938 let origin1 = RuntimeOrigin::signed(1);19391940 let data = default_nft_data();1941 create_test_item(collection_id, &data.into());19421943 assert_ok!(Unique::set_collection_permissions(1944 origin1.clone(),1945 collection_id,1946 CollectionPermissions {1947 mint_mode: None,1948 access: Some(AccessMode::AllowList),1949 nesting: None,1950 }1951 ));1952 assert_noop!(1953 Unique::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 1).map_err(|e| e.error),1954 CommonError::<Test>::AddressNotInAllowlist1955 );1956 });1957}195819591960#[test]1961fn allow_list_test_6() {1962 new_test_ext().execute_with(|| {1963 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19641965 let origin1 = RuntimeOrigin::signed(1);19661967 let data = default_nft_data();1968 create_test_item(collection_id, &data.into());19691970 assert_ok!(Unique::set_collection_permissions(1971 origin1.clone(),1972 collection_id,1973 CollectionPermissions {1974 mint_mode: None,1975 access: Some(AccessMode::AllowList),1976 nesting: None,1977 }1978 ));19791980 1981 assert_noop!(1982 Unique::approve(origin1, account(1), CollectionId(1), TokenId(1), 1)1983 .map_err(|e| e.error),1984 CommonError::<Test>::AddressNotInAllowlist1985 );1986 });1987}1988198919901991#[test]1992fn allow_list_test_7() {1993 new_test_ext().execute_with(|| {1994 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19951996 let data = default_nft_data();1997 create_test_item(collection_id, &data.into());19981999 let origin1 = RuntimeOrigin::signed(1);20002001 assert_ok!(Unique::set_collection_permissions(2002 origin1.clone(),2003 collection_id,2004 CollectionPermissions {2005 mint_mode: None,2006 access: Some(AccessMode::AllowList),2007 nesting: None,2008 }2009 ));2010 assert_ok!(Unique::add_to_allow_list(2011 origin1.clone(),2012 collection_id,2013 account(1)2014 ));2015 assert_ok!(Unique::add_to_allow_list(2016 origin1.clone(),2017 collection_id,2018 account(2)2019 ));20202021 assert_ok!(Unique::transfer(2022 origin1,2023 account(2),2024 CollectionId(1),2025 TokenId(1),2026 12027 ));2028 });2029}20302031#[test]2032fn allow_list_test_8() {2033 new_test_ext().execute_with(|| {2034 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));20352036 2037 let data = default_nft_data();2038 create_test_item(collection_id, &data.into());20392040 let origin1 = RuntimeOrigin::signed(1);20412042 2043 assert_ok!(Unique::set_collection_permissions(2044 origin1.clone(),2045 collection_id,2046 CollectionPermissions {2047 mint_mode: None,2048 access: Some(AccessMode::AllowList),2049 nesting: None,2050 }2051 ));2052 assert_ok!(Unique::add_to_allow_list(2053 origin1.clone(),2054 collection_id,2055 account(1)2056 ));2057 assert_ok!(Unique::add_to_allow_list(2058 origin1.clone(),2059 collection_id,2060 account(2)2061 ));20622063 2064 assert_ok!(Unique::approve(2065 origin1.clone(),2066 account(1),2067 CollectionId(1),2068 TokenId(1),2069 12070 ));2071 assert_eq!(2072 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),2073 account(1)2074 );20752076 2077 assert_ok!(Unique::transfer_from(2078 origin1,2079 account(1),2080 account(2),2081 CollectionId(1),2082 TokenId(1),2083 12084 ));2085 });2086}208720882089#[test]2090fn allow_list_test_9() {2091 new_test_ext().execute_with(|| {2092 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2093 let origin1 = RuntimeOrigin::signed(1);20942095 assert_ok!(Unique::set_collection_permissions(2096 origin1.clone(),2097 collection_id,2098 CollectionPermissions {2099 mint_mode: Some(false),2100 access: Some(AccessMode::AllowList),2101 nesting: None,2102 }2103 ));21042105 let data = default_nft_data();2106 create_test_item(collection_id, &data.into());2107 });2108}210921102111#[test]2112fn allow_list_test_10() {2113 new_test_ext().execute_with(|| {2114 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21152116 let origin1 = RuntimeOrigin::signed(1);2117 let origin2 = RuntimeOrigin::signed(2);21182119 assert_ok!(Unique::set_collection_permissions(2120 origin1.clone(),2121 collection_id,2122 CollectionPermissions {2123 mint_mode: Some(false),2124 access: Some(AccessMode::AllowList),2125 nesting: None,2126 }2127 ));21282129 assert_ok!(Unique::add_collection_admin(2130 origin1,2131 collection_id,2132 account(2)2133 ));21342135 assert_ok!(Unique::create_item(2136 origin2,2137 collection_id,2138 account(2),2139 default_nft_data().into()2140 ));2141 });2142}214321442145#[test]2146fn allow_list_test_11() {2147 new_test_ext().execute_with(|| {2148 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21492150 let origin1 = RuntimeOrigin::signed(1);2151 let origin2 = RuntimeOrigin::signed(2);21522153 assert_ok!(Unique::set_collection_permissions(2154 origin1.clone(),2155 collection_id,2156 CollectionPermissions {2157 mint_mode: Some(false),2158 access: Some(AccessMode::AllowList),2159 nesting: None,2160 }2161 ));2162 assert_ok!(Unique::add_to_allow_list(2163 origin1,2164 collection_id,2165 account(2)2166 ));21672168 assert_noop!(2169 Unique::create_item(2170 origin2,2171 CollectionId(1),2172 account(2),2173 default_nft_data().into()2174 )2175 .map_err(|e| e.error),2176 CommonError::<Test>::PublicMintingNotAllowed2177 );2178 });2179}218021812182#[test]2183fn allow_list_test_12() {2184 new_test_ext().execute_with(|| {2185 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21862187 let origin1 = RuntimeOrigin::signed(1);2188 let origin2 = RuntimeOrigin::signed(2);21892190 assert_ok!(Unique::set_collection_permissions(2191 origin1.clone(),2192 collection_id,2193 CollectionPermissions {2194 mint_mode: Some(false),2195 access: Some(AccessMode::AllowList),2196 nesting: None,2197 }2198 ));21992200 assert_noop!(2201 Unique::create_item(2202 origin2,2203 CollectionId(1),2204 account(2),2205 default_nft_data().into()2206 )2207 .map_err(|e| e.error),2208 CommonError::<Test>::PublicMintingNotAllowed2209 );2210 });2211}221222132214#[test]2215fn allow_list_test_13() {2216 new_test_ext().execute_with(|| {2217 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22182219 let origin1 = RuntimeOrigin::signed(1);22202221 assert_ok!(Unique::set_collection_permissions(2222 origin1.clone(),2223 collection_id,2224 CollectionPermissions {2225 mint_mode: Some(true),2226 access: Some(AccessMode::AllowList),2227 nesting: None,2228 }2229 ));22302231 let data = default_nft_data();2232 create_test_item(collection_id, &data.into());2233 });2234}223522362237#[test]2238fn allow_list_test_14() {2239 new_test_ext().execute_with(|| {2240 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22412242 let origin1 = RuntimeOrigin::signed(1);2243 let origin2 = RuntimeOrigin::signed(2);22442245 assert_ok!(Unique::set_collection_permissions(2246 origin1.clone(),2247 collection_id,2248 CollectionPermissions {2249 mint_mode: Some(true),2250 access: Some(AccessMode::AllowList),2251 nesting: None,2252 }2253 ));22542255 assert_ok!(Unique::add_collection_admin(2256 origin1,2257 collection_id,2258 account(2)2259 ));22602261 assert_ok!(Unique::create_item(2262 origin2,2263 collection_id,2264 account(2),2265 default_nft_data().into()2266 ));2267 });2268}226922702271#[test]2272fn allow_list_test_15() {2273 new_test_ext().execute_with(|| {2274 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22752276 let origin1 = RuntimeOrigin::signed(1);2277 let origin2 = RuntimeOrigin::signed(2);22782279 assert_ok!(Unique::set_collection_permissions(2280 origin1.clone(),2281 collection_id,2282 CollectionPermissions {2283 mint_mode: Some(true),2284 access: Some(AccessMode::AllowList),2285 nesting: None,2286 }2287 ));22882289 assert_noop!(2290 Unique::create_item(2291 origin2,2292 collection_id,2293 account(2),2294 default_nft_data().into()2295 )2296 .map_err(|e| e.error),2297 CommonError::<Test>::AddressNotInAllowlist2298 );2299 });2300}230123022303#[test]2304fn allow_list_test_16() {2305 new_test_ext().execute_with(|| {2306 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23072308 let origin1 = RuntimeOrigin::signed(1);2309 let origin2 = RuntimeOrigin::signed(2);23102311 assert_ok!(Unique::set_collection_permissions(2312 origin1.clone(),2313 collection_id,2314 CollectionPermissions {2315 mint_mode: Some(true),2316 access: Some(AccessMode::AllowList),2317 nesting: None,2318 }2319 ));2320 assert_ok!(Unique::add_to_allow_list(2321 origin1,2322 collection_id,2323 account(2)2324 ));23252326 assert_ok!(Unique::create_item(2327 origin2,2328 collection_id,2329 account(2),2330 default_nft_data().into()2331 ));2332 });2333}233423352336#[test]2337fn total_number_collections_bound() {2338 new_test_ext().execute_with(|| {2339 create_test_collection(&CollectionMode::NFT, CollectionId(1));2340 });2341}23422343#[test]2344fn create_max_collections() {2345 new_test_ext().execute_with(|| {2346 for i in 1..COLLECTION_NUMBER_LIMIT {2347 create_test_collection(&CollectionMode::NFT, CollectionId(i));2348 }2349 });2350}235123522353#[test]2354fn total_number_collections_bound_neg() {2355 new_test_ext().execute_with(|| {2356 let origin1 = RuntimeOrigin::signed(1);23572358 for i in 1..=COLLECTION_NUMBER_LIMIT {2359 create_test_collection(&CollectionMode::NFT, CollectionId(i));2360 }23612362 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();2363 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();2364 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();23652366 let data = CreateCollectionData {2367 name: col_name1.try_into().unwrap(),2368 description: col_desc1.try_into().unwrap(),2369 token_prefix: token_prefix1.try_into().unwrap(),2370 mode: CollectionMode::NFT,2371 ..Default::default()2372 };23732374 2375 assert_noop!(2376 Unique::create_collection_ex(origin1, data),2377 CommonError::<Test>::TotalCollectionsLimitExceeded2378 );2379 });2380}238123822383#[test]2384fn owned_tokens_bound() {2385 new_test_ext().execute_with(|| {2386 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23872388 let data = default_nft_data();2389 create_test_item(collection_id, &data.clone().into());2390 create_test_item(collection_id, &data.into());2391 });2392}239323942395#[test]2396fn owned_tokens_bound_neg() {2397 new_test_ext().execute_with(|| {2398 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23992400 let origin1 = RuntimeOrigin::signed(1);24012402 for _ in 1..=MAX_TOKEN_OWNERSHIP {2403 let data = default_nft_data();2404 create_test_item(collection_id, &data.clone().into());2405 }24062407 let data = default_nft_data();2408 assert_noop!(2409 Unique::create_item(origin1, CollectionId(1), account(1), data.into())2410 .map_err(|e| e.error),2411 CommonError::<Test>::AccountTokenLimitExceeded2412 );2413 });2414}241524162417#[test]2418fn collection_admins_bound() {2419 new_test_ext().execute_with(|| {2420 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24212422 let origin1 = RuntimeOrigin::signed(1);24232424 assert_ok!(Unique::add_collection_admin(2425 origin1.clone(),2426 collection_id,2427 account(2)2428 ));2429 assert_ok!(Unique::add_collection_admin(2430 origin1,2431 collection_id,2432 account(3)2433 ));2434 });2435}243624372438#[test]2439fn collection_admins_bound_neg() {2440 new_test_ext().execute_with(|| {2441 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24422443 let origin1 = RuntimeOrigin::signed(1);24442445 for i in 0..COLLECTION_ADMINS_LIMIT {2446 assert_ok!(Unique::add_collection_admin(2447 origin1.clone(),2448 collection_id,2449 account((2 + i).into())2450 ));2451 }2452 assert_noop!(2453 Unique::add_collection_admin(2454 origin1,2455 collection_id,2456 account((3 + COLLECTION_ADMINS_LIMIT).into())2457 ),2458 CommonError::<Test>::CollectionAdminCountExceeded2459 );2460 });2461}246224632464#[test]2465fn collection_transfer_flag_works() {2466 new_test_ext().execute_with(|| {2467 let origin1 = RuntimeOrigin::signed(1);24682469 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2470 assert_ok!(Unique::set_transfers_enabled_flag(2471 origin1,2472 collection_id,2473 true2474 ));24752476 let data = default_nft_data();2477 create_test_item(collection_id, &data.into());2478 assert_eq!(2479 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2480 12481 );2482 assert_eq!(2483 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2484 true2485 );24862487 let origin1 = RuntimeOrigin::signed(1);24882489 2490 assert_ok!(Unique::transfer(2491 origin1,2492 account(2),2493 collection_id,2494 TokenId(1),2495 12496 ));2497 assert_eq!(2498 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2499 false2500 );2501 assert_eq!(2502 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2503 true2504 );2505 assert_eq!(2506 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2507 02508 );2509 assert_eq!(2510 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2511 12512 );2513 });2514}25152516#[test]2517fn collection_transfer_flag_works_neg() {2518 new_test_ext().execute_with(|| {2519 let origin1 = RuntimeOrigin::signed(1);25202521 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2522 assert_ok!(Unique::set_transfers_enabled_flag(2523 origin1,2524 collection_id,2525 false2526 ));25272528 let data = default_nft_data();2529 create_test_item(collection_id, &data.into());2530 assert_eq!(2531 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2532 12533 );2534 assert_eq!(2535 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2536 true2537 );25382539 let origin1 = RuntimeOrigin::signed(1);25402541 2542 assert_noop!(2543 Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1)2544 .map_err(|e| e.error),2545 CommonError::<Test>::TransferNotAllowed2546 );2547 assert_eq!(2548 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2549 12550 );2551 assert_eq!(2552 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2553 02554 );2555 assert_eq!(2556 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2557 true2558 );2559 assert_eq!(2560 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2561 false2562 );2563 });2564}25652566#[test]2567fn collection_sponsoring() {2568 new_test_ext().execute_with(|| {2569 2570 let user1 = 1_u64;2571 let user2 = 777_u64;2572 let origin1 = RuntimeOrigin::signed(user1);2573 let origin2 = RuntimeOrigin::signed(user2);2574 let account2 = account(user2);25752576 let collection_id =2577 create_test_collection_for_owner(&CollectionMode::NFT, user1, CollectionId(1));2578 assert_ok!(Unique::set_collection_sponsor(2579 origin1.clone(),2580 collection_id,2581 user12582 ));2583 assert_ok!(Unique::confirm_sponsorship(origin1.clone(), collection_id));25842585 2586 assert!(Unique::create_item(2587 origin2.clone(),2588 collection_id,2589 account2.clone(),2590 default_nft_data().into()2591 )2592 .is_err());25932594 assert_ok!(Unique::set_collection_permissions(2595 origin1.clone(),2596 collection_id,2597 CollectionPermissions {2598 mint_mode: Some(true),2599 access: Some(AccessMode::AllowList),2600 nesting: None,2601 }2602 ));2603 assert_ok!(Unique::add_to_allow_list(2604 origin1.clone(),2605 collection_id,2606 account2.clone()2607 ));26082609 assert_ok!(Unique::create_item(2610 origin2,2611 collection_id,2612 account2,2613 default_nft_data().into()2614 ));2615 });2616}26172618mod check_token_permissions {2619 use super::*;2620 use pallet_common::LazyValue;26212622 fn test<FTE: FnOnce() -> bool>(2623 i: usize,2624 test_case: &pallet_common::tests::TestCase,2625 check_token_existence: &mut LazyValue<bool, FTE>,2626 ) {2627 let collection_admin = test_case.collection_admin;2628 let mut is_collection_admin = LazyValue::new(|| test_case.is_collection_admin);2629 let token_owner = test_case.token_owner;2630 let mut is_token_owner = LazyValue::new(|| Ok(test_case.is_token_owner));2631 let is_no_permission = test_case.no_permission;26322633 let result = pallet_common::tests::check_token_permissions::<Test, _, _, FTE>(2634 collection_admin,2635 token_owner,2636 &mut is_collection_admin,2637 &mut is_token_owner,2638 check_token_existence,2639 );26402641 if is_no_permission {2642 assert!(2643 result.is_err(),2644 "{i}: {test_case:?}, token_exist: {}",2645 check_token_existence.value()2646 );2647 assert_err!(result, pallet_common::Error::<Test>::NoPermission,);2648 } else if check_token_existence.has_value() && !check_token_existence.value() {2649 assert!(2650 result.is_err(),2651 "{i}: {test_case:?}, token_exist: {}",2652 check_token_existence.value()2653 );2654 assert_err!(result, pallet_common::Error::<Test>::TokenNotFound,);2655 }2656 }26572658 #[test]2659 fn no_permission_only() {2660 new_test_ext().execute_with(|| {2661 let mut check_token_existence = LazyValue::new(|| true);2662 for (i, row) in pallet_common::tests::TABLE.iter().enumerate() {2663 test(i, row, &mut check_token_existence);2664 }2665 });2666 }26672668 #[test]2669 fn no_permission_and_token_not_found() {2670 new_test_ext().execute_with(|| {2671 for (i, row) in pallet_common::tests::TABLE.iter().enumerate() {2672 2673 let mut check_token_existence = LazyValue::new(|| false);2674 test(i, row, &mut check_token_existence);2675 }2676 });2677 }2678}