git.delta.rocks / unique-network / refs/commits / 415353264b69

difftreelog

style reformat code

Yaroslav Bolyukin2022-05-30parent: #d048005.patch.diff
in: master

19 files changed

modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -30,8 +30,7 @@
 // RMRK
 use rmrk_rpc::RmrkApi as RmrkRuntimeApi;
 use up_data_structs::{
-	RmrkCollectionId, RmrkNftId, RmrkBaseId, RmrkNftChild, RmrkThemeName,
-	RmrkResourceId,
+	RmrkCollectionId, RmrkNftId, RmrkBaseId, RmrkNftChild, RmrkThemeName, RmrkResourceId,
 };
 
 pub use rmrk_unique_rpc::RmrkApi;
modifiednode/cli/src/service.rsdiffbeforeafterboth
--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -364,7 +364,8 @@
 			RmrkBaseInfo<AccountId>,
 			RmrkPartType,
 			RmrkTheme,
-		>*/ + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+		>*/
+		+ substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
 		+ sp_api::Metadata<Block>
 		+ sp_offchain::OffchainWorkerApi<Block>
 		+ cumulus_primitives_core::CollectCollationInfo<Block>,
@@ -656,7 +657,8 @@
 			RmrkBaseInfo<AccountId>,
 			RmrkPartType,
 			RmrkTheme,
-		>*/ + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+		>*/
+		+ substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
 		+ sp_api::Metadata<Block>
 		+ sp_offchain::OffchainWorkerApi<Block>
 		+ cumulus_primitives_core::CollectCollationInfo<Block>
@@ -800,7 +802,8 @@
 			RmrkBaseInfo<AccountId>,
 			RmrkPartType,
 			RmrkTheme,
-		>*/ + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
+		>*/
+		+ substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
 		+ sp_api::Metadata<Block>
 		+ sp_offchain::OffchainWorkerApi<Block>
 		+ cumulus_primitives_core::CollectCollationInfo<Block>
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -501,7 +501,6 @@
 			PhantomType<(
 				TokenData<T::CrossAccountId>,
 				RpcCollection<T::AccountId>,
-
 				// RMRK
 				RmrkCollectionInfo<T::AccountId>,
 				RmrkInstanceInfo<T::AccountId>,
@@ -526,19 +525,34 @@
 					if !v.offchain_schema.is_empty() {
 						props.push(Property {
 							key: b"_old_offchainSchema".to_vec().try_into().unwrap(),
-							value: v.offchain_schema.clone().into_inner().try_into().expect("offchain schema too big"),
+							value: v
+								.offchain_schema
+								.clone()
+								.into_inner()
+								.try_into()
+								.expect("offchain schema too big"),
 						});
 					}
 					if !v.variable_on_chain_schema.is_empty() {
 						props.push(Property {
 							key: b"_old_variableOnChainSchema".to_vec().try_into().unwrap(),
-							value: v.variable_on_chain_schema.clone().into_inner().try_into().expect("offchain schema too big"),
+							value: v
+								.variable_on_chain_schema
+								.clone()
+								.into_inner()
+								.try_into()
+								.expect("offchain schema too big"),
 						});
 					}
 					if !v.const_on_chain_schema.is_empty() {
 						props.push(Property {
 							key: b"_old_constOnChainSchema".to_vec().try_into().unwrap(),
-							value: v.const_on_chain_schema.clone().into_inner().try_into().expect("offchain schema too big"),
+							value: v
+								.const_on_chain_schema
+								.clone()
+								.into_inner()
+								.try_into()
+								.expect("offchain schema too big"),
 						});
 					}
 					props.push(Property {
@@ -546,13 +560,17 @@
 						value: match v.schema_version {
 							SchemaVersion::ImageURL => b"ImageUrl".as_slice(),
 							SchemaVersion::Unique => b"Unique".as_slice(),
-						}.to_vec().try_into().unwrap(),
+						}
+						.to_vec()
+						.try_into()
+						.unwrap(),
 					});
 					Self::set_scoped_collection_properties(
 						id,
 						PropertyScope::None,
 						props.into_iter(),
-					).expect("existing data larger than properties");
+					)
+					.expect("existing data larger than properties");
 					let mut new = CollectionVersion2::from(v.clone());
 					new.permissions.access = Some(v.access);
 					new.permissions.mint_mode = Some(v.mint_mode);
@@ -644,18 +662,12 @@
 
 		let token_property_permissions = <CollectionPropertyPermissions<T>>::get(collection)
 			.into_iter()
-			.map(|(key, permission)| PropertyKeyPermission {
-				key,
-				permission,
-			})
+			.map(|(key, permission)| PropertyKeyPermission { key, permission })
 			.collect();
 
 		let properties = <CollectionProperties<T>>::get(collection)
 			.into_iter()
-			.map(|(key, value)| Property {
-				key,
-				value,
-			})
+			.map(|(key, value)| Property { key, value })
 			.collect();
 
 		let permissions = CollectionPermissions {
@@ -751,7 +763,9 @@
 				.unwrap_or_else(|| Ok(CollectionLimits::default()))?,
 			permissions: data
 				.permissions
-				.map(|permissions| Self::clamp_permissions(data.mode.clone(), &Default::default(), permissions))
+				.map(|permissions| {
+					Self::clamp_permissions(data.mode.clone(), &Default::default(), permissions)
+				})
 				.unwrap_or_else(|| Ok(CollectionPermissions::default()))?,
 		};
 
@@ -1005,10 +1019,7 @@
 			.unwrap_or_else(|| {
 				properties
 					.into_iter()
-					.map(|(key, value)| Property {
-						key,
-						value,
-					})
+					.map(|(key, value)| Property { key, value })
 					.collect()
 			});
 
@@ -1037,10 +1048,7 @@
 			.unwrap_or_else(|| {
 				permissions
 					.into_iter()
-					.map(|(key, permission)| PropertyKeyPermission {
-						key,
-						permission,
-					})
+					.map(|(key, permission)| PropertyKeyPermission { key, permission })
 					.collect()
 			});
 
@@ -1276,17 +1284,9 @@
 		budget: &dyn Budget,
 	) -> DispatchResult;
 
-	fn nest(
-		&self,
-		under: TokenId,
-		to_nest: (CollectionId, TokenId)
-	);
+	fn nest(&self, under: TokenId, to_nest: (CollectionId, TokenId));
 
-	fn unnest(
-		&self,
-		under: TokenId,
-		to_nest: (CollectionId, TokenId)
-	);
+	fn unnest(&self, under: TokenId, to_nest: (CollectionId, TokenId));
 
 	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId>;
 	fn collection_tokens(&self) -> Vec<TokenId>;
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -298,17 +298,9 @@
 		fail!(<Error<T>>::FungibleDisallowsNesting)
 	}
 
-	fn nest(
-		&self,
-		_under: TokenId,
-		_to_nest: (CollectionId, TokenId)
-	) {}
+	fn nest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}
 
-	fn unnest(
-		&self,
-		_under: TokenId,
-		_to_nest: (CollectionId, TokenId)
-	) {}
+	fn unnest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}
 
 	fn collection_tokens(&self) -> Vec<TokenId> {
 		vec![TokenId::default()]
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -184,11 +184,7 @@
 
 		if balance == 0 {
 			<Balance<T>>::remove((collection.id, owner));
-			<PalletStructure<T>>::unnest_if_nested(
-				owner,
-				collection.id,
-				TokenId::default()
-			);
+			<PalletStructure<T>>::unnest_if_nested(owner, collection.id, TokenId::default());
 		} else {
 			<Balance<T>>::insert((collection.id, owner), balance);
 		}
@@ -249,18 +245,14 @@
 			to,
 			collection.id,
 			TokenId::default(),
-			nesting_budget
+			nesting_budget,
 		)?;
 
 		if let Some(balance_to) = balance_to {
 			// from != to
 			if balance_from == 0 {
 				<Balance<T>>::remove((collection.id, from));
-				<PalletStructure<T>>::unnest_if_nested(
-					from,
-					collection.id,
-					TokenId::default()
-				);
+				<PalletStructure<T>>::unnest_if_nested(from, collection.id, TokenId::default());
 			} else {
 				<Balance<T>>::insert((collection.id, from), balance_from);
 			}
@@ -333,7 +325,11 @@
 		<TotalSupply<T>>::insert(collection.id, total_supply);
 		for (user, amount) in balances {
 			<Balance<T>>::insert((collection.id, &user), amount);
-			<PalletStructure<T>>::nest_if_sent_to_token_unchecked(&user, collection.id, TokenId::default());
+			<PalletStructure<T>>::nest_if_sent_to_token_unchecked(
+				&user,
+				collection.id,
+				TokenId::default(),
+			);
 			<PalletEvm<T>>::deposit_log(
 				ERC20Events::Transfer {
 					from: H160::default(),
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -22,7 +22,7 @@
 	PropertyKeyPermission, PropertyValue,
 };
 use pallet_common::{
-	CommonCollectionOperations, CommonWeightInfo, with_weight, weights::WeightInfo as _
+	CommonCollectionOperations, CommonWeightInfo, with_weight, weights::WeightInfo as _,
 };
 use sp_runtime::DispatchError;
 use sp_std::vec::Vec;
@@ -353,19 +353,11 @@
 		<Pallet<T>>::check_nesting(self, sender, from, under, budget)
 	}
 
-	fn nest(
-		&self,
-		under: TokenId,
-		to_nest: (CollectionId, TokenId)
-	) {
+	fn nest(&self, under: TokenId, to_nest: (CollectionId, TokenId)) {
 		<Pallet<T>>::nest((self.id, under), to_nest);
 	}
 
-	fn unnest(
-		&self,
-		under: TokenId,
-		to_unnest: (CollectionId, TokenId)
-	) {
+	fn unnest(&self, under: TokenId, to_unnest: (CollectionId, TokenId)) {
 		<Pallet<T>>::unnest((self.id, under), to_unnest);
 	}
 
@@ -415,10 +407,7 @@
 		.unwrap_or_else(|| {
 			properties
 				.into_iter()
-				.map(|(key, value)| Property {
-					key,
-					value,
-				})
+				.map(|(key, value)| Property { key, value })
 				.collect()
 		})
 	}
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -426,11 +426,10 @@
 	Ok(a)
 }
 
-fn has_token_permission<T: Config>(
-	collection_id: CollectionId,
-	key: &PropertyKey,
-) -> bool {
-	if let Ok(token_property_permissions) = CollectionPropertyPermissions::<T>::try_get(collection_id) {
+fn has_token_permission<T: Config>(collection_id: CollectionId, key: &PropertyKey) -> bool {
+	if let Ok(token_property_permissions) =
+		CollectionPropertyPermissions::<T>::try_get(collection_id)
+	{
 		return token_property_permissions.contains_key(key);
 	}
 
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -164,31 +164,44 @@
 		fn on_runtime_upgrade() -> Weight {
 			if StorageVersion::get::<Pallet<T>>() < StorageVersion::new(1) {
 				let mut had_consts = BTreeSet::new();
-				<TokenData<T>>::translate::<ItemDataVersion1<T::CrossAccountId>, _>(|(collection, token), v| {
-					let mut props = vec![];
-					if !v.const_data.is_empty() {
-						props.push(Property {
-							key: b"_old_constData".to_vec().try_into().unwrap(),
-							value: v.const_data.clone().into_inner().try_into().expect("const too long"),
-						});
-						had_consts.insert(collection);
-					}
-					if !v.variable_data.is_empty() {
-						props.push(Property {
-							key: b"_old_variableData".to_vec().try_into().unwrap(),
-							value: v.variable_data.clone().into_inner().try_into().expect("variable too long"),
-						})
-					}
-					if !props.is_empty() {
-						Self::set_scoped_token_properties(
-							collection,
-							token,
-							PropertyScope::None,
-							props.into_iter(),
-						).expect("existing token data exceeds property storage");
-					}
-					Some(<ItemDataVersion2<T::CrossAccountId>>::from(v))
-				});
+				<TokenData<T>>::translate::<ItemDataVersion1<T::CrossAccountId>, _>(
+					|(collection, token), v| {
+						let mut props = vec![];
+						if !v.const_data.is_empty() {
+							props.push(Property {
+								key: b"_old_constData".to_vec().try_into().unwrap(),
+								value: v
+									.const_data
+									.clone()
+									.into_inner()
+									.try_into()
+									.expect("const too long"),
+							});
+							had_consts.insert(collection);
+						}
+						if !v.variable_data.is_empty() {
+							props.push(Property {
+								key: b"_old_variableData".to_vec().try_into().unwrap(),
+								value: v
+									.variable_data
+									.clone()
+									.into_inner()
+									.try_into()
+									.expect("variable too long"),
+							})
+						}
+						if !props.is_empty() {
+							Self::set_scoped_token_properties(
+								collection,
+								token,
+								PropertyScope::None,
+								props.into_iter(),
+							)
+							.expect("existing token data exceeds property storage");
+						}
+						Some(<ItemDataVersion2<T::CrossAccountId>>::from(v))
+					},
+				);
 				for collection in had_consts {
 					<PalletCommon<T>>::set_property_permission_unchecked(
 						collection,
@@ -199,8 +212,9 @@
 								collection_admin: true,
 								token_owner: false,
 							},
-						}
-					).expect("failed to configure permission");
+						},
+					)
+					.expect("failed to configure permission");
 				}
 			}
 
@@ -263,7 +277,7 @@
 		collection_id: CollectionId,
 		token_id: TokenId,
 		scope: PropertyScope,
-		properties: impl Iterator<Item=Property>,
+		properties: impl Iterator<Item = Property>,
 	) -> DispatchResult {
 		TokenProperties::<T>::try_mutate((collection_id, token_id), |stored_properties| {
 			stored_properties.try_scoped_set_from_iter(scope, properties)
@@ -347,11 +361,7 @@
 			<AccountBalance<T>>::insert((collection.id, token_data.owner.clone()), balance);
 		}
 
-		<PalletStructure<T>>::unnest_if_nested(
-			&token_data.owner,
-			collection.id,
-			token
-		);
+		<PalletStructure<T>>::unnest_if_nested(&token_data.owner, collection.id, token);
 
 		<Owned<T>>::remove((collection.id, &token_data.owner, token));
 		<TokensBurnt<T>>::insert(collection.id, burnt);
@@ -589,16 +599,12 @@
 			to,
 			collection.id,
 			token,
-			nesting_budget
+			nesting_budget,
 		)?;
 
 		// =========
 
-		<PalletStructure<T>>::unnest_if_nested(
-			from,
-			collection.id,
-			token
-		);
+		<PalletStructure<T>>::unnest_if_nested(from, collection.id, token);
 
 		<TokenData<T>>::insert(
 			(collection.id, token),
@@ -709,7 +715,11 @@
 					},
 				);
 
-				<PalletStructure<T>>::nest_if_sent_to_token_unchecked(&data.owner, collection.id, TokenId(token));
+				<PalletStructure<T>>::nest_if_sent_to_token_unchecked(
+					&data.owner,
+					collection.id,
+					TokenId(token),
+				);
 
 				if let Err(e) = Self::set_token_properties(
 					collection,
@@ -958,31 +968,24 @@
 		Ok(())
 	}
 
-	fn nest(
-		under: (CollectionId, TokenId),
-		to_nest: (CollectionId, TokenId),
-	) {
-		<TokenChildren<T>>::insert(
-			(under.0, under.1, (to_nest.0, to_nest.1)),
-			true
-		);
+	fn nest(under: (CollectionId, TokenId), to_nest: (CollectionId, TokenId)) {
+		<TokenChildren<T>>::insert((under.0, under.1, (to_nest.0, to_nest.1)), true);
 	}
 
-	fn unnest(
-		under: (CollectionId, TokenId),
-		to_unnest: (CollectionId, TokenId),
-	) {
-		<TokenChildren<T>>::remove(
-			(under.0, under.1, to_unnest)
-		);
+	fn unnest(under: (CollectionId, TokenId), to_unnest: (CollectionId, TokenId)) {
+		<TokenChildren<T>>::remove((under.0, under.1, to_unnest));
 	}
 
 	fn collection_has_tokens(collection_id: CollectionId) -> bool {
-		<TokenData<T>>::iter_prefix((collection_id,)).next().is_some()
+		<TokenData<T>>::iter_prefix((collection_id,))
+			.next()
+			.is_some()
 	}
 
 	fn token_has_children(collection_id: CollectionId, token_id: TokenId) -> bool {
-		<TokenChildren<T>>::iter_prefix((collection_id, token_id)).next().is_some()
+		<TokenChildren<T>>::iter_prefix((collection_id, token_id))
+			.next()
+			.is_some()
 	}
 
 	/// Delegated to `create_multiple_items`
modifiedpallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/lib.rs
+++ b/pallets/proxy-rmrk-core/src/lib.rs
@@ -21,7 +21,9 @@
 use sp_runtime::{DispatchError, Permill, traits::StaticLookup};
 use sp_std::vec::Vec;
 use up_data_structs::*;
-use pallet_common::{Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations};
+use pallet_common::{
+	Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations,
+};
 use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle, TokenData};
 use pallet_evm::account::CrossAccountId;
 use core::convert::AsRef;
@@ -38,18 +40,17 @@
 
 #[frame_support::pallet]
 pub mod pallet {
-    use super::*;
-    use pallet_evm::account;
+	use super::*;
+	use pallet_evm::account;
 
 	#[pallet::config]
-	pub trait Config: frame_system::Config
-                    + pallet_common::Config
-                    + pallet_nonfungible::Config
-                    + account::Config {
+	pub trait Config:
+		frame_system::Config + pallet_common::Config + pallet_nonfungible::Config + account::Config
+	{
 		type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
 	}
 
-    #[pallet::storage]
+	#[pallet::storage]
 	#[pallet::getter(fn collection_index)]
 	pub type CollectionIndex<T: Config> = StorageValue<_, RmrkCollectionId, ValueQuery>;
 
@@ -60,33 +61,33 @@
 	#[pallet::event]
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config> {
-        CollectionCreated {
+		CollectionCreated {
 			issuer: T::AccountId,
 			collection_id: RmrkCollectionId,
 		},
-        CollectionDestroyed {
+		CollectionDestroyed {
 			issuer: T::AccountId,
 			collection_id: RmrkCollectionId,
 		},
-        IssuerChanged {
+		IssuerChanged {
 			old_issuer: T::AccountId,
 			new_issuer: T::AccountId,
 			collection_id: RmrkCollectionId,
 		},
-        CollectionLocked {
+		CollectionLocked {
 			issuer: T::AccountId,
 			collection_id: RmrkCollectionId,
 		},
-        NftMinted {
+		NftMinted {
 			owner: T::AccountId,
 			collection_id: RmrkCollectionId,
 			nft_id: RmrkNftId,
 		},
-        NFTBurned {
+		NFTBurned {
 			owner: T::AccountId,
 			nft_id: RmrkNftId,
 		},
-        PropertySet {
+		PropertySet {
 			collection_id: RmrkCollectionId,
 			maybe_nft_id: Option<RmrkNftId>,
 			key: RmrkKeyString,
@@ -96,24 +97,24 @@
 
 	#[pallet::error]
 	pub enum Error<T> {
-        /* Unique-specific events */
-        CorruptedCollectionType,
-        NftTypeEncodeError,
-        RmrkPropertyKeyIsTooLong,
-        RmrkPropertyValueIsTooLong,
+		/* Unique-specific events */
+		CorruptedCollectionType,
+		NftTypeEncodeError,
+		RmrkPropertyKeyIsTooLong,
+		RmrkPropertyValueIsTooLong,
 
-        /* RMRK compatible events */
-        CollectionNotEmpty,
-        NoAvailableCollectionId,
-        NoAvailableNftId,
-        CollectionUnknown,
-        NoPermission,
-        CollectionFullOrLocked,
+		/* RMRK compatible events */
+		CollectionNotEmpty,
+		NoAvailableCollectionId,
+		NoAvailableNftId,
+		CollectionUnknown,
+		NoPermission,
+		CollectionFullOrLocked,
 	}
 
 	#[pallet::call]
 	impl<T: Config> Pallet<T> {
-        #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn create_collection(
 			origin: OriginFor<T>,
@@ -121,127 +122,141 @@
 			max: Option<u32>,
 			symbol: RmrkCollectionSymbol,
 		) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
+			let sender = ensure_signed(origin)?;
 
-            let limits = CollectionLimits {
-                owner_can_transfer: Some(false),
-                token_limit: max,
-                ..Default::default()
-            };
+			let limits = CollectionLimits {
+				owner_can_transfer: Some(false),
+				token_limit: max,
+				..Default::default()
+			};
 
-            let data = CreateCollectionData {
-                limits: Some(limits),
-                token_prefix: symbol.into_inner()
-                    .try_into()
-                    .map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,
-                ..Default::default()
-            };
+			let data = CreateCollectionData {
+				limits: Some(limits),
+				token_prefix: symbol
+					.into_inner()
+					.try_into()
+					.map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,
+				..Default::default()
+			};
 
-            let collection_id_res = <PalletNft<T>>::init_collection(sender.clone(), data);
+			let collection_id_res = <PalletNft<T>>::init_collection(sender.clone(), data);
 
-            if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {
-                return Err(<Error<T>>::NoAvailableCollectionId.into());
-            }
+			if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {
+				return Err(<Error<T>>::NoAvailableCollectionId.into());
+			}
 
-            let collection_id = collection_id_res?;
+			let collection_id = collection_id_res?;
 
-            <PalletCommon<T>>::set_scoped_collection_properties(
-                collection_id,
-                PropertyScope::Rmrk,
-                [
-                    Self::rmrk_property(Metadata, &metadata)?,
-                    Self::rmrk_property(CollectionType, &misc::CollectionType::Regular)?,
-                ].into_iter()
-            )?;
+			<PalletCommon<T>>::set_scoped_collection_properties(
+				collection_id,
+				PropertyScope::Rmrk,
+				[
+					Self::rmrk_property(Metadata, &metadata)?,
+					Self::rmrk_property(CollectionType, &misc::CollectionType::Regular)?,
+				]
+				.into_iter(),
+			)?;
 
-            <CollectionIndex<T>>::mutate(|n| *n += 1);
+			<CollectionIndex<T>>::mutate(|n| *n += 1);
 
-            Self::deposit_event(Event::CollectionCreated {
-                issuer: sender,
-                collection_id: collection_id.0
-            });
+			Self::deposit_event(Event::CollectionCreated {
+				issuer: sender,
+				collection_id: collection_id.0,
+			});
 
-            Ok(())
-        }
+			Ok(())
+		}
 
-        #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn destroy_collection(
 			origin: OriginFor<T>,
 			collection_id: RmrkCollectionId,
 		) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
-            let cross_sender = T::CrossAccountId::from_sub(sender.clone());
+			let sender = ensure_signed(origin)?;
+			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
 
-            let unique_collection_id = collection_id.into();
+			let unique_collection_id = collection_id.into();
 
-            let collection = Self::get_typed_nft_collection(unique_collection_id, misc::CollectionType::Regular)?;
+			let collection = Self::get_typed_nft_collection(
+				unique_collection_id,
+				misc::CollectionType::Regular,
+			)?;
 
-            ensure!(collection.total_supply() == 0, <Error<T>>::CollectionNotEmpty);
+			ensure!(
+				collection.total_supply() == 0,
+				<Error<T>>::CollectionNotEmpty
+			);
 
-            <PalletNft<T>>::destroy_collection(collection, &cross_sender)
-                .map_err(Self::map_common_err_to_proxy)?;
+			<PalletNft<T>>::destroy_collection(collection, &cross_sender)
+				.map_err(Self::map_common_err_to_proxy)?;
 
-            Self::deposit_event(Event::CollectionDestroyed { issuer: sender, collection_id });
+			Self::deposit_event(Event::CollectionDestroyed {
+				issuer: sender,
+				collection_id,
+			});
 
-            Ok(())
-        }
+			Ok(())
+		}
 
-        #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn change_collection_issuer(
 			origin: OriginFor<T>,
 			collection_id: RmrkCollectionId,
 			new_issuer: <T::Lookup as StaticLookup>::Source,
 		) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
+			let sender = ensure_signed(origin)?;
 
-            let new_issuer = T::Lookup::lookup(new_issuer)?;
+			let new_issuer = T::Lookup::lookup(new_issuer)?;
 
-            Self::change_collection_owner(
-                collection_id.into(),
-                misc::CollectionType::Regular,
-                sender.clone(),
-                new_issuer.clone()
-            )?;
+			Self::change_collection_owner(
+				collection_id.into(),
+				misc::CollectionType::Regular,
+				sender.clone(),
+				new_issuer.clone(),
+			)?;
 
-            Self::deposit_event(Event::IssuerChanged {
+			Self::deposit_event(Event::IssuerChanged {
 				old_issuer: sender,
 				new_issuer,
 				collection_id,
 			});
 
-            Ok(())
-        }
+			Ok(())
+		}
 
-        #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn lock_collection(
 			origin: OriginFor<T>,
 			collection_id: RmrkCollectionId,
 		) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
-            let cross_sender = T::CrossAccountId::from_sub(sender.clone());
+			let sender = ensure_signed(origin)?;
+			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
 
-            let collection = Self::get_typed_nft_collection(
-                collection_id.into(),
-                misc::CollectionType::Regular
-            )?;
+			let collection = Self::get_typed_nft_collection(
+				collection_id.into(),
+				misc::CollectionType::Regular,
+			)?;
 
-            Self::check_collection_owner(&collection, &cross_sender)?;
+			Self::check_collection_owner(&collection, &cross_sender)?;
 
-            let token_count = collection.total_supply();
+			let token_count = collection.total_supply();
 
-            let mut collection = collection.into_inner();
-            collection.limits.token_limit = Some(token_count);
-            collection.save()?;
+			let mut collection = collection.into_inner();
+			collection.limits.token_limit = Some(token_count);
+			collection.save()?;
 
-			Self::deposit_event(Event::CollectionLocked { issuer: sender, collection_id });
+			Self::deposit_event(Event::CollectionLocked {
+				issuer: sender,
+				collection_id,
+			});
 
-            Ok(())
-        }
+			Ok(())
+		}
 
-        #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn mint_nft(
 			origin: OriginFor<T>,
@@ -251,47 +266,49 @@
 			royalty_amount: Option<Permill>,
 			metadata: RmrkString,
 		) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
-            let sender = T::CrossAccountId::from_sub(sender);
-            let cross_owner = T::CrossAccountId::from_sub(owner.clone());
+			let sender = ensure_signed(origin)?;
+			let sender = T::CrossAccountId::from_sub(sender);
+			let cross_owner = T::CrossAccountId::from_sub(owner.clone());
 
-            let royalty_info = royalty_amount.map(|amount| rmrk::RoyaltyInfo {
-                recipient: recipient.unwrap_or_else(|| owner.clone()),
-                amount
-            });
+			let royalty_info = royalty_amount.map(|amount| rmrk::RoyaltyInfo {
+				recipient: recipient.unwrap_or_else(|| owner.clone()),
+				amount,
+			});
 
-            let collection = Self::get_typed_nft_collection(
-                collection_id.into(),
-                misc::CollectionType::Regular,
-            )?;
+			let collection = Self::get_typed_nft_collection(
+				collection_id.into(),
+				misc::CollectionType::Regular,
+			)?;
 
-            let nft_id = Self::create_nft(
-                &sender,
-                &cross_owner,
-                &collection,
-                NftType::Regular,
-                [
-                    Self::rmrk_property(RoyaltyInfo, &royalty_info)?,
-                    Self::rmrk_property(Metadata, &metadata)?,
-                    Self::rmrk_property(Equipped, &false)?,
-                    Self::rmrk_property(ResourceCollection, &None::<CollectionId>)?,
-                    Self::rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,
-                ].into_iter()
-            ).map_err(|err| match err {
-                DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),
-                err => Self::map_common_err_to_proxy(err)
-            })?;
+			let nft_id = Self::create_nft(
+				&sender,
+				&cross_owner,
+				&collection,
+				NftType::Regular,
+				[
+					Self::rmrk_property(RoyaltyInfo, &royalty_info)?,
+					Self::rmrk_property(Metadata, &metadata)?,
+					Self::rmrk_property(Equipped, &false)?,
+					Self::rmrk_property(ResourceCollection, &None::<CollectionId>)?,
+					Self::rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,
+				]
+				.into_iter(),
+			)
+			.map_err(|err| match err {
+				DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),
+				err => Self::map_common_err_to_proxy(err),
+			})?;
 
-            Self::deposit_event(Event::NftMinted {
-                owner,
-                collection_id,
-                nft_id: nft_id.0
-            });
+			Self::deposit_event(Event::NftMinted {
+				owner,
+				collection_id,
+				nft_id: nft_id.0,
+			});
 
-            Ok(())
-        }
+			Ok(())
+		}
 
-        #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn burn_nft(
 			origin: OriginFor<T>,
@@ -299,21 +316,24 @@
 			nft_id: RmrkNftId,
 		) -> DispatchResult {
 			let sender = ensure_signed(origin)?;
-            let cross_sender = T::CrossAccountId::from_sub(sender.clone());
+			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
 
-            Self::destroy_nft(
-                cross_sender,
-                collection_id.into(),
-                misc::CollectionType::Regular,
-                nft_id.into()
-            )?;
+			Self::destroy_nft(
+				cross_sender,
+				collection_id.into(),
+				misc::CollectionType::Regular,
+				nft_id.into(),
+			)?;
 
-            Self::deposit_event(Event::NFTBurned { owner: sender, nft_id });
+			Self::deposit_event(Event::NFTBurned {
+				owner: sender,
+				nft_id,
+			});
 
-            Ok(())
-        }
+			Ok(())
+		}
 
-        #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
 		#[transactional]
 		pub fn set_property(
 			origin: OriginFor<T>,
@@ -322,323 +342,346 @@
 			key: RmrkKeyString,
 			value: RmrkValueString,
 		) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
-            let sender = T::CrossAccountId::from_sub(sender);
+			let sender = ensure_signed(origin)?;
+			let sender = T::CrossAccountId::from_sub(sender);
 
-            let collection_id: CollectionId = rmrk_collection_id.into();
+			let collection_id: CollectionId = rmrk_collection_id.into();
 
-            match maybe_nft_id {
-                Some(nft_id) => {
-                    let token_id: TokenId = nft_id.into();
+			match maybe_nft_id {
+				Some(nft_id) => {
+					let token_id: TokenId = nft_id.into();
 
-                    Self::ensure_nft_owner(collection_id, token_id, &sender)?;
-                    Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;
+					Self::ensure_nft_owner(collection_id, token_id, &sender)?;
+					Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;
 
-                    <PalletNft<T>>::set_scoped_token_property(
-                        collection_id,
-                        token_id,
-                        PropertyScope::Rmrk,
-                        Self::rmrk_property(UserProperty(key.as_slice()), &value)?
-                    )?;
-                },
-                None => {
-                    let collection = Self::get_typed_nft_collection(
-                        collection_id,
-                        misc::CollectionType::Regular
-                    )?;
+					<PalletNft<T>>::set_scoped_token_property(
+						collection_id,
+						token_id,
+						PropertyScope::Rmrk,
+						Self::rmrk_property(UserProperty(key.as_slice()), &value)?,
+					)?;
+				}
+				None => {
+					let collection = Self::get_typed_nft_collection(
+						collection_id,
+						misc::CollectionType::Regular,
+					)?;
 
-                    Self::check_collection_owner(&collection, &sender)?;
+					Self::check_collection_owner(&collection, &sender)?;
 
-                    <PalletCommon<T>>::set_scoped_collection_property(
-                        collection_id,
-                        PropertyScope::Rmrk,
-                        Self::rmrk_property(UserProperty(key.as_slice()), &value)?
-                    )?;
-                }
-            }
+					<PalletCommon<T>>::set_scoped_collection_property(
+						collection_id,
+						PropertyScope::Rmrk,
+						Self::rmrk_property(UserProperty(key.as_slice()), &value)?,
+					)?;
+				}
+			}
 
-            Self::deposit_event(
-                Event::PropertySet {
-                    collection_id: rmrk_collection_id,
-                    maybe_nft_id,
-                    key,
-                    value
-                }
-            );
+			Self::deposit_event(Event::PropertySet {
+				collection_id: rmrk_collection_id,
+				maybe_nft_id,
+				key,
+				value,
+			});
 
-            Ok(())
-        }
+			Ok(())
+		}
 	}
 }
 
 impl<T: Config> Pallet<T> {
-    pub fn rmrk_property_key(rmrk_key: RmrkProperty) -> Result<PropertyKey, DispatchError> {
-        let key = rmrk_key.to_key::<T>()?;
+	pub fn rmrk_property_key(rmrk_key: RmrkProperty) -> Result<PropertyKey, DispatchError> {
+		let key = rmrk_key.to_key::<T>()?;
 
-        let scoped_key = PropertyScope::Rmrk.apply(key)
-            .map_err(|_| <Error<T>>::RmrkPropertyKeyIsTooLong)?;
+		let scoped_key = PropertyScope::Rmrk
+			.apply(key)
+			.map_err(|_| <Error<T>>::RmrkPropertyKeyIsTooLong)?;
 
-        Ok(scoped_key)
-    }
+		Ok(scoped_key)
+	}
 
-    pub fn rmrk_property<E: Encode>(rmrk_key: RmrkProperty, value: &E) -> Result<Property, DispatchError> {
-        let key = rmrk_key.to_key::<T>()?;
+	pub fn rmrk_property<E: Encode>(
+		rmrk_key: RmrkProperty,
+		value: &E,
+	) -> Result<Property, DispatchError> {
+		let key = rmrk_key.to_key::<T>()?;
 
-        let value = value.encode()
-            .try_into()
-            .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong)?;
+		let value = value
+			.encode()
+			.try_into()
+			.map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong)?;
 
-        let property = Property {
-            key,
-            value,
-        };
+		let property = Property { key, value };
 
-        Ok(property)
-    }
+		Ok(property)
+	}
 
-    pub fn create_nft(
-        sender: &T::CrossAccountId,
-        owner: &T::CrossAccountId,
-        collection: &NonfungibleHandle<T>,
-        nft_type: NftType,
-        properties: impl Iterator<Item=Property>
-    ) -> Result<TokenId, DispatchError> {
-        todo!("store nft type");
-        let data = CreateNftExData {
-            properties: BoundedVec::default(),
-            owner: owner.clone(),
-        };
+	pub fn create_nft(
+		sender: &T::CrossAccountId,
+		owner: &T::CrossAccountId,
+		collection: &NonfungibleHandle<T>,
+		nft_type: NftType,
+		properties: impl Iterator<Item = Property>,
+	) -> Result<TokenId, DispatchError> {
+		todo!("store nft type");
+		let data = CreateNftExData {
+			properties: BoundedVec::default(),
+			owner: owner.clone(),
+		};
 
-        let budget = budget::Value::new(2);
+		let budget = budget::Value::new(2);
 
-        <PalletNft<T>>::create_item(
-            collection,
-            sender,
-            data,
-            &budget,
-        )?;
+		<PalletNft<T>>::create_item(collection, sender, data, &budget)?;
 
-        let nft_id = <PalletNft<T>>::current_token_id(collection.id);
+		let nft_id = <PalletNft<T>>::current_token_id(collection.id);
 
-        <PalletNft<T>>::set_scoped_token_properties(
-            collection.id,
-            nft_id,
-            PropertyScope::Rmrk,
-            properties
-        )?;
+		<PalletNft<T>>::set_scoped_token_properties(
+			collection.id,
+			nft_id,
+			PropertyScope::Rmrk,
+			properties,
+		)?;
 
-        Ok(nft_id)
-    }
+		Ok(nft_id)
+	}
 
-    fn destroy_nft(
-        sender: T::CrossAccountId,
-        collection_id: CollectionId,
-        collection_type: misc::CollectionType,
-        token_id: TokenId
-    ) -> DispatchResult {
-        let collection = Self::get_typed_nft_collection(
-            collection_id,
-            collection_type
-        )?;
+	fn destroy_nft(
+		sender: T::CrossAccountId,
+		collection_id: CollectionId,
+		collection_type: misc::CollectionType,
+		token_id: TokenId,
+	) -> DispatchResult {
+		let collection = Self::get_typed_nft_collection(collection_id, collection_type)?;
 
-        <PalletNft<T>>::burn(&collection, &sender, token_id)
-            .map_err(Self::map_common_err_to_proxy)?;
+		<PalletNft<T>>::burn(&collection, &sender, token_id)
+			.map_err(Self::map_common_err_to_proxy)?;
 
-        Ok(())
-    }
+		Ok(())
+	}
 
-    fn change_collection_owner(
-        collection_id: CollectionId,
-        collection_type: misc::CollectionType,
-        sender: T::AccountId,
-        new_owner: T::AccountId,
-    ) -> DispatchResult {
-        let collection = Self::get_typed_nft_collection(
-            collection_id,
-            collection_type
-        )?;
-        Self::check_collection_owner(&collection, &T::CrossAccountId::from_sub(sender))?;
+	fn change_collection_owner(
+		collection_id: CollectionId,
+		collection_type: misc::CollectionType,
+		sender: T::AccountId,
+		new_owner: T::AccountId,
+	) -> DispatchResult {
+		let collection = Self::get_typed_nft_collection(collection_id, collection_type)?;
+		Self::check_collection_owner(&collection, &T::CrossAccountId::from_sub(sender))?;
 
-        let mut collection = collection.into_inner();
+		let mut collection = collection.into_inner();
 
-        collection.owner = new_owner;
-        collection.save()
-    }
+		collection.owner = new_owner;
+		collection.save()
+	}
 
-    fn check_collection_owner(collection: &NonfungibleHandle<T>, account: &T::CrossAccountId) -> DispatchResult {
-        collection.check_is_owner(account)
-            .map_err(Self::map_common_err_to_proxy)
-    }
+	fn check_collection_owner(
+		collection: &NonfungibleHandle<T>,
+		account: &T::CrossAccountId,
+	) -> DispatchResult {
+		collection
+			.check_is_owner(account)
+			.map_err(Self::map_common_err_to_proxy)
+	}
 
-    pub fn last_collection_idx() -> RmrkCollectionId {
-        <CollectionIndex<T>>::get()
-    }
+	pub fn last_collection_idx() -> RmrkCollectionId {
+		<CollectionIndex<T>>::get()
+	}
 
-    pub fn get_nft_collection(collection_id: CollectionId) -> Result<NonfungibleHandle<T>, DispatchError> {
-        let collection = <CollectionHandle<T>>::try_get(collection_id)
-            .map_err(|_| <Error<T>>::CollectionUnknown)?;
+	pub fn get_nft_collection(
+		collection_id: CollectionId,
+	) -> Result<NonfungibleHandle<T>, DispatchError> {
+		let collection = <CollectionHandle<T>>::try_get(collection_id)
+			.map_err(|_| <Error<T>>::CollectionUnknown)?;
 
-        match collection.mode {
-            CollectionMode::NFT => Ok(NonfungibleHandle::cast(collection)),
-            _ => Err(<Error<T>>::CollectionUnknown.into())
-        }
-    }
+		match collection.mode {
+			CollectionMode::NFT => Ok(NonfungibleHandle::cast(collection)),
+			_ => Err(<Error<T>>::CollectionUnknown.into()),
+		}
+	}
 
-    pub fn collection_exists(collection_id: CollectionId) -> bool {
-        <CollectionHandle<T>>::try_get(collection_id).is_ok()
-    }
+	pub fn collection_exists(collection_id: CollectionId) -> bool {
+		<CollectionHandle<T>>::try_get(collection_id).is_ok()
+	}
 
-    pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {
-        <TokenData<T>>::contains_key((collection_id, nft_id))
-    }
+	pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {
+		<TokenData<T>>::contains_key((collection_id, nft_id))
+	}
 
-    pub fn get_collection_property(collection_id: CollectionId, key: RmrkProperty) -> Result<PropertyValue, DispatchError> {
-        let collection_property = <PalletCommon<T>>::collection_properties(collection_id)
-            .get(&Self::rmrk_property_key(key)?)
-            .ok_or(<Error<T>>::CollectionUnknown)?
-            .clone();
+	pub fn get_collection_property(
+		collection_id: CollectionId,
+		key: RmrkProperty,
+	) -> Result<PropertyValue, DispatchError> {
+		let collection_property = <PalletCommon<T>>::collection_properties(collection_id)
+			.get(&Self::rmrk_property_key(key)?)
+			.ok_or(<Error<T>>::CollectionUnknown)?
+			.clone();
 
-        Ok(collection_property)
-    }
+		Ok(collection_property)
+	}
 
-    pub fn get_collection_type(collection_id: CollectionId) -> Result<misc::CollectionType, DispatchError> {
-        let value = Self::get_collection_property(collection_id, CollectionType)?;
+	pub fn get_collection_type(
+		collection_id: CollectionId,
+	) -> Result<misc::CollectionType, DispatchError> {
+		let value = Self::get_collection_property(collection_id, CollectionType)?;
 
-        let mut value = value.as_slice();
+		let mut value = value.as_slice();
 
-        misc::CollectionType::decode(&mut value)
-            .map_err(|_| <Error<T>>::CorruptedCollectionType.into())
-    }
+		misc::CollectionType::decode(&mut value)
+			.map_err(|_| <Error<T>>::CorruptedCollectionType.into())
+	}
 
-    pub fn ensure_collection_type(collection_id: CollectionId, collection_type: misc::CollectionType) -> DispatchResult {
-        let actual_type = Self::get_collection_type(collection_id)?;
-        ensure!(actual_type == collection_type, <CommonError<T>>::NoPermission);
+	pub fn ensure_collection_type(
+		collection_id: CollectionId,
+		collection_type: misc::CollectionType,
+	) -> DispatchResult {
+		let actual_type = Self::get_collection_type(collection_id)?;
+		ensure!(
+			actual_type == collection_type,
+			<CommonError<T>>::NoPermission
+		);
 
-        Ok(())
-    }
+		Ok(())
+	}
 
-    pub fn get_nft_property(collection_id: CollectionId, nft_id: TokenId, key: RmrkProperty) -> Result<PropertyValue, DispatchError> {
-        let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))
-            .get(&Self::rmrk_property_key(key)?)
-            .ok_or(<Error<T>>::NoAvailableNftId)?
-            .clone();
+	pub fn get_nft_property(
+		collection_id: CollectionId,
+		nft_id: TokenId,
+		key: RmrkProperty,
+	) -> Result<PropertyValue, DispatchError> {
+		let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))
+			.get(&Self::rmrk_property_key(key)?)
+			.ok_or(<Error<T>>::NoAvailableNftId)?
+			.clone();
 
-        Ok(nft_property)
-    }
+		Ok(nft_property)
+	}
 
-    pub fn get_nft_type(_collection_id: CollectionId, _token_id: TokenId) -> Result<NftType, DispatchError> {
-        todo!("should get it from properties?")
-    }
+	pub fn get_nft_type(
+		_collection_id: CollectionId,
+		_token_id: TokenId,
+	) -> Result<NftType, DispatchError> {
+		todo!("should get it from properties?")
+	}
 
-    pub fn ensure_nft_type(collection_id: CollectionId, token_id: TokenId, nft_type: NftType) -> DispatchResult {
-        let actual_type = Self::get_nft_type(collection_id, token_id)?;
-        ensure!(actual_type == nft_type, <Error<T>>::NoPermission);
+	pub fn ensure_nft_type(
+		collection_id: CollectionId,
+		token_id: TokenId,
+		nft_type: NftType,
+	) -> DispatchResult {
+		let actual_type = Self::get_nft_type(collection_id, token_id)?;
+		ensure!(actual_type == nft_type, <Error<T>>::NoPermission);
 
-        Ok(())
-    }
+		Ok(())
+	}
 
-    pub fn ensure_nft_owner(
-        collection_id: CollectionId,
-        token_id: TokenId,
-        possible_owner: &T::CrossAccountId
-    ) -> DispatchResult {
-        let token_data = <TokenData<T>>::get((collection_id, token_id))
-            .ok_or(<Error<T>>::NoAvailableNftId)?;
+	pub fn ensure_nft_owner(
+		collection_id: CollectionId,
+		token_id: TokenId,
+		possible_owner: &T::CrossAccountId,
+	) -> DispatchResult {
+		let token_data =
+			<TokenData<T>>::get((collection_id, token_id)).ok_or(<Error<T>>::NoAvailableNftId)?;
 
-        ensure!(token_data.owner == *possible_owner, <Error<T>>::NoPermission);
+		ensure!(
+			token_data.owner == *possible_owner,
+			<Error<T>>::NoPermission
+		);
 
-        Ok(())
-    }
+		Ok(())
+	}
 
-    pub fn filter_user_properties<Key, Value, R, Mapper>(
-        collection_id: CollectionId,
-        token_id: Option<TokenId>,
-        filter_keys: Option<Vec<RmrkPropertyKey>>,
-        mapper: Mapper,
-    ) -> Result<Vec<R>, DispatchError>
-    where
-        Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,
-        Value: Decode + Default,
-        Mapper: Fn(Key, Value) -> R
-    {
-        filter_keys.map(|keys| {
-            let properties = keys.into_iter()
-                .filter_map(|key| {
-                    let key: Key = key.try_into().ok()?;
+	pub fn filter_user_properties<Key, Value, R, Mapper>(
+		collection_id: CollectionId,
+		token_id: Option<TokenId>,
+		filter_keys: Option<Vec<RmrkPropertyKey>>,
+		mapper: Mapper,
+	) -> Result<Vec<R>, DispatchError>
+	where
+		Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,
+		Value: Decode + Default,
+		Mapper: Fn(Key, Value) -> R,
+	{
+		filter_keys
+			.map(|keys| {
+				let properties = keys
+					.into_iter()
+					.filter_map(|key| {
+						let key: Key = key.try_into().ok()?;
 
-                    let value = match token_id {
-                        Some(token_id) => Self::get_nft_property(
-                            collection_id,
-                            token_id,
-                            UserProperty(key.as_ref())
-                        ),
-                        None => Self::get_collection_property(
-                            collection_id,
-                            UserProperty(key.as_ref())
-                        )
-                    }.ok()?.decode_or_default();
+						let value = match token_id {
+							Some(token_id) => Self::get_nft_property(
+								collection_id,
+								token_id,
+								UserProperty(key.as_ref()),
+							),
+							None => Self::get_collection_property(
+								collection_id,
+								UserProperty(key.as_ref()),
+							),
+						}
+						.ok()?
+						.decode_or_default();
 
-                    Some(mapper(key, value))
-                })
-                .collect();
+						Some(mapper(key, value))
+					})
+					.collect();
 
-            Ok(properties)
-        }).unwrap_or_else(|| {
-            let properties = Self::iterate_user_properties(collection_id, token_id, mapper)?
-                .collect();
+				Ok(properties)
+			})
+			.unwrap_or_else(|| {
+				let properties =
+					Self::iterate_user_properties(collection_id, token_id, mapper)?.collect();
 
-            Ok(properties)
-        })
-    }
+				Ok(properties)
+			})
+	}
 
-    pub fn iterate_user_properties<Key, Value, R, Mapper>(
-        collection_id: CollectionId,
-        token_id: Option<TokenId>,
-        mapper: Mapper,
-    ) -> Result<impl Iterator<Item=R>, DispatchError>
-    where
-        Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,
-        Value: Decode + Default,
-        Mapper: Fn(Key, Value) -> R
-    {
-        let key_prefix = Self::rmrk_property_key(UserProperty(b""))?;
+	pub fn iterate_user_properties<Key, Value, R, Mapper>(
+		collection_id: CollectionId,
+		token_id: Option<TokenId>,
+		mapper: Mapper,
+	) -> Result<impl Iterator<Item = R>, DispatchError>
+	where
+		Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,
+		Value: Decode + Default,
+		Mapper: Fn(Key, Value) -> R,
+	{
+		let key_prefix = Self::rmrk_property_key(UserProperty(b""))?;
 
-        let properties = match token_id {
-            Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),
-            None => <PalletCommon<T>>::collection_properties(collection_id)
-        };
+		let properties = match token_id {
+			Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),
+			None => <PalletCommon<T>>::collection_properties(collection_id),
+		};
 
-        let properties = properties
-            .into_iter()
-            .filter_map(move |(key, value)| {
-                let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;
+		let properties = properties.into_iter().filter_map(move |(key, value)| {
+			let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;
 
-                let key: Key = key.to_vec().try_into().ok()?;
-                let value: Value = value.decode_or_default();
+			let key: Key = key.to_vec().try_into().ok()?;
+			let value: Value = value.decode_or_default();
 
-                Some(mapper(key, value))
-            });
+			Some(mapper(key, value))
+		});
 
-        Ok(properties)
-    }
+		Ok(properties)
+	}
 
-    pub fn get_typed_nft_collection(
-        collection_id: CollectionId,
-        collection_type: misc::CollectionType
-    ) -> Result<NonfungibleHandle<T>, DispatchError> {
-        Self::ensure_collection_type(collection_id, collection_type)?;
+	pub fn get_typed_nft_collection(
+		collection_id: CollectionId,
+		collection_type: misc::CollectionType,
+	) -> Result<NonfungibleHandle<T>, DispatchError> {
+		Self::ensure_collection_type(collection_id, collection_type)?;
 
-        Self::get_nft_collection(collection_id)
-    }
+		Self::get_nft_collection(collection_id)
+	}
 
-    fn map_common_err_to_proxy(err: DispatchError) -> DispatchError {
-        map_common_err_to_proxy! {
-            match err {
-                NoPermission => NoPermission,
-                CollectionTokenLimitExceeded => CollectionFullOrLocked,
-                PublicMintingNotAllowed => NoPermission,
-                TokenNotFound => NoAvailableNftId
-            }
-        }
-    }
+	fn map_common_err_to_proxy(err: DispatchError) -> DispatchError {
+		map_common_err_to_proxy! {
+			match err {
+				NoPermission => NoPermission,
+				CollectionTokenLimitExceeded => CollectionFullOrLocked,
+				PublicMintingNotAllowed => NoPermission,
+				TokenNotFound => NoAvailableNftId
+			}
+		}
+	}
 }
modifiedpallets/proxy-rmrk-core/src/misc.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/misc.rs
+++ b/pallets/proxy-rmrk-core/src/misc.rs
@@ -15,41 +15,42 @@
 }
 
 pub trait RmrkDecode<T: Decode + Default, S> {
-    fn decode_or_default(&self) -> T;
+	fn decode_or_default(&self) -> T;
 }
 
 impl<T: Decode + Default, S> RmrkDecode<T, S> for BoundedVec<u8, S> {
-    fn decode_or_default(&self) -> T {
-        let mut value = self.as_slice();
+	fn decode_or_default(&self) -> T {
+		let mut value = self.as_slice();
 
-        T::decode(&mut value).unwrap_or_default()
-    }
+		T::decode(&mut value).unwrap_or_default()
+	}
 }
 
 pub trait RmrkRebind<T, S> {
-    fn rebind(&self) -> BoundedVec<u8, S>;
+	fn rebind(&self) -> BoundedVec<u8, S>;
 }
 
-impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T> where BoundedVec<u8, S>: TryFrom<Vec<u8>> {
-    fn rebind(&self) -> BoundedVec<u8, S> {
-        BoundedVec::<u8, S>::try_from(
-            self.clone().into_inner()
-        ).unwrap_or_default()
-    }
+impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T>
+where
+	BoundedVec<u8, S>: TryFrom<Vec<u8>>,
+{
+	fn rebind(&self) -> BoundedVec<u8, S> {
+		BoundedVec::<u8, S>::try_from(self.clone().into_inner()).unwrap_or_default()
+	}
 }
 
 #[derive(Encode, Decode, PartialEq, Eq)]
 pub enum CollectionType {
-    Regular,
-    Resource,
-    Base,
+	Regular,
+	Resource,
+	Base,
 }
 
 #[derive(Encode, Decode, PartialEq, Eq)]
 pub enum NftType {
-    Regular,
-    Resource,
-    FixedPart,
-    SlotPart,
-    Theme
+	Regular,
+	Resource,
+	FixedPart,
+	SlotPart,
+	Theme,
 }
modifiedpallets/proxy-rmrk-core/src/property.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/property.rs
+++ b/pallets/proxy-rmrk-core/src/property.rs
@@ -2,38 +2,38 @@
 use core::convert::AsRef;
 
 pub enum RmrkProperty<'r> {
-    Metadata,
-    CollectionType,
-    RoyaltyInfo,
-    Equipped,
-    ResourceCollection,
-    ResourcePriorities,
-    ResourceType,
-    PendingResourceAccept,
-    PendingResourceRemoval,
-    Parts,
-    Base,
-    Src,
-    Slot,
-    License,
-    Thumb,
-    EquippedNft,
-    BaseType,
-    ExternalPartId,
-    EquippableList,
-    ZIndex,
-    ThemeName,
-    ThemeInherit,
-    UserProperty(&'r [u8]),
+	Metadata,
+	CollectionType,
+	RoyaltyInfo,
+	Equipped,
+	ResourceCollection,
+	ResourcePriorities,
+	ResourceType,
+	PendingResourceAccept,
+	PendingResourceRemoval,
+	Parts,
+	Base,
+	Src,
+	Slot,
+	License,
+	Thumb,
+	EquippedNft,
+	BaseType,
+	ExternalPartId,
+	EquippableList,
+	ZIndex,
+	ThemeName,
+	ThemeInherit,
+	UserProperty(&'r [u8]),
 }
 
 impl<'r> RmrkProperty<'r> {
-    pub fn to_key<T: Config>(self) -> Result<PropertyKey, Error<T>> {
-        fn get_bytes<T: AsRef<[u8]>>(container: &T) -> &[u8] {
-            container.as_ref()
-        }
+	pub fn to_key<T: Config>(self) -> Result<PropertyKey, Error<T>> {
+		fn get_bytes<T: AsRef<[u8]>>(container: &T) -> &[u8] {
+			container.as_ref()
+		}
 
-        macro_rules! key {
+		macro_rules! key {
             ($($component:expr),+) => {
                 PropertyKey::try_from([$(key!(@ &$component)),+].concat())
                     .map_err(|_| <Error<T>>::RmrkPropertyKeyIsTooLong)
@@ -44,30 +44,30 @@
             };
         }
 
-        match self {
-            Self::Metadata => key!("metadata"),
-            Self::CollectionType => key!("collection-type"),
-            Self::RoyaltyInfo => key!("royalty-info"),
-            Self::Equipped => key!("equipped"),
-            Self::ResourceCollection => key!("resource-collection"),
-            Self::ResourcePriorities => key!("resource-priorities"),
-            Self::ResourceType => key!("resource-type"),
-            Self::PendingResourceAccept => key!("pending-accept"),
-            Self::PendingResourceRemoval => key!("pending-removal"),
-            Self::Parts => key!("parts"),
-            Self::Base => key!("base"),
-            Self::Src => key!("src"),
-            Self::Slot => key!("slot"),
-            Self::License => key!("license"),
-            Self::Thumb => key!("thumb"),
-            Self::EquippedNft => key!("equipped-nft"),
-            Self::BaseType => key!("base-type"),
-            Self::ExternalPartId => key!("ext-part-id"),
-            Self::EquippableList => key!("equippable-list"),
-            Self::ZIndex => key!("z-index"),
-            Self::ThemeName => key!("theme-name"),
-            Self::ThemeInherit => key!("theme-inherit"),
-            Self::UserProperty(name) => key!("userprop-", name),
-        }
-    }
+		match self {
+			Self::Metadata => key!("metadata"),
+			Self::CollectionType => key!("collection-type"),
+			Self::RoyaltyInfo => key!("royalty-info"),
+			Self::Equipped => key!("equipped"),
+			Self::ResourceCollection => key!("resource-collection"),
+			Self::ResourcePriorities => key!("resource-priorities"),
+			Self::ResourceType => key!("resource-type"),
+			Self::PendingResourceAccept => key!("pending-accept"),
+			Self::PendingResourceRemoval => key!("pending-removal"),
+			Self::Parts => key!("parts"),
+			Self::Base => key!("base"),
+			Self::Src => key!("src"),
+			Self::Slot => key!("slot"),
+			Self::License => key!("license"),
+			Self::Thumb => key!("thumb"),
+			Self::EquippedNft => key!("equipped-nft"),
+			Self::BaseType => key!("base-type"),
+			Self::ExternalPartId => key!("ext-part-id"),
+			Self::EquippableList => key!("equippable-list"),
+			Self::ZIndex => key!("z-index"),
+			Self::ThemeName => key!("theme-name"),
+			Self::ThemeInherit => key!("theme-inherit"),
+			Self::UserProperty(name) => key!("userprop-", name),
+		}
+	}
 }
modifiedpallets/proxy-rmrk-equip/src/lib.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-equip/src/lib.rs
+++ b/pallets/proxy-rmrk-equip/src/lib.rs
@@ -21,7 +21,11 @@
 use sp_runtime::DispatchError;
 use up_data_structs::*;
 use pallet_common::{Pallet as PalletCommon, Error as CommonError};
-use pallet_rmrk_core::{Pallet as PalletCore, misc::{self, *}, property::RmrkProperty::*};
+use pallet_rmrk_core::{
+	Pallet as PalletCore,
+	misc::{self, *},
+	property::RmrkProperty::*,
+};
 use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle};
 use pallet_evm::account::CrossAccountId;
 
@@ -29,212 +33,206 @@
 
 #[frame_support::pallet]
 pub mod pallet {
-    use super::*;
+	use super::*;
 
 	#[pallet::config]
-	pub trait Config: frame_system::Config
-                    + pallet_rmrk_core::Config {
+	pub trait Config: frame_system::Config + pallet_rmrk_core::Config {
 		type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
 	}
 
-    #[pallet::storage]
+	#[pallet::storage]
 	#[pallet::getter(fn internal_part_id)]
-	pub type InernalPartId<T: Config> = StorageDoubleMap<
-        _,
-        Twox64Concat,
-        CollectionId,
-        Twox64Concat,
-        RmrkPartId,
-        TokenId
-    >;
+	pub type InernalPartId<T: Config> =
+		StorageDoubleMap<_, Twox64Concat, CollectionId, Twox64Concat, RmrkPartId, TokenId>;
 
-    #[pallet::storage]
+	#[pallet::storage]
 	#[pallet::getter(fn base_has_default_theme)]
-    pub type BaseHasDefaultTheme<T: Config> = StorageMap<
-        _,
-        Twox64Concat,
-        CollectionId,
-        bool,
-        ValueQuery
-    >;
+	pub type BaseHasDefaultTheme<T: Config> =
+		StorageMap<_, Twox64Concat, CollectionId, bool, ValueQuery>;
 
-    #[pallet::pallet]
+	#[pallet::pallet]
 	#[pallet::generate_store(pub(super) trait Store)]
 	pub struct Pallet<T>(_);
 
 	#[pallet::event]
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config> {
-        BaseCreated {
+		BaseCreated {
 			issuer: T::AccountId,
 			base_id: RmrkBaseId,
 		},
-    }
+	}
 
-    #[pallet::error]
+	#[pallet::error]
 	pub enum Error<T> {
-        PermissionError,
-        NoAvailableBaseId,
-        NoAvailablePartId,
-        BaseDoesntExist,
-        NeedsDefaultThemeFirst,
-    }
+		PermissionError,
+		NoAvailableBaseId,
+		NoAvailablePartId,
+		BaseDoesntExist,
+		NeedsDefaultThemeFirst,
+	}
 
-    #[pallet::call]
+	#[pallet::call]
 	impl<T: Config> Pallet<T> {
-        #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
-        #[transactional]
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
 		pub fn create_base(
 			origin: OriginFor<T>,
 			base_type: RmrkString,
 			symbol: RmrkString,
 			parts: BoundedVec<RmrkPartType, RmrkPartsLimit>,
 		) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
-            let cross_sender = T::CrossAccountId::from_sub(sender.clone());
+			let sender = ensure_signed(origin)?;
+			let cross_sender = T::CrossAccountId::from_sub(sender.clone());
 
-            let data = CreateCollectionData {
-                limits: None,
-                token_prefix: symbol.into_inner()
-                    .try_into()
-                    .map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,
-                ..Default::default()
-            };
+			let data = CreateCollectionData {
+				limits: None,
+				token_prefix: symbol
+					.into_inner()
+					.try_into()
+					.map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,
+				..Default::default()
+			};
 
-            let collection_id_res = <PalletNft<T>>::init_collection(sender.clone(), data);
+			let collection_id_res = <PalletNft<T>>::init_collection(sender.clone(), data);
 
-            if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {
-                return Err(<Error<T>>::NoAvailableBaseId.into());
-            }
+			if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {
+				return Err(<Error<T>>::NoAvailableBaseId.into());
+			}
 
-            let collection_id = collection_id_res?;
+			let collection_id = collection_id_res?;
 
-            <PalletCommon<T>>::set_scoped_collection_properties(
-                collection_id,
-                PropertyScope::Rmrk,
-                [
-                    <PalletCore<T>>::rmrk_property(CollectionType, &misc::CollectionType::Base)?,
-                    <PalletCore<T>>::rmrk_property(BaseType, &base_type)?,
-                ].into_iter()
-            )?;
+			<PalletCommon<T>>::set_scoped_collection_properties(
+				collection_id,
+				PropertyScope::Rmrk,
+				[
+					<PalletCore<T>>::rmrk_property(CollectionType, &misc::CollectionType::Base)?,
+					<PalletCore<T>>::rmrk_property(BaseType, &base_type)?,
+				]
+				.into_iter(),
+			)?;
 
-            let collection = <PalletCore<T>>::get_nft_collection(collection_id)?;
+			let collection = <PalletCore<T>>::get_nft_collection(collection_id)?;
 
-            for part in parts {
-                let part_id = part.id();
-                let part_token_id = Self::create_part(
-                    &cross_sender,
-                    &collection,
-                    part
-                )?;
+			for part in parts {
+				let part_id = part.id();
+				let part_token_id = Self::create_part(&cross_sender, &collection, part)?;
 
-                <InernalPartId<T>>::insert(collection_id, part_id, part_token_id);
+				<InernalPartId<T>>::insert(collection_id, part_id, part_token_id);
 
-                <PalletNft<T>>::set_scoped_token_property(
-                    collection_id,
-                    part_token_id,
-                    PropertyScope::Rmrk,
-                    <PalletCore<T>>::rmrk_property(ExternalPartId, &part_id)?
-                )?;
-            }
+				<PalletNft<T>>::set_scoped_token_property(
+					collection_id,
+					part_token_id,
+					PropertyScope::Rmrk,
+					<PalletCore<T>>::rmrk_property(ExternalPartId, &part_id)?,
+				)?;
+			}
 
-            Self::deposit_event(Event::BaseCreated { issuer: sender, base_id: collection_id.0 });
+			Self::deposit_event(Event::BaseCreated {
+				issuer: sender,
+				base_id: collection_id.0,
+			});
 
-            Ok(())
-        }
+			Ok(())
+		}
 
-        #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
-        #[transactional]
+		#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+		#[transactional]
 		pub fn theme_add(
 			origin: OriginFor<T>,
 			base_id: RmrkBaseId,
 			theme: RmrkTheme,
 		) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
+			let sender = ensure_signed(origin)?;
 
-            let sender = T::CrossAccountId::from_sub(sender);
-            let owner = &sender;
+			let sender = T::CrossAccountId::from_sub(sender);
+			let owner = &sender;
 
-            let collection_id: CollectionId = base_id.into();
+			let collection_id: CollectionId = base_id.into();
 
-            let collection = <PalletCore<T>>::get_typed_nft_collection(
-                collection_id,
-                misc::CollectionType::Base
-            ).map_err(|_| <Error<T>>::BaseDoesntExist)?;
+			let collection = <PalletCore<T>>::get_typed_nft_collection(
+				collection_id,
+				misc::CollectionType::Base,
+			)
+			.map_err(|_| <Error<T>>::BaseDoesntExist)?;
 
-            if theme.name.as_slice() == b"default" {
-                <BaseHasDefaultTheme<T>>::insert(collection_id, true);
-            } else if !Self::base_has_default_theme(collection_id) {
-                return Err(<Error<T>>::NeedsDefaultThemeFirst.into());
-            }
+			if theme.name.as_slice() == b"default" {
+				<BaseHasDefaultTheme<T>>::insert(collection_id, true);
+			} else if !Self::base_has_default_theme(collection_id) {
+				return Err(<Error<T>>::NeedsDefaultThemeFirst.into());
+			}
 
-            let token_id = <PalletCore<T>>::create_nft(
-                &sender,
-                owner,
-                &collection,
-                NftType::Theme,
-                [
-                    <PalletCore<T>>::rmrk_property(ThemeName, &theme.name)?,
-                    <PalletCore<T>>::rmrk_property(ThemeInherit, &theme.inherit)?
-                ].into_iter()
-            ).map_err(|_| <Error<T>>::PermissionError)?;
+			let token_id = <PalletCore<T>>::create_nft(
+				&sender,
+				owner,
+				&collection,
+				NftType::Theme,
+				[
+					<PalletCore<T>>::rmrk_property(ThemeName, &theme.name)?,
+					<PalletCore<T>>::rmrk_property(ThemeInherit, &theme.inherit)?,
+				]
+				.into_iter(),
+			)
+			.map_err(|_| <Error<T>>::PermissionError)?;
 
-            for property in theme.properties {
-                <PalletNft<T>>::set_scoped_token_property(
-                    collection_id,
-                    token_id,
-                    PropertyScope::Rmrk,
-                    <PalletCore<T>>::rmrk_property(
-                        UserProperty(property.key.as_slice()),
-                        &property.value
-                    )?
-                )?;
-            }
+			for property in theme.properties {
+				<PalletNft<T>>::set_scoped_token_property(
+					collection_id,
+					token_id,
+					PropertyScope::Rmrk,
+					<PalletCore<T>>::rmrk_property(
+						UserProperty(property.key.as_slice()),
+						&property.value,
+					)?,
+				)?;
+			}
 
-            Ok(())
-        }
-    }
+			Ok(())
+		}
+	}
 }
 
 impl<T: Config> Pallet<T> {
-    fn create_part(
-        sender: &T::CrossAccountId,
-        collection: &NonfungibleHandle<T>,
-        part: RmrkPartType
-    ) -> Result<TokenId, DispatchError> {
-        let owner = sender;
+	fn create_part(
+		sender: &T::CrossAccountId,
+		collection: &NonfungibleHandle<T>,
+		part: RmrkPartType,
+	) -> Result<TokenId, DispatchError> {
+		let owner = sender;
 
-        let src = part.src();
-        let z_index = part.z_index();
+		let src = part.src();
+		let z_index = part.z_index();
 
-        let nft_type = match part {
-            RmrkPartType::FixedPart(_) => NftType::FixedPart,
-            RmrkPartType::SlotPart(_) => NftType::SlotPart,
-        };
+		let nft_type = match part {
+			RmrkPartType::FixedPart(_) => NftType::FixedPart,
+			RmrkPartType::SlotPart(_) => NftType::SlotPart,
+		};
 
-        let token_id = <PalletCore<T>>::create_nft(
-            sender,
-            owner,
-            collection,
-            nft_type,
-            [
-                <PalletCore<T>>::rmrk_property(Src, &src)?,
-                <PalletCore<T>>::rmrk_property(ZIndex, &z_index)?
-            ].into_iter()
-        ).map_err(|err| match err {
-            DispatchError::Arithmetic(_) => <Error<T>>::NoAvailablePartId.into(),
-            err => err
-        })?;
+		let token_id = <PalletCore<T>>::create_nft(
+			sender,
+			owner,
+			collection,
+			nft_type,
+			[
+				<PalletCore<T>>::rmrk_property(Src, &src)?,
+				<PalletCore<T>>::rmrk_property(ZIndex, &z_index)?,
+			]
+			.into_iter(),
+		)
+		.map_err(|err| match err {
+			DispatchError::Arithmetic(_) => <Error<T>>::NoAvailablePartId.into(),
+			err => err,
+		})?;
 
-        if let RmrkPartType::SlotPart(part) = part {
-            <PalletNft<T>>::set_scoped_token_property(
-                collection.id,
-                token_id,
-                PropertyScope::Rmrk,
-                <PalletCore<T>>::rmrk_property(EquippableList, &part.equippable)?
-            )?;
-        }
+		if let RmrkPartType::SlotPart(part) = part {
+			<PalletNft<T>>::set_scoped_token_property(
+				collection.id,
+				token_id,
+				PropertyScope::Rmrk,
+				<PalletCore<T>>::rmrk_property(EquippableList, &part.equippable)?,
+			)?;
+		}
 
-        Ok(token_id)
-    }
+		Ok(token_id)
+	}
 }
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -313,17 +313,9 @@
 		fail!(<Error<T>>::RefungibleDisallowsNesting)
 	}
 
-	fn nest(
-		&self,
-		_under: TokenId,
-		_to_nest: (CollectionId, TokenId)
-	) {}
+	fn nest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}
 
-	fn unnest(
-		&self,
-		_under: TokenId,
-		_to_nest: (CollectionId, TokenId)
-	) {}
+	fn unnest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}
 
 	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
 		<Owned<T>>::iter_prefix((self.id, account))
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -22,9 +22,7 @@
 	CreateCollectionData, CreateRefungibleExData, mapping::TokenAddressMapping, budget::Budget,
 };
 use pallet_evm::account::CrossAccountId;
-use pallet_common::{
-	Error as CommonError, Event as CommonEvent, Pallet as PalletCommon,
-};
+use pallet_common::{Error as CommonError, Event as CommonEvent, Pallet as PalletCommon};
 use pallet_structure::Pallet as PalletStructure;
 use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
 use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
@@ -230,7 +228,9 @@
 	}
 
 	fn collection_has_tokens(collection_id: CollectionId) -> bool {
-		<TokenData<T>>::iter_prefix((collection_id,)).next().is_some()
+		<TokenData<T>>::iter_prefix((collection_id,))
+			.next()
+			.is_some()
 	}
 
 	pub fn burn_token(collection: &RefungibleHandle<T>, token_id: TokenId) -> DispatchResult {
@@ -388,18 +388,14 @@
 			to,
 			collection.id,
 			token,
-			nesting_budget
+			nesting_budget,
 		)?;
 
 		if let Some(balance_to) = balance_to {
 			// from != to
 			if balance_from == 0 {
 				<Balance<T>>::remove((collection.id, token, from));
-				<PalletStructure<T>>::unnest_if_nested(
-					from,
-					collection.id,
-					token
-				);
+				<PalletStructure<T>>::unnest_if_nested(from, collection.id, token);
 			} else {
 				<Balance<T>>::insert((collection.id, token, from), balance_from);
 			}
@@ -497,7 +493,6 @@
 		for (i, token) in data.iter().enumerate() {
 			let token_id = TokenId(first_token_id + i as u32 + 1);
 			for (to, _) in token.users.iter() {
-
 				<PalletStructure<T>>::check_nesting(
 					sender.clone(),
 					to,
@@ -531,7 +526,11 @@
 				}
 				<Balance<T>>::insert((collection.id, token_id, &user), amount);
 				<Owned<T>>::insert((collection.id, &user, TokenId(token_id)), true);
-				<PalletStructure<T>>::nest_if_sent_to_token_unchecked(&user, collection.id, TokenId(token_id));
+				<PalletStructure<T>>::nest_if_sent_to_token_unchecked(
+					&user,
+					collection.id,
+					TokenId(token_id),
+				);
 
 				// TODO: ERC20 transfer event
 				<PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(
modifiedpallets/structure/src/lib.rsdiffbeforeafterboth
--- a/pallets/structure/src/lib.rs
+++ b/pallets/structure/src/lib.rs
@@ -189,17 +189,11 @@
 		under: &T::CrossAccountId,
 		collection_id: CollectionId,
 		token_id: TokenId,
-		nesting_budget: &dyn Budget
+		nesting_budget: &dyn Budget,
 	) -> DispatchResult {
-		Self::try_exec_if_owner_is_valid_nft(
-			under,
-			|d, parent_id| d.check_nesting(
-				from,
-				(collection_id, token_id),
-				parent_id,
-				nesting_budget
-			)
-		)
+		Self::try_exec_if_owner_is_valid_nft(under, |d, parent_id| {
+			d.check_nesting(from, (collection_id, token_id), parent_id, nesting_budget)
+		})
 	}
 
 	pub fn nest_if_sent_to_token(
@@ -207,69 +201,51 @@
 		under: &T::CrossAccountId,
 		collection_id: CollectionId,
 		token_id: TokenId,
-		nesting_budget: &dyn Budget
+		nesting_budget: &dyn Budget,
 	) -> DispatchResult {
-		Self::try_exec_if_owner_is_valid_nft(
-			under,
-			|d, parent_id| {
-				d.check_nesting(
-					from,
-					(collection_id, token_id),
-					parent_id,
-					nesting_budget
-				)?;
+		Self::try_exec_if_owner_is_valid_nft(under, |d, parent_id| {
+			d.check_nesting(from, (collection_id, token_id), parent_id, nesting_budget)?;
 
-				d.nest(parent_id, (collection_id, token_id));
+			d.nest(parent_id, (collection_id, token_id));
 
-				Ok(())
-			}
-		)
+			Ok(())
+		})
 	}
 
 	pub fn nest_if_sent_to_token_unchecked(
 		owner: &T::CrossAccountId,
 		collection_id: CollectionId,
-		token_id: TokenId
+		token_id: TokenId,
 	) {
-		Self::exec_if_owner_is_valid_nft(
-			owner,
-			|d, parent_id| d.nest(
-				parent_id,
-				(collection_id, token_id)
-			)
-		);
+		Self::exec_if_owner_is_valid_nft(owner, |d, parent_id| {
+			d.nest(parent_id, (collection_id, token_id))
+		});
 	}
 
 	pub fn unnest_if_nested(
 		owner: &T::CrossAccountId,
 		collection_id: CollectionId,
-		token_id: TokenId
+		token_id: TokenId,
 	) {
-		Self::exec_if_owner_is_valid_nft(
-			owner,
-			|d, parent_id| d.unnest(
-			parent_id,
-			(collection_id, token_id)
-			)
-		);
+		Self::exec_if_owner_is_valid_nft(owner, |d, parent_id| {
+			d.unnest(parent_id, (collection_id, token_id))
+		});
 	}
 
 	fn exec_if_owner_is_valid_nft(
 		account: &T::CrossAccountId,
-		action: impl FnOnce(&dyn CommonCollectionOperations<T>, TokenId)
+		action: impl FnOnce(&dyn CommonCollectionOperations<T>, TokenId),
 	) {
-		Self::try_exec_if_owner_is_valid_nft(
-			account,
-			|d, id| {
-				action(d, id);
-				Ok(())
-			}
-		).unwrap();
+		Self::try_exec_if_owner_is_valid_nft(account, |d, id| {
+			action(d, id);
+			Ok(())
+		})
+		.unwrap();
 	}
 
 	fn try_exec_if_owner_is_valid_nft(
 		account: &T::CrossAccountId,
-		action: impl FnOnce(&dyn CommonCollectionOperations<T>, TokenId) -> DispatchResult
+		action: impl FnOnce(&dyn CommonCollectionOperations<T>, TokenId) -> DispatchResult,
 	) -> DispatchResult {
 		let account = T::CrossTokenAddressMapping::address_to_token(account);
 
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -37,11 +37,10 @@
 use frame_system::{self as system, ensure_signed};
 use sp_runtime::{sp_std::prelude::Vec};
 use up_data_structs::{
-	MAX_COLLECTION_NAME_LENGTH,
-	MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, AccessMode, CreateItemData,
-	CollectionLimits, CollectionPermissions, CollectionId, CollectionMode, TokenId, SponsorshipState,
-	CreateCollectionData, CreateItemExData, budget, Property, PropertyKey,
-	PropertyKeyPermission,
+	MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
+	AccessMode, CreateItemData, CollectionLimits, CollectionPermissions, CollectionId,
+	CollectionMode, TokenId, SponsorshipState, CreateCollectionData, CreateItemExData, budget,
+	Property, PropertyKey, PropertyKeyPermission,
 };
 use pallet_evm::account::CrossAccountId;
 use pallet_common::{
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -49,7 +49,8 @@
 	},
 	NftChild as RmrkNftChild, AccountIdOrCollectionNftTuple as RmrkAccountIdOrCollectionNftTuple,
 	FixedPart as RmrkFixedPart, SlotPart as RmrkSlotPart, EquippableList as RmrkEquippableList,
-	BasicResource as RmrkBasicResource, ComposableResource as RmrkComposableResource, SlotResource as RmrkSlotResource,
+	BasicResource as RmrkBasicResource, ComposableResource as RmrkComposableResource,
+	SlotResource as RmrkSlotResource,
 };
 
 mod bounded;
@@ -361,8 +362,7 @@
 pub type CollectionPropertiesPermissionsVec =
 	BoundedVec<PropertyKeyPermission, ConstU32<MAX_PROPERTIES_PER_ITEM>>;
 
-pub type CollectionPropertiesVec =
-	BoundedVec<Property, ConstU32<MAX_PROPERTIES_PER_ITEM>>;
+pub type CollectionPropertiesVec = BoundedVec<Property, ConstU32<MAX_PROPERTIES_PER_ITEM>>;
 
 /// All fields are wrapped in `Option`s, where None means chain default
 // When adding/removing fields from this struct - don't forget to also update clamp_limits
@@ -790,8 +790,8 @@
 	>::IntoIter;
 
 	fn into_iter(self) -> Self::IntoIter {
-        self.0.into_iter()
-    }
+		self.0.into_iter()
+	}
 }
 
 impl<Value> TrySetProperty for PropertiesMap<Value> {
@@ -853,8 +853,8 @@
 	type IntoIter = <PropertiesMap<PropertyValue> as IntoIterator>::IntoIter;
 
 	fn into_iter(self) -> Self::IntoIter {
-        self.map.into_iter()
-    }
+		self.map.into_iter()
+	}
 }
 
 impl TrySetProperty for Properties {
@@ -932,11 +932,7 @@
 pub type RmrkCollectionInfo<AccountId> =
 	CollectionInfo<RmrkString, RmrkCollectionSymbol, AccountId>;
 pub type RmrkInstanceInfo<AccountId> = NftInfo<AccountId, Permill, RmrkString>;
-pub type RmrkResourceInfo = ResourceInfo<
-	RmrkBoundedResource,
-	RmrkString,
-	RmrkBoundedParts,
->;
+pub type RmrkResourceInfo = ResourceInfo<RmrkBoundedResource, RmrkString, RmrkBoundedParts>;
 pub type RmrkPropertyInfo = PropertyInfo<RmrkKeyString, RmrkValueString>;
 pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;
 pub type RmrkPartType =
modifiedprimitives/data-structs/src/rmrk.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/rmrk.rs
+++ b/primitives/data-structs/src/rmrk.rs
@@ -20,37 +20,37 @@
 
 #[cfg(feature = "std")]
 mod serialize {
-    use core::convert::AsRef;
-    use serde::ser::{self, Serialize};
+	use core::convert::AsRef;
+	use serde::ser::{self, Serialize};
 
-    pub mod vec {
-        use super::*;
+	pub mod vec {
+		use super::*;
 
-        pub fn serialize<D, V, C>(value: &C, serializer: D) -> Result<D::Ok, D::Error>
-        where
-            D: ser::Serializer,
-            V: Serialize,
-            C: AsRef<[V]>,
-        {
-            value.as_ref().serialize(serializer)
-        }
-    }
+		pub fn serialize<D, V, C>(value: &C, serializer: D) -> Result<D::Ok, D::Error>
+		where
+			D: ser::Serializer,
+			V: Serialize,
+			C: AsRef<[V]>,
+		{
+			value.as_ref().serialize(serializer)
+		}
+	}
 
-    pub mod opt_vec {
-        use super::*;
+	pub mod opt_vec {
+		use super::*;
 
-        pub fn serialize<D, V, C>(value: &Option<C>, serializer: D) -> Result<D::Ok, D::Error>
-        where
-            D: ser::Serializer,
-            V: Serialize,
-            C: AsRef<[V]>,
-        {
-            match value {
-                Some(value) => super::vec::serialize(value, serializer),
-                None => serializer.serialize_none()
-            }
-        }
-    }
+		pub fn serialize<D, V, C>(value: &Option<C>, serializer: D) -> Result<D::Ok, D::Error>
+		where
+			D: ser::Serializer,
+			V: Serialize,
+			C: AsRef<[V]>,
+		{
+			match value {
+				Some(value) => super::vec::serialize(value, serializer),
+				None => serializer.serialize_none(),
+			}
+		}
+	}
 }
 
 /// Collection info.
@@ -58,13 +58,11 @@
 #[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			AccountId: Serialize,
 			BoundedString: AsRef<[u8]>,
 			BoundedSymbol: AsRef<[u8]>
-		"#
-	)
+		"#)
 )]
 pub struct CollectionInfo<BoundedString, BoundedSymbol, AccountId> {
 	/// Current bidder and bid price.
@@ -91,9 +89,9 @@
 #[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
 pub struct RoyaltyInfo<AccountId, RoyaltyAmount> {
 	/// Recipient (AccountId) of the royalty
-    pub recipient: AccountId,
+	pub recipient: AccountId,
 	/// Amount (Permill) of the royalty
-    pub amount: RoyaltyAmount,
+	pub amount: RoyaltyAmount,
 }
 
 /// Nft info.
@@ -101,13 +99,11 @@
 #[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			AccountId: Serialize,
 			RoyaltyAmount: Serialize,
 			BoundedString: AsRef<[u8]>
-		"#
-	)
+		"#)
 )]
 pub struct NftInfo<AccountId, RoyaltyAmount, BoundedString> {
 	/// The owner of the NFT, can be either an Account or a tuple (CollectionId, NftId)
@@ -129,22 +125,19 @@
 #[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]
 pub struct NftChild {
 	pub collection_id: CollectionId,
-	pub nft_id: NftId
+	pub nft_id: NftId,
 }
 
 #[cfg_attr(feature = "std", derive(Serialize))]
 #[derive(Encode, Decode, PartialEq, TypeInfo)]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			BoundedKey: AsRef<[u8]>,
 			BoundedValue: AsRef<[u8]>
-		"#
-	)
+		"#)
 )]
-pub struct PropertyInfo<BoundedKey, BoundedValue>
-{
+pub struct PropertyInfo<BoundedKey, BoundedValue> {
 	/// Key of the property
 	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
 	pub key: BoundedKey,
@@ -156,10 +149,7 @@
 
 #[derive(Encode, Decode, Default, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = "BoundedString: AsRef<[u8]>")
-)]
+#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
 pub struct BasicResource<BoundedString> {
 	/// If the resource is Media, the base property is absent. Media src should be a URI like an
 	/// IPFS hash.
@@ -188,12 +178,10 @@
 #[cfg_attr(feature = "std", derive(Serialize))]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			BoundedString: AsRef<[u8]>,
 			BoundedParts: AsRef<[PartId]>
-		"#
-	)
+		"#)
 )]
 pub struct ComposableResource<BoundedString, BoundedParts> {
 	/// If a resource is composed, it will have an array of parts that compose it
@@ -235,10 +223,7 @@
 
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "std", derive(Serialize))]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = "BoundedString: AsRef<[u8]>")
-)]
+#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
 pub struct SlotResource<BoundedString> {
 	/// A Base is uniquely identified by the combination of the word `base`, its minting block
 	/// number, and user provided symbol during Base creation, glued by dashes `-`, e.g.
@@ -279,14 +264,12 @@
 #[cfg_attr(feature = "std", derive(Serialize))]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			BoundedString: AsRef<[u8]>,
 			BoundedParts: AsRef<[PartId]>
-		"#
-	)
+		"#)
 )]
-#[derivative(Default(bound=""))]
+#[derivative(Default(bound = ""))]
 pub enum ResourceTypes<BoundedString: Default, BoundedParts> {
 	#[derivative(Default)]
 	Basic(BasicResource<BoundedString>),
@@ -294,18 +277,15 @@
 	Slot(SlotResource<BoundedString>),
 }
 
-
 #[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(feature = "std", derive(Serialize))]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			BoundedResource: AsRef<[u8]>,
 			BoundedString: AsRef<[u8]>,
 			BoundedParts: AsRef<[PartId]>
-		"#
-	)
+		"#)
 )]
 pub struct ResourceInfo<BoundedResource, BoundedString: Default, BoundedParts> {
 	/// id is a 5-character string of reasonable uniqueness.
@@ -328,12 +308,10 @@
 #[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			AccountId: Serialize,
 			BoundedString: AsRef<[u8]>
-		"#
-	)
+		"#)
 )]
 pub struct BaseInfo<AccountId, BoundedString> {
 	/// Original creator of the Base
@@ -350,10 +328,7 @@
 
 #[cfg_attr(feature = "std", derive(Serialize))]
 #[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = "BoundedString: AsRef<[u8]>")
-)]
+#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
 pub struct FixedPart<BoundedString> {
 	pub id: PartId,
 	pub z: ZIndex,
@@ -368,29 +343,24 @@
 	feature = "std",
 	serde(bound = "BoundedCollectionList: AsRef<[CollectionId]>")
 )]
-#[derivative(Default(bound=""))]
+#[derivative(Default(bound = ""))]
 pub enum EquippableList<BoundedCollectionList> {
 	All,
 
 	#[derivative(Default)]
 	Empty,
 
-	Custom(
-		#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
-		BoundedCollectionList
-	),
+	Custom(#[cfg_attr(feature = "std", serde(with = "serialize::vec"))] BoundedCollectionList),
 }
 
 #[cfg_attr(feature = "std", derive(Serialize))]
 #[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			BoundedString: AsRef<[u8]>,
 			BoundedCollectionList: AsRef<[CollectionId]>
-		"#
-	)
+		"#)
 )]
 pub struct SlotPart<BoundedString, BoundedCollectionList> {
 	pub id: PartId,
@@ -406,12 +376,10 @@
 #[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, Eq, MaxEncodedLen)]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			BoundedString: AsRef<[u8]>,
 			BoundedCollectionList: AsRef<[CollectionId]>
-		"#
-	)
+		"#)
 )]
 pub enum PartType<BoundedString, BoundedCollectionList> {
 	FixedPart(FixedPart<BoundedString>),
@@ -422,21 +390,21 @@
 	pub fn id(&self) -> PartId {
 		match self {
 			Self::FixedPart(part) => part.id,
-			Self::SlotPart(part) => part.id
+			Self::SlotPart(part) => part.id,
 		}
 	}
 
 	pub fn src(&self) -> &BoundedString {
 		match self {
 			Self::FixedPart(part) => &part.src,
-			Self::SlotPart(part) => &part.src
+			Self::SlotPart(part) => &part.src,
 		}
 	}
 
 	pub fn z_index(&self) -> ZIndex {
 		match self {
 			Self::FixedPart(part) => part.z,
-			Self::SlotPart(part) => part.z
+			Self::SlotPart(part) => part.z,
 		}
 	}
 }
@@ -445,12 +413,10 @@
 #[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq)]
 #[cfg_attr(
 	feature = "std",
-	serde(
-		bound = r#"
+	serde(bound = r#"
 			BoundedString: AsRef<[u8]>,
 			PropertyList: AsRef<[ThemeProperty<BoundedString>]>,
-		"#
-	)
+		"#)
 )]
 pub struct Theme<BoundedString, PropertyList> {
 	/// Name of the theme
@@ -466,10 +432,7 @@
 
 #[cfg_attr(feature = "std", derive(Eq, Serialize))]
 #[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq)]
-#[cfg_attr(
-	feature = "std",
-	serde(bound = "BoundedString: AsRef<[u8]>")
-)]
+#[cfg_attr(feature = "std", serde(bound = "BoundedString: AsRef<[u8]>"))]
 pub struct ThemeProperty<BoundedString> {
 	/// Key of the property
 	#[cfg_attr(feature = "std", serde(with = "serialize::vec"))]
modifiedruntime/tests/src/tests.rsdiffbeforeafterboth
before · runtime/tests/src/tests.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Tests to be written here18use crate::{Test, TestCrossAccountId, CollectionCreationPrice, Origin, Unique, new_test_ext};19use up_data_structs::{20	COLLECTION_NUMBER_LIMIT, CollectionId, CreateItemData, CreateFungibleData, CreateNftData,21	CreateReFungibleData, MAX_DECIMAL_POINTS, COLLECTION_ADMINS_LIMIT, TokenId,22	MAX_TOKEN_OWNERSHIP, CreateCollectionData, CollectionMode,23	AccessMode, CollectionPermissions, PropertyKeyPermission, PropertyPermission,24	Property, CollectionPropertiesVec, CollectionPropertiesPermissionsVec,25};26use frame_support::{assert_noop, assert_ok, assert_err};27use sp_std::convert::TryInto;28use pallet_evm::account::CrossAccountId;29use pallet_common::Error as CommonError;30use pallet_unique::Error as UniqueError;3132fn add_balance(user: u64, value: u64) {33	const DONOR_USER: u64 = 999;34	assert_ok!(<pallet_balances::Pallet<Test>>::set_balance(35		Origin::root(),36		DONOR_USER,37		value,38		039	));40	assert_ok!(<pallet_balances::Pallet<Test>>::force_transfer(41		Origin::root(),42		DONOR_USER,43		user,44		value45	));46}4748fn default_nft_data() -> CreateNftData {49	CreateNftData {50		properties: vec![51			Property {52				key: b"test-prop".to_vec().try_into().unwrap(),53				value: b"test-nft-prop".to_vec().try_into().unwrap(),54			},55		].try_into().unwrap(),56	}57}5859fn default_fungible_data() -> CreateFungibleData {60	CreateFungibleData { value: 5 }61}6263fn default_re_fungible_data() -> CreateReFungibleData {64	CreateReFungibleData {65		const_data: vec![1, 2, 3].try_into().unwrap(),66		pieces: 1023,67	}68}6970fn create_test_collection_for_owner(71	mode: &CollectionMode,72	owner: u64,73	id: CollectionId,74) -> CollectionId {75	add_balance(owner, CollectionCreationPrice::get() as u64 + 1);7677	let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();78	let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();79	let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();80	let token_property_permissions: CollectionPropertiesPermissionsVec = vec![81		PropertyKeyPermission {82			key: b"test-prop".to_vec().try_into().unwrap(),83			permission: PropertyPermission {84				mutable: true,85				collection_admin: false,86				token_owner: true,87			},88		},89	].try_into().unwrap();90	let properties: CollectionPropertiesVec = vec![91		Property {92			key: b"test-collection-prop".to_vec().try_into().unwrap(),93			value: b"test-collection-value".to_vec().try_into().unwrap(),94		}95	].try_into().unwrap();9697	let data: CreateCollectionData<u64> = CreateCollectionData {98		name: col_name1.try_into().unwrap(),99		description: col_desc1.try_into().unwrap(),100		token_prefix: token_prefix1.try_into().unwrap(),101		mode: mode.clone(),102		token_property_permissions: token_property_permissions.clone(),103		properties: properties.clone(),104		..Default::default()105	};106107	let origin1 = Origin::signed(owner);108	assert_ok!(Unique::create_collection_ex(origin1, data));109110	let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();111	let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();112	let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();113	assert_eq!(114		<pallet_common::CollectionById<Test>>::get(id)115			.unwrap()116			.owner,117		owner118	);119	assert_eq!(120		<pallet_common::CollectionById<Test>>::get(id).unwrap().name,121		saved_col_name122	);123	assert_eq!(124		<pallet_common::CollectionById<Test>>::get(id).unwrap().mode,125		*mode126	);127	assert_eq!(128		<pallet_common::CollectionById<Test>>::get(id)129			.unwrap()130			.description,131		saved_description132	);133	assert_eq!(134		<pallet_common::CollectionById<Test>>::get(id)135			.unwrap()136			.token_prefix,137		saved_prefix138	);139	assert_eq!(140		get_collection_property_permissions(id).as_slice(),141		token_property_permissions.as_slice()142	);143	assert_eq!(144		get_collection_properties(id).as_slice(),145		properties.as_slice()146	);147	id148}149150fn get_collection_property_permissions(collection_id: CollectionId) -> Vec<PropertyKeyPermission> {151	<pallet_common::Pallet<Test>>::property_permissions(collection_id)152		.into_iter()153		.map(|(key, permission)| PropertyKeyPermission {154			key,155			permission,156		})157		.collect()158}159160fn get_collection_properties(collection_id: CollectionId) -> Vec<Property> {161	<pallet_common::Pallet<Test>>::collection_properties(collection_id)162		.into_iter()163		.map(|(key, value)| Property {164			key,165			value,166		})167		.collect()168}169170fn get_token_properties(collection_id: CollectionId, token_id: TokenId) -> Vec<Property> {171	<pallet_nonfungible::Pallet<Test>>::token_properties((collection_id, token_id))172		.into_iter()173		.map(|(key, value)| Property {174			key,175			value,176		})177		.collect()178}179180fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {181	create_test_collection_for_owner(&mode, 1, id)182}183184fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {185	let origin1 = Origin::signed(1);186	assert_ok!(Unique::create_item(187		origin1,188		collection_id,189		account(1),190		data.clone()191	));192}193194fn account(sub: u64) -> TestCrossAccountId {195	TestCrossAccountId::from_sub(sub)196}197198// Use cases tests region199// #region200201#[test]202fn check_not_sufficient_founds() {203	new_test_ext().execute_with(|| {204		let acc: u64 = 1;205		<pallet_balances::Pallet<Test>>::set_balance(Origin::root(), acc, 0, 0).unwrap();206207		let name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();208		let description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();209		let token_prefix: Vec<u8> = b"token_prefix1\0".to_vec();210211		let data: CreateCollectionData<<Test as frame_system::Config>::AccountId> =212			CreateCollectionData {213				name: name.try_into().unwrap(),214				description: description.try_into().unwrap(),215				token_prefix: token_prefix.try_into().unwrap(),216				mode: CollectionMode::NFT,217				..Default::default()218			};219220		let result = Unique::create_collection_ex(Origin::signed(acc), data);221		assert_err!(result, <CommonError<Test>>::NotSufficientFounds);222	});223}224225#[test]226fn create_fungible_collection_fails_with_large_decimal_numbers() {227	new_test_ext().execute_with(|| {228		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();229		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();230		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();231232		let data: CreateCollectionData<u64> = CreateCollectionData {233			name: col_name1.try_into().unwrap(),234			description: col_desc1.try_into().unwrap(),235			token_prefix: token_prefix1.try_into().unwrap(),236			mode: CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1),237			..Default::default()238		};239240		let origin1 = Origin::signed(1);241		assert_noop!(242			Unique::create_collection_ex(origin1, data),243			UniqueError::<Test>::CollectionDecimalPointLimitExceeded244		);245	});246}247248#[test]249fn create_nft_item() {250	new_test_ext().execute_with(|| {251		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));252253		let data = default_nft_data();254		create_test_item(collection_id, &data.clone().into());255256		assert_eq!(257			get_token_properties(collection_id, TokenId(1)).as_slice(),258			data.properties.as_slice(),259		);260	});261}262263// Use cases tests region264// #region265#[test]266fn create_nft_multiple_items() {267	new_test_ext().execute_with(|| {268		create_test_collection(&CollectionMode::NFT, CollectionId(1));269270		let origin1 = Origin::signed(1);271272		let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];273274		assert_ok!(Unique::create_multiple_items(275			origin1,276			CollectionId(1),277			account(1),278			items_data279				.clone()280				.into_iter()281				.map(|d| { d.into() })282				.collect()283		));284		for (index, data) in items_data.into_iter().enumerate() {285			assert_eq!(286				get_token_properties(CollectionId(1), TokenId(index as u32 + 1)).as_slice(),287				data.properties.as_slice()288			);289		}290	});291}292293#[test]294fn create_refungible_item() {295	new_test_ext().execute_with(|| {296		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));297298		let data = default_re_fungible_data();299		create_test_item(collection_id, &data.clone().into());300		let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));301		let balance =302			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));303		assert_eq!(item.const_data, data.const_data.into_inner());304		assert_eq!(balance, 1023);305	});306}307308#[test]309fn create_multiple_refungible_items() {310	new_test_ext().execute_with(|| {311		create_test_collection(&CollectionMode::ReFungible, CollectionId(1));312313		let origin1 = Origin::signed(1);314315		let items_data = vec![316			default_re_fungible_data(),317			default_re_fungible_data(),318			default_re_fungible_data(),319		];320321		assert_ok!(Unique::create_multiple_items(322			origin1,323			CollectionId(1),324			account(1),325			items_data326				.clone()327				.into_iter()328				.map(|d| { d.into() })329				.collect()330		));331		for (index, data) in items_data.into_iter().enumerate() {332			let item = <pallet_refungible::TokenData<Test>>::get((333				CollectionId(1),334				TokenId((index + 1) as u32),335			));336			let balance =337				<pallet_refungible::Balance<Test>>::get((CollectionId(1), TokenId(1), account(1)));338			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());339			assert_eq!(balance, 1023);340		}341	});342}343344#[test]345fn create_fungible_item() {346	new_test_ext().execute_with(|| {347		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));348349		let data = default_fungible_data();350		create_test_item(collection_id, &data.into());351352		assert_eq!(353			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),354			5355		);356	});357}358359//#[test]360// fn create_multiple_fungible_items() {361//     new_test_ext().execute_with(|| {362//         default_limits();363364//         create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));365366//         let origin1 = Origin::signed(1);367368//         let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];369370//         assert_ok!(Unique::create_multiple_items(371//             origin1.clone(),372//             1,373//             1,374//             items_data.clone().into_iter().map(|d| { d.into() }).collect()375//         ));376377//         for (index, _) in items_data.iter().enumerate() {378//             assert_eq!(Unique::fungible_item_id(1, (index + 1) as TokenId).value, 5);379//         }380//         assert_eq!(Unique::balance_count(1, 1), 3000);381//         assert_eq!(Unique::address_tokens(1, 1), [1, 2, 3]);382//     });383// }384385#[test]386fn transfer_fungible_item() {387	new_test_ext().execute_with(|| {388		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));389390		let origin1 = Origin::signed(1);391		let origin2 = Origin::signed(2);392393		let data = default_fungible_data();394		create_test_item(collection_id, &data.into());395396		assert_eq!(397			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),398			5399		);400401		// change owner scenario402		assert_ok!(Unique::transfer(403			origin1,404			account(2),405			CollectionId(1),406			TokenId(0),407			5408		));409		assert_eq!(410			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),411			0412		);413414		// split item scenario415		assert_ok!(Unique::transfer(416			origin2.clone(),417			account(3),418			CollectionId(1),419			TokenId(0),420			3421		));422423		// split item and new owner has account scenario424		assert_ok!(Unique::transfer(425			origin2,426			account(3),427			CollectionId(1),428			TokenId(0),429			1430		));431		assert_eq!(432			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(2))),433			1434		);435		assert_eq!(436			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(3))),437			4438		);439	});440}441442#[test]443fn transfer_refungible_item() {444	new_test_ext().execute_with(|| {445		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));446447		// Create RFT 1 in 1023 pieces for account 1448		let data = default_re_fungible_data();449		create_test_item(collection_id, &data.clone().into());450		let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));451		assert_eq!(item.const_data, data.const_data.into_inner());452		assert_eq!(453			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),454			1455		);456		assert_eq!(457			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),458			1023459		);460		assert_eq!(461			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),462			true463		);464465		// Account 1 transfers all 1023 pieces of RFT 1 to account 2466		let origin1 = Origin::signed(1);467		let origin2 = Origin::signed(2);468		assert_ok!(Unique::transfer(469			origin1,470			account(2),471			CollectionId(1),472			TokenId(1),473			1023474		));475		assert_eq!(476			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),477			1023478		);479		assert_eq!(480			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),481			0482		);483		assert_eq!(484			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),485			1486		);487		assert_eq!(488			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),489			false490		);491		assert_eq!(492			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),493			true494		);495496		// Account 2 transfers 500 pieces of RFT 1 to account 3497		assert_ok!(Unique::transfer(498			origin2.clone(),499			account(3),500			CollectionId(1),501			TokenId(1),502			500503		));504		assert_eq!(505			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),506			523507		);508		assert_eq!(509			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),510			500511		);512		assert_eq!(513			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),514			1515		);516		assert_eq!(517			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),518			1519		);520		assert_eq!(521			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),522			true523		);524		assert_eq!(525			<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),526			true527		);528529		// Account 2 transfers 200 more pieces of RFT 1 to account 3 with pre-existing balance530		assert_ok!(Unique::transfer(531			origin2,532			account(3),533			CollectionId(1),534			TokenId(1),535			200536		));537		assert_eq!(538			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),539			323540		);541		assert_eq!(542			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),543			700544		);545		assert_eq!(546			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),547			1548		);549		assert_eq!(550			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),551			1552		);553		assert_eq!(554			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),555			true556		);557		assert_eq!(558			<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),559			true560		);561	});562}563564#[test]565fn transfer_nft_item() {566	new_test_ext().execute_with(|| {567		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));568569		let data = default_nft_data();570		create_test_item(collection_id, &data.into());571		assert_eq!(572			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),573			1574		);575		assert_eq!(576			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),577			true578		);579580		let origin1 = Origin::signed(1);581		// default scenario582		assert_ok!(Unique::transfer(583			origin1,584			account(2),585			CollectionId(1),586			TokenId(1),587			1588		));589		assert_eq!(590			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),591			0592		);593		assert_eq!(594			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),595			1596		);597		assert_eq!(598			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),599			false600		);601		assert_eq!(602			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),603			true604		);605	});606}607608#[test]609fn transfer_nft_item_wrong_value() {610	new_test_ext().execute_with(|| {611		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));612613		let data = default_nft_data();614		create_test_item(collection_id, &data.into());615		assert_eq!(616			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),617			1618		);619		assert_eq!(620			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),621			true622		);623624		let origin1 = Origin::signed(1);625626		assert_noop!(627			Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 2)628				.map_err(|e| e.error),629			<pallet_nonfungible::Error::<Test>>::NonfungibleItemsHaveNoAmount630		);631	});632}633634#[test]635fn transfer_nft_item_zero_value() {636	new_test_ext().execute_with(|| {637		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));638639		let data = default_nft_data();640		create_test_item(collection_id, &data.into());641		assert_eq!(642			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),643			1644		);645		assert_eq!(646			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),647			true648		);649650		let origin1 = Origin::signed(1);651652		// Transferring 0 amount works on NFT...653		assert_ok!(Unique::transfer(654			origin1,655			account(2),656			CollectionId(1),657			TokenId(1),658			0659		));660		// ... and results in no transfer661		assert_eq!(662			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),663			1664		);665		assert_eq!(666			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),667			true668		);669	});670}671672#[test]673fn nft_approve_and_transfer_from() {674	new_test_ext().execute_with(|| {675		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));676677		let data = default_nft_data();678		create_test_item(collection_id, &data.into());679680		let origin1 = Origin::signed(1);681		let origin2 = Origin::signed(2);682683		assert_eq!(684			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),685			1686		);687		assert_eq!(688			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),689			true690		);691692		// neg transfer_from693		assert_noop!(694			Unique::transfer_from(695				origin2.clone(),696				account(1),697				account(2),698				CollectionId(1),699				TokenId(1),700				1701			)702			.map_err(|e| e.error),703			CommonError::<Test>::ApprovedValueTooLow704		);705706		// do approve707		assert_ok!(Unique::approve(708			origin1,709			account(2),710			CollectionId(1),711			TokenId(1),712			1713		));714		assert_eq!(715			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),716			account(2)717		);718719		assert_ok!(Unique::transfer_from(720			origin2,721			account(1),722			account(3),723			CollectionId(1),724			TokenId(1),725			1726		));727		assert!(728			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()729		);730	});731}732733#[test]734fn nft_approve_and_transfer_from_allow_list() {735	new_test_ext().execute_with(|| {736		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));737738		let origin1 = Origin::signed(1);739		let origin2 = Origin::signed(2);740741		// Create NFT 1 for account 1742		let data = default_nft_data();743		create_test_item(collection_id, &data.clone().into());744		assert_eq!(745			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),746			1747		);748		assert_eq!(749			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),750			true751		);752753		// Allow allow-list users to mint and add accounts 1, 2, and 3 to allow-list754		assert_ok!(Unique::set_collection_permissions(755			origin1.clone(),756			CollectionId(1),757			CollectionPermissions {758				mint_mode: Some(true),759				access: Some(AccessMode::AllowList),760				nesting: None,761			}762		));763		assert_ok!(Unique::add_to_allow_list(764			origin1.clone(),765			CollectionId(1),766			account(1)767		));768		assert_ok!(Unique::add_to_allow_list(769			origin1.clone(),770			CollectionId(1),771			account(2)772		));773		assert_ok!(Unique::add_to_allow_list(774			origin1.clone(),775			CollectionId(1),776			account(3)777		));778779		// Account 1 approves account 2 for NFT 1780		assert_ok!(Unique::approve(781			origin1.clone(),782			account(2),783			CollectionId(1),784			TokenId(1),785			1786		));787		assert_eq!(788			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),789			account(2)790		);791792		// Account 2 transfers NFT 1 from account 1 to account 3793		assert_ok!(Unique::transfer_from(794			origin2,795			account(1),796			account(3),797			CollectionId(1),798			TokenId(1),799			1800		));801		assert!(802			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()803		);804	});805}806807#[test]808fn refungible_approve_and_transfer_from() {809	new_test_ext().execute_with(|| {810		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));811812		let origin1 = Origin::signed(1);813		let origin2 = Origin::signed(2);814815		// Create RFT 1 in 1023 pieces for account 1816		let data = default_re_fungible_data();817		create_test_item(collection_id, &data.into());818819		assert_eq!(820			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),821			1822		);823		assert_eq!(824			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),825			1023826		);827		assert_eq!(828			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),829			true830		);831832		// Allow public minting, enable allow-list and add accounts 1, 2, 3 to allow-list833		assert_ok!(Unique::set_collection_permissions(834			origin1.clone(),835			CollectionId(1),836			CollectionPermissions {837				mint_mode: Some(true),838				access: Some(AccessMode::AllowList),839				nesting: None,840			}841		));842		assert_ok!(Unique::add_to_allow_list(843			origin1.clone(),844			CollectionId(1),845			account(1)846		));847		assert_ok!(Unique::add_to_allow_list(848			origin1.clone(),849			CollectionId(1),850			account(2)851		));852		assert_ok!(Unique::add_to_allow_list(853			origin1.clone(),854			CollectionId(1),855			account(3)856		));857858		// Account 1 approves account 2 for 1023 pieces of RFT 1859		assert_ok!(Unique::approve(860			origin1,861			account(2),862			CollectionId(1),863			TokenId(1),864			1023865		));866		assert_eq!(867			<pallet_refungible::Allowance<Test>>::get((868				CollectionId(1),869				TokenId(1),870				account(1),871				account(2)872			)),873			1023874		);875876		// Account 2 transfers 100 pieces of RFT 1 from account 1 to account 3877		assert_ok!(Unique::transfer_from(878			origin2,879			account(1),880			account(3),881			CollectionId(1),882			TokenId(1),883			100884		));885		assert_eq!(886			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),887			1888		);889		assert_eq!(890			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),891			1892		);893		assert_eq!(894			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),895			923896		);897		assert_eq!(898			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),899			100900		);901		assert_eq!(902			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),903			true904		);905		assert_eq!(906			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),907			true908		);909		assert_eq!(910			<pallet_refungible::Allowance<Test>>::get((911				CollectionId(1),912				TokenId(1),913				account(1),914				account(2)915			)),916			923917		);918	});919}920921#[test]922fn fungible_approve_and_transfer_from() {923	new_test_ext().execute_with(|| {924		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));925926		let data = default_fungible_data();927		create_test_item(collection_id, &data.into());928929		let origin1 = Origin::signed(1);930		let origin2 = Origin::signed(2);931932		assert_ok!(Unique::set_collection_permissions(933			origin1.clone(),934			CollectionId(1),935			CollectionPermissions {936				mint_mode: Some(true),937				access: Some(AccessMode::AllowList),938				nesting: None,939			}940		));941		assert_ok!(Unique::add_to_allow_list(942			origin1.clone(),943			CollectionId(1),944			account(1)945		));946		assert_ok!(Unique::add_to_allow_list(947			origin1.clone(),948			CollectionId(1),949			account(2)950		));951		assert_ok!(Unique::add_to_allow_list(952			origin1.clone(),953			CollectionId(1),954			account(3)955		));956957		// do approve958		assert_ok!(Unique::approve(959			origin1.clone(),960			account(2),961			CollectionId(1),962			TokenId(0),963			5964		));965		assert_eq!(966			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),967			5968		);969		assert_ok!(Unique::approve(970			origin1,971			account(3),972			CollectionId(1),973			TokenId(0),974			5975		));976		assert_eq!(977			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),978			5979		);980		assert_eq!(981			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(3))),982			5983		);984985		assert_ok!(Unique::transfer_from(986			origin2.clone(),987			account(1),988			account(3),989			CollectionId(1),990			TokenId(0),991			4992		));993994		assert_eq!(995			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),996			1997		);998999		assert_noop!(1000			Unique::transfer_from(1001				origin2,1002				account(1),1003				account(3),1004				CollectionId(1),1005				TokenId(0),1006				41007			)1008			.map_err(|e| e.error),1009			CommonError::<Test>::ApprovedValueTooLow1010		);1011	});1012}10131014#[test]1015fn change_collection_owner() {1016	new_test_ext().execute_with(|| {1017		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10181019		let origin1 = Origin::signed(1);1020		assert_ok!(Unique::change_collection_owner(origin1, collection_id, 2));1021		assert_eq!(1022			<pallet_common::CollectionById<Test>>::get(collection_id)1023				.unwrap()1024				.owner,1025			21026		);1027	});1028}10291030#[test]1031fn destroy_collection() {1032	new_test_ext().execute_with(|| {1033		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10341035		let origin1 = Origin::signed(1);1036		assert_ok!(Unique::destroy_collection(origin1, collection_id));1037	});1038}10391040#[test]1041fn burn_nft_item() {1042	new_test_ext().execute_with(|| {1043		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10441045		let origin1 = Origin::signed(1);10461047		let data = default_nft_data();1048		create_test_item(collection_id, &data.into());10491050		// check balance (collection with id = 1, user id = 1)1051		assert_eq!(1052			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1053			11054		);10551056		// burn item1057		assert_ok!(Unique::burn_item(1058			origin1.clone(),1059			collection_id,1060			TokenId(1),1061			11062		));1063		assert_eq!(1064			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1065			01066		);1067	});1068}10691070#[test]1071fn burn_same_nft_item_twice() {1072	new_test_ext().execute_with(|| {1073		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10741075		let origin1 = Origin::signed(1);10761077		let data = default_nft_data();1078		create_test_item(collection_id, &data.into());10791080		// check balance (collection with id = 1, user id = 1)1081		assert_eq!(1082			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1083			11084		);10851086		// burn item1087		assert_ok!(Unique::burn_item(1088			origin1.clone(),1089			collection_id,1090			TokenId(1),1091			11092		));10931094		// burn item again1095		assert_noop!(1096			Unique::burn_item(origin1, collection_id, TokenId(1), 1).map_err(|e| e.error),1097			CommonError::<Test>::TokenNotFound1098		);10991100		assert_eq!(1101			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1102			01103		);1104	});1105}11061107#[test]1108fn burn_fungible_item() {1109	new_test_ext().execute_with(|| {1110		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11111112		let origin1 = Origin::signed(1);1113		assert_ok!(Unique::add_collection_admin(1114			origin1.clone(),1115			collection_id,1116			account(2)1117		));11181119		let data = default_fungible_data();1120		create_test_item(collection_id, &data.into());11211122		// check balance (collection with id = 1, user id = 1)1123		assert_eq!(1124			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1125			51126		);11271128		// burn item1129		assert_ok!(Unique::burn_item(1130			origin1.clone(),1131			CollectionId(1),1132			TokenId(0),1133			51134		));1135		assert_noop!(1136			Unique::burn_item(origin1, CollectionId(1), TokenId(0), 5).map_err(|e| e.error),1137			CommonError::<Test>::TokenValueTooLow1138		);11391140		assert_eq!(1141			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1142			01143		);1144	});1145}11461147#[test]1148fn burn_fungible_item_with_token_id() {1149	new_test_ext().execute_with(|| {1150		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11511152		let origin1 = Origin::signed(1);1153		assert_ok!(Unique::add_collection_admin(1154			origin1.clone(),1155			collection_id,1156			account(2)1157		));11581159		let data = default_fungible_data();1160		create_test_item(collection_id, &data.into());11611162		// check balance (collection with id = 1, user id = 1)1163		assert_eq!(1164			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1165			51166		);11671168		// Try to burn item using Token ID1169		assert_noop!(1170			Unique::burn_item(origin1, CollectionId(1), TokenId(1), 5).map_err(|e| e.error),1171			<pallet_fungible::Error::<Test>>::FungibleItemsHaveNoId1172		);1173	});1174}1175#[test]1176fn burn_refungible_item() {1177	new_test_ext().execute_with(|| {1178		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));1179		let origin1 = Origin::signed(1);11801181		assert_ok!(Unique::set_collection_permissions(1182			origin1.clone(),1183			collection_id,1184			CollectionPermissions {1185				mint_mode: Some(true),1186				access: Some(AccessMode::AllowList),1187				nesting: None,1188			}1189		));1190		assert_ok!(Unique::add_to_allow_list(1191			origin1.clone(),1192			collection_id,1193			account(1)1194		));11951196		assert_ok!(Unique::add_collection_admin(1197			origin1.clone(),1198			collection_id,1199			account(2)1200		));12011202		let data = default_re_fungible_data();1203		create_test_item(collection_id, &data.into());12041205		// check balance (collection with id = 1, user id = 2)1206		assert_eq!(1207			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),1208			11209		);1210		assert_eq!(1211			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1212			10231213		);12141215		// burn item1216		assert_ok!(Unique::burn_item(1217			origin1.clone(),1218			collection_id,1219			TokenId(1),1220			10231221		));1222		assert_noop!(1223			Unique::burn_item(origin1, collection_id, TokenId(1), 1023).map_err(|e| e.error),1224			CommonError::<Test>::TokenValueTooLow1225		);12261227		assert_eq!(1228			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1229			01230		);1231	});1232}12331234#[test]1235fn add_collection_admin() {1236	new_test_ext().execute_with(|| {1237		let collection1_id =1238			create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1239		let origin1 = Origin::signed(1);12401241		// Add collection admins1242		assert_ok!(Unique::add_collection_admin(1243			origin1.clone(),1244			collection1_id,1245			account(2)1246		));1247		assert_ok!(Unique::add_collection_admin(1248			origin1,1249			collection1_id,1250			account(3)1251		));12521253		// Owner is not an admin by default1254		assert_eq!(1255			<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(1))),1256			false1257		);1258		assert!(<pallet_common::IsAdmin<Test>>::get((1259			CollectionId(1),1260			account(2)1261		)));1262		assert!(<pallet_common::IsAdmin<Test>>::get((1263			CollectionId(1),1264			account(3)1265		)));1266	});1267}12681269#[test]1270fn remove_collection_admin() {1271	new_test_ext().execute_with(|| {1272		let collection1_id =1273			create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1274		let origin1 = Origin::signed(1);1275		let origin2 = Origin::signed(2);12761277		// Add collection admins 2 and 31278		assert_ok!(Unique::add_collection_admin(1279			origin1.clone(),1280			collection1_id,1281			account(2)1282		));1283		assert_ok!(Unique::add_collection_admin(1284			origin1,1285			collection1_id,1286			account(3)1287		));12881289		assert!(<pallet_common::IsAdmin<Test>>::get((1290			CollectionId(1),1291			account(2)1292		)));1293		assert!(<pallet_common::IsAdmin<Test>>::get((1294			CollectionId(1),1295			account(3)1296		)));12971298		// remove admin 31299		assert_ok!(Unique::remove_collection_admin(1300			origin2,1301			CollectionId(1),1302			account(3)1303		));13041305		// 2 is still admin, 3 is not an admin anymore1306		assert!(<pallet_common::IsAdmin<Test>>::get((1307			CollectionId(1),1308			account(2)1309		)));1310		assert_eq!(1311			<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))),1312			false1313		);1314	});1315}13161317#[test]1318fn balance_of() {1319	new_test_ext().execute_with(|| {1320		let nft_collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1321		let fungible_collection_id =1322			create_test_collection(&CollectionMode::Fungible(3), CollectionId(2));1323		let re_fungible_collection_id =1324			create_test_collection(&CollectionMode::ReFungible, CollectionId(3));13251326		// check balance before1327		assert_eq!(1328			<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1329			01330		);1331		assert_eq!(1332			<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1333			01334		);1335		assert_eq!(1336			<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1337			01338		);13391340		let nft_data = default_nft_data();1341		create_test_item(nft_collection_id, &nft_data.into());13421343		let fungible_data = default_fungible_data();1344		create_test_item(fungible_collection_id, &fungible_data.into());13451346		let re_fungible_data = default_re_fungible_data();1347		create_test_item(re_fungible_collection_id, &re_fungible_data.into());13481349		// check balance (collection with id = 1, user id = 1)1350		assert_eq!(1351			<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1352			11353		);1354		assert_eq!(1355			<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1356			51357		);1358		assert_eq!(1359			<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1360			11361		);13621363		assert_eq!(1364			<pallet_nonfungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))),1365			true1366		);1367		assert_eq!(1368			<pallet_refungible::Owned<Test>>::get((1369				re_fungible_collection_id,1370				account(1),1371				TokenId(1)1372			)),1373			true1374		);1375	});1376}13771378#[test]1379fn approve() {1380	new_test_ext().execute_with(|| {1381		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));13821383		let data = default_nft_data();1384		create_test_item(collection_id, &data.into());13851386		let origin1 = Origin::signed(1);13871388		// approve1389		assert_ok!(Unique::approve(1390			origin1,1391			account(2),1392			CollectionId(1),1393			TokenId(1),1394			11395		));1396		assert_eq!(1397			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1398			account(2)1399		);1400	});1401}14021403#[test]1404fn transfer_from() {1405	new_test_ext().execute_with(|| {1406		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1407		let origin1 = Origin::signed(1);1408		let origin2 = Origin::signed(2);14091410		let data = default_nft_data();1411		create_test_item(collection_id, &data.into());14121413		// approve1414		assert_ok!(Unique::approve(1415			origin1.clone(),1416			account(2),1417			CollectionId(1),1418			TokenId(1),1419			11420		));1421		assert_eq!(1422			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1423			account(2)1424		);14251426		assert_ok!(Unique::set_collection_permissions(1427			origin1.clone(),1428			CollectionId(1),1429			CollectionPermissions {1430				mint_mode: Some(true),1431				access: Some(AccessMode::AllowList),1432				nesting: None,1433			}1434		));1435		assert_ok!(Unique::add_to_allow_list(1436			origin1.clone(),1437			CollectionId(1),1438			account(1)1439		));1440		assert_ok!(Unique::add_to_allow_list(1441			origin1.clone(),1442			CollectionId(1),1443			account(2)1444		));1445		assert_ok!(Unique::add_to_allow_list(1446			origin1,1447			CollectionId(1),1448			account(3)1449		));14501451		assert_ok!(Unique::transfer_from(1452			origin2,1453			account(1),1454			account(2),1455			CollectionId(1),1456			TokenId(1),1457			11458		));14591460		// after transfer1461		assert_eq!(1462			<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(1))),1463			01464		);1465		assert_eq!(1466			<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(2))),1467			11468		);1469	});1470}14711472// #endregion14731474// Coverage tests region1475// #region14761477#[test]1478fn owner_can_add_address_to_allow_list() {1479	new_test_ext().execute_with(|| {1480		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));14811482		let origin1 = Origin::signed(1);1483		assert_ok!(Unique::add_to_allow_list(1484			origin1,1485			collection_id,1486			account(2)1487		));1488		assert!(<pallet_common::Allowlist<Test>>::get((1489			collection_id,1490			account(2)1491		)));1492	});1493}14941495#[test]1496fn admin_can_add_address_to_allow_list() {1497	new_test_ext().execute_with(|| {1498		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1499		let origin1 = Origin::signed(1);1500		let origin2 = Origin::signed(2);15011502		assert_ok!(Unique::add_collection_admin(1503			origin1,1504			collection_id,1505			account(2)1506		));1507		assert_ok!(Unique::add_to_allow_list(1508			origin2,1509			collection_id,1510			account(3)1511		));1512		assert!(<pallet_common::Allowlist<Test>>::get((1513			collection_id,1514			account(3)1515		)));1516	});1517}15181519#[test]1520fn nonprivileged_user_cannot_add_address_to_allow_list() {1521	new_test_ext().execute_with(|| {1522		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15231524		let origin2 = Origin::signed(2);1525		assert_noop!(1526			Unique::add_to_allow_list(origin2, collection_id, account(3)),1527			CommonError::<Test>::NoPermission1528		);1529	});1530}15311532#[test]1533fn nobody_can_add_address_to_allow_list_of_nonexisting_collection() {1534	new_test_ext().execute_with(|| {1535		let origin1 = Origin::signed(1);15361537		assert_noop!(1538			Unique::add_to_allow_list(origin1, CollectionId(1), account(2)),1539			CommonError::<Test>::CollectionNotFound1540		);1541	});1542}15431544#[test]1545fn nobody_can_add_address_to_allow_list_of_deleted_collection() {1546	new_test_ext().execute_with(|| {1547		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15481549		let origin1 = Origin::signed(1);1550		assert_ok!(Unique::destroy_collection(origin1.clone(), collection_id));1551		assert_noop!(1552			Unique::add_to_allow_list(origin1, collection_id, account(2)),1553			CommonError::<Test>::CollectionNotFound1554		);1555	});1556}15571558// If address is already added to allow list, nothing happens1559#[test]1560fn address_is_already_added_to_allow_list() {1561	new_test_ext().execute_with(|| {1562		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1563		let origin1 = Origin::signed(1);15641565		assert_ok!(Unique::add_to_allow_list(1566			origin1.clone(),1567			collection_id,1568			account(2)1569		));1570		assert_ok!(Unique::add_to_allow_list(1571			origin1,1572			collection_id,1573			account(2)1574		));1575		assert!(<pallet_common::Allowlist<Test>>::get((1576			collection_id,1577			account(2)1578		)));1579	});1580}15811582#[test]1583fn owner_can_remove_address_from_allow_list() {1584	new_test_ext().execute_with(|| {1585		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15861587		let origin1 = Origin::signed(1);1588		assert_ok!(Unique::add_to_allow_list(1589			origin1.clone(),1590			collection_id,1591			account(2)1592		));1593		assert_ok!(Unique::remove_from_allow_list(1594			origin1,1595			collection_id,1596			account(2)1597		));1598		assert_eq!(1599			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1600			false1601		);1602	});1603}16041605#[test]1606fn admin_can_remove_address_from_allow_list() {1607	new_test_ext().execute_with(|| {1608		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1609		let origin1 = Origin::signed(1);1610		let origin2 = Origin::signed(2);16111612		// Owner adds admin1613		assert_ok!(Unique::add_collection_admin(1614			origin1.clone(),1615			collection_id,1616			account(2)1617		));16181619		// Owner adds address 3 to allow list1620		assert_ok!(Unique::add_to_allow_list(1621			origin1,1622			collection_id,1623			account(3)1624		));16251626		// Admin removes address 3 from allow list1627		assert_ok!(Unique::remove_from_allow_list(1628			origin2,1629			collection_id,1630			account(3)1631		));1632		assert_eq!(1633			<pallet_common::Allowlist<Test>>::get((collection_id, account(3))),1634			false1635		);1636	});1637}16381639#[test]1640fn nonprivileged_user_cannot_remove_address_from_allow_list() {1641	new_test_ext().execute_with(|| {1642		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1643		let origin1 = Origin::signed(1);1644		let origin2 = Origin::signed(2);16451646		assert_ok!(Unique::add_to_allow_list(1647			origin1,1648			collection_id,1649			account(2)1650		));1651		assert_noop!(1652			Unique::remove_from_allow_list(origin2, collection_id, account(2)),1653			CommonError::<Test>::NoPermission1654		);1655		assert!(<pallet_common::Allowlist<Test>>::get((1656			collection_id,1657			account(2)1658		)));1659	});1660}16611662#[test]1663fn nobody_can_remove_address_from_allow_list_of_nonexisting_collection() {1664	new_test_ext().execute_with(|| {1665		let origin1 = Origin::signed(1);16661667		assert_noop!(1668			Unique::remove_from_allow_list(origin1, CollectionId(1), account(2)),1669			CommonError::<Test>::CollectionNotFound1670		);1671	});1672}16731674#[test]1675fn nobody_can_remove_address_from_allow_list_of_deleted_collection() {1676	new_test_ext().execute_with(|| {1677		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1678		let origin1 = Origin::signed(1);1679		let origin2 = Origin::signed(2);16801681		// Add account 2 to allow list1682		assert_ok!(Unique::add_to_allow_list(1683			origin1.clone(),1684			collection_id,1685			account(2)1686		));16871688		// Account 2 is in collection allow-list1689		assert!(<pallet_common::Allowlist<Test>>::get((1690			collection_id,1691			account(2)1692		)));16931694		// Destroy collection1695		assert_ok!(Unique::destroy_collection(origin1, collection_id));16961697		// Attempt to remove account 2 from collection allow-list => error1698		assert_noop!(1699			Unique::remove_from_allow_list(origin2, collection_id, account(2)),1700			CommonError::<Test>::CollectionNotFound1701		);17021703		// Account 2 is not found in collection allow-list anyway1704		assert_eq!(1705			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1706			false1707		);1708	});1709}17101711// If address is already removed from allow list, nothing happens1712#[test]1713fn address_is_already_removed_from_allow_list() {1714	new_test_ext().execute_with(|| {1715		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1716		let origin1 = Origin::signed(1);17171718		assert_ok!(Unique::add_to_allow_list(1719			origin1.clone(),1720			collection_id,1721			account(2)1722		));1723		assert_ok!(Unique::remove_from_allow_list(1724			origin1.clone(),1725			collection_id,1726			account(2)1727		));1728		assert_eq!(1729			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1730			false1731		);1732		assert_ok!(Unique::remove_from_allow_list(1733			origin1,1734			collection_id,1735			account(2)1736		));1737		assert_eq!(1738			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1739			false1740		);1741	});1742}17431744// If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom (2 tests)1745#[test]1746fn allow_list_test_1() {1747	new_test_ext().execute_with(|| {1748		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));17491750		let origin1 = Origin::signed(1);17511752		let data = default_nft_data();1753		create_test_item(collection_id, &data.into());17541755		assert_ok!(Unique::set_collection_permissions(1756			origin1.clone(),1757			collection_id,1758			CollectionPermissions {1759				mint_mode: None,1760				access: Some(AccessMode::AllowList),1761				nesting: None,1762			}1763		));1764		assert_ok!(Unique::add_to_allow_list(1765			origin1.clone(),1766			collection_id,1767			account(2)1768		));17691770		assert_noop!(1771			Unique::transfer(origin1, account(3), CollectionId(1), TokenId(1), 1)1772				.map_err(|e| e.error),1773			CommonError::<Test>::AddressNotInAllowlist1774		);1775	});1776}17771778#[test]1779fn allow_list_test_2() {1780	new_test_ext().execute_with(|| {1781		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1782		let origin1 = Origin::signed(1);17831784		let data = default_nft_data();1785		create_test_item(collection_id, &data.into());17861787		assert_ok!(Unique::set_collection_permissions(1788			origin1.clone(),1789			collection_id,1790			CollectionPermissions {1791				mint_mode: None,1792				access: Some(AccessMode::AllowList),1793				nesting: None,1794			}1795		));1796		assert_ok!(Unique::add_to_allow_list(1797			origin1.clone(),1798			collection_id,1799			account(1)1800		));1801		assert_ok!(Unique::add_to_allow_list(1802			origin1.clone(),1803			collection_id,1804			account(2)1805		));18061807		// do approve1808		assert_ok!(Unique::approve(1809			origin1.clone(),1810			account(1),1811			collection_id,1812			TokenId(1),1813			11814		));1815		assert_eq!(1816			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1817			account(1)1818		);18191820		assert_ok!(Unique::remove_from_allow_list(1821			origin1.clone(),1822			collection_id,1823			account(1)1824		));18251826		assert_noop!(1827			Unique::transfer_from(1828				origin1,1829				account(1),1830				account(3),1831				CollectionId(1),1832				TokenId(1),1833				11834			)1835			.map_err(|e| e.error),1836			CommonError::<Test>::AddressNotInAllowlist1837		);1838	});1839}18401841// If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom (2 tests)1842#[test]1843fn allow_list_test_3() {1844	new_test_ext().execute_with(|| {1845		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18461847		let origin1 = Origin::signed(1);18481849		let data = default_nft_data();1850		create_test_item(collection_id, &data.into());18511852		assert_ok!(Unique::set_collection_permissions(1853			origin1.clone(),1854			collection_id,1855			CollectionPermissions {1856				mint_mode: None,1857				access: Some(AccessMode::AllowList),1858				nesting: None,1859			}1860		));1861		assert_ok!(Unique::add_to_allow_list(1862			origin1.clone(),1863			collection_id,1864			account(1)1865		));18661867		assert_noop!(1868			Unique::transfer(origin1, account(3), collection_id, TokenId(1), 1)1869				.map_err(|e| e.error),1870			CommonError::<Test>::AddressNotInAllowlist1871		);1872	});1873}18741875#[test]1876fn allow_list_test_4() {1877	new_test_ext().execute_with(|| {1878		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18791880		let origin1 = Origin::signed(1);18811882		let data = default_nft_data();1883		create_test_item(collection_id, &data.into());18841885		assert_ok!(Unique::set_collection_permissions(1886			origin1.clone(),1887			collection_id,1888			CollectionPermissions {1889				mint_mode: None,1890				access: Some(AccessMode::AllowList),1891				nesting: None,1892			}1893		));1894		assert_ok!(Unique::add_to_allow_list(1895			origin1.clone(),1896			collection_id,1897			account(1)1898		));1899		assert_ok!(Unique::add_to_allow_list(1900			origin1.clone(),1901			collection_id,1902			account(2)1903		));19041905		// do approve1906		assert_ok!(Unique::approve(1907			origin1.clone(),1908			account(1),1909			collection_id,1910			TokenId(1),1911			11912		));1913		assert_eq!(1914			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1915			account(1)1916		);19171918		assert_ok!(Unique::remove_from_allow_list(1919			origin1.clone(),1920			collection_id,1921			account(2)1922		));19231924		assert_noop!(1925			Unique::transfer_from(1926				origin1,1927				account(1),1928				account(3),1929				collection_id,1930				TokenId(1),1931				11932			)1933			.map_err(|e| e.error),1934			CommonError::<Test>::AddressNotInAllowlist1935		);1936	});1937}19381939// If Public Access mode is set to AllowList, tokens can’t be destroyed by a non-allowlisted address (even if it owned them before enabling AllowList mode)1940#[test]1941fn allow_list_test_5() {1942	new_test_ext().execute_with(|| {1943		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19441945		let origin1 = Origin::signed(1);19461947		let data = default_nft_data();1948		create_test_item(collection_id, &data.into());19491950		assert_ok!(Unique::set_collection_permissions(1951			origin1.clone(),1952			collection_id,1953			CollectionPermissions {1954				mint_mode: None,1955				access: Some(AccessMode::AllowList),1956				nesting: None,1957			}1958		));1959		assert_noop!(1960			Unique::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 1).map_err(|e| e.error),1961			CommonError::<Test>::AddressNotInAllowlist1962		);1963	});1964}19651966// If Public Access mode is set to AllowList, token transfers can’t be Approved by a non-allowlisted address (see Approve method).1967#[test]1968fn allow_list_test_6() {1969	new_test_ext().execute_with(|| {1970		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19711972		let origin1 = Origin::signed(1);19731974		let data = default_nft_data();1975		create_test_item(collection_id, &data.into());19761977		assert_ok!(Unique::set_collection_permissions(1978			origin1.clone(),1979			collection_id,1980			CollectionPermissions {1981				mint_mode: None,1982				access: Some(AccessMode::AllowList),1983				nesting: None,1984			}1985		));19861987		// do approve1988		assert_noop!(1989			Unique::approve(origin1, account(1), CollectionId(1), TokenId(1), 1)1990				.map_err(|e| e.error),1991			CommonError::<Test>::AddressNotInAllowlist1992		);1993	});1994}19951996// If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests) and1997//          tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests)1998#[test]1999fn allow_list_test_7() {2000	new_test_ext().execute_with(|| {2001		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));20022003		let data = default_nft_data();2004		create_test_item(collection_id, &data.into());20052006		let origin1 = Origin::signed(1);20072008		assert_ok!(Unique::set_collection_permissions(2009			origin1.clone(),2010			collection_id,2011			CollectionPermissions {2012				mint_mode: None,2013				access: Some(AccessMode::AllowList),2014				nesting: None,2015			}2016		));2017		assert_ok!(Unique::add_to_allow_list(2018			origin1.clone(),2019			collection_id,2020			account(1)2021		));2022		assert_ok!(Unique::add_to_allow_list(2023			origin1.clone(),2024			collection_id,2025			account(2)2026		));20272028		assert_ok!(Unique::transfer(2029			origin1,2030			account(2),2031			CollectionId(1),2032			TokenId(1),2033			12034		));2035	});2036}20372038#[test]2039fn allow_list_test_8() {2040	new_test_ext().execute_with(|| {2041		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));20422043		// Create NFT for account 12044		let data = default_nft_data();2045		create_test_item(collection_id, &data.into());20462047		let origin1 = Origin::signed(1);20482049		// Toggle Allow List mode and add accounts 1 and 22050		assert_ok!(Unique::set_collection_permissions(2051			origin1.clone(),2052			collection_id,2053			CollectionPermissions {2054				mint_mode: None,2055				access: Some(AccessMode::AllowList),2056				nesting: None,2057			}2058		));2059		assert_ok!(Unique::add_to_allow_list(2060			origin1.clone(),2061			collection_id,2062			account(1)2063		));2064		assert_ok!(Unique::add_to_allow_list(2065			origin1.clone(),2066			collection_id,2067			account(2)2068		));20692070		// Sself-approve account 1 for NFT 12071		assert_ok!(Unique::approve(2072			origin1.clone(),2073			account(1),2074			CollectionId(1),2075			TokenId(1),2076			12077		));2078		assert_eq!(2079			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),2080			account(1)2081		);20822083		// Transfer from 1 to 22084		assert_ok!(Unique::transfer_from(2085			origin1,2086			account(1),2087			account(2),2088			CollectionId(1),2089			TokenId(1),2090			12091		));2092	});2093}20942095// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by owner.2096#[test]2097fn allow_list_test_9() {2098	new_test_ext().execute_with(|| {2099		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2100		let origin1 = Origin::signed(1);21012102		assert_ok!(Unique::set_collection_permissions(2103			origin1.clone(),2104			collection_id,2105			CollectionPermissions {2106				mint_mode: Some(false),2107				access: Some(AccessMode::AllowList),2108				nesting: None,2109			}2110		));21112112		let data = default_nft_data();2113		create_test_item(collection_id, &data.into());2114	});2115}21162117// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by admin.2118#[test]2119fn allow_list_test_10() {2120	new_test_ext().execute_with(|| {2121		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21222123		let origin1 = Origin::signed(1);2124		let origin2 = Origin::signed(2);21252126		assert_ok!(Unique::set_collection_permissions(2127			origin1.clone(),2128			collection_id,2129			CollectionPermissions {2130				mint_mode: Some(false),2131				access: Some(AccessMode::AllowList),2132				nesting: None,2133			}2134		));21352136		assert_ok!(Unique::add_collection_admin(2137			origin1,2138			collection_id,2139			account(2)2140		));21412142		assert_ok!(Unique::create_item(2143			origin2,2144			collection_id,2145			account(2),2146			default_nft_data().into()2147		));2148	});2149}21502151// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and allow listed address.2152#[test]2153fn allow_list_test_11() {2154	new_test_ext().execute_with(|| {2155		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21562157		let origin1 = Origin::signed(1);2158		let origin2 = Origin::signed(2);21592160		assert_ok!(Unique::set_collection_permissions(2161			origin1.clone(),2162			collection_id,2163			CollectionPermissions {2164				mint_mode: Some(false),2165				access: Some(AccessMode::AllowList),2166				nesting: None,2167			}2168		));2169		assert_ok!(Unique::add_to_allow_list(2170			origin1,2171			collection_id,2172			account(2)2173		));21742175		assert_noop!(2176			Unique::create_item(2177				origin2,2178				CollectionId(1),2179				account(2),2180				default_nft_data().into()2181			)2182			.map_err(|e| e.error),2183			CommonError::<Test>::PublicMintingNotAllowed2184		);2185	});2186}21872188// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-allow listed address.2189#[test]2190fn allow_list_test_12() {2191	new_test_ext().execute_with(|| {2192		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21932194		let origin1 = Origin::signed(1);2195		let origin2 = Origin::signed(2);21962197		assert_ok!(Unique::set_collection_permissions(2198			origin1.clone(),2199			collection_id,2200			CollectionPermissions {2201				mint_mode: Some(false),2202				access: Some(AccessMode::AllowList),2203				nesting: None,2204			}2205		));22062207		assert_noop!(2208			Unique::create_item(2209				origin2,2210				CollectionId(1),2211				account(2),2212				default_nft_data().into()2213			)2214			.map_err(|e| e.error),2215			CommonError::<Test>::PublicMintingNotAllowed2216		);2217	});2218}22192220// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by owner.2221#[test]2222fn allow_list_test_13() {2223	new_test_ext().execute_with(|| {2224		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22252226		let origin1 = Origin::signed(1);22272228		assert_ok!(Unique::set_collection_permissions(2229			origin1.clone(),2230			collection_id,2231			CollectionPermissions {2232				mint_mode: Some(true),2233				access: Some(AccessMode::AllowList),2234				nesting: None,2235			}2236		));22372238		let data = default_nft_data();2239		create_test_item(collection_id, &data.into());2240	});2241}22422243// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by admin.2244#[test]2245fn allow_list_test_14() {2246	new_test_ext().execute_with(|| {2247		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22482249		let origin1 = Origin::signed(1);2250		let origin2 = Origin::signed(2);22512252		assert_ok!(Unique::set_collection_permissions(2253			origin1.clone(),2254			collection_id,2255			CollectionPermissions {2256				mint_mode: Some(true),2257				access: Some(AccessMode::AllowList),2258				nesting: None,2259			}2260		));22612262		assert_ok!(Unique::add_collection_admin(2263			origin1,2264			collection_id,2265			account(2)2266		));22672268		assert_ok!(Unique::create_item(2269			origin2,2270			collection_id,2271			account(2),2272			default_nft_data().into()2273		));2274	});2275}22762277// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-allow listed address.2278#[test]2279fn allow_list_test_15() {2280	new_test_ext().execute_with(|| {2281		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22822283		let origin1 = Origin::signed(1);2284		let origin2 = Origin::signed(2);22852286		assert_ok!(Unique::set_collection_permissions(2287			origin1.clone(),2288			collection_id,2289			CollectionPermissions {2290				mint_mode: Some(true),2291				access: Some(AccessMode::AllowList),2292				nesting: None,2293			}2294		));22952296		assert_noop!(2297			Unique::create_item(2298				origin2,2299				collection_id,2300				account(2),2301				default_nft_data().into()2302			)2303			.map_err(|e| e.error),2304			CommonError::<Test>::AddressNotInAllowlist2305		);2306	});2307}23082309// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by non-privileged and allow listed address.2310#[test]2311fn allow_list_test_16() {2312	new_test_ext().execute_with(|| {2313		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23142315		let origin1 = Origin::signed(1);2316		let origin2 = Origin::signed(2);23172318		assert_ok!(Unique::set_collection_permissions(2319			origin1.clone(),2320			collection_id,2321			CollectionPermissions {2322				mint_mode: Some(true),2323				access: Some(AccessMode::AllowList),2324				nesting: None,2325			}2326		));2327		assert_ok!(Unique::add_to_allow_list(2328			origin1,2329			collection_id,2330			account(2)2331		));23322333		assert_ok!(Unique::create_item(2334			origin2,2335			collection_id,2336			account(2),2337			default_nft_data().into()2338		));2339	});2340}23412342// Total number of collections. Positive test2343#[test]2344fn total_number_collections_bound() {2345	new_test_ext().execute_with(|| {2346		create_test_collection(&CollectionMode::NFT, CollectionId(1));2347	});2348}23492350#[test]2351fn create_max_collections() {2352	new_test_ext().execute_with(|| {2353		for i in 1..COLLECTION_NUMBER_LIMIT {2354			create_test_collection(&CollectionMode::NFT, CollectionId(i));2355		}2356	});2357}23582359// Total number of collections. Negative test2360#[test]2361fn total_number_collections_bound_neg() {2362	new_test_ext().execute_with(|| {2363		let origin1 = Origin::signed(1);23642365		for i in 1..=COLLECTION_NUMBER_LIMIT {2366			create_test_collection(&CollectionMode::NFT, CollectionId(i));2367		}23682369		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();2370		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();2371		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();23722373		let data: CreateCollectionData<u64> = CreateCollectionData {2374			name: col_name1.try_into().unwrap(),2375			description: col_desc1.try_into().unwrap(),2376			token_prefix: token_prefix1.try_into().unwrap(),2377			mode: CollectionMode::NFT,2378			..Default::default()2379		};23802381		// 11-th collection in chain. Expects error2382		assert_noop!(2383			Unique::create_collection_ex(origin1, data),2384			CommonError::<Test>::TotalCollectionsLimitExceeded2385		);2386	});2387}23882389// Owned tokens by a single address. Positive test2390#[test]2391fn owned_tokens_bound() {2392	new_test_ext().execute_with(|| {2393		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23942395		let data = default_nft_data();2396		create_test_item(collection_id, &data.clone().into());2397		create_test_item(collection_id, &data.into());2398	});2399}24002401// Owned tokens by a single address. Negotive test2402#[test]2403fn owned_tokens_bound_neg() {2404	new_test_ext().execute_with(|| {2405		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24062407		let origin1 = Origin::signed(1);24082409		for _ in 1..=MAX_TOKEN_OWNERSHIP {2410			let data = default_nft_data();2411			create_test_item(collection_id, &data.clone().into());2412		}24132414		let data = default_nft_data();2415		assert_noop!(2416			Unique::create_item(origin1, CollectionId(1), account(1), data.into())2417				.map_err(|e| e.error),2418			CommonError::<Test>::AccountTokenLimitExceeded2419		);2420	});2421}24222423// Number of collection admins. Positive test2424#[test]2425fn collection_admins_bound() {2426	new_test_ext().execute_with(|| {2427		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24282429		let origin1 = Origin::signed(1);24302431		assert_ok!(Unique::add_collection_admin(2432			origin1.clone(),2433			collection_id,2434			account(2)2435		));2436		assert_ok!(Unique::add_collection_admin(2437			origin1,2438			collection_id,2439			account(3)2440		));2441	});2442}24432444// Number of collection admins. Negotive test2445#[test]2446fn collection_admins_bound_neg() {2447	new_test_ext().execute_with(|| {2448		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24492450		let origin1 = Origin::signed(1);24512452		for i in 0..COLLECTION_ADMINS_LIMIT {2453			assert_ok!(Unique::add_collection_admin(2454				origin1.clone(),2455				collection_id,2456				account((2 + i).into())2457			));2458		}2459		assert_noop!(2460			Unique::add_collection_admin(2461				origin1,2462				collection_id,2463				account((3 + COLLECTION_ADMINS_LIMIT).into())2464			),2465			CommonError::<Test>::CollectionAdminCountExceeded2466		);2467	});2468}2469// #endregion24702471#[test]2472fn collection_transfer_flag_works() {2473	new_test_ext().execute_with(|| {2474		let origin1 = Origin::signed(1);24752476		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2477		assert_ok!(Unique::set_transfers_enabled_flag(2478			origin1,2479			collection_id,2480			true2481		));24822483		let data = default_nft_data();2484		create_test_item(collection_id, &data.into());2485		assert_eq!(2486			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2487			12488		);2489		assert_eq!(2490			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2491			true2492		);24932494		let origin1 = Origin::signed(1);24952496		// default scenario2497		assert_ok!(Unique::transfer(2498			origin1,2499			account(2),2500			collection_id,2501			TokenId(1),2502			12503		));2504		assert_eq!(2505			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2506			false2507		);2508		assert_eq!(2509			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2510			true2511		);2512		assert_eq!(2513			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2514			02515		);2516		assert_eq!(2517			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2518			12519		);2520	});2521}25222523#[test]2524fn collection_transfer_flag_works_neg() {2525	new_test_ext().execute_with(|| {2526		let origin1 = Origin::signed(1);25272528		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2529		assert_ok!(Unique::set_transfers_enabled_flag(2530			origin1,2531			collection_id,2532			false2533		));25342535		let data = default_nft_data();2536		create_test_item(collection_id, &data.into());2537		assert_eq!(2538			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2539			12540		);2541		assert_eq!(2542			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2543			true2544		);25452546		let origin1 = Origin::signed(1);25472548		// default scenario2549		assert_noop!(2550			Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1)2551				.map_err(|e| e.error),2552			CommonError::<Test>::TransferNotAllowed2553		);2554		assert_eq!(2555			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2556			12557		);2558		assert_eq!(2559			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2560			02561		);2562		assert_eq!(2563			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2564			true2565		);2566		assert_eq!(2567			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2568			false2569		);2570	});2571}25722573#[test]2574fn collection_sponsoring() {2575	new_test_ext().execute_with(|| {2576		// default_limits();2577		let user1 = 1_u64;2578		let user2 = 777_u64;2579		let origin1 = Origin::signed(user1);2580		let origin2 = Origin::signed(user2);2581		let account2 = account(user2);25822583		let collection_id =2584			create_test_collection_for_owner(&CollectionMode::NFT, user1, CollectionId(1));2585		assert_ok!(Unique::set_collection_sponsor(2586			origin1.clone(),2587			collection_id,2588			user12589		));2590		assert_ok!(Unique::confirm_sponsorship(origin1.clone(), collection_id));25912592		// Expect error while have no permissions2593		assert!(Unique::create_item(2594			origin2.clone(),2595			collection_id,2596			account2.clone(),2597			default_nft_data().into()2598		)2599		.is_err());26002601		assert_ok!(Unique::set_collection_permissions(2602			origin1.clone(),2603			collection_id,2604			CollectionPermissions {2605				mint_mode: Some(true),2606				access: Some(AccessMode::AllowList),2607				nesting: None,2608			}2609		));2610		assert_ok!(Unique::add_to_allow_list(2611			origin1.clone(),2612			collection_id,2613			account2.clone()2614		));26152616		assert_ok!(Unique::create_item(2617			origin2,2618			collection_id,2619			account2,2620			default_nft_data().into()2621		));2622	});2623}
after · runtime/tests/src/tests.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Tests to be written here18use crate::{Test, TestCrossAccountId, CollectionCreationPrice, Origin, Unique, new_test_ext};19use up_data_structs::{20	COLLECTION_NUMBER_LIMIT, CollectionId, CreateItemData, CreateFungibleData, CreateNftData,21	CreateReFungibleData, MAX_DECIMAL_POINTS, COLLECTION_ADMINS_LIMIT, TokenId,22	MAX_TOKEN_OWNERSHIP, CreateCollectionData, CollectionMode, AccessMode, CollectionPermissions,23	PropertyKeyPermission, PropertyPermission, Property, CollectionPropertiesVec,24	CollectionPropertiesPermissionsVec,25};26use frame_support::{assert_noop, assert_ok, assert_err};27use sp_std::convert::TryInto;28use pallet_evm::account::CrossAccountId;29use pallet_common::Error as CommonError;30use pallet_unique::Error as UniqueError;3132fn add_balance(user: u64, value: u64) {33	const DONOR_USER: u64 = 999;34	assert_ok!(<pallet_balances::Pallet<Test>>::set_balance(35		Origin::root(),36		DONOR_USER,37		value,38		039	));40	assert_ok!(<pallet_balances::Pallet<Test>>::force_transfer(41		Origin::root(),42		DONOR_USER,43		user,44		value45	));46}4748fn default_nft_data() -> CreateNftData {49	CreateNftData {50		properties: vec![Property {51			key: b"test-prop".to_vec().try_into().unwrap(),52			value: b"test-nft-prop".to_vec().try_into().unwrap(),53		}]54		.try_into()55		.unwrap(),56	}57}5859fn default_fungible_data() -> CreateFungibleData {60	CreateFungibleData { value: 5 }61}6263fn default_re_fungible_data() -> CreateReFungibleData {64	CreateReFungibleData {65		const_data: vec![1, 2, 3].try_into().unwrap(),66		pieces: 1023,67	}68}6970fn create_test_collection_for_owner(71	mode: &CollectionMode,72	owner: u64,73	id: CollectionId,74) -> CollectionId {75	add_balance(owner, CollectionCreationPrice::get() as u64 + 1);7677	let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();78	let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();79	let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();80	let token_property_permissions: CollectionPropertiesPermissionsVec =81		vec![PropertyKeyPermission {82			key: b"test-prop".to_vec().try_into().unwrap(),83			permission: PropertyPermission {84				mutable: true,85				collection_admin: false,86				token_owner: true,87			},88		}]89		.try_into()90		.unwrap();91	let properties: CollectionPropertiesVec = vec![Property {92		key: b"test-collection-prop".to_vec().try_into().unwrap(),93		value: b"test-collection-value".to_vec().try_into().unwrap(),94	}]95	.try_into()96	.unwrap();9798	let data: CreateCollectionData<u64> = CreateCollectionData {99		name: col_name1.try_into().unwrap(),100		description: col_desc1.try_into().unwrap(),101		token_prefix: token_prefix1.try_into().unwrap(),102		mode: mode.clone(),103		token_property_permissions: token_property_permissions.clone(),104		properties: properties.clone(),105		..Default::default()106	};107108	let origin1 = Origin::signed(owner);109	assert_ok!(Unique::create_collection_ex(origin1, data));110111	let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();112	let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();113	let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();114	assert_eq!(115		<pallet_common::CollectionById<Test>>::get(id)116			.unwrap()117			.owner,118		owner119	);120	assert_eq!(121		<pallet_common::CollectionById<Test>>::get(id).unwrap().name,122		saved_col_name123	);124	assert_eq!(125		<pallet_common::CollectionById<Test>>::get(id).unwrap().mode,126		*mode127	);128	assert_eq!(129		<pallet_common::CollectionById<Test>>::get(id)130			.unwrap()131			.description,132		saved_description133	);134	assert_eq!(135		<pallet_common::CollectionById<Test>>::get(id)136			.unwrap()137			.token_prefix,138		saved_prefix139	);140	assert_eq!(141		get_collection_property_permissions(id).as_slice(),142		token_property_permissions.as_slice()143	);144	assert_eq!(145		get_collection_properties(id).as_slice(),146		properties.as_slice()147	);148	id149}150151fn get_collection_property_permissions(collection_id: CollectionId) -> Vec<PropertyKeyPermission> {152	<pallet_common::Pallet<Test>>::property_permissions(collection_id)153		.into_iter()154		.map(|(key, permission)| PropertyKeyPermission { key, permission })155		.collect()156}157158fn get_collection_properties(collection_id: CollectionId) -> Vec<Property> {159	<pallet_common::Pallet<Test>>::collection_properties(collection_id)160		.into_iter()161		.map(|(key, value)| Property { key, value })162		.collect()163}164165fn get_token_properties(collection_id: CollectionId, token_id: TokenId) -> Vec<Property> {166	<pallet_nonfungible::Pallet<Test>>::token_properties((collection_id, token_id))167		.into_iter()168		.map(|(key, value)| Property { key, value })169		.collect()170}171172fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {173	create_test_collection_for_owner(&mode, 1, id)174}175176fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {177	let origin1 = Origin::signed(1);178	assert_ok!(Unique::create_item(179		origin1,180		collection_id,181		account(1),182		data.clone()183	));184}185186fn account(sub: u64) -> TestCrossAccountId {187	TestCrossAccountId::from_sub(sub)188}189190// Use cases tests region191// #region192193#[test]194fn check_not_sufficient_founds() {195	new_test_ext().execute_with(|| {196		let acc: u64 = 1;197		<pallet_balances::Pallet<Test>>::set_balance(Origin::root(), acc, 0, 0).unwrap();198199		let name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();200		let description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();201		let token_prefix: Vec<u8> = b"token_prefix1\0".to_vec();202203		let data: CreateCollectionData<<Test as frame_system::Config>::AccountId> =204			CreateCollectionData {205				name: name.try_into().unwrap(),206				description: description.try_into().unwrap(),207				token_prefix: token_prefix.try_into().unwrap(),208				mode: CollectionMode::NFT,209				..Default::default()210			};211212		let result = Unique::create_collection_ex(Origin::signed(acc), data);213		assert_err!(result, <CommonError<Test>>::NotSufficientFounds);214	});215}216217#[test]218fn create_fungible_collection_fails_with_large_decimal_numbers() {219	new_test_ext().execute_with(|| {220		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();221		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();222		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();223224		let data: CreateCollectionData<u64> = CreateCollectionData {225			name: col_name1.try_into().unwrap(),226			description: col_desc1.try_into().unwrap(),227			token_prefix: token_prefix1.try_into().unwrap(),228			mode: CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1),229			..Default::default()230		};231232		let origin1 = Origin::signed(1);233		assert_noop!(234			Unique::create_collection_ex(origin1, data),235			UniqueError::<Test>::CollectionDecimalPointLimitExceeded236		);237	});238}239240#[test]241fn create_nft_item() {242	new_test_ext().execute_with(|| {243		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));244245		let data = default_nft_data();246		create_test_item(collection_id, &data.clone().into());247248		assert_eq!(249			get_token_properties(collection_id, TokenId(1)).as_slice(),250			data.properties.as_slice(),251		);252	});253}254255// Use cases tests region256// #region257#[test]258fn create_nft_multiple_items() {259	new_test_ext().execute_with(|| {260		create_test_collection(&CollectionMode::NFT, CollectionId(1));261262		let origin1 = Origin::signed(1);263264		let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];265266		assert_ok!(Unique::create_multiple_items(267			origin1,268			CollectionId(1),269			account(1),270			items_data271				.clone()272				.into_iter()273				.map(|d| { d.into() })274				.collect()275		));276		for (index, data) in items_data.into_iter().enumerate() {277			assert_eq!(278				get_token_properties(CollectionId(1), TokenId(index as u32 + 1)).as_slice(),279				data.properties.as_slice()280			);281		}282	});283}284285#[test]286fn create_refungible_item() {287	new_test_ext().execute_with(|| {288		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));289290		let data = default_re_fungible_data();291		create_test_item(collection_id, &data.clone().into());292		let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));293		let balance =294			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));295		assert_eq!(item.const_data, data.const_data.into_inner());296		assert_eq!(balance, 1023);297	});298}299300#[test]301fn create_multiple_refungible_items() {302	new_test_ext().execute_with(|| {303		create_test_collection(&CollectionMode::ReFungible, CollectionId(1));304305		let origin1 = Origin::signed(1);306307		let items_data = vec![308			default_re_fungible_data(),309			default_re_fungible_data(),310			default_re_fungible_data(),311		];312313		assert_ok!(Unique::create_multiple_items(314			origin1,315			CollectionId(1),316			account(1),317			items_data318				.clone()319				.into_iter()320				.map(|d| { d.into() })321				.collect()322		));323		for (index, data) in items_data.into_iter().enumerate() {324			let item = <pallet_refungible::TokenData<Test>>::get((325				CollectionId(1),326				TokenId((index + 1) as u32),327			));328			let balance =329				<pallet_refungible::Balance<Test>>::get((CollectionId(1), TokenId(1), account(1)));330			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());331			assert_eq!(balance, 1023);332		}333	});334}335336#[test]337fn create_fungible_item() {338	new_test_ext().execute_with(|| {339		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));340341		let data = default_fungible_data();342		create_test_item(collection_id, &data.into());343344		assert_eq!(345			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),346			5347		);348	});349}350351//#[test]352// fn create_multiple_fungible_items() {353//     new_test_ext().execute_with(|| {354//         default_limits();355356//         create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));357358//         let origin1 = Origin::signed(1);359360//         let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];361362//         assert_ok!(Unique::create_multiple_items(363//             origin1.clone(),364//             1,365//             1,366//             items_data.clone().into_iter().map(|d| { d.into() }).collect()367//         ));368369//         for (index, _) in items_data.iter().enumerate() {370//             assert_eq!(Unique::fungible_item_id(1, (index + 1) as TokenId).value, 5);371//         }372//         assert_eq!(Unique::balance_count(1, 1), 3000);373//         assert_eq!(Unique::address_tokens(1, 1), [1, 2, 3]);374//     });375// }376377#[test]378fn transfer_fungible_item() {379	new_test_ext().execute_with(|| {380		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));381382		let origin1 = Origin::signed(1);383		let origin2 = Origin::signed(2);384385		let data = default_fungible_data();386		create_test_item(collection_id, &data.into());387388		assert_eq!(389			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),390			5391		);392393		// change owner scenario394		assert_ok!(Unique::transfer(395			origin1,396			account(2),397			CollectionId(1),398			TokenId(0),399			5400		));401		assert_eq!(402			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),403			0404		);405406		// split item scenario407		assert_ok!(Unique::transfer(408			origin2.clone(),409			account(3),410			CollectionId(1),411			TokenId(0),412			3413		));414415		// split item and new owner has account scenario416		assert_ok!(Unique::transfer(417			origin2,418			account(3),419			CollectionId(1),420			TokenId(0),421			1422		));423		assert_eq!(424			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(2))),425			1426		);427		assert_eq!(428			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(3))),429			4430		);431	});432}433434#[test]435fn transfer_refungible_item() {436	new_test_ext().execute_with(|| {437		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));438439		// Create RFT 1 in 1023 pieces for account 1440		let data = default_re_fungible_data();441		create_test_item(collection_id, &data.clone().into());442		let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));443		assert_eq!(item.const_data, data.const_data.into_inner());444		assert_eq!(445			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),446			1447		);448		assert_eq!(449			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),450			1023451		);452		assert_eq!(453			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),454			true455		);456457		// Account 1 transfers all 1023 pieces of RFT 1 to account 2458		let origin1 = Origin::signed(1);459		let origin2 = Origin::signed(2);460		assert_ok!(Unique::transfer(461			origin1,462			account(2),463			CollectionId(1),464			TokenId(1),465			1023466		));467		assert_eq!(468			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),469			1023470		);471		assert_eq!(472			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),473			0474		);475		assert_eq!(476			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),477			1478		);479		assert_eq!(480			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),481			false482		);483		assert_eq!(484			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),485			true486		);487488		// Account 2 transfers 500 pieces of RFT 1 to account 3489		assert_ok!(Unique::transfer(490			origin2.clone(),491			account(3),492			CollectionId(1),493			TokenId(1),494			500495		));496		assert_eq!(497			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),498			523499		);500		assert_eq!(501			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),502			500503		);504		assert_eq!(505			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),506			1507		);508		assert_eq!(509			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),510			1511		);512		assert_eq!(513			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),514			true515		);516		assert_eq!(517			<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),518			true519		);520521		// Account 2 transfers 200 more pieces of RFT 1 to account 3 with pre-existing balance522		assert_ok!(Unique::transfer(523			origin2,524			account(3),525			CollectionId(1),526			TokenId(1),527			200528		));529		assert_eq!(530			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),531			323532		);533		assert_eq!(534			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),535			700536		);537		assert_eq!(538			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),539			1540		);541		assert_eq!(542			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),543			1544		);545		assert_eq!(546			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),547			true548		);549		assert_eq!(550			<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),551			true552		);553	});554}555556#[test]557fn transfer_nft_item() {558	new_test_ext().execute_with(|| {559		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));560561		let data = default_nft_data();562		create_test_item(collection_id, &data.into());563		assert_eq!(564			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),565			1566		);567		assert_eq!(568			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),569			true570		);571572		let origin1 = Origin::signed(1);573		// default scenario574		assert_ok!(Unique::transfer(575			origin1,576			account(2),577			CollectionId(1),578			TokenId(1),579			1580		));581		assert_eq!(582			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),583			0584		);585		assert_eq!(586			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),587			1588		);589		assert_eq!(590			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),591			false592		);593		assert_eq!(594			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),595			true596		);597	});598}599600#[test]601fn transfer_nft_item_wrong_value() {602	new_test_ext().execute_with(|| {603		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));604605		let data = default_nft_data();606		create_test_item(collection_id, &data.into());607		assert_eq!(608			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),609			1610		);611		assert_eq!(612			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),613			true614		);615616		let origin1 = Origin::signed(1);617618		assert_noop!(619			Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 2)620				.map_err(|e| e.error),621			<pallet_nonfungible::Error::<Test>>::NonfungibleItemsHaveNoAmount622		);623	});624}625626#[test]627fn transfer_nft_item_zero_value() {628	new_test_ext().execute_with(|| {629		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));630631		let data = default_nft_data();632		create_test_item(collection_id, &data.into());633		assert_eq!(634			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),635			1636		);637		assert_eq!(638			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),639			true640		);641642		let origin1 = Origin::signed(1);643644		// Transferring 0 amount works on NFT...645		assert_ok!(Unique::transfer(646			origin1,647			account(2),648			CollectionId(1),649			TokenId(1),650			0651		));652		// ... and results in no transfer653		assert_eq!(654			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),655			1656		);657		assert_eq!(658			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),659			true660		);661	});662}663664#[test]665fn nft_approve_and_transfer_from() {666	new_test_ext().execute_with(|| {667		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));668669		let data = default_nft_data();670		create_test_item(collection_id, &data.into());671672		let origin1 = Origin::signed(1);673		let origin2 = Origin::signed(2);674675		assert_eq!(676			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),677			1678		);679		assert_eq!(680			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),681			true682		);683684		// neg transfer_from685		assert_noop!(686			Unique::transfer_from(687				origin2.clone(),688				account(1),689				account(2),690				CollectionId(1),691				TokenId(1),692				1693			)694			.map_err(|e| e.error),695			CommonError::<Test>::ApprovedValueTooLow696		);697698		// do approve699		assert_ok!(Unique::approve(700			origin1,701			account(2),702			CollectionId(1),703			TokenId(1),704			1705		));706		assert_eq!(707			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),708			account(2)709		);710711		assert_ok!(Unique::transfer_from(712			origin2,713			account(1),714			account(3),715			CollectionId(1),716			TokenId(1),717			1718		));719		assert!(720			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()721		);722	});723}724725#[test]726fn nft_approve_and_transfer_from_allow_list() {727	new_test_ext().execute_with(|| {728		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));729730		let origin1 = Origin::signed(1);731		let origin2 = Origin::signed(2);732733		// Create NFT 1 for account 1734		let data = default_nft_data();735		create_test_item(collection_id, &data.clone().into());736		assert_eq!(737			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),738			1739		);740		assert_eq!(741			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),742			true743		);744745		// Allow allow-list users to mint and add accounts 1, 2, and 3 to allow-list746		assert_ok!(Unique::set_collection_permissions(747			origin1.clone(),748			CollectionId(1),749			CollectionPermissions {750				mint_mode: Some(true),751				access: Some(AccessMode::AllowList),752				nesting: None,753			}754		));755		assert_ok!(Unique::add_to_allow_list(756			origin1.clone(),757			CollectionId(1),758			account(1)759		));760		assert_ok!(Unique::add_to_allow_list(761			origin1.clone(),762			CollectionId(1),763			account(2)764		));765		assert_ok!(Unique::add_to_allow_list(766			origin1.clone(),767			CollectionId(1),768			account(3)769		));770771		// Account 1 approves account 2 for NFT 1772		assert_ok!(Unique::approve(773			origin1.clone(),774			account(2),775			CollectionId(1),776			TokenId(1),777			1778		));779		assert_eq!(780			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),781			account(2)782		);783784		// Account 2 transfers NFT 1 from account 1 to account 3785		assert_ok!(Unique::transfer_from(786			origin2,787			account(1),788			account(3),789			CollectionId(1),790			TokenId(1),791			1792		));793		assert!(794			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()795		);796	});797}798799#[test]800fn refungible_approve_and_transfer_from() {801	new_test_ext().execute_with(|| {802		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));803804		let origin1 = Origin::signed(1);805		let origin2 = Origin::signed(2);806807		// Create RFT 1 in 1023 pieces for account 1808		let data = default_re_fungible_data();809		create_test_item(collection_id, &data.into());810811		assert_eq!(812			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),813			1814		);815		assert_eq!(816			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),817			1023818		);819		assert_eq!(820			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),821			true822		);823824		// Allow public minting, enable allow-list and add accounts 1, 2, 3 to allow-list825		assert_ok!(Unique::set_collection_permissions(826			origin1.clone(),827			CollectionId(1),828			CollectionPermissions {829				mint_mode: Some(true),830				access: Some(AccessMode::AllowList),831				nesting: None,832			}833		));834		assert_ok!(Unique::add_to_allow_list(835			origin1.clone(),836			CollectionId(1),837			account(1)838		));839		assert_ok!(Unique::add_to_allow_list(840			origin1.clone(),841			CollectionId(1),842			account(2)843		));844		assert_ok!(Unique::add_to_allow_list(845			origin1.clone(),846			CollectionId(1),847			account(3)848		));849850		// Account 1 approves account 2 for 1023 pieces of RFT 1851		assert_ok!(Unique::approve(852			origin1,853			account(2),854			CollectionId(1),855			TokenId(1),856			1023857		));858		assert_eq!(859			<pallet_refungible::Allowance<Test>>::get((860				CollectionId(1),861				TokenId(1),862				account(1),863				account(2)864			)),865			1023866		);867868		// Account 2 transfers 100 pieces of RFT 1 from account 1 to account 3869		assert_ok!(Unique::transfer_from(870			origin2,871			account(1),872			account(3),873			CollectionId(1),874			TokenId(1),875			100876		));877		assert_eq!(878			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),879			1880		);881		assert_eq!(882			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),883			1884		);885		assert_eq!(886			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),887			923888		);889		assert_eq!(890			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),891			100892		);893		assert_eq!(894			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),895			true896		);897		assert_eq!(898			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),899			true900		);901		assert_eq!(902			<pallet_refungible::Allowance<Test>>::get((903				CollectionId(1),904				TokenId(1),905				account(1),906				account(2)907			)),908			923909		);910	});911}912913#[test]914fn fungible_approve_and_transfer_from() {915	new_test_ext().execute_with(|| {916		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));917918		let data = default_fungible_data();919		create_test_item(collection_id, &data.into());920921		let origin1 = Origin::signed(1);922		let origin2 = Origin::signed(2);923924		assert_ok!(Unique::set_collection_permissions(925			origin1.clone(),926			CollectionId(1),927			CollectionPermissions {928				mint_mode: Some(true),929				access: Some(AccessMode::AllowList),930				nesting: None,931			}932		));933		assert_ok!(Unique::add_to_allow_list(934			origin1.clone(),935			CollectionId(1),936			account(1)937		));938		assert_ok!(Unique::add_to_allow_list(939			origin1.clone(),940			CollectionId(1),941			account(2)942		));943		assert_ok!(Unique::add_to_allow_list(944			origin1.clone(),945			CollectionId(1),946			account(3)947		));948949		// do approve950		assert_ok!(Unique::approve(951			origin1.clone(),952			account(2),953			CollectionId(1),954			TokenId(0),955			5956		));957		assert_eq!(958			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),959			5960		);961		assert_ok!(Unique::approve(962			origin1,963			account(3),964			CollectionId(1),965			TokenId(0),966			5967		));968		assert_eq!(969			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),970			5971		);972		assert_eq!(973			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(3))),974			5975		);976977		assert_ok!(Unique::transfer_from(978			origin2.clone(),979			account(1),980			account(3),981			CollectionId(1),982			TokenId(0),983			4984		));985986		assert_eq!(987			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),988			1989		);990991		assert_noop!(992			Unique::transfer_from(993				origin2,994				account(1),995				account(3),996				CollectionId(1),997				TokenId(0),998				4999			)1000			.map_err(|e| e.error),1001			CommonError::<Test>::ApprovedValueTooLow1002		);1003	});1004}10051006#[test]1007fn change_collection_owner() {1008	new_test_ext().execute_with(|| {1009		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10101011		let origin1 = Origin::signed(1);1012		assert_ok!(Unique::change_collection_owner(origin1, collection_id, 2));1013		assert_eq!(1014			<pallet_common::CollectionById<Test>>::get(collection_id)1015				.unwrap()1016				.owner,1017			21018		);1019	});1020}10211022#[test]1023fn destroy_collection() {1024	new_test_ext().execute_with(|| {1025		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10261027		let origin1 = Origin::signed(1);1028		assert_ok!(Unique::destroy_collection(origin1, collection_id));1029	});1030}10311032#[test]1033fn burn_nft_item() {1034	new_test_ext().execute_with(|| {1035		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10361037		let origin1 = Origin::signed(1);10381039		let data = default_nft_data();1040		create_test_item(collection_id, &data.into());10411042		// check balance (collection with id = 1, user id = 1)1043		assert_eq!(1044			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1045			11046		);10471048		// burn item1049		assert_ok!(Unique::burn_item(1050			origin1.clone(),1051			collection_id,1052			TokenId(1),1053			11054		));1055		assert_eq!(1056			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1057			01058		);1059	});1060}10611062#[test]1063fn burn_same_nft_item_twice() {1064	new_test_ext().execute_with(|| {1065		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10661067		let origin1 = Origin::signed(1);10681069		let data = default_nft_data();1070		create_test_item(collection_id, &data.into());10711072		// check balance (collection with id = 1, user id = 1)1073		assert_eq!(1074			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1075			11076		);10771078		// burn item1079		assert_ok!(Unique::burn_item(1080			origin1.clone(),1081			collection_id,1082			TokenId(1),1083			11084		));10851086		// burn item again1087		assert_noop!(1088			Unique::burn_item(origin1, collection_id, TokenId(1), 1).map_err(|e| e.error),1089			CommonError::<Test>::TokenNotFound1090		);10911092		assert_eq!(1093			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1094			01095		);1096	});1097}10981099#[test]1100fn burn_fungible_item() {1101	new_test_ext().execute_with(|| {1102		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11031104		let origin1 = Origin::signed(1);1105		assert_ok!(Unique::add_collection_admin(1106			origin1.clone(),1107			collection_id,1108			account(2)1109		));11101111		let data = default_fungible_data();1112		create_test_item(collection_id, &data.into());11131114		// check balance (collection with id = 1, user id = 1)1115		assert_eq!(1116			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1117			51118		);11191120		// burn item1121		assert_ok!(Unique::burn_item(1122			origin1.clone(),1123			CollectionId(1),1124			TokenId(0),1125			51126		));1127		assert_noop!(1128			Unique::burn_item(origin1, CollectionId(1), TokenId(0), 5).map_err(|e| e.error),1129			CommonError::<Test>::TokenValueTooLow1130		);11311132		assert_eq!(1133			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1134			01135		);1136	});1137}11381139#[test]1140fn burn_fungible_item_with_token_id() {1141	new_test_ext().execute_with(|| {1142		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11431144		let origin1 = Origin::signed(1);1145		assert_ok!(Unique::add_collection_admin(1146			origin1.clone(),1147			collection_id,1148			account(2)1149		));11501151		let data = default_fungible_data();1152		create_test_item(collection_id, &data.into());11531154		// check balance (collection with id = 1, user id = 1)1155		assert_eq!(1156			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1157			51158		);11591160		// Try to burn item using Token ID1161		assert_noop!(1162			Unique::burn_item(origin1, CollectionId(1), TokenId(1), 5).map_err(|e| e.error),1163			<pallet_fungible::Error::<Test>>::FungibleItemsHaveNoId1164		);1165	});1166}1167#[test]1168fn burn_refungible_item() {1169	new_test_ext().execute_with(|| {1170		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));1171		let origin1 = Origin::signed(1);11721173		assert_ok!(Unique::set_collection_permissions(1174			origin1.clone(),1175			collection_id,1176			CollectionPermissions {1177				mint_mode: Some(true),1178				access: Some(AccessMode::AllowList),1179				nesting: None,1180			}1181		));1182		assert_ok!(Unique::add_to_allow_list(1183			origin1.clone(),1184			collection_id,1185			account(1)1186		));11871188		assert_ok!(Unique::add_collection_admin(1189			origin1.clone(),1190			collection_id,1191			account(2)1192		));11931194		let data = default_re_fungible_data();1195		create_test_item(collection_id, &data.into());11961197		// check balance (collection with id = 1, user id = 2)1198		assert_eq!(1199			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),1200			11201		);1202		assert_eq!(1203			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1204			10231205		);12061207		// burn item1208		assert_ok!(Unique::burn_item(1209			origin1.clone(),1210			collection_id,1211			TokenId(1),1212			10231213		));1214		assert_noop!(1215			Unique::burn_item(origin1, collection_id, TokenId(1), 1023).map_err(|e| e.error),1216			CommonError::<Test>::TokenValueTooLow1217		);12181219		assert_eq!(1220			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1221			01222		);1223	});1224}12251226#[test]1227fn add_collection_admin() {1228	new_test_ext().execute_with(|| {1229		let collection1_id =1230			create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1231		let origin1 = Origin::signed(1);12321233		// Add collection admins1234		assert_ok!(Unique::add_collection_admin(1235			origin1.clone(),1236			collection1_id,1237			account(2)1238		));1239		assert_ok!(Unique::add_collection_admin(1240			origin1,1241			collection1_id,1242			account(3)1243		));12441245		// Owner is not an admin by default1246		assert_eq!(1247			<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(1))),1248			false1249		);1250		assert!(<pallet_common::IsAdmin<Test>>::get((1251			CollectionId(1),1252			account(2)1253		)));1254		assert!(<pallet_common::IsAdmin<Test>>::get((1255			CollectionId(1),1256			account(3)1257		)));1258	});1259}12601261#[test]1262fn remove_collection_admin() {1263	new_test_ext().execute_with(|| {1264		let collection1_id =1265			create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1266		let origin1 = Origin::signed(1);1267		let origin2 = Origin::signed(2);12681269		// Add collection admins 2 and 31270		assert_ok!(Unique::add_collection_admin(1271			origin1.clone(),1272			collection1_id,1273			account(2)1274		));1275		assert_ok!(Unique::add_collection_admin(1276			origin1,1277			collection1_id,1278			account(3)1279		));12801281		assert!(<pallet_common::IsAdmin<Test>>::get((1282			CollectionId(1),1283			account(2)1284		)));1285		assert!(<pallet_common::IsAdmin<Test>>::get((1286			CollectionId(1),1287			account(3)1288		)));12891290		// remove admin 31291		assert_ok!(Unique::remove_collection_admin(1292			origin2,1293			CollectionId(1),1294			account(3)1295		));12961297		// 2 is still admin, 3 is not an admin anymore1298		assert!(<pallet_common::IsAdmin<Test>>::get((1299			CollectionId(1),1300			account(2)1301		)));1302		assert_eq!(1303			<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))),1304			false1305		);1306	});1307}13081309#[test]1310fn balance_of() {1311	new_test_ext().execute_with(|| {1312		let nft_collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1313		let fungible_collection_id =1314			create_test_collection(&CollectionMode::Fungible(3), CollectionId(2));1315		let re_fungible_collection_id =1316			create_test_collection(&CollectionMode::ReFungible, CollectionId(3));13171318		// check balance before1319		assert_eq!(1320			<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1321			01322		);1323		assert_eq!(1324			<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1325			01326		);1327		assert_eq!(1328			<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1329			01330		);13311332		let nft_data = default_nft_data();1333		create_test_item(nft_collection_id, &nft_data.into());13341335		let fungible_data = default_fungible_data();1336		create_test_item(fungible_collection_id, &fungible_data.into());13371338		let re_fungible_data = default_re_fungible_data();1339		create_test_item(re_fungible_collection_id, &re_fungible_data.into());13401341		// check balance (collection with id = 1, user id = 1)1342		assert_eq!(1343			<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1344			11345		);1346		assert_eq!(1347			<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1348			51349		);1350		assert_eq!(1351			<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1352			11353		);13541355		assert_eq!(1356			<pallet_nonfungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))),1357			true1358		);1359		assert_eq!(1360			<pallet_refungible::Owned<Test>>::get((1361				re_fungible_collection_id,1362				account(1),1363				TokenId(1)1364			)),1365			true1366		);1367	});1368}13691370#[test]1371fn approve() {1372	new_test_ext().execute_with(|| {1373		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));13741375		let data = default_nft_data();1376		create_test_item(collection_id, &data.into());13771378		let origin1 = Origin::signed(1);13791380		// approve1381		assert_ok!(Unique::approve(1382			origin1,1383			account(2),1384			CollectionId(1),1385			TokenId(1),1386			11387		));1388		assert_eq!(1389			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1390			account(2)1391		);1392	});1393}13941395#[test]1396fn transfer_from() {1397	new_test_ext().execute_with(|| {1398		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1399		let origin1 = Origin::signed(1);1400		let origin2 = Origin::signed(2);14011402		let data = default_nft_data();1403		create_test_item(collection_id, &data.into());14041405		// approve1406		assert_ok!(Unique::approve(1407			origin1.clone(),1408			account(2),1409			CollectionId(1),1410			TokenId(1),1411			11412		));1413		assert_eq!(1414			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1415			account(2)1416		);14171418		assert_ok!(Unique::set_collection_permissions(1419			origin1.clone(),1420			CollectionId(1),1421			CollectionPermissions {1422				mint_mode: Some(true),1423				access: Some(AccessMode::AllowList),1424				nesting: None,1425			}1426		));1427		assert_ok!(Unique::add_to_allow_list(1428			origin1.clone(),1429			CollectionId(1),1430			account(1)1431		));1432		assert_ok!(Unique::add_to_allow_list(1433			origin1.clone(),1434			CollectionId(1),1435			account(2)1436		));1437		assert_ok!(Unique::add_to_allow_list(1438			origin1,1439			CollectionId(1),1440			account(3)1441		));14421443		assert_ok!(Unique::transfer_from(1444			origin2,1445			account(1),1446			account(2),1447			CollectionId(1),1448			TokenId(1),1449			11450		));14511452		// after transfer1453		assert_eq!(1454			<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(1))),1455			01456		);1457		assert_eq!(1458			<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(2))),1459			11460		);1461	});1462}14631464// #endregion14651466// Coverage tests region1467// #region14681469#[test]1470fn owner_can_add_address_to_allow_list() {1471	new_test_ext().execute_with(|| {1472		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));14731474		let origin1 = Origin::signed(1);1475		assert_ok!(Unique::add_to_allow_list(1476			origin1,1477			collection_id,1478			account(2)1479		));1480		assert!(<pallet_common::Allowlist<Test>>::get((1481			collection_id,1482			account(2)1483		)));1484	});1485}14861487#[test]1488fn admin_can_add_address_to_allow_list() {1489	new_test_ext().execute_with(|| {1490		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1491		let origin1 = Origin::signed(1);1492		let origin2 = Origin::signed(2);14931494		assert_ok!(Unique::add_collection_admin(1495			origin1,1496			collection_id,1497			account(2)1498		));1499		assert_ok!(Unique::add_to_allow_list(1500			origin2,1501			collection_id,1502			account(3)1503		));1504		assert!(<pallet_common::Allowlist<Test>>::get((1505			collection_id,1506			account(3)1507		)));1508	});1509}15101511#[test]1512fn nonprivileged_user_cannot_add_address_to_allow_list() {1513	new_test_ext().execute_with(|| {1514		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15151516		let origin2 = Origin::signed(2);1517		assert_noop!(1518			Unique::add_to_allow_list(origin2, collection_id, account(3)),1519			CommonError::<Test>::NoPermission1520		);1521	});1522}15231524#[test]1525fn nobody_can_add_address_to_allow_list_of_nonexisting_collection() {1526	new_test_ext().execute_with(|| {1527		let origin1 = Origin::signed(1);15281529		assert_noop!(1530			Unique::add_to_allow_list(origin1, CollectionId(1), account(2)),1531			CommonError::<Test>::CollectionNotFound1532		);1533	});1534}15351536#[test]1537fn nobody_can_add_address_to_allow_list_of_deleted_collection() {1538	new_test_ext().execute_with(|| {1539		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15401541		let origin1 = Origin::signed(1);1542		assert_ok!(Unique::destroy_collection(origin1.clone(), collection_id));1543		assert_noop!(1544			Unique::add_to_allow_list(origin1, collection_id, account(2)),1545			CommonError::<Test>::CollectionNotFound1546		);1547	});1548}15491550// If address is already added to allow list, nothing happens1551#[test]1552fn address_is_already_added_to_allow_list() {1553	new_test_ext().execute_with(|| {1554		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1555		let origin1 = Origin::signed(1);15561557		assert_ok!(Unique::add_to_allow_list(1558			origin1.clone(),1559			collection_id,1560			account(2)1561		));1562		assert_ok!(Unique::add_to_allow_list(1563			origin1,1564			collection_id,1565			account(2)1566		));1567		assert!(<pallet_common::Allowlist<Test>>::get((1568			collection_id,1569			account(2)1570		)));1571	});1572}15731574#[test]1575fn owner_can_remove_address_from_allow_list() {1576	new_test_ext().execute_with(|| {1577		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15781579		let origin1 = Origin::signed(1);1580		assert_ok!(Unique::add_to_allow_list(1581			origin1.clone(),1582			collection_id,1583			account(2)1584		));1585		assert_ok!(Unique::remove_from_allow_list(1586			origin1,1587			collection_id,1588			account(2)1589		));1590		assert_eq!(1591			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1592			false1593		);1594	});1595}15961597#[test]1598fn admin_can_remove_address_from_allow_list() {1599	new_test_ext().execute_with(|| {1600		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1601		let origin1 = Origin::signed(1);1602		let origin2 = Origin::signed(2);16031604		// Owner adds admin1605		assert_ok!(Unique::add_collection_admin(1606			origin1.clone(),1607			collection_id,1608			account(2)1609		));16101611		// Owner adds address 3 to allow list1612		assert_ok!(Unique::add_to_allow_list(1613			origin1,1614			collection_id,1615			account(3)1616		));16171618		// Admin removes address 3 from allow list1619		assert_ok!(Unique::remove_from_allow_list(1620			origin2,1621			collection_id,1622			account(3)1623		));1624		assert_eq!(1625			<pallet_common::Allowlist<Test>>::get((collection_id, account(3))),1626			false1627		);1628	});1629}16301631#[test]1632fn nonprivileged_user_cannot_remove_address_from_allow_list() {1633	new_test_ext().execute_with(|| {1634		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1635		let origin1 = Origin::signed(1);1636		let origin2 = Origin::signed(2);16371638		assert_ok!(Unique::add_to_allow_list(1639			origin1,1640			collection_id,1641			account(2)1642		));1643		assert_noop!(1644			Unique::remove_from_allow_list(origin2, collection_id, account(2)),1645			CommonError::<Test>::NoPermission1646		);1647		assert!(<pallet_common::Allowlist<Test>>::get((1648			collection_id,1649			account(2)1650		)));1651	});1652}16531654#[test]1655fn nobody_can_remove_address_from_allow_list_of_nonexisting_collection() {1656	new_test_ext().execute_with(|| {1657		let origin1 = Origin::signed(1);16581659		assert_noop!(1660			Unique::remove_from_allow_list(origin1, CollectionId(1), account(2)),1661			CommonError::<Test>::CollectionNotFound1662		);1663	});1664}16651666#[test]1667fn nobody_can_remove_address_from_allow_list_of_deleted_collection() {1668	new_test_ext().execute_with(|| {1669		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1670		let origin1 = Origin::signed(1);1671		let origin2 = Origin::signed(2);16721673		// Add account 2 to allow list1674		assert_ok!(Unique::add_to_allow_list(1675			origin1.clone(),1676			collection_id,1677			account(2)1678		));16791680		// Account 2 is in collection allow-list1681		assert!(<pallet_common::Allowlist<Test>>::get((1682			collection_id,1683			account(2)1684		)));16851686		// Destroy collection1687		assert_ok!(Unique::destroy_collection(origin1, collection_id));16881689		// Attempt to remove account 2 from collection allow-list => error1690		assert_noop!(1691			Unique::remove_from_allow_list(origin2, collection_id, account(2)),1692			CommonError::<Test>::CollectionNotFound1693		);16941695		// Account 2 is not found in collection allow-list anyway1696		assert_eq!(1697			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1698			false1699		);1700	});1701}17021703// If address is already removed from allow list, nothing happens1704#[test]1705fn address_is_already_removed_from_allow_list() {1706	new_test_ext().execute_with(|| {1707		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1708		let origin1 = Origin::signed(1);17091710		assert_ok!(Unique::add_to_allow_list(1711			origin1.clone(),1712			collection_id,1713			account(2)1714		));1715		assert_ok!(Unique::remove_from_allow_list(1716			origin1.clone(),1717			collection_id,1718			account(2)1719		));1720		assert_eq!(1721			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1722			false1723		);1724		assert_ok!(Unique::remove_from_allow_list(1725			origin1,1726			collection_id,1727			account(2)1728		));1729		assert_eq!(1730			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1731			false1732		);1733	});1734}17351736// If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom (2 tests)1737#[test]1738fn allow_list_test_1() {1739	new_test_ext().execute_with(|| {1740		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));17411742		let origin1 = Origin::signed(1);17431744		let data = default_nft_data();1745		create_test_item(collection_id, &data.into());17461747		assert_ok!(Unique::set_collection_permissions(1748			origin1.clone(),1749			collection_id,1750			CollectionPermissions {1751				mint_mode: None,1752				access: Some(AccessMode::AllowList),1753				nesting: None,1754			}1755		));1756		assert_ok!(Unique::add_to_allow_list(1757			origin1.clone(),1758			collection_id,1759			account(2)1760		));17611762		assert_noop!(1763			Unique::transfer(origin1, account(3), CollectionId(1), TokenId(1), 1)1764				.map_err(|e| e.error),1765			CommonError::<Test>::AddressNotInAllowlist1766		);1767	});1768}17691770#[test]1771fn allow_list_test_2() {1772	new_test_ext().execute_with(|| {1773		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1774		let origin1 = Origin::signed(1);17751776		let data = default_nft_data();1777		create_test_item(collection_id, &data.into());17781779		assert_ok!(Unique::set_collection_permissions(1780			origin1.clone(),1781			collection_id,1782			CollectionPermissions {1783				mint_mode: None,1784				access: Some(AccessMode::AllowList),1785				nesting: None,1786			}1787		));1788		assert_ok!(Unique::add_to_allow_list(1789			origin1.clone(),1790			collection_id,1791			account(1)1792		));1793		assert_ok!(Unique::add_to_allow_list(1794			origin1.clone(),1795			collection_id,1796			account(2)1797		));17981799		// do approve1800		assert_ok!(Unique::approve(1801			origin1.clone(),1802			account(1),1803			collection_id,1804			TokenId(1),1805			11806		));1807		assert_eq!(1808			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1809			account(1)1810		);18111812		assert_ok!(Unique::remove_from_allow_list(1813			origin1.clone(),1814			collection_id,1815			account(1)1816		));18171818		assert_noop!(1819			Unique::transfer_from(1820				origin1,1821				account(1),1822				account(3),1823				CollectionId(1),1824				TokenId(1),1825				11826			)1827			.map_err(|e| e.error),1828			CommonError::<Test>::AddressNotInAllowlist1829		);1830	});1831}18321833// If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom (2 tests)1834#[test]1835fn allow_list_test_3() {1836	new_test_ext().execute_with(|| {1837		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18381839		let origin1 = Origin::signed(1);18401841		let data = default_nft_data();1842		create_test_item(collection_id, &data.into());18431844		assert_ok!(Unique::set_collection_permissions(1845			origin1.clone(),1846			collection_id,1847			CollectionPermissions {1848				mint_mode: None,1849				access: Some(AccessMode::AllowList),1850				nesting: None,1851			}1852		));1853		assert_ok!(Unique::add_to_allow_list(1854			origin1.clone(),1855			collection_id,1856			account(1)1857		));18581859		assert_noop!(1860			Unique::transfer(origin1, account(3), collection_id, TokenId(1), 1)1861				.map_err(|e| e.error),1862			CommonError::<Test>::AddressNotInAllowlist1863		);1864	});1865}18661867#[test]1868fn allow_list_test_4() {1869	new_test_ext().execute_with(|| {1870		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18711872		let origin1 = Origin::signed(1);18731874		let data = default_nft_data();1875		create_test_item(collection_id, &data.into());18761877		assert_ok!(Unique::set_collection_permissions(1878			origin1.clone(),1879			collection_id,1880			CollectionPermissions {1881				mint_mode: None,1882				access: Some(AccessMode::AllowList),1883				nesting: None,1884			}1885		));1886		assert_ok!(Unique::add_to_allow_list(1887			origin1.clone(),1888			collection_id,1889			account(1)1890		));1891		assert_ok!(Unique::add_to_allow_list(1892			origin1.clone(),1893			collection_id,1894			account(2)1895		));18961897		// do approve1898		assert_ok!(Unique::approve(1899			origin1.clone(),1900			account(1),1901			collection_id,1902			TokenId(1),1903			11904		));1905		assert_eq!(1906			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1907			account(1)1908		);19091910		assert_ok!(Unique::remove_from_allow_list(1911			origin1.clone(),1912			collection_id,1913			account(2)1914		));19151916		assert_noop!(1917			Unique::transfer_from(1918				origin1,1919				account(1),1920				account(3),1921				collection_id,1922				TokenId(1),1923				11924			)1925			.map_err(|e| e.error),1926			CommonError::<Test>::AddressNotInAllowlist1927		);1928	});1929}19301931// If Public Access mode is set to AllowList, tokens can’t be destroyed by a non-allowlisted address (even if it owned them before enabling AllowList mode)1932#[test]1933fn allow_list_test_5() {1934	new_test_ext().execute_with(|| {1935		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19361937		let origin1 = Origin::signed(1);19381939		let data = default_nft_data();1940		create_test_item(collection_id, &data.into());19411942		assert_ok!(Unique::set_collection_permissions(1943			origin1.clone(),1944			collection_id,1945			CollectionPermissions {1946				mint_mode: None,1947				access: Some(AccessMode::AllowList),1948				nesting: None,1949			}1950		));1951		assert_noop!(1952			Unique::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 1).map_err(|e| e.error),1953			CommonError::<Test>::AddressNotInAllowlist1954		);1955	});1956}19571958// If Public Access mode is set to AllowList, token transfers can’t be Approved by a non-allowlisted address (see Approve method).1959#[test]1960fn allow_list_test_6() {1961	new_test_ext().execute_with(|| {1962		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19631964		let origin1 = Origin::signed(1);19651966		let data = default_nft_data();1967		create_test_item(collection_id, &data.into());19681969		assert_ok!(Unique::set_collection_permissions(1970			origin1.clone(),1971			collection_id,1972			CollectionPermissions {1973				mint_mode: None,1974				access: Some(AccessMode::AllowList),1975				nesting: None,1976			}1977		));19781979		// do approve1980		assert_noop!(1981			Unique::approve(origin1, account(1), CollectionId(1), TokenId(1), 1)1982				.map_err(|e| e.error),1983			CommonError::<Test>::AddressNotInAllowlist1984		);1985	});1986}19871988// If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests) and1989//          tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests)1990#[test]1991fn allow_list_test_7() {1992	new_test_ext().execute_with(|| {1993		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19941995		let data = default_nft_data();1996		create_test_item(collection_id, &data.into());19971998		let origin1 = Origin::signed(1);19992000		assert_ok!(Unique::set_collection_permissions(2001			origin1.clone(),2002			collection_id,2003			CollectionPermissions {2004				mint_mode: None,2005				access: Some(AccessMode::AllowList),2006				nesting: None,2007			}2008		));2009		assert_ok!(Unique::add_to_allow_list(2010			origin1.clone(),2011			collection_id,2012			account(1)2013		));2014		assert_ok!(Unique::add_to_allow_list(2015			origin1.clone(),2016			collection_id,2017			account(2)2018		));20192020		assert_ok!(Unique::transfer(2021			origin1,2022			account(2),2023			CollectionId(1),2024			TokenId(1),2025			12026		));2027	});2028}20292030#[test]2031fn allow_list_test_8() {2032	new_test_ext().execute_with(|| {2033		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));20342035		// Create NFT for account 12036		let data = default_nft_data();2037		create_test_item(collection_id, &data.into());20382039		let origin1 = Origin::signed(1);20402041		// Toggle Allow List mode and add accounts 1 and 22042		assert_ok!(Unique::set_collection_permissions(2043			origin1.clone(),2044			collection_id,2045			CollectionPermissions {2046				mint_mode: None,2047				access: Some(AccessMode::AllowList),2048				nesting: None,2049			}2050		));2051		assert_ok!(Unique::add_to_allow_list(2052			origin1.clone(),2053			collection_id,2054			account(1)2055		));2056		assert_ok!(Unique::add_to_allow_list(2057			origin1.clone(),2058			collection_id,2059			account(2)2060		));20612062		// Sself-approve account 1 for NFT 12063		assert_ok!(Unique::approve(2064			origin1.clone(),2065			account(1),2066			CollectionId(1),2067			TokenId(1),2068			12069		));2070		assert_eq!(2071			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),2072			account(1)2073		);20742075		// Transfer from 1 to 22076		assert_ok!(Unique::transfer_from(2077			origin1,2078			account(1),2079			account(2),2080			CollectionId(1),2081			TokenId(1),2082			12083		));2084	});2085}20862087// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by owner.2088#[test]2089fn allow_list_test_9() {2090	new_test_ext().execute_with(|| {2091		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2092		let origin1 = Origin::signed(1);20932094		assert_ok!(Unique::set_collection_permissions(2095			origin1.clone(),2096			collection_id,2097			CollectionPermissions {2098				mint_mode: Some(false),2099				access: Some(AccessMode::AllowList),2100				nesting: None,2101			}2102		));21032104		let data = default_nft_data();2105		create_test_item(collection_id, &data.into());2106	});2107}21082109// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by admin.2110#[test]2111fn allow_list_test_10() {2112	new_test_ext().execute_with(|| {2113		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21142115		let origin1 = Origin::signed(1);2116		let origin2 = Origin::signed(2);21172118		assert_ok!(Unique::set_collection_permissions(2119			origin1.clone(),2120			collection_id,2121			CollectionPermissions {2122				mint_mode: Some(false),2123				access: Some(AccessMode::AllowList),2124				nesting: None,2125			}2126		));21272128		assert_ok!(Unique::add_collection_admin(2129			origin1,2130			collection_id,2131			account(2)2132		));21332134		assert_ok!(Unique::create_item(2135			origin2,2136			collection_id,2137			account(2),2138			default_nft_data().into()2139		));2140	});2141}21422143// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and allow listed address.2144#[test]2145fn allow_list_test_11() {2146	new_test_ext().execute_with(|| {2147		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21482149		let origin1 = Origin::signed(1);2150		let origin2 = Origin::signed(2);21512152		assert_ok!(Unique::set_collection_permissions(2153			origin1.clone(),2154			collection_id,2155			CollectionPermissions {2156				mint_mode: Some(false),2157				access: Some(AccessMode::AllowList),2158				nesting: None,2159			}2160		));2161		assert_ok!(Unique::add_to_allow_list(2162			origin1,2163			collection_id,2164			account(2)2165		));21662167		assert_noop!(2168			Unique::create_item(2169				origin2,2170				CollectionId(1),2171				account(2),2172				default_nft_data().into()2173			)2174			.map_err(|e| e.error),2175			CommonError::<Test>::PublicMintingNotAllowed2176		);2177	});2178}21792180// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-allow listed address.2181#[test]2182fn allow_list_test_12() {2183	new_test_ext().execute_with(|| {2184		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21852186		let origin1 = Origin::signed(1);2187		let origin2 = Origin::signed(2);21882189		assert_ok!(Unique::set_collection_permissions(2190			origin1.clone(),2191			collection_id,2192			CollectionPermissions {2193				mint_mode: Some(false),2194				access: Some(AccessMode::AllowList),2195				nesting: None,2196			}2197		));21982199		assert_noop!(2200			Unique::create_item(2201				origin2,2202				CollectionId(1),2203				account(2),2204				default_nft_data().into()2205			)2206			.map_err(|e| e.error),2207			CommonError::<Test>::PublicMintingNotAllowed2208		);2209	});2210}22112212// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by owner.2213#[test]2214fn allow_list_test_13() {2215	new_test_ext().execute_with(|| {2216		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22172218		let origin1 = Origin::signed(1);22192220		assert_ok!(Unique::set_collection_permissions(2221			origin1.clone(),2222			collection_id,2223			CollectionPermissions {2224				mint_mode: Some(true),2225				access: Some(AccessMode::AllowList),2226				nesting: None,2227			}2228		));22292230		let data = default_nft_data();2231		create_test_item(collection_id, &data.into());2232	});2233}22342235// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by admin.2236#[test]2237fn allow_list_test_14() {2238	new_test_ext().execute_with(|| {2239		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22402241		let origin1 = Origin::signed(1);2242		let origin2 = Origin::signed(2);22432244		assert_ok!(Unique::set_collection_permissions(2245			origin1.clone(),2246			collection_id,2247			CollectionPermissions {2248				mint_mode: Some(true),2249				access: Some(AccessMode::AllowList),2250				nesting: None,2251			}2252		));22532254		assert_ok!(Unique::add_collection_admin(2255			origin1,2256			collection_id,2257			account(2)2258		));22592260		assert_ok!(Unique::create_item(2261			origin2,2262			collection_id,2263			account(2),2264			default_nft_data().into()2265		));2266	});2267}22682269// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-allow listed address.2270#[test]2271fn allow_list_test_15() {2272	new_test_ext().execute_with(|| {2273		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22742275		let origin1 = Origin::signed(1);2276		let origin2 = Origin::signed(2);22772278		assert_ok!(Unique::set_collection_permissions(2279			origin1.clone(),2280			collection_id,2281			CollectionPermissions {2282				mint_mode: Some(true),2283				access: Some(AccessMode::AllowList),2284				nesting: None,2285			}2286		));22872288		assert_noop!(2289			Unique::create_item(2290				origin2,2291				collection_id,2292				account(2),2293				default_nft_data().into()2294			)2295			.map_err(|e| e.error),2296			CommonError::<Test>::AddressNotInAllowlist2297		);2298	});2299}23002301// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by non-privileged and allow listed address.2302#[test]2303fn allow_list_test_16() {2304	new_test_ext().execute_with(|| {2305		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23062307		let origin1 = Origin::signed(1);2308		let origin2 = Origin::signed(2);23092310		assert_ok!(Unique::set_collection_permissions(2311			origin1.clone(),2312			collection_id,2313			CollectionPermissions {2314				mint_mode: Some(true),2315				access: Some(AccessMode::AllowList),2316				nesting: None,2317			}2318		));2319		assert_ok!(Unique::add_to_allow_list(2320			origin1,2321			collection_id,2322			account(2)2323		));23242325		assert_ok!(Unique::create_item(2326			origin2,2327			collection_id,2328			account(2),2329			default_nft_data().into()2330		));2331	});2332}23332334// Total number of collections. Positive test2335#[test]2336fn total_number_collections_bound() {2337	new_test_ext().execute_with(|| {2338		create_test_collection(&CollectionMode::NFT, CollectionId(1));2339	});2340}23412342#[test]2343fn create_max_collections() {2344	new_test_ext().execute_with(|| {2345		for i in 1..COLLECTION_NUMBER_LIMIT {2346			create_test_collection(&CollectionMode::NFT, CollectionId(i));2347		}2348	});2349}23502351// Total number of collections. Negative test2352#[test]2353fn total_number_collections_bound_neg() {2354	new_test_ext().execute_with(|| {2355		let origin1 = Origin::signed(1);23562357		for i in 1..=COLLECTION_NUMBER_LIMIT {2358			create_test_collection(&CollectionMode::NFT, CollectionId(i));2359		}23602361		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();2362		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();2363		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();23642365		let data: CreateCollectionData<u64> = CreateCollectionData {2366			name: col_name1.try_into().unwrap(),2367			description: col_desc1.try_into().unwrap(),2368			token_prefix: token_prefix1.try_into().unwrap(),2369			mode: CollectionMode::NFT,2370			..Default::default()2371		};23722373		// 11-th collection in chain. Expects error2374		assert_noop!(2375			Unique::create_collection_ex(origin1, data),2376			CommonError::<Test>::TotalCollectionsLimitExceeded2377		);2378	});2379}23802381// Owned tokens by a single address. Positive test2382#[test]2383fn owned_tokens_bound() {2384	new_test_ext().execute_with(|| {2385		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23862387		let data = default_nft_data();2388		create_test_item(collection_id, &data.clone().into());2389		create_test_item(collection_id, &data.into());2390	});2391}23922393// Owned tokens by a single address. Negotive test2394#[test]2395fn owned_tokens_bound_neg() {2396	new_test_ext().execute_with(|| {2397		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23982399		let origin1 = Origin::signed(1);24002401		for _ in 1..=MAX_TOKEN_OWNERSHIP {2402			let data = default_nft_data();2403			create_test_item(collection_id, &data.clone().into());2404		}24052406		let data = default_nft_data();2407		assert_noop!(2408			Unique::create_item(origin1, CollectionId(1), account(1), data.into())2409				.map_err(|e| e.error),2410			CommonError::<Test>::AccountTokenLimitExceeded2411		);2412	});2413}24142415// Number of collection admins. Positive test2416#[test]2417fn collection_admins_bound() {2418	new_test_ext().execute_with(|| {2419		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24202421		let origin1 = Origin::signed(1);24222423		assert_ok!(Unique::add_collection_admin(2424			origin1.clone(),2425			collection_id,2426			account(2)2427		));2428		assert_ok!(Unique::add_collection_admin(2429			origin1,2430			collection_id,2431			account(3)2432		));2433	});2434}24352436// Number of collection admins. Negotive test2437#[test]2438fn collection_admins_bound_neg() {2439	new_test_ext().execute_with(|| {2440		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24412442		let origin1 = Origin::signed(1);24432444		for i in 0..COLLECTION_ADMINS_LIMIT {2445			assert_ok!(Unique::add_collection_admin(2446				origin1.clone(),2447				collection_id,2448				account((2 + i).into())2449			));2450		}2451		assert_noop!(2452			Unique::add_collection_admin(2453				origin1,2454				collection_id,2455				account((3 + COLLECTION_ADMINS_LIMIT).into())2456			),2457			CommonError::<Test>::CollectionAdminCountExceeded2458		);2459	});2460}2461// #endregion24622463#[test]2464fn collection_transfer_flag_works() {2465	new_test_ext().execute_with(|| {2466		let origin1 = Origin::signed(1);24672468		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2469		assert_ok!(Unique::set_transfers_enabled_flag(2470			origin1,2471			collection_id,2472			true2473		));24742475		let data = default_nft_data();2476		create_test_item(collection_id, &data.into());2477		assert_eq!(2478			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2479			12480		);2481		assert_eq!(2482			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2483			true2484		);24852486		let origin1 = Origin::signed(1);24872488		// default scenario2489		assert_ok!(Unique::transfer(2490			origin1,2491			account(2),2492			collection_id,2493			TokenId(1),2494			12495		));2496		assert_eq!(2497			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2498			false2499		);2500		assert_eq!(2501			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2502			true2503		);2504		assert_eq!(2505			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2506			02507		);2508		assert_eq!(2509			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2510			12511		);2512	});2513}25142515#[test]2516fn collection_transfer_flag_works_neg() {2517	new_test_ext().execute_with(|| {2518		let origin1 = Origin::signed(1);25192520		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2521		assert_ok!(Unique::set_transfers_enabled_flag(2522			origin1,2523			collection_id,2524			false2525		));25262527		let data = default_nft_data();2528		create_test_item(collection_id, &data.into());2529		assert_eq!(2530			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2531			12532		);2533		assert_eq!(2534			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2535			true2536		);25372538		let origin1 = Origin::signed(1);25392540		// default scenario2541		assert_noop!(2542			Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1)2543				.map_err(|e| e.error),2544			CommonError::<Test>::TransferNotAllowed2545		);2546		assert_eq!(2547			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2548			12549		);2550		assert_eq!(2551			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2552			02553		);2554		assert_eq!(2555			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2556			true2557		);2558		assert_eq!(2559			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2560			false2561		);2562	});2563}25642565#[test]2566fn collection_sponsoring() {2567	new_test_ext().execute_with(|| {2568		// default_limits();2569		let user1 = 1_u64;2570		let user2 = 777_u64;2571		let origin1 = Origin::signed(user1);2572		let origin2 = Origin::signed(user2);2573		let account2 = account(user2);25742575		let collection_id =2576			create_test_collection_for_owner(&CollectionMode::NFT, user1, CollectionId(1));2577		assert_ok!(Unique::set_collection_sponsor(2578			origin1.clone(),2579			collection_id,2580			user12581		));2582		assert_ok!(Unique::confirm_sponsorship(origin1.clone(), collection_id));25832584		// Expect error while have no permissions2585		assert!(Unique::create_item(2586			origin2.clone(),2587			collection_id,2588			account2.clone(),2589			default_nft_data().into()2590		)2591		.is_err());25922593		assert_ok!(Unique::set_collection_permissions(2594			origin1.clone(),2595			collection_id,2596			CollectionPermissions {2597				mint_mode: Some(true),2598				access: Some(AccessMode::AllowList),2599				nesting: None,2600			}2601		));2602		assert_ok!(Unique::add_to_allow_list(2603			origin1.clone(),2604			collection_id,2605			account2.clone()2606		));26072608		assert_ok!(Unique::create_item(2609			origin2,2610			collection_id,2611			account2,2612			default_nft_data().into()2613		));2614	});2615}