git.delta.rocks / unique-network / refs/commits / 8bbc6aebf29e

difftreelog

Merge pull request #197 from UniqueNetwork/feature/CORE-167

kozyrevdev2021-10-04parents: #511eef6 #854f33e.patch.diff
in: master
Limits logic fixed. Tests added

5 files changed

modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -306,9 +306,6 @@
 		/// Amount of collections destroyed, used for total amount tracking with
 		/// CreatedCollectionCount
 		DestroyedCollectionCount: u32;
-		/// Total amount of account owned tokens (NFTs + RFTs + unique fungibles)
-		/// Account id (real)
-		pub AccountItemCount get(fn account_item_count): map hasher(twox_64_concat) T::AccountId => u32;
 		//#endregion
 
 		//#region Basic collections
@@ -1125,6 +1122,7 @@
 			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
 
 			let collection = Self::get_collection(collection_id)?;
+			Self::meta_update_check(&sender, &collection, item_id)?;
 
 			Self::set_variable_meta_data_internal(&sender, &collection, item_id, data)?;
 
@@ -1647,11 +1645,19 @@
 		collection.consume_sload()?;
 		let account_items: u32 =
 			<AddressTokens<T>>::get(collection_id, recipient.as_sub()).len() as u32;
-		ensure!(
-			collection.limits.account_token_ownership_limit > account_items,
-			Error::<T>::AccountTokenLimitExceeded
-		);
 
+		// zero limit means collection limit is disabled
+		// otherwise get lower value
+		let limit = if collection.limits.account_token_ownership_limit == 0
+			|| collection.limits.account_token_ownership_limit > ACCOUNT_TOKEN_OWNERSHIP_LIMIT
+		{
+			ACCOUNT_TOKEN_OWNERSHIP_LIMIT
+		} else {
+			collection.limits.account_token_ownership_limit
+		};
+
+		ensure!(limit > account_items, Error::<T>::AccountTokenLimitExceeded);
+
 		// preliminary transfer check
 		ensure!(collection.transfers_enabled, Error::<T>::TransferNotAllowed);
 
@@ -1674,12 +1680,23 @@
 			as u32)
 			.checked_add(amount)
 			.ok_or(Error::<T>::AccountTokenLimitExceeded)?;
+
+		// zero limit means collection limit is disabled
+		// otherwise get lower value
+		let account_token_limit = if collection.limits.account_token_ownership_limit == 0
+			|| collection.limits.account_token_ownership_limit > ACCOUNT_TOKEN_OWNERSHIP_LIMIT
+		{
+			ACCOUNT_TOKEN_OWNERSHIP_LIMIT
+		} else {
+			collection.limits.account_token_ownership_limit
+		};
+
 		ensure!(
 			collection.limits.token_limit >= total_items,
 			Error::<T>::CollectionTokenLimitExceeded
 		);
 		ensure!(
-			collection.limits.account_token_ownership_limit >= account_items,
+			account_token_limit >= account_items,
 			Error::<T>::AccountTokenLimitExceeded
 		);
 
@@ -2409,32 +2426,19 @@
 		item_index: TokenId,
 		owner: &T::CrossAccountId,
 	) -> DispatchResult {
-		// add to account limit
 		collection.consume_sload()?;
-		if <AccountItemCount<T>>::contains_key(owner.as_sub()) {
-			// bound Owned tokens by a single address
+		let list_exists = <AddressTokens<T>>::contains_key(collection.id, owner.as_sub());
+		if list_exists {
 			collection.consume_sload()?;
-			let count = <AccountItemCount<T>>::get(owner.as_sub());
+			let mut list = <AddressTokens<T>>::get(collection.id, owner.as_sub());
+
+			// bound Owned tokens by a single address in collection
+			let account_items: u32 = list.len() as u32;
 			ensure!(
-				count < ACCOUNT_TOKEN_OWNERSHIP_LIMIT,
+				account_items < ACCOUNT_TOKEN_OWNERSHIP_LIMIT,
 				Error::<T>::AddressOwnershipLimitExceeded
 			);
 
-			collection.consume_sstore()?;
-			<AccountItemCount<T>>::insert(
-				owner.as_sub(),
-				count.checked_add(1).ok_or(Error::<T>::NumOverflow)?,
-			);
-		} else {
-			collection.consume_sstore()?;
-			<AccountItemCount<T>>::insert(owner.as_sub(), 1);
-		}
-
-		collection.consume_sload()?;
-		let list_exists = <AddressTokens<T>>::contains_key(collection.id, owner.as_sub());
-		if list_exists {
-			collection.consume_sload()?;
-			let mut list = <AddressTokens<T>>::get(collection.id, owner.as_sub());
 			let item_contains = list.contains(&item_index.clone());
 
 			if !item_contains {
@@ -2457,16 +2461,6 @@
 		item_index: TokenId,
 		owner: &T::CrossAccountId,
 	) -> DispatchResult {
-		// update counter
-		collection.consume_sload()?;
-		collection.consume_sstore()?;
-		<AccountItemCount<T>>::insert(
-			owner.as_sub(),
-			<AccountItemCount<T>>::get(owner.as_sub())
-				.checked_sub(1)
-				.ok_or(Error::<T>::NumOverflow)?,
-		);
-
 		collection.consume_sload()?;
 		let list_exists = <AddressTokens<T>>::contains_key(collection.id, owner.as_sub());
 		if list_exists {
modifiedpallets/nft/src/sponsorship.rsdiffbeforeafterboth
--- a/pallets/nft/src/sponsorship.rs
+++ b/pallets/nft/src/sponsorship.rs
@@ -61,10 +61,15 @@
 			sponsor_transfer = match collection_mode {
 				CollectionMode::NFT => {
 					// get correct limit
-					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
-						collection_limits.sponsor_transfer_timeout
+					let limit: u32 = if collection_limits.sponsor_transfer_timeout != 0 {
+						if collection_limits.sponsor_transfer_timeout > NFT_SPONSOR_TRANSFER_TIMEOUT
+						{
+							collection_limits.sponsor_transfer_timeout
+						} else {
+							NFT_SPONSOR_TRANSFER_TIMEOUT
+						}
 					} else {
-						NFT_SPONSOR_TRANSFER_TIMEOUT
+						0
 					};
 
 					let mut sponsored = true;
@@ -83,13 +88,18 @@
 				}
 				CollectionMode::Fungible(_) => {
 					// get correct limit
-					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
-						collection_limits.sponsor_transfer_timeout
+					let limit: u32 = if collection_limits.sponsor_transfer_timeout != 0 {
+						if collection_limits.sponsor_transfer_timeout
+							> FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
+						{
+							collection_limits.sponsor_transfer_timeout
+						} else {
+							FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
+						}
 					} else {
-						FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
+						0
 					};
 
-					let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
 					let mut sponsored = true;
 					if FungibleTransferBasket::<T>::contains_key(collection_id, who) {
 						let last_tx_block = FungibleTransferBasket::<T>::get(collection_id, who);
@@ -106,10 +116,16 @@
 				}
 				CollectionMode::ReFungible => {
 					// get correct limit
-					let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
-						collection_limits.sponsor_transfer_timeout
+					let limit: u32 = if collection_limits.sponsor_transfer_timeout != 0 {
+						if collection_limits.sponsor_transfer_timeout
+							> REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
+						{
+							collection_limits.sponsor_transfer_timeout
+						} else {
+							REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
+						}
 					} else {
-						REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT
+						0
 					};
 
 					let mut sponsored = true;
modifiedpallets/nft/src/tests.rsdiffbeforeafterboth
before · pallets/nft/src/tests.rs
1// Tests to be written here2use super::*;3use crate::mock::*;4use crate::{AccessMode, CollectionMode, Ownership, CreateItemData};5use nft_data_structs::{6	CreateNftData, CreateFungibleData, CreateReFungibleData, CollectionId, TokenId,7	MAX_DECIMAL_POINTS,8};9use frame_support::{assert_noop, assert_ok};10use sp_std::convert::TryInto;1112fn default_nft_data() -> CreateNftData {13	CreateNftData {14		const_data: vec![1, 2, 3].try_into().unwrap(),15		variable_data: vec![3, 2, 1].try_into().unwrap(),16	}17}1819fn default_fungible_data() -> CreateFungibleData {20	CreateFungibleData { value: 5 }21}2223fn default_re_fungible_data() -> CreateReFungibleData {24	CreateReFungibleData {25		const_data: vec![1, 2, 3].try_into().unwrap(),26		variable_data: vec![3, 2, 1].try_into().unwrap(),27		pieces: 1023,28	}29}3031fn create_test_collection_for_owner(32	mode: &CollectionMode,33	owner: u64,34	id: CollectionId,35) -> CollectionId {36	let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();37	let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();38	let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();3940	let origin1 = Origin::signed(owner);41	assert_ok!(TemplateModule::create_collection(42		origin1,43		col_name1,44		col_desc1,45		token_prefix1,46		mode.clone()47	));4849	let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();50	let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();51	let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();52	assert_eq!(TemplateModule::collection_id(id).unwrap().owner, owner);53	assert_eq!(54		TemplateModule::collection_id(id).unwrap().name,55		saved_col_name56	);57	assert_eq!(TemplateModule::collection_id(id).unwrap().mode, *mode);58	assert_eq!(59		TemplateModule::collection_id(id).unwrap().description,60		saved_description61	);62	assert_eq!(63		TemplateModule::collection_id(id).unwrap().token_prefix,64		saved_prefix65	);66	id67}6869fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {70	create_test_collection_for_owner(&mode, 1, id)71}7273fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {74	let origin1 = Origin::signed(1);75	assert_ok!(TemplateModule::create_item(76		origin1,77		collection_id,78		account(1),79		data.clone()80	));81}8283fn account(sub: u64) -> TestCrossAccountId {84	TestCrossAccountId::from_sub(sub)85}8687// Use cases tests region88// #region8990#[test]91fn set_version_schema() {92	new_test_ext().execute_with(|| {93		let origin1 = Origin::signed(1);94		let collection_id = create_test_collection(&CollectionMode::NFT, 1);9596		assert_ok!(TemplateModule::set_schema_version(97			origin1,98			collection_id,99			SchemaVersion::Unique100		));101		assert_eq!(102			TemplateModule::collection_id(collection_id)103				.unwrap()104				.schema_version,105			SchemaVersion::Unique106		);107	});108}109110#[test]111fn create_fungible_collection_fails_with_large_decimal_numbers() {112	new_test_ext().execute_with(|| {113		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();114		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();115		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();116117		let origin1 = Origin::signed(1);118		assert_noop!(119			TemplateModule::create_collection(120				origin1,121				col_name1,122				col_desc1,123				token_prefix1,124				CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1)125			),126			Error::<Test>::CollectionDecimalPointLimitExceeded127		);128	});129}130131#[test]132fn create_nft_item() {133	new_test_ext().execute_with(|| {134		let collection_id = create_test_collection(&CollectionMode::NFT, 1);135136		let data = default_nft_data();137		create_test_item(collection_id, &data.clone().into());138		let item = TemplateModule::nft_item_id(collection_id, 1).unwrap();139		assert_eq!(item.const_data, data.const_data.into_inner());140		assert_eq!(item.variable_data, data.variable_data.into_inner());141	});142}143144// Use cases tests region145// #region146#[test]147fn create_nft_multiple_items() {148	new_test_ext().execute_with(|| {149		create_test_collection(&CollectionMode::NFT, 1);150151		let origin1 = Origin::signed(1);152153		let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];154155		assert_ok!(TemplateModule::create_multiple_items(156			origin1,157			1,158			account(1),159			items_data160				.clone()161				.into_iter()162				.map(|d| { d.into() })163				.collect()164		));165		for (index, data) in items_data.into_iter().enumerate() {166			let item = TemplateModule::nft_item_id(1, (index + 1) as TokenId).unwrap();167			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());168			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());169		}170	});171}172173#[test]174fn create_refungible_item() {175	new_test_ext().execute_with(|| {176		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);177178		let data = default_re_fungible_data();179		create_test_item(collection_id, &data.clone().into());180		let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();181		assert_eq!(item.const_data, data.const_data.into_inner());182		assert_eq!(item.variable_data, data.variable_data.into_inner());183		assert_eq!(184			item.owner[0],185			Ownership {186				owner: account(1),187				fraction: 1023188			}189		);190	});191}192193#[test]194fn create_multiple_refungible_items() {195	new_test_ext().execute_with(|| {196		create_test_collection(&CollectionMode::ReFungible, 1);197198		let origin1 = Origin::signed(1);199200		let items_data = vec![201			default_re_fungible_data(),202			default_re_fungible_data(),203			default_re_fungible_data(),204		];205206		assert_ok!(TemplateModule::create_multiple_items(207			origin1,208			1,209			account(1),210			items_data211				.clone()212				.into_iter()213				.map(|d| { d.into() })214				.collect()215		));216		for (index, data) in items_data.into_iter().enumerate() {217			let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId).unwrap();218			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());219			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());220			assert_eq!(221				item.owner[0],222				Ownership {223					owner: account(1),224					fraction: 1023225				}226			);227		}228	});229}230231#[test]232fn create_fungible_item() {233	new_test_ext().execute_with(|| {234		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);235236		let data = default_fungible_data();237		create_test_item(collection_id, &data.into());238239		assert_eq!(TemplateModule::fungible_item_id(collection_id, 1).value, 5);240	});241}242243//#[test]244// fn create_multiple_fungible_items() {245//     new_test_ext().execute_with(|| {246//         default_limits();247248//         create_test_collection(&CollectionMode::Fungible(3), 1);249250//         let origin1 = Origin::signed(1);251252//         let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];253254//         assert_ok!(TemplateModule::create_multiple_items(255//             origin1.clone(),256//             1,257//             1,258//             items_data.clone().into_iter().map(|d| { d.into() }).collect()259//         ));260261//         for (index, _) in items_data.iter().enumerate() {262//             assert_eq!(TemplateModule::fungible_item_id(1, (index + 1) as TokenId).value, 5);263//         }264//         assert_eq!(TemplateModule::balance_count(1, 1), 3000);265//         assert_eq!(TemplateModule::address_tokens(1, 1), [1, 2, 3]);266//     });267// }268269#[test]270fn transfer_fungible_item() {271	new_test_ext().execute_with(|| {272		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);273274		let origin1 = Origin::signed(1);275		let origin2 = Origin::signed(2);276277		let data = default_fungible_data();278		create_test_item(collection_id, &data.into());279280		assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 5);281		assert_eq!(TemplateModule::balance_count(1, 1), 5);282283		// change owner scenario284		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 5));285		assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 0);286		assert_eq!(TemplateModule::balance_count(1, 1), 0);287		assert_eq!(TemplateModule::balance_count(1, 2), 5);288289		// split item scenario290		assert_ok!(TemplateModule::transfer(291			origin2.clone(),292			account(3),293			1,294			1,295			3296		));297		assert_eq!(TemplateModule::balance_count(1, 2), 2);298		assert_eq!(TemplateModule::balance_count(1, 3), 3);299300		// split item and new owner has account scenario301		assert_ok!(TemplateModule::transfer(origin2, account(3), 1, 1, 1));302		assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 1);303		assert_eq!(TemplateModule::fungible_item_id(1, 3).value, 4);304		assert_eq!(TemplateModule::balance_count(1, 2), 1);305		assert_eq!(TemplateModule::balance_count(1, 3), 4);306	});307}308309#[test]310fn transfer_refungible_item() {311	new_test_ext().execute_with(|| {312		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);313314		let data = default_re_fungible_data();315		create_test_item(collection_id, &data.clone().into());316317		let origin1 = Origin::signed(1);318		let origin2 = Origin::signed(2);319		{320			let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();321			assert_eq!(item.const_data, data.const_data.into_inner());322			assert_eq!(item.variable_data, data.variable_data.into_inner());323			assert_eq!(324				item.owner[0],325				Ownership {326					owner: account(1),327					fraction: 1023328				}329			);330		}331		assert_eq!(TemplateModule::balance_count(1, 1), 1023);332		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);333334		// change owner scenario335		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1023));336		assert_eq!(337			TemplateModule::refungible_item_id(1, 1).unwrap().owner[0],338			Ownership {339				owner: account(2),340				fraction: 1023341			}342		);343		assert_eq!(TemplateModule::balance_count(1, 1), 0);344		assert_eq!(TemplateModule::balance_count(1, 2), 1023);345		// assert_eq!(TemplateModule::address_tokens(1, 1), []);346		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);347348		// split item scenario349		assert_ok!(TemplateModule::transfer(350			origin2.clone(),351			account(3),352			1,353			1,354			500355		));356		{357			let item = TemplateModule::refungible_item_id(1, 1).unwrap();358			assert_eq!(359				item.owner[0],360				Ownership {361					owner: account(2),362					fraction: 523363				}364			);365			assert_eq!(366				item.owner[1],367				Ownership {368					owner: account(3),369					fraction: 500370				}371			);372		}373		assert_eq!(TemplateModule::balance_count(1, 2), 523);374		assert_eq!(TemplateModule::balance_count(1, 3), 500);375		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);376		assert_eq!(TemplateModule::address_tokens(1, 3), [1]);377378		// split item and new owner has account scenario379		assert_ok!(TemplateModule::transfer(origin2, account(3), 1, 1, 200));380		{381			let item = TemplateModule::refungible_item_id(1, 1).unwrap();382			assert_eq!(383				item.owner[0],384				Ownership {385					owner: account(2),386					fraction: 323387				}388			);389			assert_eq!(390				item.owner[1],391				Ownership {392					owner: account(3),393					fraction: 700394				}395			);396		}397		assert_eq!(TemplateModule::balance_count(1, 2), 323);398		assert_eq!(TemplateModule::balance_count(1, 3), 700);399		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);400		assert_eq!(TemplateModule::address_tokens(1, 3), [1]);401	});402}403404#[test]405fn transfer_nft_item() {406	new_test_ext().execute_with(|| {407		let collection_id = create_test_collection(&CollectionMode::NFT, 1);408409		let data = default_nft_data();410		create_test_item(collection_id, &data.into());411		assert_eq!(TemplateModule::balance_count(1, 1), 1);412		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);413414		let origin1 = Origin::signed(1);415		// default scenario416		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));417		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));418		assert_eq!(TemplateModule::balance_count(1, 1), 0);419		assert_eq!(TemplateModule::balance_count(1, 2), 1);420		// assert_eq!(TemplateModule::address_tokens(1, 1), []);421		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);422	});423}424425#[test]426fn nft_approve_and_transfer_from() {427	new_test_ext().execute_with(|| {428		let collection_id = create_test_collection(&CollectionMode::NFT, 1);429430		let data = default_nft_data();431		create_test_item(collection_id, &data.into());432433		let origin1 = Origin::signed(1);434		let origin2 = Origin::signed(2);435436		assert_eq!(TemplateModule::balance_count(1, 1), 1);437		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);438439		// neg transfer440		assert_noop!(441			TemplateModule::transfer_from(origin2.clone(), account(1), account(2), 1, 1, 1),442			Error::<Test>::NoPermission443		);444445		// do approve446		assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 5));447		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);448		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);449450		assert_ok!(TemplateModule::transfer_from(451			origin2,452			account(1),453			account(3),454			1,455			1,456			1457		));458		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);459	});460}461462#[test]463fn nft_approve_and_transfer_from_white_list() {464	new_test_ext().execute_with(|| {465		let collection_id = create_test_collection(&CollectionMode::NFT, 1);466467		let origin1 = Origin::signed(1);468		let origin2 = Origin::signed(2);469470		let data = default_nft_data();471		create_test_item(collection_id, &data.clone().into());472473		assert_eq!(474			&TemplateModule::nft_item_id(1, 1).unwrap().const_data,475			&data.const_data.into_inner()476		);477		assert_eq!(TemplateModule::balance_count(1, 1), 1);478		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);479480		assert_ok!(TemplateModule::set_mint_permission(481			origin1.clone(),482			1,483			true484		));485		assert_ok!(TemplateModule::set_public_access_mode(486			origin1.clone(),487			1,488			AccessMode::WhiteList489		));490		assert_ok!(TemplateModule::add_to_white_list(491			origin1.clone(),492			1,493			account(1)494		));495		assert_ok!(TemplateModule::add_to_white_list(496			origin1.clone(),497			1,498			account(2)499		));500		assert_ok!(TemplateModule::add_to_white_list(501			origin1.clone(),502			1,503			account(3)504		));505506		// do approve507		assert_ok!(TemplateModule::approve(508			origin1.clone(),509			account(2),510			1,511			1,512			5513		));514		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);515		assert_ok!(TemplateModule::approve(origin1, account(3), 1, 1, 5));516		assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);517518		assert_ok!(TemplateModule::transfer_from(519			origin2,520			account(1),521			account(3),522			1,523			1,524			1525		));526		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);527	});528}529530#[test]531fn refungible_approve_and_transfer_from() {532	new_test_ext().execute_with(|| {533		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);534535		let origin1 = Origin::signed(1);536		let origin2 = Origin::signed(2);537538		let data = default_re_fungible_data();539		create_test_item(collection_id, &data.into());540541		assert_eq!(TemplateModule::balance_count(1, 1), 1023);542		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);543544		assert_ok!(TemplateModule::set_mint_permission(545			origin1.clone(),546			1,547			true548		));549		assert_ok!(TemplateModule::set_public_access_mode(550			origin1.clone(),551			1,552			AccessMode::WhiteList553		));554		assert_ok!(TemplateModule::add_to_white_list(555			origin1.clone(),556			1,557			account(1)558		));559		assert_ok!(TemplateModule::add_to_white_list(560			origin1.clone(),561			1,562			account(2)563		));564		assert_ok!(TemplateModule::add_to_white_list(565			origin1.clone(),566			1,567			account(3)568		));569570		// do approve571		assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 1023));572		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1023);573574		assert_ok!(TemplateModule::transfer_from(575			origin2,576			account(1),577			account(3),578			1,579			1,580			100581		));582		assert_eq!(TemplateModule::balance_count(1, 1), 923);583		assert_eq!(TemplateModule::balance_count(1, 3), 100);584		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);585		assert_eq!(TemplateModule::address_tokens(1, 3), [1]);586587		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 923);588	});589}590591#[test]592fn fungible_approve_and_transfer_from() {593	new_test_ext().execute_with(|| {594		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);595596		let data = default_fungible_data();597		create_test_item(collection_id, &data.into());598599		let origin1 = Origin::signed(1);600		let origin2 = Origin::signed(2);601602		assert_eq!(TemplateModule::balance_count(1, 1), 5);603604		assert_ok!(TemplateModule::set_mint_permission(605			origin1.clone(),606			1,607			true608		));609		assert_ok!(TemplateModule::set_public_access_mode(610			origin1.clone(),611			1,612			AccessMode::WhiteList613		));614		assert_ok!(TemplateModule::add_to_white_list(615			origin1.clone(),616			1,617			account(1)618		));619		assert_ok!(TemplateModule::add_to_white_list(620			origin1.clone(),621			1,622			account(2)623		));624		assert_ok!(TemplateModule::add_to_white_list(625			origin1.clone(),626			1,627			account(3)628		));629630		// do approve631		assert_ok!(TemplateModule::approve(632			origin1.clone(),633			account(2),634			1,635			1,636			5637		));638		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);639		assert_ok!(TemplateModule::approve(origin1, account(3), 1, 1, 5));640		assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);641		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);642643		assert_ok!(TemplateModule::transfer_from(644			origin2.clone(),645			account(1),646			account(3),647			1,648			1,649			4650		));651		assert_eq!(TemplateModule::balance_count(1, 1), 1);652		assert_eq!(TemplateModule::balance_count(1, 3), 4);653654		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);655656		assert_noop!(657			TemplateModule::transfer_from(origin2, account(1), account(3), 1, 1, 4),658			Error::<Test>::NoPermission659		);660	});661}662663#[test]664fn change_collection_owner() {665	new_test_ext().execute_with(|| {666		let collection_id = create_test_collection(&CollectionMode::NFT, 1);667668		let origin1 = Origin::signed(1);669		assert_ok!(TemplateModule::change_collection_owner(670			origin1,671			collection_id,672			2673		));674		assert_eq!(675			TemplateModule::collection_id(collection_id).unwrap().owner,676			2677		);678	});679}680681#[test]682fn destroy_collection() {683	new_test_ext().execute_with(|| {684		let collection_id = create_test_collection(&CollectionMode::NFT, 1);685686		let origin1 = Origin::signed(1);687		assert_ok!(TemplateModule::destroy_collection(origin1, collection_id));688	});689}690691#[test]692fn burn_nft_item() {693	new_test_ext().execute_with(|| {694		let collection_id = create_test_collection(&CollectionMode::NFT, 1);695696		let origin1 = Origin::signed(1);697		assert_ok!(TemplateModule::add_collection_admin(698			origin1.clone(),699			collection_id,700			account(2)701		));702703		let data = default_nft_data();704		create_test_item(collection_id, &data.into());705706		// check balance (collection with id = 1, user id = 1)707		assert_eq!(TemplateModule::balance_count(1, 1), 1);708709		// burn item710		assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));711		assert_noop!(712			TemplateModule::burn_item(origin1, 1, 1, 5),713			Error::<Test>::TokenNotFound714		);715716		assert_eq!(TemplateModule::balance_count(1, 1), 0);717	});718}719720#[test]721fn burn_fungible_item() {722	new_test_ext().execute_with(|| {723		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);724725		let origin1 = Origin::signed(1);726		assert_ok!(TemplateModule::add_collection_admin(727			origin1.clone(),728			collection_id,729			account(2)730		));731732		let data = default_fungible_data();733		create_test_item(collection_id, &data.into());734735		// check balance (collection with id = 1, user id = 1)736		assert_eq!(TemplateModule::balance_count(1, 1), 5);737738		// burn item739		assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));740		assert_noop!(741			TemplateModule::burn_item(origin1, 1, 1, 5),742			Error::<Test>::TokenValueNotEnough743		);744745		assert_eq!(TemplateModule::balance_count(1, 1), 0);746	});747}748749#[test]750fn burn_refungible_item() {751	new_test_ext().execute_with(|| {752		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);753		let origin1 = Origin::signed(1);754755		assert_ok!(TemplateModule::set_mint_permission(756			origin1.clone(),757			collection_id,758			true759		));760		assert_ok!(TemplateModule::set_public_access_mode(761			origin1.clone(),762			collection_id,763			AccessMode::WhiteList764		));765		assert_ok!(TemplateModule::add_to_white_list(766			origin1.clone(),767			1,768			account(1)769		));770771		assert_ok!(TemplateModule::add_collection_admin(772			origin1.clone(),773			1,774			account(2)775		));776777		let data = default_re_fungible_data();778		create_test_item(collection_id, &data.into());779780		// check balance (collection with id = 1, user id = 2)781		assert_eq!(TemplateModule::balance_count(1, 1), 1023);782783		// burn item784		assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 1023));785		assert_noop!(786			TemplateModule::burn_item(origin1, 1, 1, 1023),787			Error::<Test>::TokenNotFound788		);789790		assert_eq!(TemplateModule::balance_count(1, 1), 0);791	});792}793794#[test]795fn add_collection_admin() {796	new_test_ext().execute_with(|| {797		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);798		create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);799		create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);800801		let origin1 = Origin::signed(1);802803		// collection admin804		assert_ok!(TemplateModule::add_collection_admin(805			origin1.clone(),806			collection1_id,807			account(2)808		));809		assert_ok!(TemplateModule::add_collection_admin(810			origin1,811			collection1_id,812			account(3)813		));814815		assert!(TemplateModule::admin_list_collection(collection1_id).contains(&account(2)),);816		assert!(TemplateModule::admin_list_collection(collection1_id).contains(&account(3)),);817	});818}819820#[test]821fn remove_collection_admin() {822	new_test_ext().execute_with(|| {823		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);824		create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);825		create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);826827		let origin1 = Origin::signed(1);828		let origin2 = Origin::signed(2);829830		// collection admin831		assert_ok!(TemplateModule::add_collection_admin(832			origin1.clone(),833			collection1_id,834			account(2)835		));836		assert_ok!(TemplateModule::add_collection_admin(837			origin1,838			collection1_id,839			account(3)840		));841842		assert!(TemplateModule::admin_list_collection(1).contains(&account(2)),);843		assert!(TemplateModule::admin_list_collection(1).contains(&account(3)),);844845		// remove admin846		assert_ok!(TemplateModule::remove_collection_admin(847			origin2,848			1,849			account(3)850		));851		assert!(!TemplateModule::admin_list_collection(1).contains(&account(3)),);852	});853}854855#[test]856fn balance_of() {857	new_test_ext().execute_with(|| {858		let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);859		let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);860		let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible, 3);861862		// check balance before863		assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);864		assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);865		assert_eq!(866			TemplateModule::balance_count(re_fungible_collection_id, 1),867			0868		);869870		let nft_data = default_nft_data();871		create_test_item(nft_collection_id, &nft_data.into());872873		let fungible_data = default_fungible_data();874		create_test_item(fungible_collection_id, &fungible_data.into());875876		let re_fungible_data = default_re_fungible_data();877		create_test_item(re_fungible_collection_id, &re_fungible_data.into());878879		// check balance (collection with id = 1, user id = 1)880		assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1);881		assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 5);882		assert_eq!(883			TemplateModule::balance_count(re_fungible_collection_id, 1),884			1023885		);886		assert_eq!(887			TemplateModule::nft_item_id(nft_collection_id, 1)888				.unwrap()889				.owner,890			account(1)891		);892		assert_eq!(893			TemplateModule::fungible_item_id(fungible_collection_id, 1).value,894			5895		);896		assert_eq!(897			TemplateModule::refungible_item_id(re_fungible_collection_id, 1)898				.unwrap()899				.owner[0]900				.owner,901			account(1)902		);903	});904}905906#[test]907fn approve() {908	new_test_ext().execute_with(|| {909		let collection_id = create_test_collection(&CollectionMode::NFT, 1);910911		let data = default_nft_data();912		create_test_item(collection_id, &data.into());913914		let origin1 = Origin::signed(1);915916		// approve917		assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 1));918		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);919	});920}921922#[test]923fn transfer_from() {924	new_test_ext().execute_with(|| {925		let collection_id = create_test_collection(&CollectionMode::NFT, 1);926		let origin1 = Origin::signed(1);927		let origin2 = Origin::signed(2);928929		let data = default_nft_data();930		create_test_item(collection_id, &data.into());931932		// approve933		assert_ok!(TemplateModule::approve(934			origin1.clone(),935			account(2),936			1,937			1,938			1939		));940		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);941942		assert_ok!(TemplateModule::set_mint_permission(943			origin1.clone(),944			1,945			true946		));947		assert_ok!(TemplateModule::set_public_access_mode(948			origin1.clone(),949			1,950			AccessMode::WhiteList951		));952		assert_ok!(TemplateModule::add_to_white_list(953			origin1.clone(),954			1,955			account(1)956		));957		assert_ok!(TemplateModule::add_to_white_list(958			origin1.clone(),959			1,960			account(2)961		));962		assert_ok!(TemplateModule::add_to_white_list(origin1, 1, account(3)));963964		assert_ok!(TemplateModule::transfer_from(965			origin2,966			account(1),967			account(2),968			1,969			1,970			1971		));972973		// after transfer974		assert_eq!(TemplateModule::balance_count(1, 1), 0);975		assert_eq!(TemplateModule::balance_count(1, 2), 1);976	});977}978979// #endregion980981// Coverage tests region982// #region983984#[test]985fn owner_can_add_address_to_white_list() {986	new_test_ext().execute_with(|| {987		let collection_id = create_test_collection(&CollectionMode::NFT, 1);988989		let origin1 = Origin::signed(1);990		assert_ok!(TemplateModule::add_to_white_list(991			origin1,992			collection_id,993			account(2)994		));995		assert!(TemplateModule::white_list(collection_id, 2));996	});997}998999#[test]1000fn admin_can_add_address_to_white_list() {1001	new_test_ext().execute_with(|| {1002		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1003		let origin1 = Origin::signed(1);1004		let origin2 = Origin::signed(2);10051006		assert_ok!(TemplateModule::add_collection_admin(1007			origin1,1008			collection_id,1009			account(2)1010		));1011		assert_ok!(TemplateModule::add_to_white_list(1012			origin2,1013			collection_id,1014			account(3)1015		));1016		assert!(TemplateModule::white_list(collection_id, 3));1017	});1018}10191020#[test]1021fn nonprivileged_user_cannot_add_address_to_white_list() {1022	new_test_ext().execute_with(|| {1023		let collection_id = create_test_collection(&CollectionMode::NFT, 1);10241025		let origin2 = Origin::signed(2);1026		assert_noop!(1027			TemplateModule::add_to_white_list(origin2, collection_id, account(3)),1028			Error::<Test>::NoPermission1029		);1030	});1031}10321033#[test]1034fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {1035	new_test_ext().execute_with(|| {1036		let origin1 = Origin::signed(1);10371038		assert_noop!(1039			TemplateModule::add_to_white_list(origin1, 1, account(2)),1040			Error::<Test>::CollectionNotFound1041		);1042	});1043}10441045#[test]1046fn nobody_can_add_address_to_white_list_of_deleted_collection() {1047	new_test_ext().execute_with(|| {1048		let collection_id = create_test_collection(&CollectionMode::NFT, 1);10491050		let origin1 = Origin::signed(1);1051		assert_ok!(TemplateModule::destroy_collection(1052			origin1.clone(),1053			collection_id1054		));1055		assert_noop!(1056			TemplateModule::add_to_white_list(origin1, collection_id, account(2)),1057			Error::<Test>::CollectionNotFound1058		);1059	});1060}10611062// If address is already added to white list, nothing happens1063#[test]1064fn address_is_already_added_to_white_list() {1065	new_test_ext().execute_with(|| {1066		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1067		let origin1 = Origin::signed(1);10681069		assert_ok!(TemplateModule::add_to_white_list(1070			origin1.clone(),1071			collection_id,1072			account(2)1073		));1074		assert_ok!(TemplateModule::add_to_white_list(1075			origin1,1076			collection_id,1077			account(2)1078		));1079		assert!(TemplateModule::white_list(collection_id, 2));1080	});1081}10821083#[test]1084fn owner_can_remove_address_from_white_list() {1085	new_test_ext().execute_with(|| {1086		let collection_id = create_test_collection(&CollectionMode::NFT, 1);10871088		let origin1 = Origin::signed(1);1089		assert_ok!(TemplateModule::add_to_white_list(1090			origin1.clone(),1091			collection_id,1092			account(2)1093		));1094		assert_ok!(TemplateModule::remove_from_white_list(1095			origin1,1096			collection_id,1097			account(2)1098		));1099		assert!(!TemplateModule::white_list(collection_id, 2));1100	});1101}11021103#[test]1104fn admin_can_remove_address_from_white_list() {1105	new_test_ext().execute_with(|| {1106		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1107		let origin1 = Origin::signed(1);1108		let origin2 = Origin::signed(2);11091110		assert_ok!(TemplateModule::add_collection_admin(1111			origin1.clone(),1112			collection_id,1113			account(2)1114		));11151116		assert_ok!(TemplateModule::add_to_white_list(1117			origin1,1118			collection_id,1119			account(3)1120		));1121		assert_ok!(TemplateModule::remove_from_white_list(1122			origin2,1123			collection_id,1124			account(3)1125		));1126		assert!(!TemplateModule::white_list(collection_id, 3));1127	});1128}11291130#[test]1131fn nonprivileged_user_cannot_remove_address_from_white_list() {1132	new_test_ext().execute_with(|| {1133		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1134		let origin1 = Origin::signed(1);1135		let origin2 = Origin::signed(2);11361137		assert_ok!(TemplateModule::add_to_white_list(1138			origin1,1139			collection_id,1140			account(2)1141		));1142		assert_noop!(1143			TemplateModule::remove_from_white_list(origin2, collection_id, account(2)),1144			Error::<Test>::NoPermission1145		);1146		assert!(TemplateModule::white_list(collection_id, 2));1147	});1148}11491150#[test]1151fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1152	new_test_ext().execute_with(|| {1153		let origin1 = Origin::signed(1);11541155		assert_noop!(1156			TemplateModule::remove_from_white_list(origin1, 1, account(2)),1157			Error::<Test>::CollectionNotFound1158		);1159	});1160}11611162#[test]1163fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1164	new_test_ext().execute_with(|| {1165		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1166		let origin1 = Origin::signed(1);1167		let origin2 = Origin::signed(2);11681169		assert_ok!(TemplateModule::add_to_white_list(1170			origin1.clone(),1171			collection_id,1172			account(2)1173		));1174		assert_ok!(TemplateModule::destroy_collection(origin1, collection_id));1175		assert_noop!(1176			TemplateModule::remove_from_white_list(origin2, collection_id, account(2)),1177			Error::<Test>::CollectionNotFound1178		);1179		assert!(!TemplateModule::white_list(collection_id, 2));1180	});1181}11821183// If address is already removed from white list, nothing happens1184#[test]1185fn address_is_already_removed_from_white_list() {1186	new_test_ext().execute_with(|| {1187		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1188		let origin1 = Origin::signed(1);11891190		assert_ok!(TemplateModule::add_to_white_list(1191			origin1.clone(),1192			collection_id,1193			account(2)1194		));1195		assert_ok!(TemplateModule::remove_from_white_list(1196			origin1.clone(),1197			collection_id,1198			account(2)1199		));1200		assert_ok!(TemplateModule::remove_from_white_list(1201			origin1,1202			collection_id,1203			account(2)1204		));1205		assert!(!TemplateModule::white_list(collection_id, 2));1206	});1207}12081209// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1210#[test]1211fn white_list_test_1() {1212	new_test_ext().execute_with(|| {1213		let collection_id = create_test_collection(&CollectionMode::NFT, 1);12141215		let origin1 = Origin::signed(1);12161217		let data = default_nft_data();1218		create_test_item(collection_id, &data.into());12191220		assert_ok!(TemplateModule::set_public_access_mode(1221			origin1.clone(),1222			collection_id,1223			AccessMode::WhiteList1224		));1225		assert_ok!(TemplateModule::add_to_white_list(1226			origin1.clone(),1227			collection_id,1228			account(2)1229		));12301231		assert_noop!(1232			TemplateModule::transfer(origin1, account(3), 1, 1, 1),1233			Error::<Test>::AddresNotInWhiteList1234		);1235	});1236}12371238#[test]1239fn white_list_test_2() {1240	new_test_ext().execute_with(|| {1241		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1242		let origin1 = Origin::signed(1);12431244		let data = default_nft_data();1245		create_test_item(collection_id, &data.into());12461247		assert_ok!(TemplateModule::set_public_access_mode(1248			origin1.clone(),1249			collection_id,1250			AccessMode::WhiteList1251		));1252		assert_ok!(TemplateModule::add_to_white_list(1253			origin1.clone(),1254			1,1255			account(1)1256		));1257		assert_ok!(TemplateModule::add_to_white_list(1258			origin1.clone(),1259			1,1260			account(2)1261		));12621263		// do approve1264		assert_ok!(TemplateModule::approve(1265			origin1.clone(),1266			account(1),1267			1,1268			1,1269			11270		));1271		assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);12721273		assert_ok!(TemplateModule::remove_from_white_list(1274			origin1.clone(),1275			1,1276			account(1)1277		));12781279		assert_noop!(1280			TemplateModule::transfer_from(origin1, account(1), account(3), 1, 1, 1),1281			Error::<Test>::AddresNotInWhiteList1282		);1283	});1284}12851286// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1287#[test]1288fn white_list_test_3() {1289	new_test_ext().execute_with(|| {1290		let collection_id = create_test_collection(&CollectionMode::NFT, 1);12911292		let origin1 = Origin::signed(1);12931294		let data = default_nft_data();1295		create_test_item(collection_id, &data.into());12961297		assert_ok!(TemplateModule::set_public_access_mode(1298			origin1.clone(),1299			collection_id,1300			AccessMode::WhiteList1301		));1302		assert_ok!(TemplateModule::add_to_white_list(1303			origin1.clone(),1304			1,1305			account(1)1306		));13071308		assert_noop!(1309			TemplateModule::transfer(origin1, account(3), 1, 1, 1),1310			Error::<Test>::AddresNotInWhiteList1311		);1312	});1313}13141315#[test]1316fn white_list_test_4() {1317	new_test_ext().execute_with(|| {1318		let collection_id = create_test_collection(&CollectionMode::NFT, 1);13191320		let origin1 = Origin::signed(1);13211322		let data = default_nft_data();1323		create_test_item(collection_id, &data.into());13241325		assert_ok!(TemplateModule::set_public_access_mode(1326			origin1.clone(),1327			collection_id,1328			AccessMode::WhiteList1329		));1330		assert_ok!(TemplateModule::add_to_white_list(1331			origin1.clone(),1332			collection_id,1333			account(1)1334		));1335		assert_ok!(TemplateModule::add_to_white_list(1336			origin1.clone(),1337			collection_id,1338			account(2)1339		));13401341		// do approve1342		assert_ok!(TemplateModule::approve(1343			origin1.clone(),1344			account(1),1345			1,1346			1,1347			11348		));1349		assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);13501351		assert_ok!(TemplateModule::remove_from_white_list(1352			origin1.clone(),1353			collection_id,1354			account(2)1355		));13561357		assert_noop!(1358			TemplateModule::transfer_from(origin1, account(1), account(3), 1, 1, 1),1359			Error::<Test>::AddresNotInWhiteList1360		);1361	});1362}13631364// If Public Access mode is set to WhiteList, tokens can’t be destroyed by a non-whitelisted address (even if it owned them before enabling WhiteList mode)1365#[test]1366fn white_list_test_5() {1367	new_test_ext().execute_with(|| {1368		let collection_id = create_test_collection(&CollectionMode::NFT, 1);13691370		let origin1 = Origin::signed(1);13711372		let data = default_nft_data();1373		create_test_item(collection_id, &data.into());13741375		assert_ok!(TemplateModule::set_public_access_mode(1376			origin1.clone(),1377			collection_id,1378			AccessMode::WhiteList1379		));1380		assert_noop!(1381			TemplateModule::burn_item(origin1, 1, 1, 5),1382			Error::<Test>::AddresNotInWhiteList1383		);1384	});1385}13861387// If Public Access mode is set to WhiteList, token transfers can’t be Approved by a non-whitelisted address (see Approve method).1388#[test]1389fn white_list_test_6() {1390	new_test_ext().execute_with(|| {1391		let collection_id = create_test_collection(&CollectionMode::NFT, 1);13921393		let origin1 = Origin::signed(1);13941395		let data = default_nft_data();1396		create_test_item(collection_id, &data.into());13971398		assert_ok!(TemplateModule::set_public_access_mode(1399			origin1.clone(),1400			collection_id,1401			AccessMode::WhiteList1402		));14031404		// do approve1405		assert_noop!(1406			TemplateModule::approve(origin1, account(1), 1, 1, 5),1407			Error::<Test>::AddresNotInWhiteList1408		);1409	});1410}14111412// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1413//          tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1414#[test]1415fn white_list_test_7() {1416	new_test_ext().execute_with(|| {1417		let collection_id = create_test_collection(&CollectionMode::NFT, 1);14181419		let data = default_nft_data();1420		create_test_item(collection_id, &data.into());14211422		let origin1 = Origin::signed(1);14231424		assert_ok!(TemplateModule::set_public_access_mode(1425			origin1.clone(),1426			collection_id,1427			AccessMode::WhiteList1428		));1429		assert_ok!(TemplateModule::add_to_white_list(1430			origin1.clone(),1431			collection_id,1432			account(1)1433		));1434		assert_ok!(TemplateModule::add_to_white_list(1435			origin1.clone(),1436			collection_id,1437			account(2)1438		));14391440		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1));1441	});1442}14431444#[test]1445fn white_list_test_8() {1446	new_test_ext().execute_with(|| {1447		let collection_id = create_test_collection(&CollectionMode::NFT, 1);14481449		let data = default_nft_data();1450		create_test_item(collection_id, &data.into());14511452		let origin1 = Origin::signed(1);14531454		assert_ok!(TemplateModule::set_public_access_mode(1455			origin1.clone(),1456			collection_id,1457			AccessMode::WhiteList1458		));1459		assert_ok!(TemplateModule::add_to_white_list(1460			origin1.clone(),1461			collection_id,1462			account(1)1463		));1464		assert_ok!(TemplateModule::add_to_white_list(1465			origin1.clone(),1466			collection_id,1467			account(2)1468		));14691470		// do approve1471		assert_ok!(TemplateModule::approve(1472			origin1.clone(),1473			account(1),1474			1,1475			1,1476			51477		));1478		assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 5);14791480		assert_ok!(TemplateModule::transfer_from(1481			origin1,1482			account(1),1483			account(2),1484			1,1485			1,1486			11487		));1488	});1489}14901491// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1492#[test]1493fn white_list_test_9() {1494	new_test_ext().execute_with(|| {1495		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1496		let origin1 = Origin::signed(1);14971498		assert_ok!(TemplateModule::set_public_access_mode(1499			origin1.clone(),1500			collection_id,1501			AccessMode::WhiteList1502		));1503		assert_ok!(TemplateModule::set_mint_permission(1504			origin1,1505			collection_id,1506			false1507		));15081509		let data = default_nft_data();1510		create_test_item(collection_id, &data.into());1511	});1512}15131514// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1515#[test]1516fn white_list_test_10() {1517	new_test_ext().execute_with(|| {1518		let collection_id = create_test_collection(&CollectionMode::NFT, 1);15191520		let origin1 = Origin::signed(1);1521		let origin2 = Origin::signed(2);15221523		assert_ok!(TemplateModule::set_public_access_mode(1524			origin1.clone(),1525			collection_id,1526			AccessMode::WhiteList1527		));1528		assert_ok!(TemplateModule::set_mint_permission(1529			origin1.clone(),1530			collection_id,1531			false1532		));15331534		assert_ok!(TemplateModule::add_collection_admin(1535			origin1,1536			collection_id,1537			account(2)1538		));15391540		assert_ok!(TemplateModule::create_item(1541			origin2,1542			collection_id,1543			account(2),1544			default_nft_data().into()1545		));1546	});1547}15481549// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and white listed address.1550#[test]1551fn white_list_test_11() {1552	new_test_ext().execute_with(|| {1553		let collection_id = create_test_collection(&CollectionMode::NFT, 1);15541555		let origin1 = Origin::signed(1);1556		let origin2 = Origin::signed(2);15571558		assert_ok!(TemplateModule::set_public_access_mode(1559			origin1.clone(),1560			collection_id,1561			AccessMode::WhiteList1562		));1563		assert_ok!(TemplateModule::set_mint_permission(1564			origin1.clone(),1565			collection_id,1566			false1567		));1568		assert_ok!(TemplateModule::add_to_white_list(1569			origin1,1570			collection_id,1571			account(2)1572		));15731574		assert_noop!(1575			TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),1576			Error::<Test>::PublicMintingNotAllowed1577		);1578	});1579}15801581// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-white listed address.1582#[test]1583fn white_list_test_12() {1584	new_test_ext().execute_with(|| {1585		let collection_id = create_test_collection(&CollectionMode::NFT, 1);15861587		let origin1 = Origin::signed(1);1588		let origin2 = Origin::signed(2);15891590		assert_ok!(TemplateModule::set_public_access_mode(1591			origin1.clone(),1592			collection_id,1593			AccessMode::WhiteList1594		));1595		assert_ok!(TemplateModule::set_mint_permission(1596			origin1,1597			collection_id,1598			false1599		));16001601		assert_noop!(1602			TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),1603			Error::<Test>::PublicMintingNotAllowed1604		);1605	});1606}16071608// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1609#[test]1610fn white_list_test_13() {1611	new_test_ext().execute_with(|| {1612		let collection_id = create_test_collection(&CollectionMode::NFT, 1);16131614		let origin1 = Origin::signed(1);16151616		assert_ok!(TemplateModule::set_public_access_mode(1617			origin1.clone(),1618			collection_id,1619			AccessMode::WhiteList1620		));1621		assert_ok!(TemplateModule::set_mint_permission(1622			origin1,1623			collection_id,1624			true1625		));16261627		let data = default_nft_data();1628		create_test_item(collection_id, &data.into());1629	});1630}16311632// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1633#[test]1634fn white_list_test_14() {1635	new_test_ext().execute_with(|| {1636		let collection_id = create_test_collection(&CollectionMode::NFT, 1);16371638		let origin1 = Origin::signed(1);1639		let origin2 = Origin::signed(2);16401641		assert_ok!(TemplateModule::set_public_access_mode(1642			origin1.clone(),1643			collection_id,1644			AccessMode::WhiteList1645		));1646		assert_ok!(TemplateModule::set_mint_permission(1647			origin1.clone(),1648			collection_id,1649			true1650		));16511652		assert_ok!(TemplateModule::add_collection_admin(1653			origin1,1654			collection_id,1655			account(2)1656		));16571658		assert_ok!(TemplateModule::create_item(1659			origin2,1660			1,1661			account(2),1662			default_nft_data().into()1663		));1664	});1665}16661667// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-white listed address.1668#[test]1669fn white_list_test_15() {1670	new_test_ext().execute_with(|| {1671		let collection_id = create_test_collection(&CollectionMode::NFT, 1);16721673		let origin1 = Origin::signed(1);1674		let origin2 = Origin::signed(2);16751676		assert_ok!(TemplateModule::set_public_access_mode(1677			origin1.clone(),1678			collection_id,1679			AccessMode::WhiteList1680		));1681		assert_ok!(TemplateModule::set_mint_permission(1682			origin1,1683			collection_id,1684			true1685		));16861687		assert_noop!(1688			TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),1689			Error::<Test>::AddresNotInWhiteList1690		);1691	});1692}16931694// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by non-privileged and white listed address.1695#[test]1696fn white_list_test_16() {1697	new_test_ext().execute_with(|| {1698		let collection_id = create_test_collection(&CollectionMode::NFT, 1);16991700		let origin1 = Origin::signed(1);1701		let origin2 = Origin::signed(2);17021703		assert_ok!(TemplateModule::set_public_access_mode(1704			origin1.clone(),1705			collection_id,1706			AccessMode::WhiteList1707		));1708		assert_ok!(TemplateModule::set_mint_permission(1709			origin1.clone(),1710			collection_id,1711			true1712		));1713		assert_ok!(TemplateModule::add_to_white_list(1714			origin1,1715			collection_id,1716			account(2)1717		));17181719		assert_ok!(TemplateModule::create_item(1720			origin2,1721			1,1722			account(2),1723			default_nft_data().into()1724		));1725	});1726}17271728// Total number of collections. Positive test1729#[test]1730fn total_number_collections_bound() {1731	new_test_ext().execute_with(|| {1732		create_test_collection(&CollectionMode::NFT, 1);1733	});1734}17351736// Total number of collections. Negotive test1737#[test]1738fn total_number_collections_bound_neg() {1739	new_test_ext().execute_with(|| {1740		let origin1 = Origin::signed(1);17411742		for i in 0..COLLECTION_NUMBER_LIMIT {1743			create_test_collection(&CollectionMode::NFT, i + 1);1744		}17451746		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1747		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1748		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();17491750		// 11-th collection in chain. Expects error1751		assert_noop!(1752			TemplateModule::create_collection(1753				origin1,1754				col_name1,1755				col_desc1,1756				token_prefix1,1757				CollectionMode::NFT1758			),1759			Error::<Test>::TotalCollectionsLimitExceeded1760		);1761	});1762}17631764// Owned tokens by a single address. Positive test1765#[test]1766fn owned_tokens_bound() {1767	new_test_ext().execute_with(|| {1768		let collection_id = create_test_collection(&CollectionMode::NFT, 1);17691770		let data = default_nft_data();1771		create_test_item(collection_id, &data.clone().into());1772		create_test_item(collection_id, &data.into());1773	});1774}17751776// Owned tokens by a single address. Negotive test1777#[test]1778fn owned_tokens_bound_neg() {1779	new_test_ext().execute_with(|| {1780		let collection_id = create_test_collection(&CollectionMode::NFT, 1);17811782		let origin1 = Origin::signed(1);17831784		for _ in 0..ACCOUNT_TOKEN_OWNERSHIP_LIMIT {1785			let data = default_nft_data();1786			create_test_item(collection_id, &data.clone().into());1787		}17881789		let data = default_nft_data();1790		assert_noop!(1791			TemplateModule::create_item(origin1, 1, account(1), data.into()),1792			Error::<Test>::AddressOwnershipLimitExceeded1793		);1794	});1795}17961797// Number of collection admins. Positive test1798#[test]1799fn collection_admins_bound() {1800	new_test_ext().execute_with(|| {1801		let collection_id = create_test_collection(&CollectionMode::NFT, 1);18021803		let origin1 = Origin::signed(1);18041805		assert_ok!(TemplateModule::add_collection_admin(1806			origin1.clone(),1807			collection_id,1808			account(2)1809		));1810		assert_ok!(TemplateModule::add_collection_admin(1811			origin1,1812			collection_id,1813			account(3)1814		));1815	});1816}18171818// Number of collection admins. Negotive test1819#[test]1820fn collection_admins_bound_neg() {1821	new_test_ext().execute_with(|| {1822		let collection_id = create_test_collection(&CollectionMode::NFT, 1);18231824		let origin1 = Origin::signed(1);18251826		for i in 0..COLLECTION_ADMINS_LIMIT {1827			assert_ok!(TemplateModule::add_collection_admin(1828				origin1.clone(),1829				collection_id,1830				account(2 + i)1831			));1832		}1833		assert_noop!(1834			TemplateModule::add_collection_admin(1835				origin1,1836				collection_id,1837				account(3 + COLLECTION_ADMINS_LIMIT)1838			),1839			Error::<Test>::CollectionAdminsLimitExceeded1840		);1841	});1842}1843// #endregion18441845#[test]1846fn set_const_on_chain_schema() {1847	new_test_ext().execute_with(|| {1848		let collection_id = create_test_collection(&CollectionMode::NFT, 1);18491850		let origin1 = Origin::signed(1);1851		assert_ok!(TemplateModule::set_const_on_chain_schema(1852			origin1,1853			collection_id,1854			b"test const on chain schema".to_vec()1855		));18561857		assert_eq!(1858			TemplateModule::collection_id(collection_id)1859				.unwrap()1860				.const_on_chain_schema,1861			b"test const on chain schema".to_vec()1862		);1863		assert_eq!(1864			TemplateModule::collection_id(collection_id)1865				.unwrap()1866				.variable_on_chain_schema,1867			b"".to_vec()1868		);1869	});1870}18711872#[test]1873fn set_variable_on_chain_schema() {1874	new_test_ext().execute_with(|| {1875		let collection_id = create_test_collection(&CollectionMode::NFT, 1);18761877		let origin1 = Origin::signed(1);1878		assert_ok!(TemplateModule::set_variable_on_chain_schema(1879			origin1,1880			collection_id,1881			b"test variable on chain schema".to_vec()1882		));18831884		assert_eq!(1885			TemplateModule::collection_id(collection_id)1886				.unwrap()1887				.const_on_chain_schema,1888			b"".to_vec()1889		);1890		assert_eq!(1891			TemplateModule::collection_id(collection_id)1892				.unwrap()1893				.variable_on_chain_schema,1894			b"test variable on chain schema".to_vec()1895		);1896	});1897}18981899#[test]1900fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {1901	new_test_ext().execute_with(|| {1902		let collection_id = create_test_collection(&CollectionMode::NFT, 1);19031904		let origin1 = Origin::signed(1);19051906		let data = default_nft_data();1907		create_test_item(1, &data.into());19081909		let variable_data = b"test data".to_vec();1910		assert_ok!(TemplateModule::set_variable_meta_data(1911			origin1,1912			collection_id,1913			1,1914			variable_data.clone()1915		));19161917		assert_eq!(1918			TemplateModule::nft_item_id(collection_id, 1)1919				.unwrap()1920				.variable_data,1921			variable_data1922		);1923	});1924}19251926#[test]1927fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {1928	new_test_ext().execute_with(|| {1929		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);19301931		let origin1 = Origin::signed(1);19321933		let data = default_re_fungible_data();1934		create_test_item(1, &data.into());19351936		let variable_data = b"test data".to_vec();1937		assert_ok!(TemplateModule::set_variable_meta_data(1938			origin1,1939			collection_id,1940			1,1941			variable_data.clone()1942		));19431944		assert_eq!(1945			TemplateModule::refungible_item_id(collection_id, 1)1946				.unwrap()1947				.variable_data,1948			variable_data1949		);1950	});1951}19521953#[test]1954fn set_variable_meta_data_on_fungible_token_fails() {1955	new_test_ext().execute_with(|| {1956		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);19571958		let origin1 = Origin::signed(1);19591960		let data = default_fungible_data();1961		create_test_item(1, &data.into());19621963		let variable_data = b"test data".to_vec();1964		assert_noop!(1965			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),1966			Error::<Test>::CantStoreMetadataInFungibleTokens1967		);1968	});1969}19701971#[test]1972fn set_variable_meta_data_on_nft_token_fails_for_big_data() {1973	new_test_ext().execute_with(|| {1974		let collection_id = create_test_collection(&CollectionMode::NFT, 1);19751976		let origin1 = Origin::signed(1);19771978		let data = default_nft_data();1979		create_test_item(1, &data.into());19801981		let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1982		assert_noop!(1983			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),1984			Error::<Test>::TokenVariableDataLimitExceeded1985		);1986	});1987}19881989#[test]1990fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {1991	new_test_ext().execute_with(|| {1992		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);19931994		let origin1 = Origin::signed(1);19951996		let data = default_re_fungible_data();1997		create_test_item(1, &data.into());19981999		let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();2000		assert_noop!(2001			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),2002			Error::<Test>::TokenVariableDataLimitExceeded2003		);2004	});2005}20062007#[test]2008fn set_variable_meta_data_on_nft_with_item_owner_permission_flag() {2009	new_test_ext().execute_with(|| {2010		//default_limits();20112012		let collection_id = create_test_collection(&CollectionMode::NFT, 1);20132014		let origin1 = Origin::signed(1);20152016		let data = default_nft_data();2017		create_test_item(1, &data.into());20182019		TemplateModule::set_meta_update_permission_flag(2020			origin1.clone(),2021			collection_id,2022			MetaUpdatePermission::ItemOwner,2023		);20242025		let variable_data = b"ten chars.".to_vec();2026		assert_ok!(TemplateModule::set_variable_meta_data(2027			origin1,2028			collection_id,2029			1,2030			variable_data.clone()2031		));20322033		assert_eq!(2034			TemplateModule::nft_item_id(collection_id, 1)2035				.unwrap()2036				.variable_data,2037			variable_data2038		);2039	});2040}20412042#[test]2043fn set_variable_meta_data_on_nft_with_item_owner_permission_flag_neg() {2044	new_test_ext().execute_with(|| {2045		// default_limits();20462047		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);20482049		let origin1 = Origin::signed(1);2050		let origin2 = Origin::signed(2);20512052		assert_ok!(TemplateModule::set_mint_permission(2053			origin2.clone(),2054			collection_id,2055			true2056		));2057		assert_ok!(TemplateModule::add_to_white_list(2058			origin2.clone(),2059			collection_id,2060			account(1)2061		));20622063		let data = default_nft_data();2064		create_test_item(1, &data.into());20652066		assert_ok!(TemplateModule::set_meta_update_permission_flag(2067			origin2.clone(),2068			collection_id,2069			MetaUpdatePermission::ItemOwner,2070		));20712072		let variable_data = b"ten chars.++".to_vec();2073		assert_noop!(2074			TemplateModule::set_variable_meta_data(2075				origin2,2076				collection_id,2077				1,2078				variable_data.clone()2079			),2080			Error::<Test>::TokenVariableDataLimitExceeded2081		);20822083		#[test]2084		fn collection_transfer_flag_works() {2085			new_test_ext().execute_with(|| {2086				let origin1 = Origin::signed(1);20872088				let collection_id = create_test_collection(&CollectionMode::NFT, 1);2089				assert_ok!(TemplateModule::set_transfers_enabled_flag(origin1, 1, true));20902091				let data = default_nft_data();2092				create_test_item(collection_id, &data.into());2093				assert_eq!(TemplateModule::balance_count(1, 1), 1);2094				assert_eq!(TemplateModule::address_tokens(1, 1), [1]);20952096				let origin1 = Origin::signed(1);20972098				// default scenario2099				assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));2100				assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));2101				assert_eq!(TemplateModule::balance_count(1, 1), 0);2102				assert_eq!(TemplateModule::balance_count(1, 2), 1);21032104				assert_eq!(TemplateModule::address_tokens(1, 2), [1]);2105			});2106		}21072108		#[test]2109		fn set_variable_meta_data_on_nft_with_admin_flag() {2110			new_test_ext().execute_with(|| {2111				// default_limits();21122113				let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);21142115				let origin1 = Origin::signed(1);2116				let origin2 = Origin::signed(2);21172118				assert_ok!(TemplateModule::set_mint_permission(2119					origin2.clone(),2120					collection_id,2121					true2122				));2123				assert_ok!(TemplateModule::add_to_white_list(2124					origin2.clone(),2125					collection_id,2126					account(1)2127				));21282129				assert_ok!(TemplateModule::add_collection_admin(2130					origin2.clone(),2131					collection_id,2132					account(1)2133				));21342135				let data = default_nft_data();2136				create_test_item(1, &data.into());21372138				assert_ok!(TemplateModule::set_meta_update_permission_flag(2139					origin2.clone(),2140					collection_id,2141					MetaUpdatePermission::Admin,2142				));21432144				let variable_data = b"test set_variable_meta_data method.".to_vec();2145				assert_ok!(TemplateModule::set_variable_meta_data(2146					origin1,2147					collection_id,2148					1,2149					variable_data.clone()2150				));21512152				assert_eq!(2153					TemplateModule::nft_item_id(collection_id, 1)2154						.unwrap()2155						.variable_data,2156					variable_data2157				);2158			});2159		}21602161		#[test]2162		fn set_variable_meta_data_on_nft_with_admin_flag_neg() {2163			new_test_ext().execute_with(|| {2164				// default_limits();21652166				let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);21672168				let origin1 = Origin::signed(1);2169				let origin2 = Origin::signed(2);21702171				assert_ok!(TemplateModule::set_mint_permission(2172					origin2.clone(),2173					collection_id,2174					true2175				));2176				assert_ok!(TemplateModule::add_to_white_list(2177					origin2.clone(),2178					collection_id,2179					account(1)2180				));21812182				let data = default_nft_data();2183				create_test_item(1, &data.into());21842185				assert_ok!(TemplateModule::set_meta_update_permission_flag(2186					origin2.clone(),2187					collection_id,2188					MetaUpdatePermission::Admin,2189				));21902191				let variable_data = b"test set_variable_meta_data method.".to_vec();2192				assert_noop!(2193					TemplateModule::set_variable_meta_data(2194						origin1,2195						collection_id,2196						1,2197						variable_data.clone()2198					),2199					Error::<Test>::NoPermission2200				);2201			});2202		}22032204		#[test]2205		fn set_variable_meta_flag_after_freeze() {2206			new_test_ext().execute_with(|| {2207				// default_limits();22082209				let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);22102211				let origin2 = Origin::signed(2);22122213				assert_ok!(TemplateModule::set_meta_update_permission_flag(2214					origin2.clone(),2215					collection_id,2216					MetaUpdatePermission::None,2217				));2218				assert_noop!(2219					TemplateModule::set_meta_update_permission_flag(2220						origin2.clone(),2221						collection_id,2222						MetaUpdatePermission::Admin2223					),2224					Error::<Test>::MetadataFlagFrozen2225				);2226			});2227		}22282229		#[test]2230		fn set_variable_meta_data_on_nft_with_none_flag_neg() {2231			new_test_ext().execute_with(|| {2232				// default_limits();22332234				let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);2235				let origin1 = Origin::signed(1);22362237				let data = default_nft_data();2238				create_test_item(1, &data.into());22392240				assert_ok!(TemplateModule::set_meta_update_permission_flag(2241					origin1.clone(),2242					collection_id,2243					MetaUpdatePermission::None,2244				));22452246				let variable_data = b"test set_variable_meta_data method.".to_vec();2247				assert_noop!(2248					TemplateModule::set_variable_meta_data(2249						origin1.clone(),2250						collection_id,2251						1,2252						variable_data.clone()2253					),2254					Error::<Test>::MetadataUpdateDenied2255				);2256			});2257		}22582259		#[test]2260		fn collection_transfer_flag_works_neg() {2261			new_test_ext().execute_with(|| {2262				let origin1 = Origin::signed(1);22632264				let collection_id = create_test_collection(&CollectionMode::NFT, 1);2265				assert_ok!(TemplateModule::set_transfers_enabled_flag(2266					origin1, 1, false2267				));22682269				let data = default_nft_data();2270				create_test_item(collection_id, &data.into());2271				assert_eq!(TemplateModule::balance_count(1, 1), 1);2272				assert_eq!(TemplateModule::address_tokens(1, 1), [1]);22732274				let origin1 = Origin::signed(1);22752276				// default scenario2277				assert_noop!(2278					TemplateModule::transfer(origin1, account(2), 1, 1, 1000),2279					Error::<Test>::TransferNotAllowed2280				);2281				assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(1));2282				assert_eq!(TemplateModule::balance_count(1, 1), 1);2283				assert_eq!(TemplateModule::balance_count(1, 2), 0);22842285				assert_eq!(TemplateModule::address_tokens(1, 1), [1]);2286			});2287		}2288	});2289}
after · pallets/nft/src/tests.rs
1// Tests to be written here2use super::*;3use crate::mock::*;4use crate::{AccessMode, CollectionMode, Ownership, CreateItemData};5use nft_data_structs::{6	CreateNftData, CreateFungibleData, CreateReFungibleData, CollectionId, TokenId,7	MAX_DECIMAL_POINTS,8};9use frame_support::{assert_noop, assert_ok};10use sp_std::convert::TryInto;1112fn default_nft_data() -> CreateNftData {13	CreateNftData {14		const_data: vec![1, 2, 3].try_into().unwrap(),15		variable_data: vec![3, 2, 1].try_into().unwrap(),16	}17}1819fn default_fungible_data() -> CreateFungibleData {20	CreateFungibleData { value: 5 }21}2223fn default_re_fungible_data() -> CreateReFungibleData {24	CreateReFungibleData {25		const_data: vec![1, 2, 3].try_into().unwrap(),26		variable_data: vec![3, 2, 1].try_into().unwrap(),27		pieces: 1023,28	}29}3031fn create_test_collection_for_owner(32	mode: &CollectionMode,33	owner: u64,34	id: CollectionId,35) -> CollectionId {36	let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();37	let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();38	let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();3940	let origin1 = Origin::signed(owner);41	assert_ok!(TemplateModule::create_collection(42		origin1,43		col_name1,44		col_desc1,45		token_prefix1,46		mode.clone()47	));4849	let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();50	let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();51	let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();52	assert_eq!(TemplateModule::collection_id(id).unwrap().owner, owner);53	assert_eq!(54		TemplateModule::collection_id(id).unwrap().name,55		saved_col_name56	);57	assert_eq!(TemplateModule::collection_id(id).unwrap().mode, *mode);58	assert_eq!(59		TemplateModule::collection_id(id).unwrap().description,60		saved_description61	);62	assert_eq!(63		TemplateModule::collection_id(id).unwrap().token_prefix,64		saved_prefix65	);66	id67}6869fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {70	create_test_collection_for_owner(&mode, 1, id)71}7273fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {74	let origin1 = Origin::signed(1);75	assert_ok!(TemplateModule::create_item(76		origin1,77		collection_id,78		account(1),79		data.clone()80	));81}8283fn account(sub: u64) -> TestCrossAccountId {84	TestCrossAccountId::from_sub(sub)85}8687// Use cases tests region88// #region8990#[test]91fn set_version_schema() {92	new_test_ext().execute_with(|| {93		let origin1 = Origin::signed(1);94		let collection_id = create_test_collection(&CollectionMode::NFT, 1);9596		assert_ok!(TemplateModule::set_schema_version(97			origin1,98			collection_id,99			SchemaVersion::Unique100		));101		assert_eq!(102			TemplateModule::collection_id(collection_id)103				.unwrap()104				.schema_version,105			SchemaVersion::Unique106		);107	});108}109110#[test]111fn create_fungible_collection_fails_with_large_decimal_numbers() {112	new_test_ext().execute_with(|| {113		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();114		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();115		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();116117		let origin1 = Origin::signed(1);118		assert_noop!(119			TemplateModule::create_collection(120				origin1,121				col_name1,122				col_desc1,123				token_prefix1,124				CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1)125			),126			Error::<Test>::CollectionDecimalPointLimitExceeded127		);128	});129}130131#[test]132fn create_nft_item() {133	new_test_ext().execute_with(|| {134		let collection_id = create_test_collection(&CollectionMode::NFT, 1);135136		let data = default_nft_data();137		create_test_item(collection_id, &data.clone().into());138		let item = TemplateModule::nft_item_id(collection_id, 1).unwrap();139		assert_eq!(item.const_data, data.const_data.into_inner());140		assert_eq!(item.variable_data, data.variable_data.into_inner());141	});142}143144// Use cases tests region145// #region146#[test]147fn create_nft_multiple_items() {148	new_test_ext().execute_with(|| {149		create_test_collection(&CollectionMode::NFT, 1);150151		let origin1 = Origin::signed(1);152153		let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];154155		assert_ok!(TemplateModule::create_multiple_items(156			origin1,157			1,158			account(1),159			items_data160				.clone()161				.into_iter()162				.map(|d| { d.into() })163				.collect()164		));165		for (index, data) in items_data.into_iter().enumerate() {166			let item = TemplateModule::nft_item_id(1, (index + 1) as TokenId).unwrap();167			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());168			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());169		}170	});171}172173#[test]174fn create_refungible_item() {175	new_test_ext().execute_with(|| {176		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);177178		let data = default_re_fungible_data();179		create_test_item(collection_id, &data.clone().into());180		let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();181		assert_eq!(item.const_data, data.const_data.into_inner());182		assert_eq!(item.variable_data, data.variable_data.into_inner());183		assert_eq!(184			item.owner[0],185			Ownership {186				owner: account(1),187				fraction: 1023188			}189		);190	});191}192193#[test]194fn create_multiple_refungible_items() {195	new_test_ext().execute_with(|| {196		create_test_collection(&CollectionMode::ReFungible, 1);197198		let origin1 = Origin::signed(1);199200		let items_data = vec![201			default_re_fungible_data(),202			default_re_fungible_data(),203			default_re_fungible_data(),204		];205206		assert_ok!(TemplateModule::create_multiple_items(207			origin1,208			1,209			account(1),210			items_data211				.clone()212				.into_iter()213				.map(|d| { d.into() })214				.collect()215		));216		for (index, data) in items_data.into_iter().enumerate() {217			let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId).unwrap();218			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());219			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());220			assert_eq!(221				item.owner[0],222				Ownership {223					owner: account(1),224					fraction: 1023225				}226			);227		}228	});229}230231#[test]232fn create_fungible_item() {233	new_test_ext().execute_with(|| {234		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);235236		let data = default_fungible_data();237		create_test_item(collection_id, &data.into());238239		assert_eq!(TemplateModule::fungible_item_id(collection_id, 1).value, 5);240	});241}242243//#[test]244// fn create_multiple_fungible_items() {245//     new_test_ext().execute_with(|| {246//         default_limits();247248//         create_test_collection(&CollectionMode::Fungible(3), 1);249250//         let origin1 = Origin::signed(1);251252//         let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];253254//         assert_ok!(TemplateModule::create_multiple_items(255//             origin1.clone(),256//             1,257//             1,258//             items_data.clone().into_iter().map(|d| { d.into() }).collect()259//         ));260261//         for (index, _) in items_data.iter().enumerate() {262//             assert_eq!(TemplateModule::fungible_item_id(1, (index + 1) as TokenId).value, 5);263//         }264//         assert_eq!(TemplateModule::balance_count(1, 1), 3000);265//         assert_eq!(TemplateModule::address_tokens(1, 1), [1, 2, 3]);266//     });267// }268269#[test]270fn transfer_fungible_item() {271	new_test_ext().execute_with(|| {272		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);273274		let origin1 = Origin::signed(1);275		let origin2 = Origin::signed(2);276277		let data = default_fungible_data();278		create_test_item(collection_id, &data.into());279280		assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 5);281		assert_eq!(TemplateModule::balance_count(1, 1), 5);282283		// change owner scenario284		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 5));285		assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 0);286		assert_eq!(TemplateModule::balance_count(1, 1), 0);287		assert_eq!(TemplateModule::balance_count(1, 2), 5);288289		// split item scenario290		assert_ok!(TemplateModule::transfer(291			origin2.clone(),292			account(3),293			1,294			1,295			3296		));297		assert_eq!(TemplateModule::balance_count(1, 2), 2);298		assert_eq!(TemplateModule::balance_count(1, 3), 3);299300		// split item and new owner has account scenario301		assert_ok!(TemplateModule::transfer(origin2, account(3), 1, 1, 1));302		assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 1);303		assert_eq!(TemplateModule::fungible_item_id(1, 3).value, 4);304		assert_eq!(TemplateModule::balance_count(1, 2), 1);305		assert_eq!(TemplateModule::balance_count(1, 3), 4);306	});307}308309#[test]310fn transfer_refungible_item() {311	new_test_ext().execute_with(|| {312		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);313314		let data = default_re_fungible_data();315		create_test_item(collection_id, &data.clone().into());316317		let origin1 = Origin::signed(1);318		let origin2 = Origin::signed(2);319		{320			let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();321			assert_eq!(item.const_data, data.const_data.into_inner());322			assert_eq!(item.variable_data, data.variable_data.into_inner());323			assert_eq!(324				item.owner[0],325				Ownership {326					owner: account(1),327					fraction: 1023328				}329			);330		}331		assert_eq!(TemplateModule::balance_count(1, 1), 1023);332		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);333334		// change owner scenario335		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1023));336		assert_eq!(337			TemplateModule::refungible_item_id(1, 1).unwrap().owner[0],338			Ownership {339				owner: account(2),340				fraction: 1023341			}342		);343		assert_eq!(TemplateModule::balance_count(1, 1), 0);344		assert_eq!(TemplateModule::balance_count(1, 2), 1023);345		// assert_eq!(TemplateModule::address_tokens(1, 1), []);346		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);347348		// split item scenario349		assert_ok!(TemplateModule::transfer(350			origin2.clone(),351			account(3),352			1,353			1,354			500355		));356		{357			let item = TemplateModule::refungible_item_id(1, 1).unwrap();358			assert_eq!(359				item.owner[0],360				Ownership {361					owner: account(2),362					fraction: 523363				}364			);365			assert_eq!(366				item.owner[1],367				Ownership {368					owner: account(3),369					fraction: 500370				}371			);372		}373		assert_eq!(TemplateModule::balance_count(1, 2), 523);374		assert_eq!(TemplateModule::balance_count(1, 3), 500);375		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);376		assert_eq!(TemplateModule::address_tokens(1, 3), [1]);377378		// split item and new owner has account scenario379		assert_ok!(TemplateModule::transfer(origin2, account(3), 1, 1, 200));380		{381			let item = TemplateModule::refungible_item_id(1, 1).unwrap();382			assert_eq!(383				item.owner[0],384				Ownership {385					owner: account(2),386					fraction: 323387				}388			);389			assert_eq!(390				item.owner[1],391				Ownership {392					owner: account(3),393					fraction: 700394				}395			);396		}397		assert_eq!(TemplateModule::balance_count(1, 2), 323);398		assert_eq!(TemplateModule::balance_count(1, 3), 700);399		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);400		assert_eq!(TemplateModule::address_tokens(1, 3), [1]);401	});402}403404#[test]405fn transfer_nft_item() {406	new_test_ext().execute_with(|| {407		let collection_id = create_test_collection(&CollectionMode::NFT, 1);408409		let data = default_nft_data();410		create_test_item(collection_id, &data.into());411		assert_eq!(TemplateModule::balance_count(1, 1), 1);412		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);413414		let origin1 = Origin::signed(1);415		// default scenario416		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));417		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));418		assert_eq!(TemplateModule::balance_count(1, 1), 0);419		assert_eq!(TemplateModule::balance_count(1, 2), 1);420		// assert_eq!(TemplateModule::address_tokens(1, 1), []);421		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);422	});423}424425#[test]426fn nft_approve_and_transfer_from() {427	new_test_ext().execute_with(|| {428		let collection_id = create_test_collection(&CollectionMode::NFT, 1);429430		let data = default_nft_data();431		create_test_item(collection_id, &data.into());432433		let origin1 = Origin::signed(1);434		let origin2 = Origin::signed(2);435436		assert_eq!(TemplateModule::balance_count(1, 1), 1);437		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);438439		// neg transfer440		assert_noop!(441			TemplateModule::transfer_from(origin2.clone(), account(1), account(2), 1, 1, 1),442			Error::<Test>::NoPermission443		);444445		// do approve446		assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 5));447		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);448		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);449450		assert_ok!(TemplateModule::transfer_from(451			origin2,452			account(1),453			account(3),454			1,455			1,456			1457		));458		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);459	});460}461462#[test]463fn nft_approve_and_transfer_from_white_list() {464	new_test_ext().execute_with(|| {465		let collection_id = create_test_collection(&CollectionMode::NFT, 1);466467		let origin1 = Origin::signed(1);468		let origin2 = Origin::signed(2);469470		let data = default_nft_data();471		create_test_item(collection_id, &data.clone().into());472473		assert_eq!(474			&TemplateModule::nft_item_id(1, 1).unwrap().const_data,475			&data.const_data.into_inner()476		);477		assert_eq!(TemplateModule::balance_count(1, 1), 1);478		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);479480		assert_ok!(TemplateModule::set_mint_permission(481			origin1.clone(),482			1,483			true484		));485		assert_ok!(TemplateModule::set_public_access_mode(486			origin1.clone(),487			1,488			AccessMode::WhiteList489		));490		assert_ok!(TemplateModule::add_to_white_list(491			origin1.clone(),492			1,493			account(1)494		));495		assert_ok!(TemplateModule::add_to_white_list(496			origin1.clone(),497			1,498			account(2)499		));500		assert_ok!(TemplateModule::add_to_white_list(501			origin1.clone(),502			1,503			account(3)504		));505506		// do approve507		assert_ok!(TemplateModule::approve(508			origin1.clone(),509			account(2),510			1,511			1,512			5513		));514		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);515		assert_ok!(TemplateModule::approve(origin1, account(3), 1, 1, 5));516		assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);517518		assert_ok!(TemplateModule::transfer_from(519			origin2,520			account(1),521			account(3),522			1,523			1,524			1525		));526		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);527	});528}529530#[test]531fn refungible_approve_and_transfer_from() {532	new_test_ext().execute_with(|| {533		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);534535		let origin1 = Origin::signed(1);536		let origin2 = Origin::signed(2);537538		let data = default_re_fungible_data();539		create_test_item(collection_id, &data.into());540541		assert_eq!(TemplateModule::balance_count(1, 1), 1023);542		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);543544		assert_ok!(TemplateModule::set_mint_permission(545			origin1.clone(),546			1,547			true548		));549		assert_ok!(TemplateModule::set_public_access_mode(550			origin1.clone(),551			1,552			AccessMode::WhiteList553		));554		assert_ok!(TemplateModule::add_to_white_list(555			origin1.clone(),556			1,557			account(1)558		));559		assert_ok!(TemplateModule::add_to_white_list(560			origin1.clone(),561			1,562			account(2)563		));564		assert_ok!(TemplateModule::add_to_white_list(565			origin1.clone(),566			1,567			account(3)568		));569570		// do approve571		assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 1023));572		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1023);573574		assert_ok!(TemplateModule::transfer_from(575			origin2,576			account(1),577			account(3),578			1,579			1,580			100581		));582		assert_eq!(TemplateModule::balance_count(1, 1), 923);583		assert_eq!(TemplateModule::balance_count(1, 3), 100);584		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);585		assert_eq!(TemplateModule::address_tokens(1, 3), [1]);586587		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 923);588	});589}590591#[test]592fn fungible_approve_and_transfer_from() {593	new_test_ext().execute_with(|| {594		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);595596		let data = default_fungible_data();597		create_test_item(collection_id, &data.into());598599		let origin1 = Origin::signed(1);600		let origin2 = Origin::signed(2);601602		assert_eq!(TemplateModule::balance_count(1, 1), 5);603604		assert_ok!(TemplateModule::set_mint_permission(605			origin1.clone(),606			1,607			true608		));609		assert_ok!(TemplateModule::set_public_access_mode(610			origin1.clone(),611			1,612			AccessMode::WhiteList613		));614		assert_ok!(TemplateModule::add_to_white_list(615			origin1.clone(),616			1,617			account(1)618		));619		assert_ok!(TemplateModule::add_to_white_list(620			origin1.clone(),621			1,622			account(2)623		));624		assert_ok!(TemplateModule::add_to_white_list(625			origin1.clone(),626			1,627			account(3)628		));629630		// do approve631		assert_ok!(TemplateModule::approve(632			origin1.clone(),633			account(2),634			1,635			1,636			5637		));638		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);639		assert_ok!(TemplateModule::approve(origin1, account(3), 1, 1, 5));640		assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);641		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);642643		assert_ok!(TemplateModule::transfer_from(644			origin2.clone(),645			account(1),646			account(3),647			1,648			1,649			4650		));651		assert_eq!(TemplateModule::balance_count(1, 1), 1);652		assert_eq!(TemplateModule::balance_count(1, 3), 4);653654		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);655656		assert_noop!(657			TemplateModule::transfer_from(origin2, account(1), account(3), 1, 1, 4),658			Error::<Test>::NoPermission659		);660	});661}662663#[test]664fn change_collection_owner() {665	new_test_ext().execute_with(|| {666		let collection_id = create_test_collection(&CollectionMode::NFT, 1);667668		let origin1 = Origin::signed(1);669		assert_ok!(TemplateModule::change_collection_owner(670			origin1,671			collection_id,672			2673		));674		assert_eq!(675			TemplateModule::collection_id(collection_id).unwrap().owner,676			2677		);678	});679}680681#[test]682fn destroy_collection() {683	new_test_ext().execute_with(|| {684		let collection_id = create_test_collection(&CollectionMode::NFT, 1);685686		let origin1 = Origin::signed(1);687		assert_ok!(TemplateModule::destroy_collection(origin1, collection_id));688	});689}690691#[test]692fn burn_nft_item() {693	new_test_ext().execute_with(|| {694		let collection_id = create_test_collection(&CollectionMode::NFT, 1);695696		let origin1 = Origin::signed(1);697		assert_ok!(TemplateModule::add_collection_admin(698			origin1.clone(),699			collection_id,700			account(2)701		));702703		let data = default_nft_data();704		create_test_item(collection_id, &data.into());705706		// check balance (collection with id = 1, user id = 1)707		assert_eq!(TemplateModule::balance_count(1, 1), 1);708709		// burn item710		assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));711		assert_noop!(712			TemplateModule::burn_item(origin1, 1, 1, 5),713			Error::<Test>::TokenNotFound714		);715716		assert_eq!(TemplateModule::balance_count(1, 1), 0);717	});718}719720#[test]721fn burn_fungible_item() {722	new_test_ext().execute_with(|| {723		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);724725		let origin1 = Origin::signed(1);726		assert_ok!(TemplateModule::add_collection_admin(727			origin1.clone(),728			collection_id,729			account(2)730		));731732		let data = default_fungible_data();733		create_test_item(collection_id, &data.into());734735		// check balance (collection with id = 1, user id = 1)736		assert_eq!(TemplateModule::balance_count(1, 1), 5);737738		// burn item739		assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));740		assert_noop!(741			TemplateModule::burn_item(origin1, 1, 1, 5),742			Error::<Test>::TokenValueNotEnough743		);744745		assert_eq!(TemplateModule::balance_count(1, 1), 0);746	});747}748749#[test]750fn burn_refungible_item() {751	new_test_ext().execute_with(|| {752		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);753		let origin1 = Origin::signed(1);754755		assert_ok!(TemplateModule::set_mint_permission(756			origin1.clone(),757			collection_id,758			true759		));760		assert_ok!(TemplateModule::set_public_access_mode(761			origin1.clone(),762			collection_id,763			AccessMode::WhiteList764		));765		assert_ok!(TemplateModule::add_to_white_list(766			origin1.clone(),767			1,768			account(1)769		));770771		assert_ok!(TemplateModule::add_collection_admin(772			origin1.clone(),773			1,774			account(2)775		));776777		let data = default_re_fungible_data();778		create_test_item(collection_id, &data.into());779780		// check balance (collection with id = 1, user id = 2)781		assert_eq!(TemplateModule::balance_count(1, 1), 1023);782783		// burn item784		assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 1023));785		assert_noop!(786			TemplateModule::burn_item(origin1, 1, 1, 1023),787			Error::<Test>::TokenNotFound788		);789790		assert_eq!(TemplateModule::balance_count(1, 1), 0);791	});792}793794#[test]795fn add_collection_admin() {796	new_test_ext().execute_with(|| {797		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);798		create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);799		create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);800801		let origin1 = Origin::signed(1);802803		// collection admin804		assert_ok!(TemplateModule::add_collection_admin(805			origin1.clone(),806			collection1_id,807			account(2)808		));809		assert_ok!(TemplateModule::add_collection_admin(810			origin1,811			collection1_id,812			account(3)813		));814815		assert!(TemplateModule::admin_list_collection(collection1_id).contains(&account(2)),);816		assert!(TemplateModule::admin_list_collection(collection1_id).contains(&account(3)),);817	});818}819820#[test]821fn remove_collection_admin() {822	new_test_ext().execute_with(|| {823		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);824		create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);825		create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);826827		let origin1 = Origin::signed(1);828		let origin2 = Origin::signed(2);829830		// collection admin831		assert_ok!(TemplateModule::add_collection_admin(832			origin1.clone(),833			collection1_id,834			account(2)835		));836		assert_ok!(TemplateModule::add_collection_admin(837			origin1,838			collection1_id,839			account(3)840		));841842		assert!(TemplateModule::admin_list_collection(1).contains(&account(2)),);843		assert!(TemplateModule::admin_list_collection(1).contains(&account(3)),);844845		// remove admin846		assert_ok!(TemplateModule::remove_collection_admin(847			origin2,848			1,849			account(3)850		));851		assert!(!TemplateModule::admin_list_collection(1).contains(&account(3)),);852	});853}854855#[test]856fn balance_of() {857	new_test_ext().execute_with(|| {858		let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);859		let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);860		let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible, 3);861862		// check balance before863		assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);864		assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);865		assert_eq!(866			TemplateModule::balance_count(re_fungible_collection_id, 1),867			0868		);869870		let nft_data = default_nft_data();871		create_test_item(nft_collection_id, &nft_data.into());872873		let fungible_data = default_fungible_data();874		create_test_item(fungible_collection_id, &fungible_data.into());875876		let re_fungible_data = default_re_fungible_data();877		create_test_item(re_fungible_collection_id, &re_fungible_data.into());878879		// check balance (collection with id = 1, user id = 1)880		assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1);881		assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 5);882		assert_eq!(883			TemplateModule::balance_count(re_fungible_collection_id, 1),884			1023885		);886		assert_eq!(887			TemplateModule::nft_item_id(nft_collection_id, 1)888				.unwrap()889				.owner,890			account(1)891		);892		assert_eq!(893			TemplateModule::fungible_item_id(fungible_collection_id, 1).value,894			5895		);896		assert_eq!(897			TemplateModule::refungible_item_id(re_fungible_collection_id, 1)898				.unwrap()899				.owner[0]900				.owner,901			account(1)902		);903	});904}905906#[test]907fn approve() {908	new_test_ext().execute_with(|| {909		let collection_id = create_test_collection(&CollectionMode::NFT, 1);910911		let data = default_nft_data();912		create_test_item(collection_id, &data.into());913914		let origin1 = Origin::signed(1);915916		// approve917		assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 1));918		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);919	});920}921922#[test]923fn transfer_from() {924	new_test_ext().execute_with(|| {925		let collection_id = create_test_collection(&CollectionMode::NFT, 1);926		let origin1 = Origin::signed(1);927		let origin2 = Origin::signed(2);928929		let data = default_nft_data();930		create_test_item(collection_id, &data.into());931932		// approve933		assert_ok!(TemplateModule::approve(934			origin1.clone(),935			account(2),936			1,937			1,938			1939		));940		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);941942		assert_ok!(TemplateModule::set_mint_permission(943			origin1.clone(),944			1,945			true946		));947		assert_ok!(TemplateModule::set_public_access_mode(948			origin1.clone(),949			1,950			AccessMode::WhiteList951		));952		assert_ok!(TemplateModule::add_to_white_list(953			origin1.clone(),954			1,955			account(1)956		));957		assert_ok!(TemplateModule::add_to_white_list(958			origin1.clone(),959			1,960			account(2)961		));962		assert_ok!(TemplateModule::add_to_white_list(origin1, 1, account(3)));963964		assert_ok!(TemplateModule::transfer_from(965			origin2,966			account(1),967			account(2),968			1,969			1,970			1971		));972973		// after transfer974		assert_eq!(TemplateModule::balance_count(1, 1), 0);975		assert_eq!(TemplateModule::balance_count(1, 2), 1);976	});977}978979// #endregion980981// Coverage tests region982// #region983984#[test]985fn owner_can_add_address_to_white_list() {986	new_test_ext().execute_with(|| {987		let collection_id = create_test_collection(&CollectionMode::NFT, 1);988989		let origin1 = Origin::signed(1);990		assert_ok!(TemplateModule::add_to_white_list(991			origin1,992			collection_id,993			account(2)994		));995		assert!(TemplateModule::white_list(collection_id, 2));996	});997}998999#[test]1000fn admin_can_add_address_to_white_list() {1001	new_test_ext().execute_with(|| {1002		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1003		let origin1 = Origin::signed(1);1004		let origin2 = Origin::signed(2);10051006		assert_ok!(TemplateModule::add_collection_admin(1007			origin1,1008			collection_id,1009			account(2)1010		));1011		assert_ok!(TemplateModule::add_to_white_list(1012			origin2,1013			collection_id,1014			account(3)1015		));1016		assert!(TemplateModule::white_list(collection_id, 3));1017	});1018}10191020#[test]1021fn nonprivileged_user_cannot_add_address_to_white_list() {1022	new_test_ext().execute_with(|| {1023		let collection_id = create_test_collection(&CollectionMode::NFT, 1);10241025		let origin2 = Origin::signed(2);1026		assert_noop!(1027			TemplateModule::add_to_white_list(origin2, collection_id, account(3)),1028			Error::<Test>::NoPermission1029		);1030	});1031}10321033#[test]1034fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {1035	new_test_ext().execute_with(|| {1036		let origin1 = Origin::signed(1);10371038		assert_noop!(1039			TemplateModule::add_to_white_list(origin1, 1, account(2)),1040			Error::<Test>::CollectionNotFound1041		);1042	});1043}10441045#[test]1046fn nobody_can_add_address_to_white_list_of_deleted_collection() {1047	new_test_ext().execute_with(|| {1048		let collection_id = create_test_collection(&CollectionMode::NFT, 1);10491050		let origin1 = Origin::signed(1);1051		assert_ok!(TemplateModule::destroy_collection(1052			origin1.clone(),1053			collection_id1054		));1055		assert_noop!(1056			TemplateModule::add_to_white_list(origin1, collection_id, account(2)),1057			Error::<Test>::CollectionNotFound1058		);1059	});1060}10611062// If address is already added to white list, nothing happens1063#[test]1064fn address_is_already_added_to_white_list() {1065	new_test_ext().execute_with(|| {1066		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1067		let origin1 = Origin::signed(1);10681069		assert_ok!(TemplateModule::add_to_white_list(1070			origin1.clone(),1071			collection_id,1072			account(2)1073		));1074		assert_ok!(TemplateModule::add_to_white_list(1075			origin1,1076			collection_id,1077			account(2)1078		));1079		assert!(TemplateModule::white_list(collection_id, 2));1080	});1081}10821083#[test]1084fn owner_can_remove_address_from_white_list() {1085	new_test_ext().execute_with(|| {1086		let collection_id = create_test_collection(&CollectionMode::NFT, 1);10871088		let origin1 = Origin::signed(1);1089		assert_ok!(TemplateModule::add_to_white_list(1090			origin1.clone(),1091			collection_id,1092			account(2)1093		));1094		assert_ok!(TemplateModule::remove_from_white_list(1095			origin1,1096			collection_id,1097			account(2)1098		));1099		assert!(!TemplateModule::white_list(collection_id, 2));1100	});1101}11021103#[test]1104fn admin_can_remove_address_from_white_list() {1105	new_test_ext().execute_with(|| {1106		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1107		let origin1 = Origin::signed(1);1108		let origin2 = Origin::signed(2);11091110		assert_ok!(TemplateModule::add_collection_admin(1111			origin1.clone(),1112			collection_id,1113			account(2)1114		));11151116		assert_ok!(TemplateModule::add_to_white_list(1117			origin1,1118			collection_id,1119			account(3)1120		));1121		assert_ok!(TemplateModule::remove_from_white_list(1122			origin2,1123			collection_id,1124			account(3)1125		));1126		assert!(!TemplateModule::white_list(collection_id, 3));1127	});1128}11291130#[test]1131fn nonprivileged_user_cannot_remove_address_from_white_list() {1132	new_test_ext().execute_with(|| {1133		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1134		let origin1 = Origin::signed(1);1135		let origin2 = Origin::signed(2);11361137		assert_ok!(TemplateModule::add_to_white_list(1138			origin1,1139			collection_id,1140			account(2)1141		));1142		assert_noop!(1143			TemplateModule::remove_from_white_list(origin2, collection_id, account(2)),1144			Error::<Test>::NoPermission1145		);1146		assert!(TemplateModule::white_list(collection_id, 2));1147	});1148}11491150#[test]1151fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1152	new_test_ext().execute_with(|| {1153		let origin1 = Origin::signed(1);11541155		assert_noop!(1156			TemplateModule::remove_from_white_list(origin1, 1, account(2)),1157			Error::<Test>::CollectionNotFound1158		);1159	});1160}11611162#[test]1163fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1164	new_test_ext().execute_with(|| {1165		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1166		let origin1 = Origin::signed(1);1167		let origin2 = Origin::signed(2);11681169		assert_ok!(TemplateModule::add_to_white_list(1170			origin1.clone(),1171			collection_id,1172			account(2)1173		));1174		assert_ok!(TemplateModule::destroy_collection(origin1, collection_id));1175		assert_noop!(1176			TemplateModule::remove_from_white_list(origin2, collection_id, account(2)),1177			Error::<Test>::CollectionNotFound1178		);1179		assert!(!TemplateModule::white_list(collection_id, 2));1180	});1181}11821183// If address is already removed from white list, nothing happens1184#[test]1185fn address_is_already_removed_from_white_list() {1186	new_test_ext().execute_with(|| {1187		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1188		let origin1 = Origin::signed(1);11891190		assert_ok!(TemplateModule::add_to_white_list(1191			origin1.clone(),1192			collection_id,1193			account(2)1194		));1195		assert_ok!(TemplateModule::remove_from_white_list(1196			origin1.clone(),1197			collection_id,1198			account(2)1199		));1200		assert_ok!(TemplateModule::remove_from_white_list(1201			origin1,1202			collection_id,1203			account(2)1204		));1205		assert!(!TemplateModule::white_list(collection_id, 2));1206	});1207}12081209// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1210#[test]1211fn white_list_test_1() {1212	new_test_ext().execute_with(|| {1213		let collection_id = create_test_collection(&CollectionMode::NFT, 1);12141215		let origin1 = Origin::signed(1);12161217		let data = default_nft_data();1218		create_test_item(collection_id, &data.into());12191220		assert_ok!(TemplateModule::set_public_access_mode(1221			origin1.clone(),1222			collection_id,1223			AccessMode::WhiteList1224		));1225		assert_ok!(TemplateModule::add_to_white_list(1226			origin1.clone(),1227			collection_id,1228			account(2)1229		));12301231		assert_noop!(1232			TemplateModule::transfer(origin1, account(3), 1, 1, 1),1233			Error::<Test>::AddresNotInWhiteList1234		);1235	});1236}12371238#[test]1239fn white_list_test_2() {1240	new_test_ext().execute_with(|| {1241		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1242		let origin1 = Origin::signed(1);12431244		let data = default_nft_data();1245		create_test_item(collection_id, &data.into());12461247		assert_ok!(TemplateModule::set_public_access_mode(1248			origin1.clone(),1249			collection_id,1250			AccessMode::WhiteList1251		));1252		assert_ok!(TemplateModule::add_to_white_list(1253			origin1.clone(),1254			1,1255			account(1)1256		));1257		assert_ok!(TemplateModule::add_to_white_list(1258			origin1.clone(),1259			1,1260			account(2)1261		));12621263		// do approve1264		assert_ok!(TemplateModule::approve(1265			origin1.clone(),1266			account(1),1267			1,1268			1,1269			11270		));1271		assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);12721273		assert_ok!(TemplateModule::remove_from_white_list(1274			origin1.clone(),1275			1,1276			account(1)1277		));12781279		assert_noop!(1280			TemplateModule::transfer_from(origin1, account(1), account(3), 1, 1, 1),1281			Error::<Test>::AddresNotInWhiteList1282		);1283	});1284}12851286// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1287#[test]1288fn white_list_test_3() {1289	new_test_ext().execute_with(|| {1290		let collection_id = create_test_collection(&CollectionMode::NFT, 1);12911292		let origin1 = Origin::signed(1);12931294		let data = default_nft_data();1295		create_test_item(collection_id, &data.into());12961297		assert_ok!(TemplateModule::set_public_access_mode(1298			origin1.clone(),1299			collection_id,1300			AccessMode::WhiteList1301		));1302		assert_ok!(TemplateModule::add_to_white_list(1303			origin1.clone(),1304			1,1305			account(1)1306		));13071308		assert_noop!(1309			TemplateModule::transfer(origin1, account(3), 1, 1, 1),1310			Error::<Test>::AddresNotInWhiteList1311		);1312	});1313}13141315#[test]1316fn white_list_test_4() {1317	new_test_ext().execute_with(|| {1318		let collection_id = create_test_collection(&CollectionMode::NFT, 1);13191320		let origin1 = Origin::signed(1);13211322		let data = default_nft_data();1323		create_test_item(collection_id, &data.into());13241325		assert_ok!(TemplateModule::set_public_access_mode(1326			origin1.clone(),1327			collection_id,1328			AccessMode::WhiteList1329		));1330		assert_ok!(TemplateModule::add_to_white_list(1331			origin1.clone(),1332			collection_id,1333			account(1)1334		));1335		assert_ok!(TemplateModule::add_to_white_list(1336			origin1.clone(),1337			collection_id,1338			account(2)1339		));13401341		// do approve1342		assert_ok!(TemplateModule::approve(1343			origin1.clone(),1344			account(1),1345			1,1346			1,1347			11348		));1349		assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);13501351		assert_ok!(TemplateModule::remove_from_white_list(1352			origin1.clone(),1353			collection_id,1354			account(2)1355		));13561357		assert_noop!(1358			TemplateModule::transfer_from(origin1, account(1), account(3), 1, 1, 1),1359			Error::<Test>::AddresNotInWhiteList1360		);1361	});1362}13631364// If Public Access mode is set to WhiteList, tokens can’t be destroyed by a non-whitelisted address (even if it owned them before enabling WhiteList mode)1365#[test]1366fn white_list_test_5() {1367	new_test_ext().execute_with(|| {1368		let collection_id = create_test_collection(&CollectionMode::NFT, 1);13691370		let origin1 = Origin::signed(1);13711372		let data = default_nft_data();1373		create_test_item(collection_id, &data.into());13741375		assert_ok!(TemplateModule::set_public_access_mode(1376			origin1.clone(),1377			collection_id,1378			AccessMode::WhiteList1379		));1380		assert_noop!(1381			TemplateModule::burn_item(origin1, 1, 1, 5),1382			Error::<Test>::AddresNotInWhiteList1383		);1384	});1385}13861387// If Public Access mode is set to WhiteList, token transfers can’t be Approved by a non-whitelisted address (see Approve method).1388#[test]1389fn white_list_test_6() {1390	new_test_ext().execute_with(|| {1391		let collection_id = create_test_collection(&CollectionMode::NFT, 1);13921393		let origin1 = Origin::signed(1);13941395		let data = default_nft_data();1396		create_test_item(collection_id, &data.into());13971398		assert_ok!(TemplateModule::set_public_access_mode(1399			origin1.clone(),1400			collection_id,1401			AccessMode::WhiteList1402		));14031404		// do approve1405		assert_noop!(1406			TemplateModule::approve(origin1, account(1), 1, 1, 5),1407			Error::<Test>::AddresNotInWhiteList1408		);1409	});1410}14111412// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1413//          tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1414#[test]1415fn white_list_test_7() {1416	new_test_ext().execute_with(|| {1417		let collection_id = create_test_collection(&CollectionMode::NFT, 1);14181419		let data = default_nft_data();1420		create_test_item(collection_id, &data.into());14211422		let origin1 = Origin::signed(1);14231424		assert_ok!(TemplateModule::set_public_access_mode(1425			origin1.clone(),1426			collection_id,1427			AccessMode::WhiteList1428		));1429		assert_ok!(TemplateModule::add_to_white_list(1430			origin1.clone(),1431			collection_id,1432			account(1)1433		));1434		assert_ok!(TemplateModule::add_to_white_list(1435			origin1.clone(),1436			collection_id,1437			account(2)1438		));14391440		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1));1441	});1442}14431444#[test]1445fn white_list_test_8() {1446	new_test_ext().execute_with(|| {1447		let collection_id = create_test_collection(&CollectionMode::NFT, 1);14481449		let data = default_nft_data();1450		create_test_item(collection_id, &data.into());14511452		let origin1 = Origin::signed(1);14531454		assert_ok!(TemplateModule::set_public_access_mode(1455			origin1.clone(),1456			collection_id,1457			AccessMode::WhiteList1458		));1459		assert_ok!(TemplateModule::add_to_white_list(1460			origin1.clone(),1461			collection_id,1462			account(1)1463		));1464		assert_ok!(TemplateModule::add_to_white_list(1465			origin1.clone(),1466			collection_id,1467			account(2)1468		));14691470		// do approve1471		assert_ok!(TemplateModule::approve(1472			origin1.clone(),1473			account(1),1474			1,1475			1,1476			51477		));1478		assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 5);14791480		assert_ok!(TemplateModule::transfer_from(1481			origin1,1482			account(1),1483			account(2),1484			1,1485			1,1486			11487		));1488	});1489}14901491// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1492#[test]1493fn white_list_test_9() {1494	new_test_ext().execute_with(|| {1495		let collection_id = create_test_collection(&CollectionMode::NFT, 1);1496		let origin1 = Origin::signed(1);14971498		assert_ok!(TemplateModule::set_public_access_mode(1499			origin1.clone(),1500			collection_id,1501			AccessMode::WhiteList1502		));1503		assert_ok!(TemplateModule::set_mint_permission(1504			origin1,1505			collection_id,1506			false1507		));15081509		let data = default_nft_data();1510		create_test_item(collection_id, &data.into());1511	});1512}15131514// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1515#[test]1516fn white_list_test_10() {1517	new_test_ext().execute_with(|| {1518		let collection_id = create_test_collection(&CollectionMode::NFT, 1);15191520		let origin1 = Origin::signed(1);1521		let origin2 = Origin::signed(2);15221523		assert_ok!(TemplateModule::set_public_access_mode(1524			origin1.clone(),1525			collection_id,1526			AccessMode::WhiteList1527		));1528		assert_ok!(TemplateModule::set_mint_permission(1529			origin1.clone(),1530			collection_id,1531			false1532		));15331534		assert_ok!(TemplateModule::add_collection_admin(1535			origin1,1536			collection_id,1537			account(2)1538		));15391540		assert_ok!(TemplateModule::create_item(1541			origin2,1542			collection_id,1543			account(2),1544			default_nft_data().into()1545		));1546	});1547}15481549// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and white listed address.1550#[test]1551fn white_list_test_11() {1552	new_test_ext().execute_with(|| {1553		let collection_id = create_test_collection(&CollectionMode::NFT, 1);15541555		let origin1 = Origin::signed(1);1556		let origin2 = Origin::signed(2);15571558		assert_ok!(TemplateModule::set_public_access_mode(1559			origin1.clone(),1560			collection_id,1561			AccessMode::WhiteList1562		));1563		assert_ok!(TemplateModule::set_mint_permission(1564			origin1.clone(),1565			collection_id,1566			false1567		));1568		assert_ok!(TemplateModule::add_to_white_list(1569			origin1,1570			collection_id,1571			account(2)1572		));15731574		assert_noop!(1575			TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),1576			Error::<Test>::PublicMintingNotAllowed1577		);1578	});1579}15801581// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-white listed address.1582#[test]1583fn white_list_test_12() {1584	new_test_ext().execute_with(|| {1585		let collection_id = create_test_collection(&CollectionMode::NFT, 1);15861587		let origin1 = Origin::signed(1);1588		let origin2 = Origin::signed(2);15891590		assert_ok!(TemplateModule::set_public_access_mode(1591			origin1.clone(),1592			collection_id,1593			AccessMode::WhiteList1594		));1595		assert_ok!(TemplateModule::set_mint_permission(1596			origin1,1597			collection_id,1598			false1599		));16001601		assert_noop!(1602			TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),1603			Error::<Test>::PublicMintingNotAllowed1604		);1605	});1606}16071608// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1609#[test]1610fn white_list_test_13() {1611	new_test_ext().execute_with(|| {1612		let collection_id = create_test_collection(&CollectionMode::NFT, 1);16131614		let origin1 = Origin::signed(1);16151616		assert_ok!(TemplateModule::set_public_access_mode(1617			origin1.clone(),1618			collection_id,1619			AccessMode::WhiteList1620		));1621		assert_ok!(TemplateModule::set_mint_permission(1622			origin1,1623			collection_id,1624			true1625		));16261627		let data = default_nft_data();1628		create_test_item(collection_id, &data.into());1629	});1630}16311632// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1633#[test]1634fn white_list_test_14() {1635	new_test_ext().execute_with(|| {1636		let collection_id = create_test_collection(&CollectionMode::NFT, 1);16371638		let origin1 = Origin::signed(1);1639		let origin2 = Origin::signed(2);16401641		assert_ok!(TemplateModule::set_public_access_mode(1642			origin1.clone(),1643			collection_id,1644			AccessMode::WhiteList1645		));1646		assert_ok!(TemplateModule::set_mint_permission(1647			origin1.clone(),1648			collection_id,1649			true1650		));16511652		assert_ok!(TemplateModule::add_collection_admin(1653			origin1,1654			collection_id,1655			account(2)1656		));16571658		assert_ok!(TemplateModule::create_item(1659			origin2,1660			1,1661			account(2),1662			default_nft_data().into()1663		));1664	});1665}16661667// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-white listed address.1668#[test]1669fn white_list_test_15() {1670	new_test_ext().execute_with(|| {1671		let collection_id = create_test_collection(&CollectionMode::NFT, 1);16721673		let origin1 = Origin::signed(1);1674		let origin2 = Origin::signed(2);16751676		assert_ok!(TemplateModule::set_public_access_mode(1677			origin1.clone(),1678			collection_id,1679			AccessMode::WhiteList1680		));1681		assert_ok!(TemplateModule::set_mint_permission(1682			origin1,1683			collection_id,1684			true1685		));16861687		assert_noop!(1688			TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),1689			Error::<Test>::AddresNotInWhiteList1690		);1691	});1692}16931694// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by non-privileged and white listed address.1695#[test]1696fn white_list_test_16() {1697	new_test_ext().execute_with(|| {1698		let collection_id = create_test_collection(&CollectionMode::NFT, 1);16991700		let origin1 = Origin::signed(1);1701		let origin2 = Origin::signed(2);17021703		assert_ok!(TemplateModule::set_public_access_mode(1704			origin1.clone(),1705			collection_id,1706			AccessMode::WhiteList1707		));1708		assert_ok!(TemplateModule::set_mint_permission(1709			origin1.clone(),1710			collection_id,1711			true1712		));1713		assert_ok!(TemplateModule::add_to_white_list(1714			origin1,1715			collection_id,1716			account(2)1717		));17181719		assert_ok!(TemplateModule::create_item(1720			origin2,1721			1,1722			account(2),1723			default_nft_data().into()1724		));1725	});1726}17271728// Total number of collections. Positive test1729#[test]1730fn total_number_collections_bound() {1731	new_test_ext().execute_with(|| {1732		create_test_collection(&CollectionMode::NFT, 1);1733	});1734}17351736// Total number of collections. Negotive test1737#[test]1738fn total_number_collections_bound_neg() {1739	new_test_ext().execute_with(|| {1740		let origin1 = Origin::signed(1);17411742		for i in 0..COLLECTION_NUMBER_LIMIT {1743			create_test_collection(&CollectionMode::NFT, i + 1);1744		}17451746		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1747		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1748		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();17491750		// 11-th collection in chain. Expects error1751		assert_noop!(1752			TemplateModule::create_collection(1753				origin1,1754				col_name1,1755				col_desc1,1756				token_prefix1,1757				CollectionMode::NFT1758			),1759			Error::<Test>::TotalCollectionsLimitExceeded1760		);1761	});1762}17631764// Owned tokens by a single address. Positive test1765#[test]1766fn owned_tokens_bound() {1767	new_test_ext().execute_with(|| {1768		let collection_id = create_test_collection(&CollectionMode::NFT, 1);17691770		let data = default_nft_data();1771		create_test_item(collection_id, &data.clone().into());1772		create_test_item(collection_id, &data.into());1773	});1774}17751776// Owned tokens by a single address. Negotive test1777#[test]1778fn owned_tokens_bound_neg() {1779	new_test_ext().execute_with(|| {1780		let collection_id = create_test_collection(&CollectionMode::NFT, 1);17811782		let origin1 = Origin::signed(1);17831784		for _ in 0..ACCOUNT_TOKEN_OWNERSHIP_LIMIT {1785			let data = default_nft_data();1786			create_test_item(collection_id, &data.clone().into());1787		}17881789		let data = default_nft_data();1790		assert_noop!(1791			TemplateModule::create_item(origin1, 1, account(1), data.into()),1792			Error::<Test>::AccountTokenLimitExceeded1793		);1794	});1795}17961797// Number of collection admins. Positive test1798#[test]1799fn collection_admins_bound() {1800	new_test_ext().execute_with(|| {1801		let collection_id = create_test_collection(&CollectionMode::NFT, 1);18021803		let origin1 = Origin::signed(1);18041805		assert_ok!(TemplateModule::add_collection_admin(1806			origin1.clone(),1807			collection_id,1808			account(2)1809		));1810		assert_ok!(TemplateModule::add_collection_admin(1811			origin1,1812			collection_id,1813			account(3)1814		));1815	});1816}18171818// Number of collection admins. Negotive test1819#[test]1820fn collection_admins_bound_neg() {1821	new_test_ext().execute_with(|| {1822		let collection_id = create_test_collection(&CollectionMode::NFT, 1);18231824		let origin1 = Origin::signed(1);18251826		for i in 0..COLLECTION_ADMINS_LIMIT {1827			assert_ok!(TemplateModule::add_collection_admin(1828				origin1.clone(),1829				collection_id,1830				account(2 + i)1831			));1832		}1833		assert_noop!(1834			TemplateModule::add_collection_admin(1835				origin1,1836				collection_id,1837				account(3 + COLLECTION_ADMINS_LIMIT)1838			),1839			Error::<Test>::CollectionAdminsLimitExceeded1840		);1841	});1842}1843// #endregion18441845#[test]1846fn set_const_on_chain_schema() {1847	new_test_ext().execute_with(|| {1848		let collection_id = create_test_collection(&CollectionMode::NFT, 1);18491850		let origin1 = Origin::signed(1);1851		assert_ok!(TemplateModule::set_const_on_chain_schema(1852			origin1,1853			collection_id,1854			b"test const on chain schema".to_vec()1855		));18561857		assert_eq!(1858			TemplateModule::collection_id(collection_id)1859				.unwrap()1860				.const_on_chain_schema,1861			b"test const on chain schema".to_vec()1862		);1863		assert_eq!(1864			TemplateModule::collection_id(collection_id)1865				.unwrap()1866				.variable_on_chain_schema,1867			b"".to_vec()1868		);1869	});1870}18711872#[test]1873fn set_variable_on_chain_schema() {1874	new_test_ext().execute_with(|| {1875		let collection_id = create_test_collection(&CollectionMode::NFT, 1);18761877		let origin1 = Origin::signed(1);1878		assert_ok!(TemplateModule::set_variable_on_chain_schema(1879			origin1,1880			collection_id,1881			b"test variable on chain schema".to_vec()1882		));18831884		assert_eq!(1885			TemplateModule::collection_id(collection_id)1886				.unwrap()1887				.const_on_chain_schema,1888			b"".to_vec()1889		);1890		assert_eq!(1891			TemplateModule::collection_id(collection_id)1892				.unwrap()1893				.variable_on_chain_schema,1894			b"test variable on chain schema".to_vec()1895		);1896	});1897}18981899#[test]1900fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {1901	new_test_ext().execute_with(|| {1902		let collection_id = create_test_collection(&CollectionMode::NFT, 1);19031904		let origin1 = Origin::signed(1);19051906		let data = default_nft_data();1907		create_test_item(1, &data.into());19081909		let variable_data = b"test data".to_vec();1910		assert_ok!(TemplateModule::set_variable_meta_data(1911			origin1,1912			collection_id,1913			1,1914			variable_data.clone()1915		));19161917		assert_eq!(1918			TemplateModule::nft_item_id(collection_id, 1)1919				.unwrap()1920				.variable_data,1921			variable_data1922		);1923	});1924}19251926#[test]1927fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {1928	new_test_ext().execute_with(|| {1929		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);19301931		let origin1 = Origin::signed(1);19321933		let data = default_re_fungible_data();1934		create_test_item(1, &data.into());19351936		let variable_data = b"test data".to_vec();1937		assert_ok!(TemplateModule::set_variable_meta_data(1938			origin1,1939			collection_id,1940			1,1941			variable_data.clone()1942		));19431944		assert_eq!(1945			TemplateModule::refungible_item_id(collection_id, 1)1946				.unwrap()1947				.variable_data,1948			variable_data1949		);1950	});1951}19521953#[test]1954fn set_variable_meta_data_on_fungible_token_fails() {1955	new_test_ext().execute_with(|| {1956		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);19571958		let origin1 = Origin::signed(1);19591960		let data = default_fungible_data();1961		create_test_item(1, &data.into());19621963		let variable_data = b"test data".to_vec();1964		assert_noop!(1965			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),1966			Error::<Test>::CantStoreMetadataInFungibleTokens1967		);1968	});1969}19701971#[test]1972fn set_variable_meta_data_on_nft_token_fails_for_big_data() {1973	new_test_ext().execute_with(|| {1974		let collection_id = create_test_collection(&CollectionMode::NFT, 1);19751976		let origin1 = Origin::signed(1);19771978		let data = default_nft_data();1979		create_test_item(1, &data.into());19801981		let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1982		assert_noop!(1983			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),1984			Error::<Test>::TokenVariableDataLimitExceeded1985		);1986	});1987}19881989#[test]1990fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {1991	new_test_ext().execute_with(|| {1992		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);19931994		let origin1 = Origin::signed(1);19951996		let data = default_re_fungible_data();1997		create_test_item(1, &data.into());19981999		let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();2000		assert_noop!(2001			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),2002			Error::<Test>::TokenVariableDataLimitExceeded2003		);2004	});2005}20062007#[test]2008fn set_variable_meta_data_on_nft_with_item_owner_permission_flag() {2009	new_test_ext().execute_with(|| {2010		//default_limits();20112012		let collection_id = create_test_collection(&CollectionMode::NFT, 1);20132014		let origin1 = Origin::signed(1);20152016		let data = default_nft_data();2017		create_test_item(1, &data.into());20182019		assert_ok!(TemplateModule::set_meta_update_permission_flag(2020			origin1.clone(),2021			collection_id,2022			MetaUpdatePermission::ItemOwner,2023		));20242025		let variable_data = b"ten chars.".to_vec();2026		assert_ok!(TemplateModule::set_variable_meta_data(2027			origin1,2028			collection_id,2029			1,2030			variable_data.clone()2031		));20322033		assert_eq!(2034			TemplateModule::nft_item_id(collection_id, 1)2035				.unwrap()2036				.variable_data,2037			variable_data2038		);2039	});2040}20412042#[test]2043fn set_variable_meta_data_on_nft_with_item_owner_permission_flag_neg() {2044	new_test_ext().execute_with(|| {2045		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);20462047		let origin1 = Origin::signed(1);20482049		assert_ok!(TemplateModule::set_mint_permission(2050			origin1.clone(),2051			collection_id,2052			true2053		));2054		assert_ok!(TemplateModule::add_to_white_list(2055			origin1.clone(),2056			collection_id,2057			account(1)2058		));20592060		let data = default_nft_data();2061		create_test_item(1, &data.into());20622063		assert_ok!(TemplateModule::set_meta_update_permission_flag(2064			origin1.clone(),2065			collection_id,2066			MetaUpdatePermission::ItemOwner,2067		));20682069		let variable_data = b"1234567890123".to_vec();2070		assert_noop!(2071			TemplateModule::set_variable_meta_data(2072				origin1,2073				collection_id,2074				1,2075				variable_data.clone()2076			),2077			Error::<Test>::TokenVariableDataLimitExceeded2078		);2079	})2080}20812082#[test]2083fn collection_transfer_flag_works() {2084	new_test_ext().execute_with(|| {2085		let origin1 = Origin::signed(1);20862087		let collection_id = create_test_collection(&CollectionMode::NFT, 1);2088		assert_ok!(TemplateModule::set_transfers_enabled_flag(origin1, 1, true));20892090		let data = default_nft_data();2091		create_test_item(collection_id, &data.into());2092		assert_eq!(TemplateModule::balance_count(1, 1), 1);2093		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);20942095		let origin1 = Origin::signed(1);20962097		// default scenario2098		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));2099		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));2100		assert_eq!(TemplateModule::balance_count(1, 1), 0);2101		assert_eq!(TemplateModule::balance_count(1, 2), 1);21022103		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);2104	});2105}21062107#[test]2108fn set_variable_meta_data_on_nft_with_admin_flag() {2109	new_test_ext().execute_with(|| {2110		// default_limits();21112112		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);21132114		let origin1 = Origin::signed(1);2115		let origin2 = Origin::signed(2);21162117		assert_ok!(TemplateModule::set_mint_permission(2118			origin2.clone(),2119			collection_id,2120			true2121		));2122		assert_ok!(TemplateModule::add_to_white_list(2123			origin2.clone(),2124			collection_id,2125			account(1)2126		));21272128		assert_ok!(TemplateModule::add_collection_admin(2129			origin2.clone(),2130			collection_id,2131			account(1)2132		));21332134		let data = default_nft_data();2135		create_test_item(1, &data.into());21362137		assert_ok!(TemplateModule::set_meta_update_permission_flag(2138			origin2.clone(),2139			collection_id,2140			MetaUpdatePermission::Admin,2141		));21422143		let variable_data = b"test.".to_vec();2144		assert_ok!(TemplateModule::set_variable_meta_data(2145			origin1,2146			collection_id,2147			1,2148			variable_data.clone()2149		));21502151		assert_eq!(2152			TemplateModule::nft_item_id(collection_id, 1)2153				.unwrap()2154				.variable_data,2155			variable_data2156		);2157	});2158}21592160#[test]2161fn set_variable_meta_data_on_nft_with_admin_flag_neg() {2162	new_test_ext().execute_with(|| {2163		// default_limits();21642165		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);21662167		let origin1 = Origin::signed(1);2168		let origin2 = Origin::signed(2);21692170		assert_ok!(TemplateModule::set_mint_permission(2171			origin2.clone(),2172			collection_id,2173			true2174		));2175		assert_ok!(TemplateModule::add_to_white_list(2176			origin2.clone(),2177			collection_id,2178			account(1)2179		));21802181		let data = default_nft_data();2182		create_test_item(1, &data.into());21832184		assert_ok!(TemplateModule::set_meta_update_permission_flag(2185			origin2.clone(),2186			collection_id,2187			MetaUpdatePermission::Admin,2188		));21892190		let variable_data = b"test.".to_vec();2191		assert_noop!(2192			TemplateModule::set_variable_meta_data(2193				origin1,2194				collection_id,2195				1,2196				variable_data.clone()2197			),2198			Error::<Test>::NoPermission2199		);2200	});2201}22022203#[test]2204fn set_variable_meta_flag_after_freeze() {2205	new_test_ext().execute_with(|| {2206		// default_limits();22072208		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);22092210		let origin2 = Origin::signed(2);22112212		assert_ok!(TemplateModule::set_meta_update_permission_flag(2213			origin2.clone(),2214			collection_id,2215			MetaUpdatePermission::None,2216		));2217		assert_noop!(2218			TemplateModule::set_meta_update_permission_flag(2219				origin2.clone(),2220				collection_id,2221				MetaUpdatePermission::Admin2222			),2223			Error::<Test>::MetadataFlagFrozen2224		);2225	});2226}22272228#[test]2229fn set_variable_meta_data_on_nft_with_none_flag_neg() {2230	new_test_ext().execute_with(|| {2231		// default_limits();22322233		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);2234		let origin1 = Origin::signed(1);22352236		let data = default_nft_data();2237		create_test_item(1, &data.into());22382239		assert_ok!(TemplateModule::set_meta_update_permission_flag(2240			origin1.clone(),2241			collection_id,2242			MetaUpdatePermission::None,2243		));22442245		let variable_data = b"test.".to_vec();2246		assert_noop!(2247			TemplateModule::set_variable_meta_data(2248				origin1.clone(),2249				collection_id,2250				1,2251				variable_data.clone()2252			),2253			Error::<Test>::MetadataUpdateDenied2254		);2255	});2256}22572258#[test]2259fn collection_transfer_flag_works_neg() {2260	new_test_ext().execute_with(|| {2261		let origin1 = Origin::signed(1);22622263		let collection_id = create_test_collection(&CollectionMode::NFT, 1);2264		assert_ok!(TemplateModule::set_transfers_enabled_flag(2265			origin1, 1, false2266		));22672268		let data = default_nft_data();2269		create_test_item(collection_id, &data.into());2270		assert_eq!(TemplateModule::balance_count(1, 1), 1);2271		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);22722273		let origin1 = Origin::signed(1);22742275		// default scenario2276		assert_noop!(2277			TemplateModule::transfer(origin1, account(2), 1, 1, 1000),2278			Error::<Test>::TransferNotAllowed2279		);2280		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(1));2281		assert_eq!(TemplateModule::balance_count(1, 1), 1);2282		assert_eq!(TemplateModule::balance_count(1, 2), 0);22832284		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);2285	});2286}
addedtests/src/limits.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/limits.test.ts
@@ -0,0 +1,378 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import { IKeyringPair } from '@polkadot/types/types';
+import privateKey from './substrate/privateKey';
+import usingApi from './substrate/substrate-api';
+import {
+  createCollectionExpectSuccess,
+  destroyCollectionExpectSuccess,
+  setCollectionLimitsExpectSuccess,
+  setCollectionSponsorExpectSuccess,
+  confirmSponsorshipExpectSuccess,
+  createItemExpectSuccess,
+  createItemExpectFailure,
+  transferExpectSuccess,
+  getFreeBalance,
+  waitNewBlocks,
+} from './util/helpers'; 
+import { expect } from 'chai';
+
+describe('Number of tokens per address (NFT)', () => {
+  let Alice: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+    });
+  });
+
+  it('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {
+      
+    const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { AccountTokenOwnershipLimit: 20 });
+    for(let i = 0; i < 10; i++){
+      await createItemExpectSuccess(Alice, collectionId, 'NFT');
+    }
+    await createItemExpectFailure(Alice, collectionId, 'NFT');
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+
+  it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {
+
+    const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { AccountTokenOwnershipLimit: 1 });
+    await createItemExpectSuccess(Alice, collectionId, 'NFT');
+    await createItemExpectFailure(Alice, collectionId, 'NFT');
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+});
+
+describe('Number of tokens per address (ReFungible)', () => {
+  let Alice: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+    });
+  });
+
+  it('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {   
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible' }});
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { AccountTokenOwnershipLimit: 20 });
+    for(let i = 0; i < 10; i++){
+      await createItemExpectSuccess(Alice, collectionId, 'ReFungible');
+    }
+    await createItemExpectFailure(Alice, collectionId, 'ReFungible');
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+
+  it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible' }});
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { AccountTokenOwnershipLimit: 1 });
+    await createItemExpectSuccess(Alice, collectionId, 'ReFungible');
+    await createItemExpectFailure(Alice, collectionId, 'ReFungible');
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+});
+
+describe('Sponsor timeout (NFT)', () => {
+  let Alice: IKeyringPair;
+  let Bob: IKeyringPair;
+  let Charlie: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+      Charlie = privateKey('//Charlie');
+    });
+  });
+
+  it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {  
+    const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { SponsorTimeout: 7 });
+    const tokenId = await createItemExpectSuccess(Alice, collectionId, 'NFT');
+    await setCollectionSponsorExpectSuccess(collectionId, Alice.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
+    await transferExpectSuccess(collectionId, tokenId, Alice, Bob);
+    const aliceBalanceBefore = (await getFreeBalance(Alice)).toNumber();
+
+    // check setting SponsorTimeout = 5, fail
+    await waitNewBlocks(5);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie);
+    const aliceBalanceAfterUnsponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
+
+    // check setting SponsorTimeout = 7, success
+    await waitNewBlocks(2); // 5 + 2
+    await transferExpectSuccess(collectionId, tokenId, Charlie, Bob);
+    const aliceBalanceAfterSponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+
+  it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {
+
+    const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { SponsorTimeout: 1 });
+    const tokenId = await createItemExpectSuccess(Alice, collectionId, 'NFT');
+    await setCollectionSponsorExpectSuccess(collectionId, Alice.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
+    await transferExpectSuccess(collectionId, tokenId, Alice, Bob);
+    const aliceBalanceBefore = (await getFreeBalance(Alice)).toNumber();
+
+    // check setting SponsorTimeout = 1, fail
+    await waitNewBlocks(1);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie);
+    const aliceBalanceAfterUnsponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
+
+    // check setting SponsorTimeout = 5, success
+    await waitNewBlocks(4);
+    await transferExpectSuccess(collectionId, tokenId, Charlie, Bob);
+    const aliceBalanceAfterSponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+});
+
+describe('Sponsor timeout (Fungible)', () => {
+  let Alice: IKeyringPair;
+  let Bob: IKeyringPair;
+  let Charlie: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+      Charlie = privateKey('//Charlie');
+    });
+  });
+
+  it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {  
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { SponsorTimeout: 7 });
+    const tokenId = await createItemExpectSuccess(Alice, collectionId, 'Fungible');
+    await setCollectionSponsorExpectSuccess(collectionId, Alice.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
+    await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 10, 'Fungible');
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');
+    const aliceBalanceBefore = (await getFreeBalance(Alice)).toNumber();
+
+    // check setting SponsorTimeout = 5, fail
+    await waitNewBlocks(5);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');
+    const aliceBalanceAfterUnsponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
+
+    // check setting SponsorTimeout = 7, success
+    await waitNewBlocks(2); // 5 + 2
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');
+    const aliceBalanceAfterSponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
+
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+
+  it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {
+
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { SponsorTimeout: 1 });
+    const tokenId = await createItemExpectSuccess(Alice, collectionId, 'Fungible');
+    await setCollectionSponsorExpectSuccess(collectionId, Alice.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
+    await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 10, 'Fungible');
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');
+    const aliceBalanceBefore = (await getFreeBalance(Alice)).toNumber();
+
+    // check setting SponsorTimeout = 1, fail
+    await waitNewBlocks(1);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');
+    const aliceBalanceAfterUnsponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
+
+    // check setting SponsorTimeout = 5, success
+    await waitNewBlocks(4);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');
+    const aliceBalanceAfterSponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
+
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+});
+
+describe('Sponsor timeout (ReFungible)', () => {
+  let Alice: IKeyringPair;
+  let Bob: IKeyringPair;
+  let Charlie: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+      Charlie = privateKey('//Charlie');
+    });
+  });
+
+  it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {  
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible' }});
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { SponsorTimeout: 7 });
+    const tokenId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible');
+    await setCollectionSponsorExpectSuccess(collectionId, Alice.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
+    await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 100, 'ReFungible');
+    const aliceBalanceBefore = (await getFreeBalance(Alice)).toNumber();
+
+    // check setting SponsorTimeout = 5, fail
+    await waitNewBlocks(5);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 20, 'ReFungible');
+    const aliceBalanceAfterUnsponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
+
+    // check setting SponsorTimeout = 7, success
+    await waitNewBlocks(2); // 5 + 2
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 20, 'ReFungible');
+    const aliceBalanceAfterSponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+
+  it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {
+
+    const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { SponsorTimeout: 1 });
+    const tokenId = await createItemExpectSuccess(Alice, collectionId, 'NFT');
+    await setCollectionSponsorExpectSuccess(collectionId, Alice.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
+    await transferExpectSuccess(collectionId, tokenId, Alice, Bob);
+    const aliceBalanceBefore = (await getFreeBalance(Alice)).toNumber();
+
+    // check setting SponsorTimeout = 1, fail
+    await waitNewBlocks(1);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie);
+    const aliceBalanceAfterUnsponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);
+
+    // check setting SponsorTimeout = 5, success
+    await waitNewBlocks(4);
+    await transferExpectSuccess(collectionId, tokenId, Charlie, Bob);
+    const aliceBalanceAfterSponsoredTransaction = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
+    await destroyCollectionExpectSuccess(collectionId);
+  });
+});
+
+describe('Collection zero limits (NFT)', () => {
+  let Alice: IKeyringPair;
+  let Bob: IKeyringPair;
+  let Charlie: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+      Charlie = privateKey('//Charlie');
+    });
+  });
+
+  it('Limits have 0 in tokens per address field, the chain limits are applied', async () => {  
+    const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { AccountTokenOwnershipLimit: 0 });
+    for(let i = 0; i < 10; i++){
+      await createItemExpectSuccess(Alice, collectionId, 'NFT');
+    }
+    await createItemExpectFailure(Alice, collectionId, 'NFT');
+  });
+
+  it('Limits have 0 in sponsor timeout, no limits are applied', async () => {
+
+    const collectionId = await createCollectionExpectSuccess({ mode: { type: 'NFT' } });
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { SponsorTimeout: 0 });
+    const tokenId = await createItemExpectSuccess(Alice, collectionId, 'NFT');
+    await setCollectionSponsorExpectSuccess(collectionId, Alice.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
+    await transferExpectSuccess(collectionId, tokenId, Alice, Bob);
+    const aliceBalanceBefore = (await getFreeBalance(Alice)).toNumber();
+
+    // check setting SponsorTimeout = 0, success with next block
+    await waitNewBlocks(1);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie);
+    const aliceBalanceAfterSponsoredTransaction1 = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
+  });
+});
+
+describe.only('Collection zero limits (Fungible)', () => {
+  let Alice: IKeyringPair;
+  let Bob: IKeyringPair;
+  let Charlie: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+      Charlie = privateKey('//Charlie');
+    });
+  });
+
+  it('Limits have 0 in sponsor timeout, no limits are applied', async () => {
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { SponsorTimeout: 0 });
+    const tokenId = await createItemExpectSuccess(Alice, collectionId, 'Fungible');
+    await setCollectionSponsorExpectSuccess(collectionId, Alice.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
+    await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 10, 'Fungible');
+    const aliceBalanceBefore = (await getFreeBalance(Alice)).toNumber();
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');
+
+    // check setting SponsorTimeout = 0, success with next block
+    await waitNewBlocks(1);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 2, 'Fungible');
+    const aliceBalanceAfterSponsoredTransaction1 = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
+  });
+});
+
+describe.only('Collection zero limits (ReFungible)', () => {
+  let Alice: IKeyringPair;
+  let Bob: IKeyringPair;
+  let Charlie: IKeyringPair;
+
+  before(async () => {
+    await usingApi(async () => {
+      Alice = privateKey('//Alice');
+      Bob = privateKey('//Bob');
+      Charlie = privateKey('//Charlie');
+    });
+  });
+
+  it('Limits have 0 in tokens per address field, the chain limits are applied', async () => {  
+    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible' }});
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { AccountTokenOwnershipLimit: 0 });
+    for(let i = 0; i < 10; i++){
+      await createItemExpectSuccess(Alice, collectionId, 'ReFungible');
+    }
+    await createItemExpectFailure(Alice, collectionId, 'ReFungible');
+  });
+
+  it('Limits have 0 in sponsor timeout, no limits are applied', async () => {
+
+    const collectionId = await createCollectionExpectSuccess({ mode: { type: 'ReFungible' } });
+    await setCollectionLimitsExpectSuccess(Alice, collectionId, { SponsorTimeout: 0 });
+    const tokenId = await createItemExpectSuccess(Alice, collectionId, 'ReFungible');
+    await setCollectionSponsorExpectSuccess(collectionId, Alice.address);
+    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
+    await transferExpectSuccess(collectionId, tokenId, Alice, Bob, 100, 'ReFungible');
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 20, 'ReFungible');
+    const aliceBalanceBefore = (await getFreeBalance(Alice)).toNumber();
+
+    // check setting SponsorTimeout = 0, success with next block
+    await waitNewBlocks(1);
+    await transferExpectSuccess(collectionId, tokenId, Bob, Charlie, 20, 'ReFungible');
+    const aliceBalanceAfterSponsoredTransaction1 = (await getFreeBalance(Alice)).toNumber();
+    expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
+  });
+});
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -811,6 +811,17 @@
 }
 
 export async function
+getFreeBalance(account: IKeyringPair) : Promise<BigNumber>
+{
+  let balance = new BigNumber(0) ;
+  await usingApi(async (api) => { 
+    balance = new BigNumber((await api.query.system.account(account.address)).data.free.toString());  
+  });
+
+  return balance;
+}
+
+export async function
 scheduleTransferExpectSuccess(
   collectionId: number,
   tokenId: number,
@@ -884,8 +895,11 @@
     if (type === 'ReFungible') {
       const nftItemData =
         (await api.query.nft.reFungibleItemList(collectionId, tokenId)).toJSON() as unknown as IReFungibleTokenDataType;
-      expect(nftItemData.Owner[0].Owner).to.be.deep.equal(to);
-      expect(nftItemData.Owner[0].Fraction.toString()).to.be.equal(value.toString());
+      const expectedOwner = toSubstrateAddress(to);
+      const ownerIndex = nftItemData.Owner.findIndex(v => toSubstrateAddress(v.Owner as any as string) == expectedOwner);
+      expect(ownerIndex).to.not.equal(-1);
+      expect(nftItemData.Owner[ownerIndex].Owner).to.be.deep.equal(normalizeAccountId(to));
+      expect(nftItemData.Owner[ownerIndex].Fraction).to.be.greaterThanOrEqual(value as number);
     }
   });
 }
@@ -1190,7 +1204,6 @@
 export async function waitNewBlocks(blocksCount = 1): Promise<void> {
   await usingApi(async (api) => {
     const promise = new Promise<void>(async (resolve) => {
-
       const unsubscribe = await api.rpc.chain.subscribeNewHeads(() => {
         if (blocksCount > 0) {
           blocksCount--;