difftreelog
major: move RFT const data to depricated.
in: master
9 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6320,7 +6320,7 @@
[[package]]
name = "pallet-refungible"
-version = "0.1.2"
+version = "0.2.0"
dependencies = [
"ethereum",
"evm-coder",
@@ -12737,7 +12737,7 @@
[[package]]
name = "up-data-structs"
-version = "0.1.2"
+version = "0.2.0"
dependencies = [
"derivative",
"frame-support",
pallets/refungible/CHANGELOG.mddiffbeforeafterboth--- a/pallets/refungible/CHANGELOG.md
+++ b/pallets/refungible/CHANGELOG.md
@@ -2,6 +2,11 @@
All notable changes to this project will be documented in this file.
+## [v0.2.0] - 2022-08-01
+### Deprecated
+- `ItemData`
+- `TokenData`
+
## [v0.1.2] - 2022-07-14
### Other changes
pallets/refungible/Cargo.tomldiffbeforeafterboth--- a/pallets/refungible/Cargo.toml
+++ b/pallets/refungible/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "pallet-refungible"
-version = "0.1.2"
+version = "0.2.0"
license = "GPLv3"
edition = "2021"
pallets/refungible/src/common.rsdiffbeforeafterboth--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -32,7 +32,7 @@
use crate::{
AccountBalance, Allowance, Balance, Config, Error, Owned, Pallet, RefungibleHandle,
- SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted,
+ SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted, TotalSupply,
};
macro_rules! max_weight_of {
@@ -155,7 +155,6 @@
) -> Result<CreateRefungibleExData<T::CrossAccountId>, DispatchError> {
match data {
up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateRefungibleExData {
- const_data: data.const_data,
users: {
let mut out = BTreeMap::new();
out.insert(to.clone(), data.pieces);
@@ -421,7 +420,7 @@
}
fn collection_tokens(&self) -> Vec<TokenId> {
- <TokenData<T>>::iter_prefix((self.id,))
+ <TotalSupply<T>>::iter_prefix((self.id,))
.map(|(id, _)| id)
.collect()
}
pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -123,6 +123,7 @@
/// for the convenience of database access. Notably contains the token metadata.
#[struct_versioning::versioned(version = 2, upper)]
#[derive(Encode, Decode, Default, TypeInfo, MaxEncodedLen)]
+#[deprecated(since = "0.2.0", note = "ItemData is no more contains usefull data")]
pub struct ItemData {
pub const_data: BoundedVec<u8, CustomDataLimit>,
@@ -180,7 +181,9 @@
StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
/// Token data, used to partially describe a token.
+ // TODO: remove
#[pallet::storage]
+ #[deprecated(since = "0.2.0", note = "ItemData is no more contains usefull data")]
pub type TokenData<T: Config> = StorageNMap<
Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
Value = ItemData,
@@ -260,10 +263,13 @@
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_runtime_upgrade() -> Weight {
- if StorageVersion::get::<Pallet<T>>() < StorageVersion::new(1) {
+ let storage_version = StorageVersion::get::<Pallet<T>>();
+ if storage_version < StorageVersion::new(1) {
<TokenData<T>>::translate_values::<ItemDataVersion1, _>(|v| {
Some(<ItemDataVersion2>::from(v))
})
+ } else if storage_version < StorageVersion::new(2) {
+ <TokenData<T>>::remove_all(None);
}
0
@@ -377,7 +383,6 @@
<TokensMinted<T>>::remove(id);
<TokensBurnt<T>>::remove(id);
- <TokenData<T>>::remove_prefix((id,), None);
<TotalSupply<T>>::remove_prefix((id,), None);
<Balance<T>>::remove_prefix((id,), None);
<Allowance<T>>::remove_prefix((id,), None);
@@ -387,7 +392,7 @@
}
fn collection_has_tokens(collection_id: CollectionId) -> bool {
- <TokenData<T>>::iter_prefix((collection_id,))
+ <TotalSupply<T>>::iter_prefix((collection_id,))
.next()
.is_some()
}
@@ -401,7 +406,6 @@
.ok_or(ArithmeticError::Overflow)?;
<TokensBurnt<T>>::insert(collection.id, burnt);
- <TokenData<T>>::remove((collection.id, token_id));
<TokenProperties<T>>::remove((collection.id, token_id));
<TotalSupply<T>>::remove((collection.id, token_id));
<Balance<T>>::remove_prefix((collection.id, token_id), None);
@@ -882,13 +886,6 @@
for (i, data) in data.iter().enumerate() {
let token_id = first_token_id + i as u32 + 1;
<TotalSupply<T>>::insert((collection.id, token_id), totals[i]);
-
- <TokenData<T>>::insert(
- (collection.id, token_id),
- ItemData {
- const_data: data.const_data.clone(),
- },
- );
for (user, amount) in data.users.iter() {
if *amount == 0 {
primitives/data-structs/CHANGELOG.mddiffbeforeafterboth--- a/primitives/data-structs/CHANGELOG.md
+++ b/primitives/data-structs/CHANGELOG.md
@@ -2,6 +2,9 @@
All notable changes to this project will be documented in this file.
+## [v0.2.0] - 2022-08-01
+### Deprecated
+- `CreateReFungibleData::const_data`
## [v0.1.2] - 2022-07-25
### Added
primitives/data-structs/Cargo.tomldiffbeforeafterboth--- a/primitives/data-structs/Cargo.toml
+++ b/primitives/data-structs/Cargo.toml
@@ -6,7 +6,7 @@
license = 'GPLv3'
homepage = "https://unique.network"
repository = 'https://github.com/UniqueNetwork/unique-chain'
-version = '0.1.2'
+version = '0.2.0'
[dependencies]
scale-info = { version = "2.0.1", default-features = false, features = [
primitives/data-structs/src/lib.rsdiffbeforeafterboth--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -780,12 +780,7 @@
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
#[derivative(Debug)]
pub struct CreateReFungibleData {
- /// Immutable metadata of the token
- #[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
- #[derivative(Debug(format_with = "bounded::vec_debug"))]
- pub const_data: BoundedVec<u8, CustomDataLimit>,
-
- /// Pieces of created token.
+ /// Number of pieces the RFT is split into
pub pieces: u128,
/// Key-value pairs used to describe the token as metadata
@@ -832,11 +827,6 @@
#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
#[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]
pub struct CreateRefungibleExData<CrossAccountId> {
- /// Custom data stored in token.
- #[derivative(Debug(format_with = "bounded::vec_debug"))]
- pub const_data: BoundedVec<u8, CustomDataLimit>,
-
- /// Users who will be assigned the specified number of token parts.
#[derivative(Debug(format_with = "bounded::map_debug"))]
pub users: BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,
#[derivative(Debug(format_with = "bounded::vec_debug"))]
@@ -874,10 +864,7 @@
impl CreateItemData {
/// Get size of custom data.
pub fn data_size(&self) -> usize {
- match self {
- CreateItemData::ReFungible(data) => data.const_data.len(),
- _ => 0,
- }
+ 0
}
}
runtime/tests/src/tests.rsdiffbeforeafterboth1// 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 properties: vec![Property {68 key: b"test-prop".to_vec().try_into().unwrap(),69 value: b"test-nft-prop".to_vec().try_into().unwrap(),70 }]71 .try_into()72 .unwrap(),73 }74}7576fn create_test_collection_for_owner(77 mode: &CollectionMode,78 owner: u64,79 id: CollectionId,80) -> CollectionId {81 add_balance(owner, CollectionCreationPrice::get() as u64 + 1);8283 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();84 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();85 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();86 let token_property_permissions: CollectionPropertiesPermissionsVec =87 vec![PropertyKeyPermission {88 key: b"test-prop".to_vec().try_into().unwrap(),89 permission: PropertyPermission {90 mutable: true,91 collection_admin: false,92 token_owner: true,93 },94 }]95 .try_into()96 .unwrap();97 let properties: CollectionPropertiesVec = vec![Property {98 key: b"test-collection-prop".to_vec().try_into().unwrap(),99 value: b"test-collection-value".to_vec().try_into().unwrap(),100 }]101 .try_into()102 .unwrap();103104 let data: CreateCollectionData<u64> = CreateCollectionData {105 name: col_name1.try_into().unwrap(),106 description: col_desc1.try_into().unwrap(),107 token_prefix: token_prefix1.try_into().unwrap(),108 mode: mode.clone(),109 token_property_permissions: token_property_permissions.clone(),110 properties: properties.clone(),111 ..Default::default()112 };113114 let origin1 = Origin::signed(owner);115 assert_ok!(Unique::create_collection_ex(origin1, data));116117 let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();118 let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();119 let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();120 assert_eq!(121 <pallet_common::CollectionById<Test>>::get(id)122 .unwrap()123 .owner,124 owner125 );126 assert_eq!(127 <pallet_common::CollectionById<Test>>::get(id).unwrap().name,128 saved_col_name129 );130 assert_eq!(131 <pallet_common::CollectionById<Test>>::get(id).unwrap().mode,132 *mode133 );134 assert_eq!(135 <pallet_common::CollectionById<Test>>::get(id)136 .unwrap()137 .description,138 saved_description139 );140 assert_eq!(141 <pallet_common::CollectionById<Test>>::get(id)142 .unwrap()143 .token_prefix,144 saved_prefix145 );146 assert_eq!(147 get_collection_property_permissions(id).as_slice(),148 token_property_permissions.as_slice()149 );150 assert_eq!(151 get_collection_properties(id).as_slice(),152 properties.as_slice()153 );154 id155}156157fn get_collection_property_permissions(collection_id: CollectionId) -> Vec<PropertyKeyPermission> {158 <pallet_common::Pallet<Test>>::property_permissions(collection_id)159 .into_iter()160 .map(|(key, permission)| PropertyKeyPermission { key, permission })161 .collect()162}163164fn get_collection_properties(collection_id: CollectionId) -> Vec<Property> {165 <pallet_common::Pallet<Test>>::collection_properties(collection_id)166 .into_iter()167 .map(|(key, value)| Property { key, value })168 .collect()169}170171fn get_token_properties(collection_id: CollectionId, token_id: TokenId) -> Vec<Property> {172 <pallet_nonfungible::Pallet<Test>>::token_properties((collection_id, token_id))173 .into_iter()174 .map(|(key, value)| Property { key, value })175 .collect()176}177178fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {179 create_test_collection_for_owner(&mode, 1, id)180}181182fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {183 let origin1 = Origin::signed(1);184 assert_ok!(Unique::create_item(185 origin1,186 collection_id,187 account(1),188 data.clone()189 ));190}191192fn account(sub: u64) -> TestCrossAccountId {193 TestCrossAccountId::from_sub(sub)194}195196// Use cases tests region197// #region198199#[test]200fn check_not_sufficient_founds() {201 new_test_ext().execute_with(|| {202 let acc: u64 = 1;203 <pallet_balances::Pallet<Test>>::set_balance(Origin::root(), acc, 0, 0).unwrap();204205 let name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();206 let description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();207 let token_prefix: Vec<u8> = b"token_prefix1\0".to_vec();208209 let data: CreateCollectionData<<Test as frame_system::Config>::AccountId> =210 CreateCollectionData {211 name: name.try_into().unwrap(),212 description: description.try_into().unwrap(),213 token_prefix: token_prefix.try_into().unwrap(),214 mode: CollectionMode::NFT,215 ..Default::default()216 };217218 let result = Unique::create_collection_ex(Origin::signed(acc), data);219 assert_err!(result, <CommonError<Test>>::NotSufficientFounds);220 });221}222223#[test]224fn create_fungible_collection_fails_with_large_decimal_numbers() {225 new_test_ext().execute_with(|| {226 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();227 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();228 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();229230 let data: CreateCollectionData<u64> = CreateCollectionData {231 name: col_name1.try_into().unwrap(),232 description: col_desc1.try_into().unwrap(),233 token_prefix: token_prefix1.try_into().unwrap(),234 mode: CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1),235 ..Default::default()236 };237238 let origin1 = Origin::signed(1);239 assert_noop!(240 Unique::create_collection_ex(origin1, data),241 UniqueError::<Test>::CollectionDecimalPointLimitExceeded242 );243 });244}245246#[test]247fn create_nft_item() {248 new_test_ext().execute_with(|| {249 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));250251 let data = default_nft_data();252 create_test_item(collection_id, &data.clone().into());253254 assert_eq!(255 get_token_properties(collection_id, TokenId(1)).as_slice(),256 data.properties.as_slice(),257 );258 });259}260261// Use cases tests region262// #region263#[test]264fn create_nft_multiple_items() {265 new_test_ext().execute_with(|| {266 create_test_collection(&CollectionMode::NFT, CollectionId(1));267268 let origin1 = Origin::signed(1);269270 let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];271272 assert_ok!(Unique::create_multiple_items(273 origin1,274 CollectionId(1),275 account(1),276 items_data277 .clone()278 .into_iter()279 .map(|d| { d.into() })280 .collect()281 ));282 for (index, data) in items_data.into_iter().enumerate() {283 assert_eq!(284 get_token_properties(CollectionId(1), TokenId(index as u32 + 1)).as_slice(),285 data.properties.as_slice()286 );287 }288 });289}290291#[test]292fn create_refungible_item() {293 new_test_ext().execute_with(|| {294 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));295296 let data = default_re_fungible_data();297 create_test_item(collection_id, &data.clone().into());298 let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));299 let balance =300 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));301 assert_eq!(item.const_data, data.const_data.into_inner());302 assert_eq!(balance, 1023);303 });304}305306#[test]307fn create_multiple_refungible_items() {308 new_test_ext().execute_with(|| {309 create_test_collection(&CollectionMode::ReFungible, CollectionId(1));310311 let origin1 = Origin::signed(1);312313 let items_data = vec![314 default_re_fungible_data(),315 default_re_fungible_data(),316 default_re_fungible_data(),317 ];318319 assert_ok!(Unique::create_multiple_items(320 origin1,321 CollectionId(1),322 account(1),323 items_data324 .clone()325 .into_iter()326 .map(|d| { d.into() })327 .collect()328 ));329 for (index, data) in items_data.into_iter().enumerate() {330 let item = <pallet_refungible::TokenData<Test>>::get((331 CollectionId(1),332 TokenId((index + 1) as u32),333 ));334 let balance =335 <pallet_refungible::Balance<Test>>::get((CollectionId(1), TokenId(1), account(1)));336 assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());337 assert_eq!(balance, 1023);338 }339 });340}341342#[test]343fn create_fungible_item() {344 new_test_ext().execute_with(|| {345 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));346347 let data = default_fungible_data();348 create_test_item(collection_id, &data.into());349350 assert_eq!(351 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),352 5353 );354 });355}356357//#[test]358// fn create_multiple_fungible_items() {359// new_test_ext().execute_with(|| {360// default_limits();361362// create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));363364// let origin1 = Origin::signed(1);365366// let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];367368// assert_ok!(Unique::create_multiple_items(369// origin1.clone(),370// 1,371// 1,372// items_data.clone().into_iter().map(|d| { d.into() }).collect()373// ));374375// for (index, _) in items_data.iter().enumerate() {376// assert_eq!(Unique::fungible_item_id(1, (index + 1) as TokenId).value, 5);377// }378// assert_eq!(Unique::balance_count(1, 1), 3000);379// assert_eq!(Unique::address_tokens(1, 1), [1, 2, 3]);380// });381// }382383#[test]384fn transfer_fungible_item() {385 new_test_ext().execute_with(|| {386 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));387388 let origin1 = Origin::signed(1);389 let origin2 = Origin::signed(2);390391 let data = default_fungible_data();392 create_test_item(collection_id, &data.into());393394 assert_eq!(395 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),396 5397 );398399 // change owner scenario400 assert_ok!(Unique::transfer(401 origin1,402 account(2),403 CollectionId(1),404 TokenId(0),405 5406 ));407 assert_eq!(408 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),409 0410 );411412 // split item scenario413 assert_ok!(Unique::transfer(414 origin2.clone(),415 account(3),416 CollectionId(1),417 TokenId(0),418 3419 ));420421 // split item and new owner has account scenario422 assert_ok!(Unique::transfer(423 origin2,424 account(3),425 CollectionId(1),426 TokenId(0),427 1428 ));429 assert_eq!(430 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(2))),431 1432 );433 assert_eq!(434 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(3))),435 4436 );437 });438}439440#[test]441fn transfer_refungible_item() {442 new_test_ext().execute_with(|| {443 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));444445 // Create RFT 1 in 1023 pieces for account 1446 let data = default_re_fungible_data();447 create_test_item(collection_id, &data.clone().into());448 let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));449 assert_eq!(item.const_data, data.const_data.into_inner());450 assert_eq!(451 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),452 1453 );454 assert_eq!(455 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),456 1023457 );458 assert_eq!(459 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),460 true461 );462463 // Account 1 transfers all 1023 pieces of RFT 1 to account 2464 let origin1 = Origin::signed(1);465 let origin2 = Origin::signed(2);466 assert_ok!(Unique::transfer(467 origin1,468 account(2),469 CollectionId(1),470 TokenId(1),471 1023472 ));473 assert_eq!(474 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),475 1023476 );477 assert_eq!(478 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),479 0480 );481 assert_eq!(482 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),483 1484 );485 assert_eq!(486 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),487 false488 );489 assert_eq!(490 <pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),491 true492 );493494 // Account 2 transfers 500 pieces of RFT 1 to account 3495 assert_ok!(Unique::transfer(496 origin2.clone(),497 account(3),498 CollectionId(1),499 TokenId(1),500 500501 ));502 assert_eq!(503 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),504 523505 );506 assert_eq!(507 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),508 500509 );510 assert_eq!(511 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),512 1513 );514 assert_eq!(515 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),516 1517 );518 assert_eq!(519 <pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),520 true521 );522 assert_eq!(523 <pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),524 true525 );526527 // Account 2 transfers 200 more pieces of RFT 1 to account 3 with pre-existing balance528 assert_ok!(Unique::transfer(529 origin2,530 account(3),531 CollectionId(1),532 TokenId(1),533 200534 ));535 assert_eq!(536 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),537 323538 );539 assert_eq!(540 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),541 700542 );543 assert_eq!(544 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),545 1546 );547 assert_eq!(548 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),549 1550 );551 assert_eq!(552 <pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),553 true554 );555 assert_eq!(556 <pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),557 true558 );559 });560}561562#[test]563fn transfer_nft_item() {564 new_test_ext().execute_with(|| {565 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));566567 let data = default_nft_data();568 create_test_item(collection_id, &data.into());569 assert_eq!(570 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),571 1572 );573 assert_eq!(574 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),575 true576 );577578 let origin1 = Origin::signed(1);579 // default scenario580 assert_ok!(Unique::transfer(581 origin1,582 account(2),583 CollectionId(1),584 TokenId(1),585 1586 ));587 assert_eq!(588 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),589 0590 );591 assert_eq!(592 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),593 1594 );595 assert_eq!(596 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),597 false598 );599 assert_eq!(600 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),601 true602 );603 });604}605606#[test]607fn transfer_nft_item_wrong_value() {608 new_test_ext().execute_with(|| {609 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));610611 let data = default_nft_data();612 create_test_item(collection_id, &data.into());613 assert_eq!(614 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),615 1616 );617 assert_eq!(618 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),619 true620 );621622 let origin1 = Origin::signed(1);623624 assert_noop!(625 Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 2)626 .map_err(|e| e.error),627 <pallet_nonfungible::Error::<Test>>::NonfungibleItemsHaveNoAmount628 );629 });630}631632#[test]633fn transfer_nft_item_zero_value() {634 new_test_ext().execute_with(|| {635 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));636637 let data = default_nft_data();638 create_test_item(collection_id, &data.into());639 assert_eq!(640 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),641 1642 );643 assert_eq!(644 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),645 true646 );647648 let origin1 = Origin::signed(1);649650 // Transferring 0 amount works on NFT...651 assert_ok!(Unique::transfer(652 origin1,653 account(2),654 CollectionId(1),655 TokenId(1),656 0657 ));658 // ... and results in no transfer659 assert_eq!(660 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),661 1662 );663 assert_eq!(664 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),665 true666 );667 });668}669670#[test]671fn nft_approve_and_transfer_from() {672 new_test_ext().execute_with(|| {673 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));674675 let data = default_nft_data();676 create_test_item(collection_id, &data.into());677678 let origin1 = Origin::signed(1);679 let origin2 = Origin::signed(2);680681 assert_eq!(682 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),683 1684 );685 assert_eq!(686 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),687 true688 );689690 // neg transfer_from691 assert_noop!(692 Unique::transfer_from(693 origin2.clone(),694 account(1),695 account(2),696 CollectionId(1),697 TokenId(1),698 1699 )700 .map_err(|e| e.error),701 CommonError::<Test>::ApprovedValueTooLow702 );703704 // do approve705 assert_ok!(Unique::approve(706 origin1,707 account(2),708 CollectionId(1),709 TokenId(1),710 1711 ));712 assert_eq!(713 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),714 account(2)715 );716717 assert_ok!(Unique::transfer_from(718 origin2,719 account(1),720 account(3),721 CollectionId(1),722 TokenId(1),723 1724 ));725 assert!(726 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()727 );728 });729}730731#[test]732fn nft_approve_and_transfer_from_allow_list() {733 new_test_ext().execute_with(|| {734 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));735736 let origin1 = Origin::signed(1);737 let origin2 = Origin::signed(2);738739 // Create NFT 1 for account 1740 let data = default_nft_data();741 create_test_item(collection_id, &data.clone().into());742 assert_eq!(743 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),744 1745 );746 assert_eq!(747 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),748 true749 );750751 // Allow allow-list users to mint and add accounts 1, 2, and 3 to allow-list752 assert_ok!(Unique::set_collection_permissions(753 origin1.clone(),754 CollectionId(1),755 CollectionPermissions {756 mint_mode: Some(true),757 access: Some(AccessMode::AllowList),758 nesting: None,759 }760 ));761 assert_ok!(Unique::add_to_allow_list(762 origin1.clone(),763 CollectionId(1),764 account(1)765 ));766 assert_ok!(Unique::add_to_allow_list(767 origin1.clone(),768 CollectionId(1),769 account(2)770 ));771 assert_ok!(Unique::add_to_allow_list(772 origin1.clone(),773 CollectionId(1),774 account(3)775 ));776777 // Account 1 approves account 2 for NFT 1778 assert_ok!(Unique::approve(779 origin1.clone(),780 account(2),781 CollectionId(1),782 TokenId(1),783 1784 ));785 assert_eq!(786 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),787 account(2)788 );789790 // Account 2 transfers NFT 1 from account 1 to account 3791 assert_ok!(Unique::transfer_from(792 origin2,793 account(1),794 account(3),795 CollectionId(1),796 TokenId(1),797 1798 ));799 assert!(800 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()801 );802 });803}804805#[test]806fn refungible_approve_and_transfer_from() {807 new_test_ext().execute_with(|| {808 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));809810 let origin1 = Origin::signed(1);811 let origin2 = Origin::signed(2);812813 // Create RFT 1 in 1023 pieces for account 1814 let data = default_re_fungible_data();815 create_test_item(collection_id, &data.into());816817 assert_eq!(818 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),819 1820 );821 assert_eq!(822 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),823 1023824 );825 assert_eq!(826 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),827 true828 );829830 // Allow public minting, enable allow-list and add accounts 1, 2, 3 to allow-list831 assert_ok!(Unique::set_collection_permissions(832 origin1.clone(),833 CollectionId(1),834 CollectionPermissions {835 mint_mode: Some(true),836 access: Some(AccessMode::AllowList),837 nesting: None,838 }839 ));840 assert_ok!(Unique::add_to_allow_list(841 origin1.clone(),842 CollectionId(1),843 account(1)844 ));845 assert_ok!(Unique::add_to_allow_list(846 origin1.clone(),847 CollectionId(1),848 account(2)849 ));850 assert_ok!(Unique::add_to_allow_list(851 origin1.clone(),852 CollectionId(1),853 account(3)854 ));855856 // Account 1 approves account 2 for 1023 pieces of RFT 1857 assert_ok!(Unique::approve(858 origin1,859 account(2),860 CollectionId(1),861 TokenId(1),862 1023863 ));864 assert_eq!(865 <pallet_refungible::Allowance<Test>>::get((866 CollectionId(1),867 TokenId(1),868 account(1),869 account(2)870 )),871 1023872 );873874 // Account 2 transfers 100 pieces of RFT 1 from account 1 to account 3875 assert_ok!(Unique::transfer_from(876 origin2,877 account(1),878 account(3),879 CollectionId(1),880 TokenId(1),881 100882 ));883 assert_eq!(884 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),885 1886 );887 assert_eq!(888 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),889 1890 );891 assert_eq!(892 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),893 923894 );895 assert_eq!(896 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),897 100898 );899 assert_eq!(900 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),901 true902 );903 assert_eq!(904 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),905 true906 );907 assert_eq!(908 <pallet_refungible::Allowance<Test>>::get((909 CollectionId(1),910 TokenId(1),911 account(1),912 account(2)913 )),914 923915 );916 });917}918919#[test]920fn fungible_approve_and_transfer_from() {921 new_test_ext().execute_with(|| {922 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));923924 let data = default_fungible_data();925 create_test_item(collection_id, &data.into());926927 let origin1 = Origin::signed(1);928 let origin2 = Origin::signed(2);929930 assert_ok!(Unique::set_collection_permissions(931 origin1.clone(),932 CollectionId(1),933 CollectionPermissions {934 mint_mode: Some(true),935 access: Some(AccessMode::AllowList),936 nesting: None,937 }938 ));939 assert_ok!(Unique::add_to_allow_list(940 origin1.clone(),941 CollectionId(1),942 account(1)943 ));944 assert_ok!(Unique::add_to_allow_list(945 origin1.clone(),946 CollectionId(1),947 account(2)948 ));949 assert_ok!(Unique::add_to_allow_list(950 origin1.clone(),951 CollectionId(1),952 account(3)953 ));954955 // do approve956 assert_ok!(Unique::approve(957 origin1.clone(),958 account(2),959 CollectionId(1),960 TokenId(0),961 5962 ));963 assert_eq!(964 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),965 5966 );967 assert_ok!(Unique::approve(968 origin1,969 account(3),970 CollectionId(1),971 TokenId(0),972 5973 ));974 assert_eq!(975 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),976 5977 );978 assert_eq!(979 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(3))),980 5981 );982983 assert_ok!(Unique::transfer_from(984 origin2.clone(),985 account(1),986 account(3),987 CollectionId(1),988 TokenId(0),989 4990 ));991992 assert_eq!(993 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),994 1995 );996997 assert_noop!(998 Unique::transfer_from(999 origin2,1000 account(1),1001 account(3),1002 CollectionId(1),1003 TokenId(0),1004 41005 )1006 .map_err(|e| e.error),1007 CommonError::<Test>::ApprovedValueTooLow1008 );1009 });1010}10111012#[test]1013fn change_collection_owner() {1014 new_test_ext().execute_with(|| {1015 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10161017 let origin1 = Origin::signed(1);1018 assert_ok!(Unique::change_collection_owner(origin1, collection_id, 2));1019 assert_eq!(1020 <pallet_common::CollectionById<Test>>::get(collection_id)1021 .unwrap()1022 .owner,1023 21024 );1025 });1026}10271028#[test]1029fn destroy_collection() {1030 new_test_ext().execute_with(|| {1031 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10321033 let origin1 = Origin::signed(1);1034 assert_ok!(Unique::destroy_collection(origin1, collection_id));1035 });1036}10371038#[test]1039fn burn_nft_item() {1040 new_test_ext().execute_with(|| {1041 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10421043 let origin1 = Origin::signed(1);10441045 let data = default_nft_data();1046 create_test_item(collection_id, &data.into());10471048 // check balance (collection with id = 1, user id = 1)1049 assert_eq!(1050 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1051 11052 );10531054 // burn item1055 assert_ok!(Unique::burn_item(1056 origin1.clone(),1057 collection_id,1058 TokenId(1),1059 11060 ));1061 assert_eq!(1062 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1063 01064 );1065 });1066}10671068#[test]1069fn burn_same_nft_item_twice() {1070 new_test_ext().execute_with(|| {1071 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10721073 let origin1 = Origin::signed(1);10741075 let data = default_nft_data();1076 create_test_item(collection_id, &data.into());10771078 // check balance (collection with id = 1, user id = 1)1079 assert_eq!(1080 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1081 11082 );10831084 // burn item1085 assert_ok!(Unique::burn_item(1086 origin1.clone(),1087 collection_id,1088 TokenId(1),1089 11090 ));10911092 // burn item again1093 assert_noop!(1094 Unique::burn_item(origin1, collection_id, TokenId(1), 1).map_err(|e| e.error),1095 CommonError::<Test>::TokenNotFound1096 );10971098 assert_eq!(1099 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1100 01101 );1102 });1103}11041105#[test]1106fn burn_fungible_item() {1107 new_test_ext().execute_with(|| {1108 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11091110 let origin1 = Origin::signed(1);1111 assert_ok!(Unique::add_collection_admin(1112 origin1.clone(),1113 collection_id,1114 account(2)1115 ));11161117 let data = default_fungible_data();1118 create_test_item(collection_id, &data.into());11191120 // check balance (collection with id = 1, user id = 1)1121 assert_eq!(1122 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1123 51124 );11251126 // burn item1127 assert_ok!(Unique::burn_item(1128 origin1.clone(),1129 CollectionId(1),1130 TokenId(0),1131 51132 ));1133 assert_noop!(1134 Unique::burn_item(origin1, CollectionId(1), TokenId(0), 5).map_err(|e| e.error),1135 CommonError::<Test>::TokenValueTooLow1136 );11371138 assert_eq!(1139 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1140 01141 );1142 });1143}11441145#[test]1146fn burn_fungible_item_with_token_id() {1147 new_test_ext().execute_with(|| {1148 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11491150 let origin1 = Origin::signed(1);1151 assert_ok!(Unique::add_collection_admin(1152 origin1.clone(),1153 collection_id,1154 account(2)1155 ));11561157 let data = default_fungible_data();1158 create_test_item(collection_id, &data.into());11591160 // check balance (collection with id = 1, user id = 1)1161 assert_eq!(1162 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1163 51164 );11651166 // Try to burn item using Token ID1167 assert_noop!(1168 Unique::burn_item(origin1, CollectionId(1), TokenId(1), 5).map_err(|e| e.error),1169 <pallet_fungible::Error::<Test>>::FungibleItemsHaveNoId1170 );1171 });1172}1173#[test]1174fn burn_refungible_item() {1175 new_test_ext().execute_with(|| {1176 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));1177 let origin1 = Origin::signed(1);11781179 assert_ok!(Unique::set_collection_permissions(1180 origin1.clone(),1181 collection_id,1182 CollectionPermissions {1183 mint_mode: Some(true),1184 access: Some(AccessMode::AllowList),1185 nesting: None,1186 }1187 ));1188 assert_ok!(Unique::add_to_allow_list(1189 origin1.clone(),1190 collection_id,1191 account(1)1192 ));11931194 assert_ok!(Unique::add_collection_admin(1195 origin1.clone(),1196 collection_id,1197 account(2)1198 ));11991200 let data = default_re_fungible_data();1201 create_test_item(collection_id, &data.into());12021203 // check balance (collection with id = 1, user id = 2)1204 assert_eq!(1205 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),1206 11207 );1208 assert_eq!(1209 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1210 10231211 );12121213 // burn item1214 assert_ok!(Unique::burn_item(1215 origin1.clone(),1216 collection_id,1217 TokenId(1),1218 10231219 ));1220 assert_noop!(1221 Unique::burn_item(origin1, collection_id, TokenId(1), 1023).map_err(|e| e.error),1222 CommonError::<Test>::TokenValueTooLow1223 );12241225 assert_eq!(1226 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1227 01228 );1229 });1230}12311232#[test]1233fn add_collection_admin() {1234 new_test_ext().execute_with(|| {1235 let collection1_id =1236 create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1237 let origin1 = Origin::signed(1);12381239 // Add collection admins1240 assert_ok!(Unique::add_collection_admin(1241 origin1.clone(),1242 collection1_id,1243 account(2)1244 ));1245 assert_ok!(Unique::add_collection_admin(1246 origin1,1247 collection1_id,1248 account(3)1249 ));12501251 // Owner is not an admin by default1252 assert_eq!(1253 <pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(1))),1254 false1255 );1256 assert!(<pallet_common::IsAdmin<Test>>::get((1257 CollectionId(1),1258 account(2)1259 )));1260 assert!(<pallet_common::IsAdmin<Test>>::get((1261 CollectionId(1),1262 account(3)1263 )));1264 });1265}12661267#[test]1268fn remove_collection_admin() {1269 new_test_ext().execute_with(|| {1270 let collection1_id =1271 create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1272 let origin1 = Origin::signed(1);12731274 // Add collection admins 2 and 31275 assert_ok!(Unique::add_collection_admin(1276 origin1.clone(),1277 collection1_id,1278 account(2)1279 ));1280 assert_ok!(Unique::add_collection_admin(1281 origin1.clone(),1282 collection1_id,1283 account(3)1284 ));12851286 assert!(<pallet_common::IsAdmin<Test>>::get((1287 CollectionId(1),1288 account(2)1289 )));1290 assert!(<pallet_common::IsAdmin<Test>>::get((1291 CollectionId(1),1292 account(3)1293 )));12941295 // remove admin 31296 assert_ok!(Unique::remove_collection_admin(1297 origin1,1298 CollectionId(1),1299 account(3)1300 ));13011302 // 2 is still admin, 3 is not an admin anymore1303 assert!(<pallet_common::IsAdmin<Test>>::get((1304 CollectionId(1),1305 account(2)1306 )));1307 assert_eq!(1308 <pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))),1309 false1310 );1311 });1312}13131314#[test]1315fn balance_of() {1316 new_test_ext().execute_with(|| {1317 let nft_collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1318 let fungible_collection_id =1319 create_test_collection(&CollectionMode::Fungible(3), CollectionId(2));1320 let re_fungible_collection_id =1321 create_test_collection(&CollectionMode::ReFungible, CollectionId(3));13221323 // check balance before1324 assert_eq!(1325 <pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1326 01327 );1328 assert_eq!(1329 <pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1330 01331 );1332 assert_eq!(1333 <pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1334 01335 );13361337 let nft_data = default_nft_data();1338 create_test_item(nft_collection_id, &nft_data.into());13391340 let fungible_data = default_fungible_data();1341 create_test_item(fungible_collection_id, &fungible_data.into());13421343 let re_fungible_data = default_re_fungible_data();1344 create_test_item(re_fungible_collection_id, &re_fungible_data.into());13451346 // check balance (collection with id = 1, user id = 1)1347 assert_eq!(1348 <pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1349 11350 );1351 assert_eq!(1352 <pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1353 51354 );1355 assert_eq!(1356 <pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1357 11358 );13591360 assert_eq!(1361 <pallet_nonfungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))),1362 true1363 );1364 assert_eq!(1365 <pallet_refungible::Owned<Test>>::get((1366 re_fungible_collection_id,1367 account(1),1368 TokenId(1)1369 )),1370 true1371 );1372 });1373}13741375#[test]1376fn approve() {1377 new_test_ext().execute_with(|| {1378 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));13791380 let data = default_nft_data();1381 create_test_item(collection_id, &data.into());13821383 let origin1 = Origin::signed(1);13841385 // approve1386 assert_ok!(Unique::approve(1387 origin1,1388 account(2),1389 CollectionId(1),1390 TokenId(1),1391 11392 ));1393 assert_eq!(1394 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1395 account(2)1396 );1397 });1398}13991400#[test]1401fn transfer_from() {1402 new_test_ext().execute_with(|| {1403 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1404 let origin1 = Origin::signed(1);1405 let origin2 = Origin::signed(2);14061407 let data = default_nft_data();1408 create_test_item(collection_id, &data.into());14091410 // approve1411 assert_ok!(Unique::approve(1412 origin1.clone(),1413 account(2),1414 CollectionId(1),1415 TokenId(1),1416 11417 ));1418 assert_eq!(1419 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1420 account(2)1421 );14221423 assert_ok!(Unique::set_collection_permissions(1424 origin1.clone(),1425 CollectionId(1),1426 CollectionPermissions {1427 mint_mode: Some(true),1428 access: Some(AccessMode::AllowList),1429 nesting: None,1430 }1431 ));1432 assert_ok!(Unique::add_to_allow_list(1433 origin1.clone(),1434 CollectionId(1),1435 account(1)1436 ));1437 assert_ok!(Unique::add_to_allow_list(1438 origin1.clone(),1439 CollectionId(1),1440 account(2)1441 ));1442 assert_ok!(Unique::add_to_allow_list(1443 origin1,1444 CollectionId(1),1445 account(3)1446 ));14471448 assert_ok!(Unique::transfer_from(1449 origin2,1450 account(1),1451 account(2),1452 CollectionId(1),1453 TokenId(1),1454 11455 ));14561457 // after transfer1458 assert_eq!(1459 <pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(1))),1460 01461 );1462 assert_eq!(1463 <pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(2))),1464 11465 );1466 });1467}14681469// #endregion14701471// Coverage tests region1472// #region14731474#[test]1475fn owner_can_add_address_to_allow_list() {1476 new_test_ext().execute_with(|| {1477 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));14781479 let origin1 = Origin::signed(1);1480 assert_ok!(Unique::add_to_allow_list(1481 origin1,1482 collection_id,1483 account(2)1484 ));1485 assert!(<pallet_common::Allowlist<Test>>::get((1486 collection_id,1487 account(2)1488 )));1489 });1490}14911492#[test]1493fn admin_can_add_address_to_allow_list() {1494 new_test_ext().execute_with(|| {1495 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1496 let origin1 = Origin::signed(1);1497 let origin2 = Origin::signed(2);14981499 assert_ok!(Unique::add_collection_admin(1500 origin1,1501 collection_id,1502 account(2)1503 ));1504 assert_ok!(Unique::add_to_allow_list(1505 origin2,1506 collection_id,1507 account(3)1508 ));1509 assert!(<pallet_common::Allowlist<Test>>::get((1510 collection_id,1511 account(3)1512 )));1513 });1514}15151516#[test]1517fn nonprivileged_user_cannot_add_address_to_allow_list() {1518 new_test_ext().execute_with(|| {1519 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15201521 let origin2 = Origin::signed(2);1522 assert_noop!(1523 Unique::add_to_allow_list(origin2, collection_id, account(3)),1524 CommonError::<Test>::NoPermission1525 );1526 });1527}15281529#[test]1530fn nobody_can_add_address_to_allow_list_of_nonexisting_collection() {1531 new_test_ext().execute_with(|| {1532 let origin1 = Origin::signed(1);15331534 assert_noop!(1535 Unique::add_to_allow_list(origin1, CollectionId(1), account(2)),1536 CommonError::<Test>::CollectionNotFound1537 );1538 });1539}15401541#[test]1542fn nobody_can_add_address_to_allow_list_of_deleted_collection() {1543 new_test_ext().execute_with(|| {1544 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15451546 let origin1 = Origin::signed(1);1547 assert_ok!(Unique::destroy_collection(origin1.clone(), collection_id));1548 assert_noop!(1549 Unique::add_to_allow_list(origin1, collection_id, account(2)),1550 CommonError::<Test>::CollectionNotFound1551 );1552 });1553}15541555// If address is already added to allow list, nothing happens1556#[test]1557fn address_is_already_added_to_allow_list() {1558 new_test_ext().execute_with(|| {1559 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1560 let origin1 = Origin::signed(1);15611562 assert_ok!(Unique::add_to_allow_list(1563 origin1.clone(),1564 collection_id,1565 account(2)1566 ));1567 assert_ok!(Unique::add_to_allow_list(1568 origin1,1569 collection_id,1570 account(2)1571 ));1572 assert!(<pallet_common::Allowlist<Test>>::get((1573 collection_id,1574 account(2)1575 )));1576 });1577}15781579#[test]1580fn owner_can_remove_address_from_allow_list() {1581 new_test_ext().execute_with(|| {1582 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15831584 let origin1 = Origin::signed(1);1585 assert_ok!(Unique::add_to_allow_list(1586 origin1.clone(),1587 collection_id,1588 account(2)1589 ));1590 assert_ok!(Unique::remove_from_allow_list(1591 origin1,1592 collection_id,1593 account(2)1594 ));1595 assert_eq!(1596 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1597 false1598 );1599 });1600}16011602#[test]1603fn admin_can_remove_address_from_allow_list() {1604 new_test_ext().execute_with(|| {1605 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1606 let origin1 = Origin::signed(1);1607 let origin2 = Origin::signed(2);16081609 // Owner adds admin1610 assert_ok!(Unique::add_collection_admin(1611 origin1.clone(),1612 collection_id,1613 account(2)1614 ));16151616 // Owner adds address 3 to allow list1617 assert_ok!(Unique::add_to_allow_list(1618 origin1,1619 collection_id,1620 account(3)1621 ));16221623 // Admin removes address 3 from allow list1624 assert_ok!(Unique::remove_from_allow_list(1625 origin2,1626 collection_id,1627 account(3)1628 ));1629 assert_eq!(1630 <pallet_common::Allowlist<Test>>::get((collection_id, account(3))),1631 false1632 );1633 });1634}16351636#[test]1637fn nonprivileged_user_cannot_remove_address_from_allow_list() {1638 new_test_ext().execute_with(|| {1639 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1640 let origin1 = Origin::signed(1);1641 let origin2 = Origin::signed(2);16421643 assert_ok!(Unique::add_to_allow_list(1644 origin1,1645 collection_id,1646 account(2)1647 ));1648 assert_noop!(1649 Unique::remove_from_allow_list(origin2, collection_id, account(2)),1650 CommonError::<Test>::NoPermission1651 );1652 assert!(<pallet_common::Allowlist<Test>>::get((1653 collection_id,1654 account(2)1655 )));1656 });1657}16581659#[test]1660fn nobody_can_remove_address_from_allow_list_of_nonexisting_collection() {1661 new_test_ext().execute_with(|| {1662 let origin1 = Origin::signed(1);16631664 assert_noop!(1665 Unique::remove_from_allow_list(origin1, CollectionId(1), account(2)),1666 CommonError::<Test>::CollectionNotFound1667 );1668 });1669}16701671#[test]1672fn nobody_can_remove_address_from_allow_list_of_deleted_collection() {1673 new_test_ext().execute_with(|| {1674 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1675 let origin1 = Origin::signed(1);1676 let origin2 = Origin::signed(2);16771678 // Add account 2 to allow list1679 assert_ok!(Unique::add_to_allow_list(1680 origin1.clone(),1681 collection_id,1682 account(2)1683 ));16841685 // Account 2 is in collection allow-list1686 assert!(<pallet_common::Allowlist<Test>>::get((1687 collection_id,1688 account(2)1689 )));16901691 // Destroy collection1692 assert_ok!(Unique::destroy_collection(origin1, collection_id));16931694 // Attempt to remove account 2 from collection allow-list => error1695 assert_noop!(1696 Unique::remove_from_allow_list(origin2, collection_id, account(2)),1697 CommonError::<Test>::CollectionNotFound1698 );16991700 // Account 2 is not found in collection allow-list anyway1701 assert_eq!(1702 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1703 false1704 );1705 });1706}17071708// If address is already removed from allow list, nothing happens1709#[test]1710fn address_is_already_removed_from_allow_list() {1711 new_test_ext().execute_with(|| {1712 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1713 let origin1 = Origin::signed(1);17141715 assert_ok!(Unique::add_to_allow_list(1716 origin1.clone(),1717 collection_id,1718 account(2)1719 ));1720 assert_ok!(Unique::remove_from_allow_list(1721 origin1.clone(),1722 collection_id,1723 account(2)1724 ));1725 assert_eq!(1726 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1727 false1728 );1729 assert_ok!(Unique::remove_from_allow_list(1730 origin1,1731 collection_id,1732 account(2)1733 ));1734 assert_eq!(1735 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1736 false1737 );1738 });1739}17401741// If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom (2 tests)1742#[test]1743fn allow_list_test_1() {1744 new_test_ext().execute_with(|| {1745 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));17461747 let origin1 = Origin::signed(1);17481749 let data = default_nft_data();1750 create_test_item(collection_id, &data.into());17511752 assert_ok!(Unique::set_collection_permissions(1753 origin1.clone(),1754 collection_id,1755 CollectionPermissions {1756 mint_mode: None,1757 access: Some(AccessMode::AllowList),1758 nesting: None,1759 }1760 ));1761 assert_ok!(Unique::add_to_allow_list(1762 origin1.clone(),1763 collection_id,1764 account(2)1765 ));17661767 assert_noop!(1768 Unique::transfer(origin1, account(3), CollectionId(1), TokenId(1), 1)1769 .map_err(|e| e.error),1770 CommonError::<Test>::AddressNotInAllowlist1771 );1772 });1773}17741775#[test]1776fn allow_list_test_2() {1777 new_test_ext().execute_with(|| {1778 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1779 let origin1 = Origin::signed(1);17801781 let data = default_nft_data();1782 create_test_item(collection_id, &data.into());17831784 assert_ok!(Unique::set_collection_permissions(1785 origin1.clone(),1786 collection_id,1787 CollectionPermissions {1788 mint_mode: None,1789 access: Some(AccessMode::AllowList),1790 nesting: None,1791 }1792 ));1793 assert_ok!(Unique::add_to_allow_list(1794 origin1.clone(),1795 collection_id,1796 account(1)1797 ));1798 assert_ok!(Unique::add_to_allow_list(1799 origin1.clone(),1800 collection_id,1801 account(2)1802 ));18031804 // do approve1805 assert_ok!(Unique::approve(1806 origin1.clone(),1807 account(1),1808 collection_id,1809 TokenId(1),1810 11811 ));1812 assert_eq!(1813 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1814 account(1)1815 );18161817 assert_ok!(Unique::remove_from_allow_list(1818 origin1.clone(),1819 collection_id,1820 account(1)1821 ));18221823 assert_noop!(1824 Unique::transfer_from(1825 origin1,1826 account(1),1827 account(3),1828 CollectionId(1),1829 TokenId(1),1830 11831 )1832 .map_err(|e| e.error),1833 CommonError::<Test>::AddressNotInAllowlist1834 );1835 });1836}18371838// If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom (2 tests)1839#[test]1840fn allow_list_test_3() {1841 new_test_ext().execute_with(|| {1842 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18431844 let origin1 = Origin::signed(1);18451846 let data = default_nft_data();1847 create_test_item(collection_id, &data.into());18481849 assert_ok!(Unique::set_collection_permissions(1850 origin1.clone(),1851 collection_id,1852 CollectionPermissions {1853 mint_mode: None,1854 access: Some(AccessMode::AllowList),1855 nesting: None,1856 }1857 ));1858 assert_ok!(Unique::add_to_allow_list(1859 origin1.clone(),1860 collection_id,1861 account(1)1862 ));18631864 assert_noop!(1865 Unique::transfer(origin1, account(3), collection_id, TokenId(1), 1)1866 .map_err(|e| e.error),1867 CommonError::<Test>::AddressNotInAllowlist1868 );1869 });1870}18711872#[test]1873fn allow_list_test_4() {1874 new_test_ext().execute_with(|| {1875 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18761877 let origin1 = Origin::signed(1);18781879 let data = default_nft_data();1880 create_test_item(collection_id, &data.into());18811882 assert_ok!(Unique::set_collection_permissions(1883 origin1.clone(),1884 collection_id,1885 CollectionPermissions {1886 mint_mode: None,1887 access: Some(AccessMode::AllowList),1888 nesting: None,1889 }1890 ));1891 assert_ok!(Unique::add_to_allow_list(1892 origin1.clone(),1893 collection_id,1894 account(1)1895 ));1896 assert_ok!(Unique::add_to_allow_list(1897 origin1.clone(),1898 collection_id,1899 account(2)1900 ));19011902 // do approve1903 assert_ok!(Unique::approve(1904 origin1.clone(),1905 account(1),1906 collection_id,1907 TokenId(1),1908 11909 ));1910 assert_eq!(1911 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1912 account(1)1913 );19141915 assert_ok!(Unique::remove_from_allow_list(1916 origin1.clone(),1917 collection_id,1918 account(2)1919 ));19201921 assert_noop!(1922 Unique::transfer_from(1923 origin1,1924 account(1),1925 account(3),1926 collection_id,1927 TokenId(1),1928 11929 )1930 .map_err(|e| e.error),1931 CommonError::<Test>::AddressNotInAllowlist1932 );1933 });1934}19351936// 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)1937#[test]1938fn allow_list_test_5() {1939 new_test_ext().execute_with(|| {1940 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19411942 let origin1 = Origin::signed(1);19431944 let data = default_nft_data();1945 create_test_item(collection_id, &data.into());19461947 assert_ok!(Unique::set_collection_permissions(1948 origin1.clone(),1949 collection_id,1950 CollectionPermissions {1951 mint_mode: None,1952 access: Some(AccessMode::AllowList),1953 nesting: None,1954 }1955 ));1956 assert_noop!(1957 Unique::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 1).map_err(|e| e.error),1958 CommonError::<Test>::AddressNotInAllowlist1959 );1960 });1961}19621963// If Public Access mode is set to AllowList, token transfers can’t be Approved by a non-allowlisted address (see Approve method).1964#[test]1965fn allow_list_test_6() {1966 new_test_ext().execute_with(|| {1967 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19681969 let origin1 = Origin::signed(1);19701971 let data = default_nft_data();1972 create_test_item(collection_id, &data.into());19731974 assert_ok!(Unique::set_collection_permissions(1975 origin1.clone(),1976 collection_id,1977 CollectionPermissions {1978 mint_mode: None,1979 access: Some(AccessMode::AllowList),1980 nesting: None,1981 }1982 ));19831984 // do approve1985 assert_noop!(1986 Unique::approve(origin1, account(1), CollectionId(1), TokenId(1), 1)1987 .map_err(|e| e.error),1988 CommonError::<Test>::AddressNotInAllowlist1989 );1990 });1991}19921993// If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests) and1994// tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests)1995#[test]1996fn allow_list_test_7() {1997 new_test_ext().execute_with(|| {1998 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19992000 let data = default_nft_data();2001 create_test_item(collection_id, &data.into());20022003 let origin1 = Origin::signed(1);20042005 assert_ok!(Unique::set_collection_permissions(2006 origin1.clone(),2007 collection_id,2008 CollectionPermissions {2009 mint_mode: None,2010 access: Some(AccessMode::AllowList),2011 nesting: None,2012 }2013 ));2014 assert_ok!(Unique::add_to_allow_list(2015 origin1.clone(),2016 collection_id,2017 account(1)2018 ));2019 assert_ok!(Unique::add_to_allow_list(2020 origin1.clone(),2021 collection_id,2022 account(2)2023 ));20242025 assert_ok!(Unique::transfer(2026 origin1,2027 account(2),2028 CollectionId(1),2029 TokenId(1),2030 12031 ));2032 });2033}20342035#[test]2036fn allow_list_test_8() {2037 new_test_ext().execute_with(|| {2038 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));20392040 // Create NFT for account 12041 let data = default_nft_data();2042 create_test_item(collection_id, &data.into());20432044 let origin1 = Origin::signed(1);20452046 // Toggle Allow List mode and add accounts 1 and 22047 assert_ok!(Unique::set_collection_permissions(2048 origin1.clone(),2049 collection_id,2050 CollectionPermissions {2051 mint_mode: None,2052 access: Some(AccessMode::AllowList),2053 nesting: None,2054 }2055 ));2056 assert_ok!(Unique::add_to_allow_list(2057 origin1.clone(),2058 collection_id,2059 account(1)2060 ));2061 assert_ok!(Unique::add_to_allow_list(2062 origin1.clone(),2063 collection_id,2064 account(2)2065 ));20662067 // Sself-approve account 1 for NFT 12068 assert_ok!(Unique::approve(2069 origin1.clone(),2070 account(1),2071 CollectionId(1),2072 TokenId(1),2073 12074 ));2075 assert_eq!(2076 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),2077 account(1)2078 );20792080 // Transfer from 1 to 22081 assert_ok!(Unique::transfer_from(2082 origin1,2083 account(1),2084 account(2),2085 CollectionId(1),2086 TokenId(1),2087 12088 ));2089 });2090}20912092// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by owner.2093#[test]2094fn allow_list_test_9() {2095 new_test_ext().execute_with(|| {2096 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2097 let origin1 = Origin::signed(1);20982099 assert_ok!(Unique::set_collection_permissions(2100 origin1.clone(),2101 collection_id,2102 CollectionPermissions {2103 mint_mode: Some(false),2104 access: Some(AccessMode::AllowList),2105 nesting: None,2106 }2107 ));21082109 let data = default_nft_data();2110 create_test_item(collection_id, &data.into());2111 });2112}21132114// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by admin.2115#[test]2116fn allow_list_test_10() {2117 new_test_ext().execute_with(|| {2118 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21192120 let origin1 = Origin::signed(1);2121 let origin2 = Origin::signed(2);21222123 assert_ok!(Unique::set_collection_permissions(2124 origin1.clone(),2125 collection_id,2126 CollectionPermissions {2127 mint_mode: Some(false),2128 access: Some(AccessMode::AllowList),2129 nesting: None,2130 }2131 ));21322133 assert_ok!(Unique::add_collection_admin(2134 origin1,2135 collection_id,2136 account(2)2137 ));21382139 assert_ok!(Unique::create_item(2140 origin2,2141 collection_id,2142 account(2),2143 default_nft_data().into()2144 ));2145 });2146}21472148// 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.2149#[test]2150fn allow_list_test_11() {2151 new_test_ext().execute_with(|| {2152 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21532154 let origin1 = Origin::signed(1);2155 let origin2 = Origin::signed(2);21562157 assert_ok!(Unique::set_collection_permissions(2158 origin1.clone(),2159 collection_id,2160 CollectionPermissions {2161 mint_mode: Some(false),2162 access: Some(AccessMode::AllowList),2163 nesting: None,2164 }2165 ));2166 assert_ok!(Unique::add_to_allow_list(2167 origin1,2168 collection_id,2169 account(2)2170 ));21712172 assert_noop!(2173 Unique::create_item(2174 origin2,2175 CollectionId(1),2176 account(2),2177 default_nft_data().into()2178 )2179 .map_err(|e| e.error),2180 CommonError::<Test>::PublicMintingNotAllowed2181 );2182 });2183}21842185// 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.2186#[test]2187fn allow_list_test_12() {2188 new_test_ext().execute_with(|| {2189 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21902191 let origin1 = Origin::signed(1);2192 let origin2 = Origin::signed(2);21932194 assert_ok!(Unique::set_collection_permissions(2195 origin1.clone(),2196 collection_id,2197 CollectionPermissions {2198 mint_mode: Some(false),2199 access: Some(AccessMode::AllowList),2200 nesting: None,2201 }2202 ));22032204 assert_noop!(2205 Unique::create_item(2206 origin2,2207 CollectionId(1),2208 account(2),2209 default_nft_data().into()2210 )2211 .map_err(|e| e.error),2212 CommonError::<Test>::PublicMintingNotAllowed2213 );2214 });2215}22162217// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by owner.2218#[test]2219fn allow_list_test_13() {2220 new_test_ext().execute_with(|| {2221 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22222223 let origin1 = Origin::signed(1);22242225 assert_ok!(Unique::set_collection_permissions(2226 origin1.clone(),2227 collection_id,2228 CollectionPermissions {2229 mint_mode: Some(true),2230 access: Some(AccessMode::AllowList),2231 nesting: None,2232 }2233 ));22342235 let data = default_nft_data();2236 create_test_item(collection_id, &data.into());2237 });2238}22392240// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by admin.2241#[test]2242fn allow_list_test_14() {2243 new_test_ext().execute_with(|| {2244 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22452246 let origin1 = Origin::signed(1);2247 let origin2 = Origin::signed(2);22482249 assert_ok!(Unique::set_collection_permissions(2250 origin1.clone(),2251 collection_id,2252 CollectionPermissions {2253 mint_mode: Some(true),2254 access: Some(AccessMode::AllowList),2255 nesting: None,2256 }2257 ));22582259 assert_ok!(Unique::add_collection_admin(2260 origin1,2261 collection_id,2262 account(2)2263 ));22642265 assert_ok!(Unique::create_item(2266 origin2,2267 collection_id,2268 account(2),2269 default_nft_data().into()2270 ));2271 });2272}22732274// 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.2275#[test]2276fn allow_list_test_15() {2277 new_test_ext().execute_with(|| {2278 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22792280 let origin1 = Origin::signed(1);2281 let origin2 = Origin::signed(2);22822283 assert_ok!(Unique::set_collection_permissions(2284 origin1.clone(),2285 collection_id,2286 CollectionPermissions {2287 mint_mode: Some(true),2288 access: Some(AccessMode::AllowList),2289 nesting: None,2290 }2291 ));22922293 assert_noop!(2294 Unique::create_item(2295 origin2,2296 collection_id,2297 account(2),2298 default_nft_data().into()2299 )2300 .map_err(|e| e.error),2301 CommonError::<Test>::AddressNotInAllowlist2302 );2303 });2304}23052306// 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.2307#[test]2308fn allow_list_test_16() {2309 new_test_ext().execute_with(|| {2310 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23112312 let origin1 = Origin::signed(1);2313 let origin2 = Origin::signed(2);23142315 assert_ok!(Unique::set_collection_permissions(2316 origin1.clone(),2317 collection_id,2318 CollectionPermissions {2319 mint_mode: Some(true),2320 access: Some(AccessMode::AllowList),2321 nesting: None,2322 }2323 ));2324 assert_ok!(Unique::add_to_allow_list(2325 origin1,2326 collection_id,2327 account(2)2328 ));23292330 assert_ok!(Unique::create_item(2331 origin2,2332 collection_id,2333 account(2),2334 default_nft_data().into()2335 ));2336 });2337}23382339// Total number of collections. Positive test2340#[test]2341fn total_number_collections_bound() {2342 new_test_ext().execute_with(|| {2343 create_test_collection(&CollectionMode::NFT, CollectionId(1));2344 });2345}23462347#[test]2348fn create_max_collections() {2349 new_test_ext().execute_with(|| {2350 for i in 1..COLLECTION_NUMBER_LIMIT {2351 create_test_collection(&CollectionMode::NFT, CollectionId(i));2352 }2353 });2354}23552356// Total number of collections. Negative test2357#[test]2358fn total_number_collections_bound_neg() {2359 new_test_ext().execute_with(|| {2360 let origin1 = Origin::signed(1);23612362 for i in 1..=COLLECTION_NUMBER_LIMIT {2363 create_test_collection(&CollectionMode::NFT, CollectionId(i));2364 }23652366 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();2367 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();2368 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();23692370 let data: CreateCollectionData<u64> = CreateCollectionData {2371 name: col_name1.try_into().unwrap(),2372 description: col_desc1.try_into().unwrap(),2373 token_prefix: token_prefix1.try_into().unwrap(),2374 mode: CollectionMode::NFT,2375 ..Default::default()2376 };23772378 // 11-th collection in chain. Expects error2379 assert_noop!(2380 Unique::create_collection_ex(origin1, data),2381 CommonError::<Test>::TotalCollectionsLimitExceeded2382 );2383 });2384}23852386// Owned tokens by a single address. Positive test2387#[test]2388fn owned_tokens_bound() {2389 new_test_ext().execute_with(|| {2390 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23912392 let data = default_nft_data();2393 create_test_item(collection_id, &data.clone().into());2394 create_test_item(collection_id, &data.into());2395 });2396}23972398// Owned tokens by a single address. Negotive test2399#[test]2400fn owned_tokens_bound_neg() {2401 new_test_ext().execute_with(|| {2402 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24032404 let origin1 = Origin::signed(1);24052406 for _ in 1..=MAX_TOKEN_OWNERSHIP {2407 let data = default_nft_data();2408 create_test_item(collection_id, &data.clone().into());2409 }24102411 let data = default_nft_data();2412 assert_noop!(2413 Unique::create_item(origin1, CollectionId(1), account(1), data.into())2414 .map_err(|e| e.error),2415 CommonError::<Test>::AccountTokenLimitExceeded2416 );2417 });2418}24192420// Number of collection admins. Positive test2421#[test]2422fn collection_admins_bound() {2423 new_test_ext().execute_with(|| {2424 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24252426 let origin1 = Origin::signed(1);24272428 assert_ok!(Unique::add_collection_admin(2429 origin1.clone(),2430 collection_id,2431 account(2)2432 ));2433 assert_ok!(Unique::add_collection_admin(2434 origin1,2435 collection_id,2436 account(3)2437 ));2438 });2439}24402441// Number of collection admins. Negotive test2442#[test]2443fn collection_admins_bound_neg() {2444 new_test_ext().execute_with(|| {2445 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24462447 let origin1 = Origin::signed(1);24482449 for i in 0..COLLECTION_ADMINS_LIMIT {2450 assert_ok!(Unique::add_collection_admin(2451 origin1.clone(),2452 collection_id,2453 account((2 + i).into())2454 ));2455 }2456 assert_noop!(2457 Unique::add_collection_admin(2458 origin1,2459 collection_id,2460 account((3 + COLLECTION_ADMINS_LIMIT).into())2461 ),2462 CommonError::<Test>::CollectionAdminCountExceeded2463 );2464 });2465}2466// #endregion24672468#[test]2469fn collection_transfer_flag_works() {2470 new_test_ext().execute_with(|| {2471 let origin1 = Origin::signed(1);24722473 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2474 assert_ok!(Unique::set_transfers_enabled_flag(2475 origin1,2476 collection_id,2477 true2478 ));24792480 let data = default_nft_data();2481 create_test_item(collection_id, &data.into());2482 assert_eq!(2483 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2484 12485 );2486 assert_eq!(2487 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2488 true2489 );24902491 let origin1 = Origin::signed(1);24922493 // default scenario2494 assert_ok!(Unique::transfer(2495 origin1,2496 account(2),2497 collection_id,2498 TokenId(1),2499 12500 ));2501 assert_eq!(2502 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2503 false2504 );2505 assert_eq!(2506 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2507 true2508 );2509 assert_eq!(2510 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2511 02512 );2513 assert_eq!(2514 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2515 12516 );2517 });2518}25192520#[test]2521fn collection_transfer_flag_works_neg() {2522 new_test_ext().execute_with(|| {2523 let origin1 = Origin::signed(1);25242525 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2526 assert_ok!(Unique::set_transfers_enabled_flag(2527 origin1,2528 collection_id,2529 false2530 ));25312532 let data = default_nft_data();2533 create_test_item(collection_id, &data.into());2534 assert_eq!(2535 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2536 12537 );2538 assert_eq!(2539 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2540 true2541 );25422543 let origin1 = Origin::signed(1);25442545 // default scenario2546 assert_noop!(2547 Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1)2548 .map_err(|e| e.error),2549 CommonError::<Test>::TransferNotAllowed2550 );2551 assert_eq!(2552 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2553 12554 );2555 assert_eq!(2556 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2557 02558 );2559 assert_eq!(2560 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2561 true2562 );2563 assert_eq!(2564 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2565 false2566 );2567 });2568}25692570#[test]2571fn collection_sponsoring() {2572 new_test_ext().execute_with(|| {2573 // default_limits();2574 let user1 = 1_u64;2575 let user2 = 777_u64;2576 let origin1 = Origin::signed(user1);2577 let origin2 = Origin::signed(user2);2578 let account2 = account(user2);25792580 let collection_id =2581 create_test_collection_for_owner(&CollectionMode::NFT, user1, CollectionId(1));2582 assert_ok!(Unique::set_collection_sponsor(2583 origin1.clone(),2584 collection_id,2585 user12586 ));2587 assert_ok!(Unique::confirm_sponsorship(origin1.clone(), collection_id));25882589 // Expect error while have no permissions2590 assert!(Unique::create_item(2591 origin2.clone(),2592 collection_id,2593 account2.clone(),2594 default_nft_data().into()2595 )2596 .is_err());25972598 assert_ok!(Unique::set_collection_permissions(2599 origin1.clone(),2600 collection_id,2601 CollectionPermissions {2602 mint_mode: Some(true),2603 access: Some(AccessMode::AllowList),2604 nesting: None,2605 }2606 ));2607 assert_ok!(Unique::add_to_allow_list(2608 origin1.clone(),2609 collection_id,2610 account2.clone()2611 ));26122613 assert_ok!(Unique::create_item(2614 origin2,2615 collection_id,2616 account2,2617 default_nft_data().into()2618 ));2619 });2620}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 pieces: 1023,66 properties: vec![Property {67 key: b"test-prop".to_vec().try_into().unwrap(),68 value: b"test-nft-prop".to_vec().try_into().unwrap(),69 }]70 .try_into()71 .unwrap(),72 }73}7475fn create_test_collection_for_owner(76 mode: &CollectionMode,77 owner: u64,78 id: CollectionId,79) -> CollectionId {80 add_balance(owner, CollectionCreationPrice::get() as u64 + 1);8182 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();83 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();84 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();85 let token_property_permissions: CollectionPropertiesPermissionsVec =86 vec![PropertyKeyPermission {87 key: b"test-prop".to_vec().try_into().unwrap(),88 permission: PropertyPermission {89 mutable: true,90 collection_admin: false,91 token_owner: true,92 },93 }]94 .try_into()95 .unwrap();96 let properties: CollectionPropertiesVec = vec![Property {97 key: b"test-collection-prop".to_vec().try_into().unwrap(),98 value: b"test-collection-value".to_vec().try_into().unwrap(),99 }]100 .try_into()101 .unwrap();102103 let data: CreateCollectionData<u64> = CreateCollectionData {104 name: col_name1.try_into().unwrap(),105 description: col_desc1.try_into().unwrap(),106 token_prefix: token_prefix1.try_into().unwrap(),107 mode: mode.clone(),108 token_property_permissions: token_property_permissions.clone(),109 properties: properties.clone(),110 ..Default::default()111 };112113 let origin1 = Origin::signed(owner);114 assert_ok!(Unique::create_collection_ex(origin1, data));115116 let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();117 let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();118 let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();119 assert_eq!(120 <pallet_common::CollectionById<Test>>::get(id)121 .unwrap()122 .owner,123 owner124 );125 assert_eq!(126 <pallet_common::CollectionById<Test>>::get(id).unwrap().name,127 saved_col_name128 );129 assert_eq!(130 <pallet_common::CollectionById<Test>>::get(id).unwrap().mode,131 *mode132 );133 assert_eq!(134 <pallet_common::CollectionById<Test>>::get(id)135 .unwrap()136 .description,137 saved_description138 );139 assert_eq!(140 <pallet_common::CollectionById<Test>>::get(id)141 .unwrap()142 .token_prefix,143 saved_prefix144 );145 assert_eq!(146 get_collection_property_permissions(id).as_slice(),147 token_property_permissions.as_slice()148 );149 assert_eq!(150 get_collection_properties(id).as_slice(),151 properties.as_slice()152 );153 id154}155156fn get_collection_property_permissions(collection_id: CollectionId) -> Vec<PropertyKeyPermission> {157 <pallet_common::Pallet<Test>>::property_permissions(collection_id)158 .into_iter()159 .map(|(key, permission)| PropertyKeyPermission { key, permission })160 .collect()161}162163fn get_collection_properties(collection_id: CollectionId) -> Vec<Property> {164 <pallet_common::Pallet<Test>>::collection_properties(collection_id)165 .into_iter()166 .map(|(key, value)| Property { key, value })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 { key, value })174 .collect()175}176177fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {178 create_test_collection_for_owner(&mode, 1, id)179}180181fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {182 let origin1 = Origin::signed(1);183 assert_ok!(Unique::create_item(184 origin1,185 collection_id,186 account(1),187 data.clone()188 ));189}190191fn account(sub: u64) -> TestCrossAccountId {192 TestCrossAccountId::from_sub(sub)193}194195// Use cases tests region196// #region197198#[test]199fn check_not_sufficient_founds() {200 new_test_ext().execute_with(|| {201 let acc: u64 = 1;202 <pallet_balances::Pallet<Test>>::set_balance(Origin::root(), acc, 0, 0).unwrap();203204 let name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();205 let description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();206 let token_prefix: Vec<u8> = b"token_prefix1\0".to_vec();207208 let data: CreateCollectionData<<Test as frame_system::Config>::AccountId> =209 CreateCollectionData {210 name: name.try_into().unwrap(),211 description: description.try_into().unwrap(),212 token_prefix: token_prefix.try_into().unwrap(),213 mode: CollectionMode::NFT,214 ..Default::default()215 };216217 let result = Unique::create_collection_ex(Origin::signed(acc), data);218 assert_err!(result, <CommonError<Test>>::NotSufficientFounds);219 });220}221222#[test]223fn create_fungible_collection_fails_with_large_decimal_numbers() {224 new_test_ext().execute_with(|| {225 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();226 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();227 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();228229 let data: CreateCollectionData<u64> = CreateCollectionData {230 name: col_name1.try_into().unwrap(),231 description: col_desc1.try_into().unwrap(),232 token_prefix: token_prefix1.try_into().unwrap(),233 mode: CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1),234 ..Default::default()235 };236237 let origin1 = Origin::signed(1);238 assert_noop!(239 Unique::create_collection_ex(origin1, data),240 UniqueError::<Test>::CollectionDecimalPointLimitExceeded241 );242 });243}244245#[test]246fn create_nft_item() {247 new_test_ext().execute_with(|| {248 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));249250 let data = default_nft_data();251 create_test_item(collection_id, &data.clone().into());252253 assert_eq!(254 get_token_properties(collection_id, TokenId(1)).as_slice(),255 data.properties.as_slice(),256 );257 });258}259260// Use cases tests region261// #region262#[test]263fn create_nft_multiple_items() {264 new_test_ext().execute_with(|| {265 create_test_collection(&CollectionMode::NFT, CollectionId(1));266267 let origin1 = Origin::signed(1);268269 let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];270271 assert_ok!(Unique::create_multiple_items(272 origin1,273 CollectionId(1),274 account(1),275 items_data276 .clone()277 .into_iter()278 .map(|d| { d.into() })279 .collect()280 ));281 for (index, data) in items_data.into_iter().enumerate() {282 assert_eq!(283 get_token_properties(CollectionId(1), TokenId(index as u32 + 1)).as_slice(),284 data.properties.as_slice()285 );286 }287 });288}289290#[test]291fn create_refungible_item() {292 new_test_ext().execute_with(|| {293 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));294295 let data = default_re_fungible_data();296 create_test_item(collection_id, &data.clone().into());297 let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));298 let balance =299 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));300 assert_eq!(balance, 1023);301 });302}303304#[test]305fn create_multiple_refungible_items() {306 new_test_ext().execute_with(|| {307 create_test_collection(&CollectionMode::ReFungible, CollectionId(1));308309 let origin1 = Origin::signed(1);310311 let items_data = vec![312 default_re_fungible_data(),313 default_re_fungible_data(),314 default_re_fungible_data(),315 ];316317 assert_ok!(Unique::create_multiple_items(318 origin1,319 CollectionId(1),320 account(1),321 items_data322 .clone()323 .into_iter()324 .map(|d| { d.into() })325 .collect()326 ));327 for (index, data) in items_data.into_iter().enumerate() {328 let item = <pallet_refungible::TokenData<Test>>::get((329 CollectionId(1),330 TokenId((index + 1) as u32),331 ));332 let balance =333 <pallet_refungible::Balance<Test>>::get((CollectionId(1), TokenId(1), account(1)));334 assert_eq!(balance, 1023);335 }336 });337}338339#[test]340fn create_fungible_item() {341 new_test_ext().execute_with(|| {342 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));343344 let data = default_fungible_data();345 create_test_item(collection_id, &data.into());346347 assert_eq!(348 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),349 5350 );351 });352}353354//#[test]355// fn create_multiple_fungible_items() {356// new_test_ext().execute_with(|| {357// default_limits();358359// create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));360361// let origin1 = Origin::signed(1);362363// let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];364365// assert_ok!(Unique::create_multiple_items(366// origin1.clone(),367// 1,368// 1,369// items_data.clone().into_iter().map(|d| { d.into() }).collect()370// ));371372// for (index, _) in items_data.iter().enumerate() {373// assert_eq!(Unique::fungible_item_id(1, (index + 1) as TokenId).value, 5);374// }375// assert_eq!(Unique::balance_count(1, 1), 3000);376// assert_eq!(Unique::address_tokens(1, 1), [1, 2, 3]);377// });378// }379380#[test]381fn transfer_fungible_item() {382 new_test_ext().execute_with(|| {383 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));384385 let origin1 = Origin::signed(1);386 let origin2 = Origin::signed(2);387388 let data = default_fungible_data();389 create_test_item(collection_id, &data.into());390391 assert_eq!(392 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),393 5394 );395396 // change owner scenario397 assert_ok!(Unique::transfer(398 origin1,399 account(2),400 CollectionId(1),401 TokenId(0),402 5403 ));404 assert_eq!(405 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),406 0407 );408409 // split item scenario410 assert_ok!(Unique::transfer(411 origin2.clone(),412 account(3),413 CollectionId(1),414 TokenId(0),415 3416 ));417418 // split item and new owner has account scenario419 assert_ok!(Unique::transfer(420 origin2,421 account(3),422 CollectionId(1),423 TokenId(0),424 1425 ));426 assert_eq!(427 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(2))),428 1429 );430 assert_eq!(431 <pallet_fungible::Balance<Test>>::get((CollectionId(1), account(3))),432 4433 );434 });435}436437#[test]438fn transfer_refungible_item() {439 new_test_ext().execute_with(|| {440 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));441442 // Create RFT 1 in 1023 pieces for account 1443 let data = default_re_fungible_data();444 create_test_item(collection_id, &data.clone().into());445 let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));446 assert_eq!(447 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),448 1449 );450 assert_eq!(451 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),452 1023453 );454 assert_eq!(455 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),456 true457 );458459 // Account 1 transfers all 1023 pieces of RFT 1 to account 2460 let origin1 = Origin::signed(1);461 let origin2 = Origin::signed(2);462 assert_ok!(Unique::transfer(463 origin1,464 account(2),465 CollectionId(1),466 TokenId(1),467 1023468 ));469 assert_eq!(470 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),471 1023472 );473 assert_eq!(474 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),475 0476 );477 assert_eq!(478 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),479 1480 );481 assert_eq!(482 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),483 false484 );485 assert_eq!(486 <pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),487 true488 );489490 // Account 2 transfers 500 pieces of RFT 1 to account 3491 assert_ok!(Unique::transfer(492 origin2.clone(),493 account(3),494 CollectionId(1),495 TokenId(1),496 500497 ));498 assert_eq!(499 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),500 523501 );502 assert_eq!(503 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),504 500505 );506 assert_eq!(507 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),508 1509 );510 assert_eq!(511 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),512 1513 );514 assert_eq!(515 <pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),516 true517 );518 assert_eq!(519 <pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),520 true521 );522523 // Account 2 transfers 200 more pieces of RFT 1 to account 3 with pre-existing balance524 assert_ok!(Unique::transfer(525 origin2,526 account(3),527 CollectionId(1),528 TokenId(1),529 200530 ));531 assert_eq!(532 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),533 323534 );535 assert_eq!(536 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),537 700538 );539 assert_eq!(540 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),541 1542 );543 assert_eq!(544 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),545 1546 );547 assert_eq!(548 <pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),549 true550 );551 assert_eq!(552 <pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),553 true554 );555 });556}557558#[test]559fn transfer_nft_item() {560 new_test_ext().execute_with(|| {561 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));562563 let data = default_nft_data();564 create_test_item(collection_id, &data.into());565 assert_eq!(566 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),567 1568 );569 assert_eq!(570 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),571 true572 );573574 let origin1 = Origin::signed(1);575 // default scenario576 assert_ok!(Unique::transfer(577 origin1,578 account(2),579 CollectionId(1),580 TokenId(1),581 1582 ));583 assert_eq!(584 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),585 0586 );587 assert_eq!(588 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),589 1590 );591 assert_eq!(592 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),593 false594 );595 assert_eq!(596 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),597 true598 );599 });600}601602#[test]603fn transfer_nft_item_wrong_value() {604 new_test_ext().execute_with(|| {605 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));606607 let data = default_nft_data();608 create_test_item(collection_id, &data.into());609 assert_eq!(610 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),611 1612 );613 assert_eq!(614 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),615 true616 );617618 let origin1 = Origin::signed(1);619620 assert_noop!(621 Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 2)622 .map_err(|e| e.error),623 <pallet_nonfungible::Error::<Test>>::NonfungibleItemsHaveNoAmount624 );625 });626}627628#[test]629fn transfer_nft_item_zero_value() {630 new_test_ext().execute_with(|| {631 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));632633 let data = default_nft_data();634 create_test_item(collection_id, &data.into());635 assert_eq!(636 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),637 1638 );639 assert_eq!(640 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),641 true642 );643644 let origin1 = Origin::signed(1);645646 // Transferring 0 amount works on NFT...647 assert_ok!(Unique::transfer(648 origin1,649 account(2),650 CollectionId(1),651 TokenId(1),652 0653 ));654 // ... and results in no transfer655 assert_eq!(656 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),657 1658 );659 assert_eq!(660 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),661 true662 );663 });664}665666#[test]667fn nft_approve_and_transfer_from() {668 new_test_ext().execute_with(|| {669 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));670671 let data = default_nft_data();672 create_test_item(collection_id, &data.into());673674 let origin1 = Origin::signed(1);675 let origin2 = Origin::signed(2);676677 assert_eq!(678 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),679 1680 );681 assert_eq!(682 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),683 true684 );685686 // neg transfer_from687 assert_noop!(688 Unique::transfer_from(689 origin2.clone(),690 account(1),691 account(2),692 CollectionId(1),693 TokenId(1),694 1695 )696 .map_err(|e| e.error),697 CommonError::<Test>::ApprovedValueTooLow698 );699700 // do approve701 assert_ok!(Unique::approve(702 origin1,703 account(2),704 CollectionId(1),705 TokenId(1),706 1707 ));708 assert_eq!(709 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),710 account(2)711 );712713 assert_ok!(Unique::transfer_from(714 origin2,715 account(1),716 account(3),717 CollectionId(1),718 TokenId(1),719 1720 ));721 assert!(722 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()723 );724 });725}726727#[test]728fn nft_approve_and_transfer_from_allow_list() {729 new_test_ext().execute_with(|| {730 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));731732 let origin1 = Origin::signed(1);733 let origin2 = Origin::signed(2);734735 // Create NFT 1 for account 1736 let data = default_nft_data();737 create_test_item(collection_id, &data.clone().into());738 assert_eq!(739 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),740 1741 );742 assert_eq!(743 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),744 true745 );746747 // Allow allow-list users to mint and add accounts 1, 2, and 3 to allow-list748 assert_ok!(Unique::set_collection_permissions(749 origin1.clone(),750 CollectionId(1),751 CollectionPermissions {752 mint_mode: Some(true),753 access: Some(AccessMode::AllowList),754 nesting: None,755 }756 ));757 assert_ok!(Unique::add_to_allow_list(758 origin1.clone(),759 CollectionId(1),760 account(1)761 ));762 assert_ok!(Unique::add_to_allow_list(763 origin1.clone(),764 CollectionId(1),765 account(2)766 ));767 assert_ok!(Unique::add_to_allow_list(768 origin1.clone(),769 CollectionId(1),770 account(3)771 ));772773 // Account 1 approves account 2 for NFT 1774 assert_ok!(Unique::approve(775 origin1.clone(),776 account(2),777 CollectionId(1),778 TokenId(1),779 1780 ));781 assert_eq!(782 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),783 account(2)784 );785786 // Account 2 transfers NFT 1 from account 1 to account 3787 assert_ok!(Unique::transfer_from(788 origin2,789 account(1),790 account(3),791 CollectionId(1),792 TokenId(1),793 1794 ));795 assert!(796 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()797 );798 });799}800801#[test]802fn refungible_approve_and_transfer_from() {803 new_test_ext().execute_with(|| {804 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));805806 let origin1 = Origin::signed(1);807 let origin2 = Origin::signed(2);808809 // Create RFT 1 in 1023 pieces for account 1810 let data = default_re_fungible_data();811 create_test_item(collection_id, &data.into());812813 assert_eq!(814 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),815 1816 );817 assert_eq!(818 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),819 1023820 );821 assert_eq!(822 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),823 true824 );825826 // Allow public minting, enable allow-list and add accounts 1, 2, 3 to allow-list827 assert_ok!(Unique::set_collection_permissions(828 origin1.clone(),829 CollectionId(1),830 CollectionPermissions {831 mint_mode: Some(true),832 access: Some(AccessMode::AllowList),833 nesting: None,834 }835 ));836 assert_ok!(Unique::add_to_allow_list(837 origin1.clone(),838 CollectionId(1),839 account(1)840 ));841 assert_ok!(Unique::add_to_allow_list(842 origin1.clone(),843 CollectionId(1),844 account(2)845 ));846 assert_ok!(Unique::add_to_allow_list(847 origin1.clone(),848 CollectionId(1),849 account(3)850 ));851852 // Account 1 approves account 2 for 1023 pieces of RFT 1853 assert_ok!(Unique::approve(854 origin1,855 account(2),856 CollectionId(1),857 TokenId(1),858 1023859 ));860 assert_eq!(861 <pallet_refungible::Allowance<Test>>::get((862 CollectionId(1),863 TokenId(1),864 account(1),865 account(2)866 )),867 1023868 );869870 // Account 2 transfers 100 pieces of RFT 1 from account 1 to account 3871 assert_ok!(Unique::transfer_from(872 origin2,873 account(1),874 account(3),875 CollectionId(1),876 TokenId(1),877 100878 ));879 assert_eq!(880 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),881 1882 );883 assert_eq!(884 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),885 1886 );887 assert_eq!(888 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),889 923890 );891 assert_eq!(892 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),893 100894 );895 assert_eq!(896 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),897 true898 );899 assert_eq!(900 <pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),901 true902 );903 assert_eq!(904 <pallet_refungible::Allowance<Test>>::get((905 CollectionId(1),906 TokenId(1),907 account(1),908 account(2)909 )),910 923911 );912 });913}914915#[test]916fn fungible_approve_and_transfer_from() {917 new_test_ext().execute_with(|| {918 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));919920 let data = default_fungible_data();921 create_test_item(collection_id, &data.into());922923 let origin1 = Origin::signed(1);924 let origin2 = Origin::signed(2);925926 assert_ok!(Unique::set_collection_permissions(927 origin1.clone(),928 CollectionId(1),929 CollectionPermissions {930 mint_mode: Some(true),931 access: Some(AccessMode::AllowList),932 nesting: None,933 }934 ));935 assert_ok!(Unique::add_to_allow_list(936 origin1.clone(),937 CollectionId(1),938 account(1)939 ));940 assert_ok!(Unique::add_to_allow_list(941 origin1.clone(),942 CollectionId(1),943 account(2)944 ));945 assert_ok!(Unique::add_to_allow_list(946 origin1.clone(),947 CollectionId(1),948 account(3)949 ));950951 // do approve952 assert_ok!(Unique::approve(953 origin1.clone(),954 account(2),955 CollectionId(1),956 TokenId(0),957 5958 ));959 assert_eq!(960 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),961 5962 );963 assert_ok!(Unique::approve(964 origin1,965 account(3),966 CollectionId(1),967 TokenId(0),968 5969 ));970 assert_eq!(971 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),972 5973 );974 assert_eq!(975 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(3))),976 5977 );978979 assert_ok!(Unique::transfer_from(980 origin2.clone(),981 account(1),982 account(3),983 CollectionId(1),984 TokenId(0),985 4986 ));987988 assert_eq!(989 <pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),990 1991 );992993 assert_noop!(994 Unique::transfer_from(995 origin2,996 account(1),997 account(3),998 CollectionId(1),999 TokenId(0),1000 41001 )1002 .map_err(|e| e.error),1003 CommonError::<Test>::ApprovedValueTooLow1004 );1005 });1006}10071008#[test]1009fn change_collection_owner() {1010 new_test_ext().execute_with(|| {1011 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10121013 let origin1 = Origin::signed(1);1014 assert_ok!(Unique::change_collection_owner(origin1, collection_id, 2));1015 assert_eq!(1016 <pallet_common::CollectionById<Test>>::get(collection_id)1017 .unwrap()1018 .owner,1019 21020 );1021 });1022}10231024#[test]1025fn destroy_collection() {1026 new_test_ext().execute_with(|| {1027 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10281029 let origin1 = Origin::signed(1);1030 assert_ok!(Unique::destroy_collection(origin1, collection_id));1031 });1032}10331034#[test]1035fn burn_nft_item() {1036 new_test_ext().execute_with(|| {1037 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10381039 let origin1 = Origin::signed(1);10401041 let data = default_nft_data();1042 create_test_item(collection_id, &data.into());10431044 // check balance (collection with id = 1, user id = 1)1045 assert_eq!(1046 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1047 11048 );10491050 // burn item1051 assert_ok!(Unique::burn_item(1052 origin1.clone(),1053 collection_id,1054 TokenId(1),1055 11056 ));1057 assert_eq!(1058 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1059 01060 );1061 });1062}10631064#[test]1065fn burn_same_nft_item_twice() {1066 new_test_ext().execute_with(|| {1067 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10681069 let origin1 = Origin::signed(1);10701071 let data = default_nft_data();1072 create_test_item(collection_id, &data.into());10731074 // check balance (collection with id = 1, user id = 1)1075 assert_eq!(1076 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1077 11078 );10791080 // burn item1081 assert_ok!(Unique::burn_item(1082 origin1.clone(),1083 collection_id,1084 TokenId(1),1085 11086 ));10871088 // burn item again1089 assert_noop!(1090 Unique::burn_item(origin1, collection_id, TokenId(1), 1).map_err(|e| e.error),1091 CommonError::<Test>::TokenNotFound1092 );10931094 assert_eq!(1095 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1096 01097 );1098 });1099}11001101#[test]1102fn burn_fungible_item() {1103 new_test_ext().execute_with(|| {1104 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11051106 let origin1 = Origin::signed(1);1107 assert_ok!(Unique::add_collection_admin(1108 origin1.clone(),1109 collection_id,1110 account(2)1111 ));11121113 let data = default_fungible_data();1114 create_test_item(collection_id, &data.into());11151116 // check balance (collection with id = 1, user id = 1)1117 assert_eq!(1118 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1119 51120 );11211122 // burn item1123 assert_ok!(Unique::burn_item(1124 origin1.clone(),1125 CollectionId(1),1126 TokenId(0),1127 51128 ));1129 assert_noop!(1130 Unique::burn_item(origin1, CollectionId(1), TokenId(0), 5).map_err(|e| e.error),1131 CommonError::<Test>::TokenValueTooLow1132 );11331134 assert_eq!(1135 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1136 01137 );1138 });1139}11401141#[test]1142fn burn_fungible_item_with_token_id() {1143 new_test_ext().execute_with(|| {1144 let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11451146 let origin1 = Origin::signed(1);1147 assert_ok!(Unique::add_collection_admin(1148 origin1.clone(),1149 collection_id,1150 account(2)1151 ));11521153 let data = default_fungible_data();1154 create_test_item(collection_id, &data.into());11551156 // check balance (collection with id = 1, user id = 1)1157 assert_eq!(1158 <pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1159 51160 );11611162 // Try to burn item using Token ID1163 assert_noop!(1164 Unique::burn_item(origin1, CollectionId(1), TokenId(1), 5).map_err(|e| e.error),1165 <pallet_fungible::Error::<Test>>::FungibleItemsHaveNoId1166 );1167 });1168}1169#[test]1170fn burn_refungible_item() {1171 new_test_ext().execute_with(|| {1172 let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));1173 let origin1 = Origin::signed(1);11741175 assert_ok!(Unique::set_collection_permissions(1176 origin1.clone(),1177 collection_id,1178 CollectionPermissions {1179 mint_mode: Some(true),1180 access: Some(AccessMode::AllowList),1181 nesting: None,1182 }1183 ));1184 assert_ok!(Unique::add_to_allow_list(1185 origin1.clone(),1186 collection_id,1187 account(1)1188 ));11891190 assert_ok!(Unique::add_collection_admin(1191 origin1.clone(),1192 collection_id,1193 account(2)1194 ));11951196 let data = default_re_fungible_data();1197 create_test_item(collection_id, &data.into());11981199 // check balance (collection with id = 1, user id = 2)1200 assert_eq!(1201 <pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),1202 11203 );1204 assert_eq!(1205 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1206 10231207 );12081209 // burn item1210 assert_ok!(Unique::burn_item(1211 origin1.clone(),1212 collection_id,1213 TokenId(1),1214 10231215 ));1216 assert_noop!(1217 Unique::burn_item(origin1, collection_id, TokenId(1), 1023).map_err(|e| e.error),1218 CommonError::<Test>::TokenValueTooLow1219 );12201221 assert_eq!(1222 <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1223 01224 );1225 });1226}12271228#[test]1229fn add_collection_admin() {1230 new_test_ext().execute_with(|| {1231 let collection1_id =1232 create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1233 let origin1 = Origin::signed(1);12341235 // Add collection admins1236 assert_ok!(Unique::add_collection_admin(1237 origin1.clone(),1238 collection1_id,1239 account(2)1240 ));1241 assert_ok!(Unique::add_collection_admin(1242 origin1,1243 collection1_id,1244 account(3)1245 ));12461247 // Owner is not an admin by default1248 assert_eq!(1249 <pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(1))),1250 false1251 );1252 assert!(<pallet_common::IsAdmin<Test>>::get((1253 CollectionId(1),1254 account(2)1255 )));1256 assert!(<pallet_common::IsAdmin<Test>>::get((1257 CollectionId(1),1258 account(3)1259 )));1260 });1261}12621263#[test]1264fn remove_collection_admin() {1265 new_test_ext().execute_with(|| {1266 let collection1_id =1267 create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1268 let origin1 = Origin::signed(1);12691270 // Add collection admins 2 and 31271 assert_ok!(Unique::add_collection_admin(1272 origin1.clone(),1273 collection1_id,1274 account(2)1275 ));1276 assert_ok!(Unique::add_collection_admin(1277 origin1.clone(),1278 collection1_id,1279 account(3)1280 ));12811282 assert!(<pallet_common::IsAdmin<Test>>::get((1283 CollectionId(1),1284 account(2)1285 )));1286 assert!(<pallet_common::IsAdmin<Test>>::get((1287 CollectionId(1),1288 account(3)1289 )));12901291 // remove admin 31292 assert_ok!(Unique::remove_collection_admin(1293 origin1,1294 CollectionId(1),1295 account(3)1296 ));12971298 // 2 is still admin, 3 is not an admin anymore1299 assert!(<pallet_common::IsAdmin<Test>>::get((1300 CollectionId(1),1301 account(2)1302 )));1303 assert_eq!(1304 <pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))),1305 false1306 );1307 });1308}13091310#[test]1311fn balance_of() {1312 new_test_ext().execute_with(|| {1313 let nft_collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1314 let fungible_collection_id =1315 create_test_collection(&CollectionMode::Fungible(3), CollectionId(2));1316 let re_fungible_collection_id =1317 create_test_collection(&CollectionMode::ReFungible, CollectionId(3));13181319 // check balance before1320 assert_eq!(1321 <pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1322 01323 );1324 assert_eq!(1325 <pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1326 01327 );1328 assert_eq!(1329 <pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1330 01331 );13321333 let nft_data = default_nft_data();1334 create_test_item(nft_collection_id, &nft_data.into());13351336 let fungible_data = default_fungible_data();1337 create_test_item(fungible_collection_id, &fungible_data.into());13381339 let re_fungible_data = default_re_fungible_data();1340 create_test_item(re_fungible_collection_id, &re_fungible_data.into());13411342 // check balance (collection with id = 1, user id = 1)1343 assert_eq!(1344 <pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1345 11346 );1347 assert_eq!(1348 <pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1349 51350 );1351 assert_eq!(1352 <pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1353 11354 );13551356 assert_eq!(1357 <pallet_nonfungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))),1358 true1359 );1360 assert_eq!(1361 <pallet_refungible::Owned<Test>>::get((1362 re_fungible_collection_id,1363 account(1),1364 TokenId(1)1365 )),1366 true1367 );1368 });1369}13701371#[test]1372fn approve() {1373 new_test_ext().execute_with(|| {1374 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));13751376 let data = default_nft_data();1377 create_test_item(collection_id, &data.into());13781379 let origin1 = Origin::signed(1);13801381 // approve1382 assert_ok!(Unique::approve(1383 origin1,1384 account(2),1385 CollectionId(1),1386 TokenId(1),1387 11388 ));1389 assert_eq!(1390 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1391 account(2)1392 );1393 });1394}13951396#[test]1397fn transfer_from() {1398 new_test_ext().execute_with(|| {1399 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1400 let origin1 = Origin::signed(1);1401 let origin2 = Origin::signed(2);14021403 let data = default_nft_data();1404 create_test_item(collection_id, &data.into());14051406 // approve1407 assert_ok!(Unique::approve(1408 origin1.clone(),1409 account(2),1410 CollectionId(1),1411 TokenId(1),1412 11413 ));1414 assert_eq!(1415 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1416 account(2)1417 );14181419 assert_ok!(Unique::set_collection_permissions(1420 origin1.clone(),1421 CollectionId(1),1422 CollectionPermissions {1423 mint_mode: Some(true),1424 access: Some(AccessMode::AllowList),1425 nesting: None,1426 }1427 ));1428 assert_ok!(Unique::add_to_allow_list(1429 origin1.clone(),1430 CollectionId(1),1431 account(1)1432 ));1433 assert_ok!(Unique::add_to_allow_list(1434 origin1.clone(),1435 CollectionId(1),1436 account(2)1437 ));1438 assert_ok!(Unique::add_to_allow_list(1439 origin1,1440 CollectionId(1),1441 account(3)1442 ));14431444 assert_ok!(Unique::transfer_from(1445 origin2,1446 account(1),1447 account(2),1448 CollectionId(1),1449 TokenId(1),1450 11451 ));14521453 // after transfer1454 assert_eq!(1455 <pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(1))),1456 01457 );1458 assert_eq!(1459 <pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(2))),1460 11461 );1462 });1463}14641465// #endregion14661467// Coverage tests region1468// #region14691470#[test]1471fn owner_can_add_address_to_allow_list() {1472 new_test_ext().execute_with(|| {1473 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));14741475 let origin1 = Origin::signed(1);1476 assert_ok!(Unique::add_to_allow_list(1477 origin1,1478 collection_id,1479 account(2)1480 ));1481 assert!(<pallet_common::Allowlist<Test>>::get((1482 collection_id,1483 account(2)1484 )));1485 });1486}14871488#[test]1489fn admin_can_add_address_to_allow_list() {1490 new_test_ext().execute_with(|| {1491 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1492 let origin1 = Origin::signed(1);1493 let origin2 = Origin::signed(2);14941495 assert_ok!(Unique::add_collection_admin(1496 origin1,1497 collection_id,1498 account(2)1499 ));1500 assert_ok!(Unique::add_to_allow_list(1501 origin2,1502 collection_id,1503 account(3)1504 ));1505 assert!(<pallet_common::Allowlist<Test>>::get((1506 collection_id,1507 account(3)1508 )));1509 });1510}15111512#[test]1513fn nonprivileged_user_cannot_add_address_to_allow_list() {1514 new_test_ext().execute_with(|| {1515 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15161517 let origin2 = Origin::signed(2);1518 assert_noop!(1519 Unique::add_to_allow_list(origin2, collection_id, account(3)),1520 CommonError::<Test>::NoPermission1521 );1522 });1523}15241525#[test]1526fn nobody_can_add_address_to_allow_list_of_nonexisting_collection() {1527 new_test_ext().execute_with(|| {1528 let origin1 = Origin::signed(1);15291530 assert_noop!(1531 Unique::add_to_allow_list(origin1, CollectionId(1), account(2)),1532 CommonError::<Test>::CollectionNotFound1533 );1534 });1535}15361537#[test]1538fn nobody_can_add_address_to_allow_list_of_deleted_collection() {1539 new_test_ext().execute_with(|| {1540 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15411542 let origin1 = Origin::signed(1);1543 assert_ok!(Unique::destroy_collection(origin1.clone(), collection_id));1544 assert_noop!(1545 Unique::add_to_allow_list(origin1, collection_id, account(2)),1546 CommonError::<Test>::CollectionNotFound1547 );1548 });1549}15501551// If address is already added to allow list, nothing happens1552#[test]1553fn address_is_already_added_to_allow_list() {1554 new_test_ext().execute_with(|| {1555 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1556 let origin1 = Origin::signed(1);15571558 assert_ok!(Unique::add_to_allow_list(1559 origin1.clone(),1560 collection_id,1561 account(2)1562 ));1563 assert_ok!(Unique::add_to_allow_list(1564 origin1,1565 collection_id,1566 account(2)1567 ));1568 assert!(<pallet_common::Allowlist<Test>>::get((1569 collection_id,1570 account(2)1571 )));1572 });1573}15741575#[test]1576fn owner_can_remove_address_from_allow_list() {1577 new_test_ext().execute_with(|| {1578 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15791580 let origin1 = Origin::signed(1);1581 assert_ok!(Unique::add_to_allow_list(1582 origin1.clone(),1583 collection_id,1584 account(2)1585 ));1586 assert_ok!(Unique::remove_from_allow_list(1587 origin1,1588 collection_id,1589 account(2)1590 ));1591 assert_eq!(1592 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1593 false1594 );1595 });1596}15971598#[test]1599fn admin_can_remove_address_from_allow_list() {1600 new_test_ext().execute_with(|| {1601 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1602 let origin1 = Origin::signed(1);1603 let origin2 = Origin::signed(2);16041605 // Owner adds admin1606 assert_ok!(Unique::add_collection_admin(1607 origin1.clone(),1608 collection_id,1609 account(2)1610 ));16111612 // Owner adds address 3 to allow list1613 assert_ok!(Unique::add_to_allow_list(1614 origin1,1615 collection_id,1616 account(3)1617 ));16181619 // Admin removes address 3 from allow list1620 assert_ok!(Unique::remove_from_allow_list(1621 origin2,1622 collection_id,1623 account(3)1624 ));1625 assert_eq!(1626 <pallet_common::Allowlist<Test>>::get((collection_id, account(3))),1627 false1628 );1629 });1630}16311632#[test]1633fn nonprivileged_user_cannot_remove_address_from_allow_list() {1634 new_test_ext().execute_with(|| {1635 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1636 let origin1 = Origin::signed(1);1637 let origin2 = Origin::signed(2);16381639 assert_ok!(Unique::add_to_allow_list(1640 origin1,1641 collection_id,1642 account(2)1643 ));1644 assert_noop!(1645 Unique::remove_from_allow_list(origin2, collection_id, account(2)),1646 CommonError::<Test>::NoPermission1647 );1648 assert!(<pallet_common::Allowlist<Test>>::get((1649 collection_id,1650 account(2)1651 )));1652 });1653}16541655#[test]1656fn nobody_can_remove_address_from_allow_list_of_nonexisting_collection() {1657 new_test_ext().execute_with(|| {1658 let origin1 = Origin::signed(1);16591660 assert_noop!(1661 Unique::remove_from_allow_list(origin1, CollectionId(1), account(2)),1662 CommonError::<Test>::CollectionNotFound1663 );1664 });1665}16661667#[test]1668fn nobody_can_remove_address_from_allow_list_of_deleted_collection() {1669 new_test_ext().execute_with(|| {1670 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1671 let origin1 = Origin::signed(1);1672 let origin2 = Origin::signed(2);16731674 // Add account 2 to allow list1675 assert_ok!(Unique::add_to_allow_list(1676 origin1.clone(),1677 collection_id,1678 account(2)1679 ));16801681 // Account 2 is in collection allow-list1682 assert!(<pallet_common::Allowlist<Test>>::get((1683 collection_id,1684 account(2)1685 )));16861687 // Destroy collection1688 assert_ok!(Unique::destroy_collection(origin1, collection_id));16891690 // Attempt to remove account 2 from collection allow-list => error1691 assert_noop!(1692 Unique::remove_from_allow_list(origin2, collection_id, account(2)),1693 CommonError::<Test>::CollectionNotFound1694 );16951696 // Account 2 is not found in collection allow-list anyway1697 assert_eq!(1698 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1699 false1700 );1701 });1702}17031704// If address is already removed from allow list, nothing happens1705#[test]1706fn address_is_already_removed_from_allow_list() {1707 new_test_ext().execute_with(|| {1708 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1709 let origin1 = Origin::signed(1);17101711 assert_ok!(Unique::add_to_allow_list(1712 origin1.clone(),1713 collection_id,1714 account(2)1715 ));1716 assert_ok!(Unique::remove_from_allow_list(1717 origin1.clone(),1718 collection_id,1719 account(2)1720 ));1721 assert_eq!(1722 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1723 false1724 );1725 assert_ok!(Unique::remove_from_allow_list(1726 origin1,1727 collection_id,1728 account(2)1729 ));1730 assert_eq!(1731 <pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1732 false1733 );1734 });1735}17361737// If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom (2 tests)1738#[test]1739fn allow_list_test_1() {1740 new_test_ext().execute_with(|| {1741 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));17421743 let origin1 = Origin::signed(1);17441745 let data = default_nft_data();1746 create_test_item(collection_id, &data.into());17471748 assert_ok!(Unique::set_collection_permissions(1749 origin1.clone(),1750 collection_id,1751 CollectionPermissions {1752 mint_mode: None,1753 access: Some(AccessMode::AllowList),1754 nesting: None,1755 }1756 ));1757 assert_ok!(Unique::add_to_allow_list(1758 origin1.clone(),1759 collection_id,1760 account(2)1761 ));17621763 assert_noop!(1764 Unique::transfer(origin1, account(3), CollectionId(1), TokenId(1), 1)1765 .map_err(|e| e.error),1766 CommonError::<Test>::AddressNotInAllowlist1767 );1768 });1769}17701771#[test]1772fn allow_list_test_2() {1773 new_test_ext().execute_with(|| {1774 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1775 let origin1 = Origin::signed(1);17761777 let data = default_nft_data();1778 create_test_item(collection_id, &data.into());17791780 assert_ok!(Unique::set_collection_permissions(1781 origin1.clone(),1782 collection_id,1783 CollectionPermissions {1784 mint_mode: None,1785 access: Some(AccessMode::AllowList),1786 nesting: None,1787 }1788 ));1789 assert_ok!(Unique::add_to_allow_list(1790 origin1.clone(),1791 collection_id,1792 account(1)1793 ));1794 assert_ok!(Unique::add_to_allow_list(1795 origin1.clone(),1796 collection_id,1797 account(2)1798 ));17991800 // do approve1801 assert_ok!(Unique::approve(1802 origin1.clone(),1803 account(1),1804 collection_id,1805 TokenId(1),1806 11807 ));1808 assert_eq!(1809 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1810 account(1)1811 );18121813 assert_ok!(Unique::remove_from_allow_list(1814 origin1.clone(),1815 collection_id,1816 account(1)1817 ));18181819 assert_noop!(1820 Unique::transfer_from(1821 origin1,1822 account(1),1823 account(3),1824 CollectionId(1),1825 TokenId(1),1826 11827 )1828 .map_err(|e| e.error),1829 CommonError::<Test>::AddressNotInAllowlist1830 );1831 });1832}18331834// If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom (2 tests)1835#[test]1836fn allow_list_test_3() {1837 new_test_ext().execute_with(|| {1838 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18391840 let origin1 = Origin::signed(1);18411842 let data = default_nft_data();1843 create_test_item(collection_id, &data.into());18441845 assert_ok!(Unique::set_collection_permissions(1846 origin1.clone(),1847 collection_id,1848 CollectionPermissions {1849 mint_mode: None,1850 access: Some(AccessMode::AllowList),1851 nesting: None,1852 }1853 ));1854 assert_ok!(Unique::add_to_allow_list(1855 origin1.clone(),1856 collection_id,1857 account(1)1858 ));18591860 assert_noop!(1861 Unique::transfer(origin1, account(3), collection_id, TokenId(1), 1)1862 .map_err(|e| e.error),1863 CommonError::<Test>::AddressNotInAllowlist1864 );1865 });1866}18671868#[test]1869fn allow_list_test_4() {1870 new_test_ext().execute_with(|| {1871 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18721873 let origin1 = Origin::signed(1);18741875 let data = default_nft_data();1876 create_test_item(collection_id, &data.into());18771878 assert_ok!(Unique::set_collection_permissions(1879 origin1.clone(),1880 collection_id,1881 CollectionPermissions {1882 mint_mode: None,1883 access: Some(AccessMode::AllowList),1884 nesting: None,1885 }1886 ));1887 assert_ok!(Unique::add_to_allow_list(1888 origin1.clone(),1889 collection_id,1890 account(1)1891 ));1892 assert_ok!(Unique::add_to_allow_list(1893 origin1.clone(),1894 collection_id,1895 account(2)1896 ));18971898 // do approve1899 assert_ok!(Unique::approve(1900 origin1.clone(),1901 account(1),1902 collection_id,1903 TokenId(1),1904 11905 ));1906 assert_eq!(1907 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1908 account(1)1909 );19101911 assert_ok!(Unique::remove_from_allow_list(1912 origin1.clone(),1913 collection_id,1914 account(2)1915 ));19161917 assert_noop!(1918 Unique::transfer_from(1919 origin1,1920 account(1),1921 account(3),1922 collection_id,1923 TokenId(1),1924 11925 )1926 .map_err(|e| e.error),1927 CommonError::<Test>::AddressNotInAllowlist1928 );1929 });1930}19311932// 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)1933#[test]1934fn allow_list_test_5() {1935 new_test_ext().execute_with(|| {1936 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19371938 let origin1 = Origin::signed(1);19391940 let data = default_nft_data();1941 create_test_item(collection_id, &data.into());19421943 assert_ok!(Unique::set_collection_permissions(1944 origin1.clone(),1945 collection_id,1946 CollectionPermissions {1947 mint_mode: None,1948 access: Some(AccessMode::AllowList),1949 nesting: None,1950 }1951 ));1952 assert_noop!(1953 Unique::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 1).map_err(|e| e.error),1954 CommonError::<Test>::AddressNotInAllowlist1955 );1956 });1957}19581959// If Public Access mode is set to AllowList, token transfers can’t be Approved by a non-allowlisted address (see Approve method).1960#[test]1961fn allow_list_test_6() {1962 new_test_ext().execute_with(|| {1963 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19641965 let origin1 = Origin::signed(1);19661967 let data = default_nft_data();1968 create_test_item(collection_id, &data.into());19691970 assert_ok!(Unique::set_collection_permissions(1971 origin1.clone(),1972 collection_id,1973 CollectionPermissions {1974 mint_mode: None,1975 access: Some(AccessMode::AllowList),1976 nesting: None,1977 }1978 ));19791980 // do approve1981 assert_noop!(1982 Unique::approve(origin1, account(1), CollectionId(1), TokenId(1), 1)1983 .map_err(|e| e.error),1984 CommonError::<Test>::AddressNotInAllowlist1985 );1986 });1987}19881989// If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests) and1990// tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests)1991#[test]1992fn allow_list_test_7() {1993 new_test_ext().execute_with(|| {1994 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19951996 let data = default_nft_data();1997 create_test_item(collection_id, &data.into());19981999 let origin1 = Origin::signed(1);20002001 assert_ok!(Unique::set_collection_permissions(2002 origin1.clone(),2003 collection_id,2004 CollectionPermissions {2005 mint_mode: None,2006 access: Some(AccessMode::AllowList),2007 nesting: None,2008 }2009 ));2010 assert_ok!(Unique::add_to_allow_list(2011 origin1.clone(),2012 collection_id,2013 account(1)2014 ));2015 assert_ok!(Unique::add_to_allow_list(2016 origin1.clone(),2017 collection_id,2018 account(2)2019 ));20202021 assert_ok!(Unique::transfer(2022 origin1,2023 account(2),2024 CollectionId(1),2025 TokenId(1),2026 12027 ));2028 });2029}20302031#[test]2032fn allow_list_test_8() {2033 new_test_ext().execute_with(|| {2034 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));20352036 // Create NFT for account 12037 let data = default_nft_data();2038 create_test_item(collection_id, &data.into());20392040 let origin1 = Origin::signed(1);20412042 // Toggle Allow List mode and add accounts 1 and 22043 assert_ok!(Unique::set_collection_permissions(2044 origin1.clone(),2045 collection_id,2046 CollectionPermissions {2047 mint_mode: None,2048 access: Some(AccessMode::AllowList),2049 nesting: None,2050 }2051 ));2052 assert_ok!(Unique::add_to_allow_list(2053 origin1.clone(),2054 collection_id,2055 account(1)2056 ));2057 assert_ok!(Unique::add_to_allow_list(2058 origin1.clone(),2059 collection_id,2060 account(2)2061 ));20622063 // Sself-approve account 1 for NFT 12064 assert_ok!(Unique::approve(2065 origin1.clone(),2066 account(1),2067 CollectionId(1),2068 TokenId(1),2069 12070 ));2071 assert_eq!(2072 <pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),2073 account(1)2074 );20752076 // Transfer from 1 to 22077 assert_ok!(Unique::transfer_from(2078 origin1,2079 account(1),2080 account(2),2081 CollectionId(1),2082 TokenId(1),2083 12084 ));2085 });2086}20872088// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by owner.2089#[test]2090fn allow_list_test_9() {2091 new_test_ext().execute_with(|| {2092 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2093 let origin1 = Origin::signed(1);20942095 assert_ok!(Unique::set_collection_permissions(2096 origin1.clone(),2097 collection_id,2098 CollectionPermissions {2099 mint_mode: Some(false),2100 access: Some(AccessMode::AllowList),2101 nesting: None,2102 }2103 ));21042105 let data = default_nft_data();2106 create_test_item(collection_id, &data.into());2107 });2108}21092110// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by admin.2111#[test]2112fn allow_list_test_10() {2113 new_test_ext().execute_with(|| {2114 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21152116 let origin1 = Origin::signed(1);2117 let origin2 = Origin::signed(2);21182119 assert_ok!(Unique::set_collection_permissions(2120 origin1.clone(),2121 collection_id,2122 CollectionPermissions {2123 mint_mode: Some(false),2124 access: Some(AccessMode::AllowList),2125 nesting: None,2126 }2127 ));21282129 assert_ok!(Unique::add_collection_admin(2130 origin1,2131 collection_id,2132 account(2)2133 ));21342135 assert_ok!(Unique::create_item(2136 origin2,2137 collection_id,2138 account(2),2139 default_nft_data().into()2140 ));2141 });2142}21432144// 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.2145#[test]2146fn allow_list_test_11() {2147 new_test_ext().execute_with(|| {2148 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21492150 let origin1 = Origin::signed(1);2151 let origin2 = Origin::signed(2);21522153 assert_ok!(Unique::set_collection_permissions(2154 origin1.clone(),2155 collection_id,2156 CollectionPermissions {2157 mint_mode: Some(false),2158 access: Some(AccessMode::AllowList),2159 nesting: None,2160 }2161 ));2162 assert_ok!(Unique::add_to_allow_list(2163 origin1,2164 collection_id,2165 account(2)2166 ));21672168 assert_noop!(2169 Unique::create_item(2170 origin2,2171 CollectionId(1),2172 account(2),2173 default_nft_data().into()2174 )2175 .map_err(|e| e.error),2176 CommonError::<Test>::PublicMintingNotAllowed2177 );2178 });2179}21802181// 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.2182#[test]2183fn allow_list_test_12() {2184 new_test_ext().execute_with(|| {2185 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21862187 let origin1 = Origin::signed(1);2188 let origin2 = Origin::signed(2);21892190 assert_ok!(Unique::set_collection_permissions(2191 origin1.clone(),2192 collection_id,2193 CollectionPermissions {2194 mint_mode: Some(false),2195 access: Some(AccessMode::AllowList),2196 nesting: None,2197 }2198 ));21992200 assert_noop!(2201 Unique::create_item(2202 origin2,2203 CollectionId(1),2204 account(2),2205 default_nft_data().into()2206 )2207 .map_err(|e| e.error),2208 CommonError::<Test>::PublicMintingNotAllowed2209 );2210 });2211}22122213// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by owner.2214#[test]2215fn allow_list_test_13() {2216 new_test_ext().execute_with(|| {2217 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22182219 let origin1 = Origin::signed(1);22202221 assert_ok!(Unique::set_collection_permissions(2222 origin1.clone(),2223 collection_id,2224 CollectionPermissions {2225 mint_mode: Some(true),2226 access: Some(AccessMode::AllowList),2227 nesting: None,2228 }2229 ));22302231 let data = default_nft_data();2232 create_test_item(collection_id, &data.into());2233 });2234}22352236// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by admin.2237#[test]2238fn allow_list_test_14() {2239 new_test_ext().execute_with(|| {2240 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22412242 let origin1 = Origin::signed(1);2243 let origin2 = Origin::signed(2);22442245 assert_ok!(Unique::set_collection_permissions(2246 origin1.clone(),2247 collection_id,2248 CollectionPermissions {2249 mint_mode: Some(true),2250 access: Some(AccessMode::AllowList),2251 nesting: None,2252 }2253 ));22542255 assert_ok!(Unique::add_collection_admin(2256 origin1,2257 collection_id,2258 account(2)2259 ));22602261 assert_ok!(Unique::create_item(2262 origin2,2263 collection_id,2264 account(2),2265 default_nft_data().into()2266 ));2267 });2268}22692270// 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.2271#[test]2272fn allow_list_test_15() {2273 new_test_ext().execute_with(|| {2274 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22752276 let origin1 = Origin::signed(1);2277 let origin2 = Origin::signed(2);22782279 assert_ok!(Unique::set_collection_permissions(2280 origin1.clone(),2281 collection_id,2282 CollectionPermissions {2283 mint_mode: Some(true),2284 access: Some(AccessMode::AllowList),2285 nesting: None,2286 }2287 ));22882289 assert_noop!(2290 Unique::create_item(2291 origin2,2292 collection_id,2293 account(2),2294 default_nft_data().into()2295 )2296 .map_err(|e| e.error),2297 CommonError::<Test>::AddressNotInAllowlist2298 );2299 });2300}23012302// 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.2303#[test]2304fn allow_list_test_16() {2305 new_test_ext().execute_with(|| {2306 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23072308 let origin1 = Origin::signed(1);2309 let origin2 = Origin::signed(2);23102311 assert_ok!(Unique::set_collection_permissions(2312 origin1.clone(),2313 collection_id,2314 CollectionPermissions {2315 mint_mode: Some(true),2316 access: Some(AccessMode::AllowList),2317 nesting: None,2318 }2319 ));2320 assert_ok!(Unique::add_to_allow_list(2321 origin1,2322 collection_id,2323 account(2)2324 ));23252326 assert_ok!(Unique::create_item(2327 origin2,2328 collection_id,2329 account(2),2330 default_nft_data().into()2331 ));2332 });2333}23342335// Total number of collections. Positive test2336#[test]2337fn total_number_collections_bound() {2338 new_test_ext().execute_with(|| {2339 create_test_collection(&CollectionMode::NFT, CollectionId(1));2340 });2341}23422343#[test]2344fn create_max_collections() {2345 new_test_ext().execute_with(|| {2346 for i in 1..COLLECTION_NUMBER_LIMIT {2347 create_test_collection(&CollectionMode::NFT, CollectionId(i));2348 }2349 });2350}23512352// Total number of collections. Negative test2353#[test]2354fn total_number_collections_bound_neg() {2355 new_test_ext().execute_with(|| {2356 let origin1 = Origin::signed(1);23572358 for i in 1..=COLLECTION_NUMBER_LIMIT {2359 create_test_collection(&CollectionMode::NFT, CollectionId(i));2360 }23612362 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();2363 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();2364 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();23652366 let data: CreateCollectionData<u64> = CreateCollectionData {2367 name: col_name1.try_into().unwrap(),2368 description: col_desc1.try_into().unwrap(),2369 token_prefix: token_prefix1.try_into().unwrap(),2370 mode: CollectionMode::NFT,2371 ..Default::default()2372 };23732374 // 11-th collection in chain. Expects error2375 assert_noop!(2376 Unique::create_collection_ex(origin1, data),2377 CommonError::<Test>::TotalCollectionsLimitExceeded2378 );2379 });2380}23812382// Owned tokens by a single address. Positive test2383#[test]2384fn owned_tokens_bound() {2385 new_test_ext().execute_with(|| {2386 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23872388 let data = default_nft_data();2389 create_test_item(collection_id, &data.clone().into());2390 create_test_item(collection_id, &data.into());2391 });2392}23932394// Owned tokens by a single address. Negotive test2395#[test]2396fn owned_tokens_bound_neg() {2397 new_test_ext().execute_with(|| {2398 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23992400 let origin1 = Origin::signed(1);24012402 for _ in 1..=MAX_TOKEN_OWNERSHIP {2403 let data = default_nft_data();2404 create_test_item(collection_id, &data.clone().into());2405 }24062407 let data = default_nft_data();2408 assert_noop!(2409 Unique::create_item(origin1, CollectionId(1), account(1), data.into())2410 .map_err(|e| e.error),2411 CommonError::<Test>::AccountTokenLimitExceeded2412 );2413 });2414}24152416// Number of collection admins. Positive test2417#[test]2418fn collection_admins_bound() {2419 new_test_ext().execute_with(|| {2420 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24212422 let origin1 = Origin::signed(1);24232424 assert_ok!(Unique::add_collection_admin(2425 origin1.clone(),2426 collection_id,2427 account(2)2428 ));2429 assert_ok!(Unique::add_collection_admin(2430 origin1,2431 collection_id,2432 account(3)2433 ));2434 });2435}24362437// Number of collection admins. Negotive test2438#[test]2439fn collection_admins_bound_neg() {2440 new_test_ext().execute_with(|| {2441 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24422443 let origin1 = Origin::signed(1);24442445 for i in 0..COLLECTION_ADMINS_LIMIT {2446 assert_ok!(Unique::add_collection_admin(2447 origin1.clone(),2448 collection_id,2449 account((2 + i).into())2450 ));2451 }2452 assert_noop!(2453 Unique::add_collection_admin(2454 origin1,2455 collection_id,2456 account((3 + COLLECTION_ADMINS_LIMIT).into())2457 ),2458 CommonError::<Test>::CollectionAdminCountExceeded2459 );2460 });2461}2462// #endregion24632464#[test]2465fn collection_transfer_flag_works() {2466 new_test_ext().execute_with(|| {2467 let origin1 = Origin::signed(1);24682469 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2470 assert_ok!(Unique::set_transfers_enabled_flag(2471 origin1,2472 collection_id,2473 true2474 ));24752476 let data = default_nft_data();2477 create_test_item(collection_id, &data.into());2478 assert_eq!(2479 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2480 12481 );2482 assert_eq!(2483 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2484 true2485 );24862487 let origin1 = Origin::signed(1);24882489 // default scenario2490 assert_ok!(Unique::transfer(2491 origin1,2492 account(2),2493 collection_id,2494 TokenId(1),2495 12496 ));2497 assert_eq!(2498 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2499 false2500 );2501 assert_eq!(2502 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2503 true2504 );2505 assert_eq!(2506 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2507 02508 );2509 assert_eq!(2510 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2511 12512 );2513 });2514}25152516#[test]2517fn collection_transfer_flag_works_neg() {2518 new_test_ext().execute_with(|| {2519 let origin1 = Origin::signed(1);25202521 let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2522 assert_ok!(Unique::set_transfers_enabled_flag(2523 origin1,2524 collection_id,2525 false2526 ));25272528 let data = default_nft_data();2529 create_test_item(collection_id, &data.into());2530 assert_eq!(2531 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2532 12533 );2534 assert_eq!(2535 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2536 true2537 );25382539 let origin1 = Origin::signed(1);25402541 // default scenario2542 assert_noop!(2543 Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1)2544 .map_err(|e| e.error),2545 CommonError::<Test>::TransferNotAllowed2546 );2547 assert_eq!(2548 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2549 12550 );2551 assert_eq!(2552 <pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2553 02554 );2555 assert_eq!(2556 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2557 true2558 );2559 assert_eq!(2560 <pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2561 false2562 );2563 });2564}25652566#[test]2567fn collection_sponsoring() {2568 new_test_ext().execute_with(|| {2569 // default_limits();2570 let user1 = 1_u64;2571 let user2 = 777_u64;2572 let origin1 = Origin::signed(user1);2573 let origin2 = Origin::signed(user2);2574 let account2 = account(user2);25752576 let collection_id =2577 create_test_collection_for_owner(&CollectionMode::NFT, user1, CollectionId(1));2578 assert_ok!(Unique::set_collection_sponsor(2579 origin1.clone(),2580 collection_id,2581 user12582 ));2583 assert_ok!(Unique::confirm_sponsorship(origin1.clone(), collection_id));25842585 // Expect error while have no permissions2586 assert!(Unique::create_item(2587 origin2.clone(),2588 collection_id,2589 account2.clone(),2590 default_nft_data().into()2591 )2592 .is_err());25932594 assert_ok!(Unique::set_collection_permissions(2595 origin1.clone(),2596 collection_id,2597 CollectionPermissions {2598 mint_mode: Some(true),2599 access: Some(AccessMode::AllowList),2600 nesting: None,2601 }2602 ));2603 assert_ok!(Unique::add_to_allow_list(2604 origin1.clone(),2605 collection_id,2606 account2.clone()2607 ));26082609 assert_ok!(Unique::create_item(2610 origin2,2611 collection_id,2612 account2,2613 default_nft_data().into()2614 ));2615 });2616}