difftreelog
Merge branch 'develop' into feature/NFTPAR-90
in: master
7 files changed
README.mddiffbeforeafterboth--- a/README.md
+++ b/README.md
@@ -142,6 +142,12 @@
"enable_println": "bool",
"max_subject_len": "u32"
},
+ "AccessMode": {
+ "_enum": [
+ "Normal",
+ "WhiteList"
+ ]
+ },
"CollectionMode": {
"_enum": {
"Invalid": null,
@@ -181,12 +187,13 @@
"CollectionType": {
"Owner": "AccountId",
"Mode": "CollectionMode",
- "Access": "u8",
+ "Access": "AccessMode",
"DecimalPoints": "u32",
"Name": "Vec<u16>",
"Description": "Vec<u16>",
"TokenPrefix": "Vec<u8>",
"CustomDataSize": "u32",
+ "MintMode": "bool",
"OffchainSchema": "Vec<u8>",
"Sponsor": "AccountId",
"UnconfirmedSponsor": "AccountId"
@@ -196,4 +203,5 @@
"LookupSource": "AccountId",
"Weight": "u64"
}
+
```
\ No newline at end of file
node/src/chain_spec.rsdiffbeforeafterboth--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -1,8 +1,9 @@
-use nft_runtime::{
- AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig,
- SystemConfig, WASM_BINARY,
-};
-use nft_runtime::{ContractsConfig, ContractsSchedule};
+// use nft_runtime::{
+// AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig,
+// SystemConfig, WASM_BINARY,
+// };
+// use nft_runtime::{ContractsConfig, ContractsSchedule, NftConfig, CollectionType};
+use nft_runtime::*;
use sc_service::ChainType;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
use sp_core::{sr25519, Pair, Public};
@@ -128,6 +129,25 @@
.collect(),
}),
sudo: Some(SudoConfig { key: root_key }),
+ nft: Some(NftConfig {
+ collection: vec![(1, CollectionType {
+ owner: get_account_id_from_seed::<sr25519::Public>("Alice"),
+ mode: CollectionMode::NFT(50),
+ access: AccessMode::Normal,
+ decimal_points: 0,
+ name: vec!(),
+ description: vec!(),
+ token_prefix: vec!(),
+ custom_data_size: 50,
+ mint_mode: false,
+ offchain_schema: vec!(),
+ sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),
+ unconfirmed_sponsor: get_account_id_from_seed::<sr25519::Public>("Alice"),
+ })],
+ nft_item_id: vec!(),
+ fungible_item_id: vec!(),
+ refungible_item_id: vec!(),
+ }),
contracts: Some(ContractsConfig {
current_schedule: ContractsSchedule {
enable_println,
pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -1,7 +1,8 @@
#![cfg_attr(not(feature = "std"), no_std)]
-/// For more guidance on Substrate FRAME, see the example pallet
-/// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs
+#[cfg(feature = "std")]
+pub use serde::*;
+
use codec::{Decode, Encode};
pub use frame_support::{
construct_runtime, decl_event, decl_module, decl_storage,
@@ -32,7 +33,6 @@
},
FixedPointOperand, FixedU128,
};
-use sp_std::prelude::*;
#[cfg(test)]
mod mock;
@@ -40,7 +40,11 @@
#[cfg(test)]
mod tests;
-#[derive(Encode, Decode, Debug, Eq, Clone, PartialEq)]
+// Structs
+// #region
+
+#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum CollectionMode {
Invalid,
// custom data size
@@ -62,7 +66,8 @@
}
}
-#[derive(Encode, Decode, Debug, Clone, PartialEq)]
+#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum AccessMode {
Normal,
WhiteList,
@@ -79,15 +84,15 @@
}
}
-#[derive(Encode, Decode, Default, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Ownership<AccountId> {
pub owner: AccountId,
pub fraction: u128,
}
-#[derive(Encode, Decode, Default, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct CollectionType<AccountId> {
pub owner: AccountId,
pub mode: CollectionMode,
@@ -97,51 +102,52 @@
pub description: Vec<u16>, // 256 include null escape char
pub token_prefix: Vec<u8>, // 16 include null escape char
pub custom_data_size: u32,
+ pub mint_mode: bool,
pub offchain_schema: Vec<u8>,
pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender
pub unconfirmed_sponsor: AccountId, // Sponsor address that has not yet confirmed sponsorship
}
-#[derive(Encode, Decode, Default, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct CollectionAdminsType<AccountId> {
pub admin: AccountId,
pub collection_id: u64,
}
-#[derive(Encode, Decode, Default, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct NftItemType<AccountId> {
pub collection: u64,
pub owner: AccountId,
pub data: Vec<u8>,
}
-#[derive(Encode, Decode, Default, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct FungibleItemType<AccountId> {
pub collection: u64,
pub owner: AccountId,
pub value: u128,
}
-#[derive(Encode, Decode, Default, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ReFungibleItemType<AccountId> {
pub collection: u64,
pub owner: Vec<Ownership<AccountId>>,
pub data: Vec<u8>,
}
-#[derive(Encode, Decode, Default, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ApprovePermissions<AccountId> {
pub approved: AccountId,
pub amount: u64,
}
-#[derive(Encode, Decode, Default, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Debug))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct VestingItem<AccountId, Moment> {
pub sender: AccountId,
pub recipient: AccountId,
@@ -155,6 +161,8 @@
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
+// #endregion
+
decl_storage! {
trait Store for Module<T: Trait> as Nft {
@@ -164,7 +172,7 @@
ChainVersion: u64;
ItemListIndex: map hasher(blake2_128_concat) u64 => u64;
- pub Collection get(fn collection): map hasher(identity) u64 => CollectionType<T::AccountId>;
+ pub Collection get(fn collection) config(): map hasher(identity) u64 => CollectionType<T::AccountId>;
pub AdminList get(fn admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;
pub WhiteList get(fn white_list): map hasher(identity) u64 => Vec<T::AccountId>;
@@ -175,12 +183,9 @@
pub ApprovedList get(fn approved): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) (u64, T::AccountId) => Vec<ApprovePermissions<T::AccountId>>;
/// Item collections
- pub NftItemList get(fn nft_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => NftItemType<T::AccountId>;
- pub FungibleItemList get(fn fungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType<T::AccountId>;
- pub ReFungibleItemList get(fn refungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType<T::AccountId>;
-
- // Active vesting list
- // pub VestingList get(fn vesting): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => VestingItem<T::AccountId, T::Moment>;
+ pub NftItemList get(fn nft_item_id) config(): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => NftItemType<T::AccountId>;
+ pub FungibleItemList get(fn fungible_item_id) config(): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType<T::AccountId>;
+ pub ReFungibleItemList get(fn refungible_item_id) config(): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType<T::AccountId>;
/// Index list
pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;
@@ -189,6 +194,26 @@
pub ContractSponsor get(fn contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;
pub UnconfirmedContractSponsor get(fn unconfirmed_contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;
}
+ add_extra_genesis {
+ build(|config: &GenesisConfig<T>| {
+ // Modification of storage
+ for (_num, _c) in &config.collection {
+ <Module<T>>::init_collection(_c);
+ }
+
+ for (_num, _q, _i) in &config.nft_item_id {
+ <Module<T>>::init_nft_token(_i);
+ }
+
+ for (_num, _q, _i) in &config.fungible_item_id {
+ <Module<T>>::init_fungible_token(_i);
+ }
+
+ for (_num, _q, _i) in &config.refungible_item_id {
+ <Module<T>>::init_refungible_token(_i);
+ }
+ })
+ }
}
decl_event!(
@@ -209,7 +234,7 @@
fn on_initialize(now: T::BlockNumber) -> Weight {
- if ChainVersion::get() == 0
+ if ChainVersion::get() < 2
{
let value = NextCollectionID::get();
CreatedCollectionCount::put(value);
@@ -224,11 +249,11 @@
// @param customDataSz size of custom data in each collection item
// returns collection ID
#[weight = 0]
- pub fn create_collection( origin,
- collection_name: Vec<u16>,
- collection_description: Vec<u16>,
- token_prefix: Vec<u8>,
- mode: CollectionMode) -> DispatchResult {
+ pub fn create_collection(origin,
+ collection_name: Vec<u16>,
+ collection_description: Vec<u16>,
+ token_prefix: Vec<u8>,
+ mode: CollectionMode) -> DispatchResult {
// Anyone can create a collection
let who = ensure_signed(origin)?;
@@ -271,6 +296,7 @@
owner: who.clone(),
name: name,
mode: mode.clone(),
+ mint_mode: false,
access: AccessMode::Normal,
description: description,
decimal_points: decimal_points,
@@ -309,6 +335,73 @@
}
#[weight = 0]
+ pub fn add_to_white_list(origin, collection_id: u64, address: T::AccountId) -> DispatchResult{
+
+ let sender = ensure_signed(origin)?;
+ Self::check_owner_or_admin_permissions(collection_id, sender)?;
+
+ let mut white_list_collection: Vec<T::AccountId>;
+ if <WhiteList<T>>::contains_key(collection_id) {
+ white_list_collection = <WhiteList<T>>::get(collection_id);
+ if !white_list_collection.contains(&address.clone())
+ {
+ white_list_collection.push(address.clone());
+ }
+ }
+ else {
+ white_list_collection = Vec::new();
+ white_list_collection.push(address.clone());
+ }
+
+ <WhiteList<T>>::insert(collection_id, white_list_collection);
+ Ok(())
+ }
+
+ #[weight = 0]
+ pub fn remove_from_white_list(origin, collection_id: u64, address: T::AccountId) -> DispatchResult{
+
+ let sender = ensure_signed(origin)?;
+ Self::check_owner_or_admin_permissions(collection_id, sender)?;
+
+ if <WhiteList<T>>::contains_key(collection_id) {
+ let mut white_list_collection = <WhiteList<T>>::get(collection_id);
+ if white_list_collection.contains(&address.clone())
+ {
+ white_list_collection.retain(|i| *i != address.clone());
+ <WhiteList<T>>::insert(collection_id, white_list_collection);
+ }
+ }
+
+ Ok(())
+ }
+
+ #[weight = 0]
+ pub fn set_public_access_mode(origin, collection_id: u64, mode: AccessMode) -> DispatchResult
+ {
+ let sender = ensure_signed(origin)?;
+
+ Self::check_owner_permissions(collection_id, sender)?;
+ let mut target_collection = <Collection<T>>::get(collection_id);
+ target_collection.access = mode;
+ <Collection<T>>::insert(collection_id, target_collection);
+
+ Ok(())
+ }
+
+ #[weight = 0]
+ pub fn set_mint_permission(origin, collection_id: u64, mint_permission: bool) -> DispatchResult
+ {
+ let sender = ensure_signed(origin)?;
+
+ Self::check_owner_permissions(collection_id, sender)?;
+ let mut target_collection = <Collection<T>>::get(collection_id);
+ target_collection.mint_mode = mint_permission;
+ <Collection<T>>::insert(collection_id, target_collection);
+
+ Ok(())
+ }
+
+ #[weight = 0]
pub fn change_collection_owner(origin, collection_id: u64, new_owner: T::AccountId) -> DispatchResult {
let sender = ensure_signed(origin)?;
@@ -405,9 +498,14 @@
pub fn create_item(origin, collection_id: u64, properties: Vec<u8>, owner: T::AccountId) -> DispatchResult {
let sender = ensure_signed(origin)?;
+ Self::collection_exists(collection_id)?;
let target_collection = <Collection<T>>::get(collection_id);
- Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;
+ if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {
+ ensure!(target_collection.mint_mode == true, "Collection is not in mint mode");
+ Self::check_white_list(collection_id, owner.clone())?;
+ }
+
match target_collection.mode
{
CollectionMode::NFT(_) => {
@@ -469,13 +567,18 @@
pub fn burn_item(origin, collection_id: u64, item_id: u64) -> DispatchResult {
let sender = ensure_signed(origin)?;
- let item_owner = Self::is_item_owner(sender.clone(), collection_id, item_id);
- if !item_owner
- {
- Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;
- }
+ Self::collection_exists(collection_id)?;
+
+ // Transfer permissions check
let target_collection = <Collection<T>>::get(collection_id);
+ ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
+ Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ "Only item owner, collection owner and admins can modify item");
+ if target_collection.access == AccessMode::WhiteList {
+ Self::check_white_list(collection_id, sender.clone())?;
+ }
+
match target_collection.mode
{
CollectionMode::NFT(_) => Self::burn_nft_item(collection_id, item_id)?,
@@ -494,11 +597,18 @@
pub fn transfer(origin, recipient: T::AccountId, collection_id: u64, item_id: u64, value: u64) -> DispatchResult {
let sender = ensure_signed(origin)?;
- ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id), "Only item owner can call transfer method");
+ // Transfer permissions check
let target_collection = <Collection<T>>::get(collection_id);
+ ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
+ Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ "Only item owner, collection owner and admins can modify item");
- // TODO: implement other modes
+ if target_collection.access == AccessMode::WhiteList {
+ Self::check_white_list(collection_id, sender.clone())?;
+ Self::check_white_list(collection_id, recipient.clone())?;
+ }
+
match target_collection.mode
{
CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient)?,
@@ -515,11 +625,20 @@
let sender = ensure_signed(origin)?;
+ // Transfer permissions check
+ let target_collection = <Collection<T>>::get(collection_id);
+ ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
+ Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ "Only item owner, collection owner and admins can approve");
+
+ if target_collection.access == AccessMode::WhiteList {
+ Self::check_white_list(collection_id, sender.clone())?;
+ Self::check_white_list(collection_id, approved.clone())?;
+ }
+
// amount param stub
let amount = 100000000;
- ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id), "Only item owner can call transfer method");
-
let list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, sender.clone()));
if list_exists {
@@ -544,25 +663,31 @@
pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: u64, item_id: u64, value: u64 ) -> DispatchResult {
let sender = ensure_signed(origin)?;
- let approved_list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, from.clone()));
- if approved_list_exists
- {
+ let mut appoved_transfer = false;
+
+ // Check approve
+ if <ApprovedList<T>>::contains_key(collection_id, (item_id, from.clone())) {
let list_itm = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()));
let opt_item = list_itm.iter().find(|i| i.approved == sender.clone());
- ensure!(opt_item.is_some(), "No approve found");
+ appoved_transfer = opt_item.is_some();
ensure!(opt_item.unwrap().amount >= value, "Requested value more than approved");
+ }
+
+ // Transfer permissions check
+ let target_collection = <Collection<T>>::get(collection_id);
+ ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ "Only item owner, collection owner and admins can modify items");
- // remove approve
- let approve_list: Vec<ApprovePermissions<T::AccountId>> = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()))
- .into_iter().filter(|i| i.approved != sender.clone()).collect();
- <ApprovedList<T>>::insert(collection_id, (item_id, from.clone()), approve_list);
- }
- else
- {
- Self::check_owner_or_admin_permissions(collection_id, sender)?;
+ if target_collection.access == AccessMode::WhiteList {
+ Self::check_white_list(collection_id, sender.clone())?;
+ Self::check_white_list(collection_id, recipient.clone())?;
}
- let target_collection = <Collection<T>>::get(collection_id);
+ // remove approve
+ let approve_list: Vec<ApprovePermissions<T::AccountId>> = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()))
+ .into_iter().filter(|i| i.approved != sender.clone()).collect();
+ <ApprovedList<T>>::insert(collection_id, (item_id, from.clone()), approve_list);
+
match target_collection.mode
{
@@ -675,11 +800,7 @@
Ok(())
}
- fn burn_refungible_item(
- collection_id: u64,
- item_id: u64,
- owner: T::AccountId,
- ) -> DispatchResult {
+ fn burn_refungible_item(collection_id: u64, item_id: u64, owner: T::AccountId) -> DispatchResult {
ensure!(
<ReFungibleItemList<T>>::contains_key(collection_id, item_id),
"Item does not exists"
@@ -770,25 +891,27 @@
Ok(())
}
- fn check_owner_or_admin_permissions(
- collection_id: u64,
- subject: T::AccountId,
- ) -> DispatchResult {
- Self::collection_exists(collection_id)?;
+ fn is_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> bool {
let target_collection = <Collection<T>>::get(collection_id);
- let is_owner = subject == target_collection.owner;
-
- let no_perm_mes = "You do not have permissions to modify this collection";
+ let mut result: bool = subject == target_collection.owner;
let exists = <AdminList<T>>::contains_key(collection_id);
- if !is_owner {
- ensure!(exists, no_perm_mes);
- ensure!(
- <AdminList<T>>::get(collection_id).contains(&subject),
- no_perm_mes
- );
+ if !result & exists {
+ if <AdminList<T>>::get(collection_id).contains(&subject) {
+ result = true
+ }
}
+
+ result
+ }
+
+ fn check_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> DispatchResult {
+
+ Self::collection_exists(collection_id)?;
+ let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());
+
+ ensure!(result, "You do not have permissions to modify this collection");
Ok(())
}
@@ -812,6 +935,16 @@
}
}
+ fn check_white_list(collection_id: u64, address: T::AccountId) -> DispatchResult {
+
+ let mes = "Address is not in white list";
+ ensure!(<WhiteList<T>>::contains_key(collection_id), mes);
+ let wl = <WhiteList<T>>::get(collection_id);
+ ensure!(wl.contains(&address.clone()), mes);
+
+ Ok(())
+ }
+
fn transfer_fungible(
collection_id: u64,
item_id: u64,
@@ -819,6 +952,12 @@
owner: T::AccountId,
new_owner: T::AccountId,
) -> DispatchResult {
+
+ ensure!(
+ <FungibleItemList<T>>::contains_key(collection_id, item_id),
+ "Item not exists"
+ );
+
let full_item = <FungibleItemList<T>>::get(collection_id, item_id);
let amount = full_item.value;
@@ -903,6 +1042,12 @@
owner: T::AccountId,
new_owner: T::AccountId,
) -> DispatchResult {
+
+ ensure!(
+ <ReFungibleItemList<T>>::contains_key(collection_id, item_id),
+ "Item not exists"
+ );
+
let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);
let item = full_item
.owner
@@ -983,6 +1128,12 @@
sender: T::AccountId,
new_owner: T::AccountId,
) -> DispatchResult {
+
+ ensure!(
+ <NftItemList<T>>::contains_key(collection_id, item_id),
+ "Item not exists"
+ );
+
let mut item = <NftItemList<T>>::get(collection_id, item_id);
ensure!(
@@ -1014,6 +1165,80 @@
Ok(())
}
+ fn init_collection(item: &CollectionType<T::AccountId>){
+
+ // check params
+ assert!(item.decimal_points <= 4, "decimal_points parameter must be lower than 4");
+ assert!(item.name.len() <= 64, "Collection name can not be longer than 63 char");
+ assert!(item.name.len() <= 256, "Collection description can not be longer than 255 char");
+ assert!(item.token_prefix.len() <= 16, "Token prefix can not be longer than 15 char");
+
+ // Generate next collection ID
+ let next_id = CreatedCollectionCount::get()
+ .checked_add(1)
+ .expect("collection id error");
+
+ CreatedCollectionCount::put(next_id);
+ }
+
+ fn init_nft_token(item: &NftItemType<T::AccountId>){
+
+ let current_index = <ItemListIndex>::get(item.collection)
+ .checked_add(1)
+ .expect("Item list index id error");
+
+ let item_owner = item.owner.clone();
+ let collection_id = item.collection.clone();
+ Self::add_token_index(collection_id, current_index, item.owner.clone()).unwrap();
+
+ <ItemListIndex>::insert(collection_id, current_index);
+
+ // Update balance
+ let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())
+ .checked_add(1)
+ .unwrap();
+ <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);
+ }
+
+ fn init_fungible_token(item: &FungibleItemType<T::AccountId>){
+
+ let current_index = <ItemListIndex>::get(item.collection)
+ .checked_add(1)
+ .expect("Item list index id error");
+ let owner = item.owner.clone();
+ let value = item.value as u64;
+
+ Self::add_token_index(item.collection, current_index, owner.clone()).unwrap();
+
+ <ItemListIndex>::insert(item.collection, current_index);
+
+ // Update balance
+ let new_balance = <Balance<T>>::get(item.collection, owner.clone())
+ .checked_add(value)
+ .unwrap();
+ <Balance<T>>::insert(item.collection, owner.clone(), new_balance);
+ }
+
+ fn init_refungible_token(item: &ReFungibleItemType<T::AccountId>){
+
+ let current_index = <ItemListIndex>::get(item.collection)
+ .checked_add(1)
+ .expect("Item list index id error");
+
+ let value = item.owner.first().unwrap().fraction as u64;
+ let owner = item.owner.first().unwrap().owner.clone();
+
+ Self::add_token_index(item.collection, current_index, owner.clone()).unwrap();
+
+ <ItemListIndex>::insert(item.collection, current_index);
+
+ // Update balance
+ let new_balance = <Balance<T>>::get(item.collection, owner.clone())
+ .checked_add(value)
+ .unwrap();
+ <Balance<T>>::insert(item.collection, owner.clone(), new_balance);
+ }
+
fn add_token_index(collection_id: u64, item_index: u64, owner: T::AccountId) -> DispatchResult {
let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.clone());
if list_exists {
@@ -1068,6 +1293,7 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// Economic models
+// #region
/// Fee multiplier.
pub type Multiplier = FixedU128;
@@ -1262,3 +1488,4 @@
Ok(())
}
}
+// #endregion
\ No newline at end of file
pallets/nft/src/tests.rsdiffbeforeafterboth1// Tests to be written here2use crate::mock::*;3use crate::{ApprovePermissions, CollectionMode, Ownership};4use frame_support::{assert_noop, assert_ok};56#[test]7fn create_nft_item() {8 new_test_ext().execute_with(|| {9 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();10 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();11 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();12 let mode: CollectionMode = CollectionMode::NFT(2000);1314 let origin1 = Origin::signed(1);15 assert_ok!(TemplateModule::create_collection(16 origin1.clone(),17 col_name1.clone(),18 col_desc1.clone(),19 token_prefix1.clone(),20 mode21 ));22 assert_eq!(TemplateModule::collection(1).owner, 1);2324 assert_ok!(TemplateModule::create_item(25 origin1.clone(),26 1,27 [1, 2, 3].to_vec(),28 129 ));30 assert_eq!(TemplateModule::nft_item_id(1, 1).data, [1, 2, 3].to_vec());31 });32}3334#[test]35fn create_refungible_item() {36 new_test_ext().execute_with(|| {37 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();38 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();39 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();40 let mode: CollectionMode = CollectionMode::ReFungible(2000, 3);4142 let origin1 = Origin::signed(1);43 assert_ok!(TemplateModule::create_collection(44 origin1.clone(),45 col_name1.clone(),46 col_desc1.clone(),47 token_prefix1.clone(),48 mode49 ));50 assert_eq!(TemplateModule::collection(1).owner, 1);5152 assert_ok!(TemplateModule::create_item(53 origin1.clone(),54 1,55 [1, 2, 3].to_vec(),56 157 ));58 assert_eq!(59 TemplateModule::refungible_item_id(1, 1).data,60 [1, 2, 3].to_vec()61 );62 assert_eq!(63 TemplateModule::refungible_item_id(1, 1).owner[0],64 Ownership {65 owner: 1,66 fraction: 100067 }68 );69 });70}7172#[test]73fn create_fungible_item() {74 new_test_ext().execute_with(|| {75 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();76 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();77 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();78 let mode: CollectionMode = CollectionMode::Fungible(3);7980 let origin1 = Origin::signed(1);81 assert_ok!(TemplateModule::create_collection(82 origin1.clone(),83 col_name1.clone(),84 col_desc1.clone(),85 token_prefix1.clone(),86 mode87 ));88 assert_eq!(TemplateModule::collection(1).owner, 1);8990 assert_ok!(TemplateModule::create_item(91 origin1.clone(),92 1,93 [].to_vec(),94 195 ));96 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 1);97 assert_eq!(TemplateModule::balance_count(1, 1), 1000);98 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);99 });100}101102#[test]103fn transfer_fungible_item() {104 new_test_ext().execute_with(|| {105 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();106 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();107 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();108 let mode: CollectionMode = CollectionMode::Fungible(3);109110 let origin1 = Origin::signed(1);111 let origin2 = Origin::signed(2);112 assert_ok!(TemplateModule::create_collection(113 origin1.clone(),114 col_name1.clone(),115 col_desc1.clone(),116 token_prefix1.clone(),117 mode118 ));119 assert_eq!(TemplateModule::collection(1).owner, 1);120121 assert_ok!(TemplateModule::create_item(122 origin1.clone(),123 1,124 [].to_vec(),125 1126 ));127 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 1);128 assert_eq!(TemplateModule::balance_count(1, 1), 1000);129 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);130131 // change owner scenario132 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));133 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);134 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 1000);135 assert_eq!(TemplateModule::balance_count(1, 1), 0);136 assert_eq!(TemplateModule::balance_count(1, 2), 1000);137 assert_eq!(TemplateModule::address_tokens(1, 1), []);138 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);139140 // split item scenario141 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));142 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);143 assert_eq!(TemplateModule::fungible_item_id(1, 2).owner, 3);144 assert_eq!(TemplateModule::balance_count(1, 2), 500);145 assert_eq!(TemplateModule::balance_count(1, 3), 500);146 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);147 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);148149 // split item and new owner has account scenario150 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));151 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 300);152 assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 700);153 assert_eq!(TemplateModule::balance_count(1, 2), 300);154 assert_eq!(TemplateModule::balance_count(1, 3), 700);155 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);156 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);157 });158}159160#[test]161fn transfer_refungible_item() {162 new_test_ext().execute_with(|| {163 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();164 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();165 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();166 let mode: CollectionMode = CollectionMode::ReFungible(2000, 3);167168 let origin1 = Origin::signed(1);169 let origin2 = Origin::signed(2);170 assert_ok!(TemplateModule::create_collection(171 origin1.clone(),172 col_name1.clone(),173 col_desc1.clone(),174 token_prefix1.clone(),175 mode176 ));177 assert_eq!(TemplateModule::collection(1).owner, 1);178179 assert_ok!(TemplateModule::create_item(180 origin1.clone(),181 1,182 [1, 2, 3].to_vec(),183 1184 ));185 assert_eq!(186 TemplateModule::refungible_item_id(1, 1).data,187 [1, 2, 3].to_vec()188 );189 assert_eq!(190 TemplateModule::refungible_item_id(1, 1).owner[0],191 Ownership {192 owner: 1,193 fraction: 1000194 }195 );196 assert_eq!(TemplateModule::balance_count(1, 1), 1000);197 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);198199 // change owner scenario200 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));201 assert_eq!(202 TemplateModule::refungible_item_id(1, 1).owner[0],203 Ownership {204 owner: 2,205 fraction: 1000206 }207 );208 assert_eq!(TemplateModule::balance_count(1, 1), 0);209 assert_eq!(TemplateModule::balance_count(1, 2), 1000);210 assert_eq!(TemplateModule::address_tokens(1, 1), []);211 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);212213 // split item scenario214 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));215 assert_eq!(216 TemplateModule::refungible_item_id(1, 1).owner[0],217 Ownership {218 owner: 2,219 fraction: 500220 }221 );222 assert_eq!(223 TemplateModule::refungible_item_id(1, 1).owner[1],224 Ownership {225 owner: 3,226 fraction: 500227 }228 );229 assert_eq!(TemplateModule::balance_count(1, 2), 500);230 assert_eq!(TemplateModule::balance_count(1, 3), 500);231 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);232 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);233234 // split item and new owner has account scenario235 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));236 assert_eq!(237 TemplateModule::refungible_item_id(1, 1).owner[0],238 Ownership {239 owner: 2,240 fraction: 300241 }242 );243 assert_eq!(244 TemplateModule::refungible_item_id(1, 1).owner[1],245 Ownership {246 owner: 3,247 fraction: 700248 }249 );250 assert_eq!(TemplateModule::balance_count(1, 2), 300);251 assert_eq!(TemplateModule::balance_count(1, 3), 700);252 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);253 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);254 });255}256257#[test]258fn transfer_nft_item() {259 new_test_ext().execute_with(|| {260 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();261 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();262 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();263 let mode: CollectionMode = CollectionMode::NFT(2000);264265 let origin1 = Origin::signed(1);266 assert_ok!(TemplateModule::create_collection(267 origin1.clone(),268 col_name1.clone(),269 col_desc1.clone(),270 token_prefix1.clone(),271 mode272 ));273 assert_eq!(TemplateModule::collection(1).owner, 1);274275 assert_ok!(TemplateModule::create_item(276 origin1.clone(),277 1,278 [1, 2, 3].to_vec(),279 1280 ));281 assert_eq!(TemplateModule::nft_item_id(1, 1).data, [1, 2, 3].to_vec());282 assert_eq!(TemplateModule::balance_count(1, 1), 1);283 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);284285 // default scenario286 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));287 assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2);288 assert_eq!(TemplateModule::balance_count(1, 1), 0);289 assert_eq!(TemplateModule::balance_count(1, 2), 1);290 assert_eq!(TemplateModule::address_tokens(1, 1), []);291 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);292 });293}294295#[test]296fn nft_approve_and_transfer_from() {297 new_test_ext().execute_with(|| {298 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();299 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();300 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();301 let mode: CollectionMode = CollectionMode::NFT(2000);302303 let origin1 = Origin::signed(1);304 let origin2 = Origin::signed(2);305 assert_ok!(TemplateModule::create_collection(306 origin1.clone(),307 col_name1.clone(),308 col_desc1.clone(),309 token_prefix1.clone(),310 mode311 ));312 assert_eq!(TemplateModule::collection(1).owner, 1);313314 assert_ok!(TemplateModule::create_item(315 origin1.clone(),316 1,317 [1, 2, 3].to_vec(),318 1319 ));320 assert_eq!(TemplateModule::nft_item_id(1, 1).data, [1, 2, 3].to_vec());321 assert_eq!(TemplateModule::balance_count(1, 1), 1);322 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);323324 assert_noop!(325 TemplateModule::transfer_from(origin2.clone(), 1, 3, 1, 1, 1),326 "You do not have permissions to modify this collection"327 );328329 // do approve330 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));331 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);332 assert_ok!(TemplateModule::approve(origin1.clone(), 10, 1, 1));333 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);334 assert_eq!(335 TemplateModule::approved(1, (1, 1))[0],336 ApprovePermissions {337 approved: 2,338 amount: 100000000339 }340 );341342 assert_ok!(TemplateModule::transfer_from(343 origin2.clone(),344 1,345 3,346 1,347 1,348 1349 ));350 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);351 });352}353354#[test]355fn refungible_approve_and_transfer_from() {356 new_test_ext().execute_with(|| {357 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();358 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();359 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();360 let mode: CollectionMode = CollectionMode::ReFungible(2000, 3);361362 let origin1 = Origin::signed(1);363 let origin2 = Origin::signed(2);364 assert_ok!(TemplateModule::create_collection(365 origin1.clone(),366 col_name1.clone(),367 col_desc1.clone(),368 token_prefix1.clone(),369 mode370 ));371 assert_eq!(TemplateModule::collection(1).owner, 1);372373 assert_ok!(TemplateModule::create_item(374 origin1.clone(),375 1,376 [1, 2, 3].to_vec(),377 1378 ));379 assert_eq!(380 TemplateModule::refungible_item_id(1, 1).data,381 [1, 2, 3].to_vec()382 );383 assert_eq!(384 TemplateModule::refungible_item_id(1, 1).owner[0],385 Ownership {386 owner: 1,387 fraction: 1000388 }389 );390 assert_eq!(TemplateModule::balance_count(1, 1), 1000);391 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);392393 assert_noop!(394 TemplateModule::transfer_from(origin2.clone(), 1, 3, 1, 1, 1),395 "You do not have permissions to modify this collection"396 );397398 // do approve399 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));400 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);401 assert_ok!(TemplateModule::approve(origin1.clone(), 10, 1, 1));402 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);403 assert_eq!(404 TemplateModule::approved(1, (1, 1))[0],405 ApprovePermissions {406 approved: 2,407 amount: 100000000408 }409 );410411 assert_ok!(TemplateModule::transfer_from(412 origin2.clone(),413 1,414 3,415 1,416 1,417 100418 ));419 assert_eq!(TemplateModule::balance_count(1, 1), 900);420 assert_eq!(TemplateModule::balance_count(1, 3), 100);421 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);422 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);423424 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);425 assert_eq!(426 TemplateModule::approved(1, (1, 1))[0],427 ApprovePermissions {428 approved: 10,429 amount: 100000000430 }431 );432 });433}434435#[test]436fn fungible_approve_and_transfer_from() {437 new_test_ext().execute_with(|| {438 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();439 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();440 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();441 let mode: CollectionMode = CollectionMode::Fungible(3);442443 let origin1 = Origin::signed(1);444 let origin2 = Origin::signed(2);445 assert_ok!(TemplateModule::create_collection(446 origin1.clone(),447 col_name1.clone(),448 col_desc1.clone(),449 token_prefix1.clone(),450 mode451 ));452 assert_eq!(TemplateModule::collection(1).owner, 1);453454 assert_ok!(TemplateModule::create_item(455 origin1.clone(),456 1,457 [].to_vec(),458 1459 ));460 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 1);461 assert_eq!(TemplateModule::balance_count(1, 1), 1000);462 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);463464 assert_noop!(465 TemplateModule::transfer_from(origin2.clone(), 1, 3, 1, 1, 1),466 "You do not have permissions to modify this collection"467 );468469 // do approve470 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));471 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);472 assert_ok!(TemplateModule::approve(origin1.clone(), 10, 1, 1));473 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);474 assert_eq!(475 TemplateModule::approved(1, (1, 1))[0],476 ApprovePermissions {477 approved: 2,478 amount: 100000000479 }480 );481482 assert_ok!(TemplateModule::transfer_from(483 origin2.clone(),484 1,485 3,486 1,487 1,488 100489 ));490 assert_eq!(TemplateModule::balance_count(1, 1), 900);491 assert_eq!(TemplateModule::balance_count(1, 3), 100);492 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);493 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);494495 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);496 assert_eq!(497 TemplateModule::approved(1, (1, 1))[0],498 ApprovePermissions {499 approved: 10,500 amount: 100000000501 }502 );503504 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));505 assert_ok!(TemplateModule::transfer_from(506 origin2.clone(),507 1,508 3,509 1,510 1,511 900512 ));513 assert_eq!(TemplateModule::balance_count(1, 1), 0);514 assert_eq!(TemplateModule::balance_count(1, 3), 1000);515 assert_eq!(TemplateModule::address_tokens(1, 1), []);516 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);517518 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);519 });520}521522#[test]523fn change_collection_owner() {524 new_test_ext().execute_with(|| {525 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();526 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();527 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();528 let mode: CollectionMode = CollectionMode::NFT(2000);529530 let origin1 = Origin::signed(1);531 assert_ok!(TemplateModule::create_collection(532 origin1.clone(),533 col_name1.clone(),534 col_desc1.clone(),535 token_prefix1.clone(),536 mode537 ));538 assert_ok!(TemplateModule::change_collection_owner(539 origin1.clone(),540 1,541 2542 ));543 assert_eq!(TemplateModule::collection(1).owner, 2);544 });545}546547#[test]548fn destroy_collection() {549 new_test_ext().execute_with(|| {550 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();551 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();552 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();553 let mode: CollectionMode = CollectionMode::NFT(2000);554555 let origin1 = Origin::signed(1);556 assert_ok!(TemplateModule::create_collection(557 origin1.clone(),558 col_name1.clone(),559 col_desc1.clone(),560 token_prefix1.clone(),561 mode562 ));563 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), 1));564 });565}566567#[test]568fn burn_nft_item() {569 new_test_ext().execute_with(|| {570 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();571 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();572 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();573 let mode: CollectionMode = CollectionMode::NFT(2000);574575 let origin1 = Origin::signed(1);576 let origin2 = Origin::signed(2);577 assert_ok!(TemplateModule::create_collection(578 origin1.clone(),579 col_name1.clone(),580 col_desc1.clone(),581 token_prefix1.clone(),582 mode583 ));584 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));585 assert_ok!(TemplateModule::create_item(586 origin2.clone(),587 1,588 [1, 2, 3].to_vec(),589 1590 ));591592 assert_eq!(TemplateModule::nft_item_id(1, 1).data, [1, 2, 3].to_vec());593594 // check balance (collection with id = 1, user id = 1)595 assert_eq!(TemplateModule::balance_count(1, 1), 1);596597 // burn item598 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));599 assert_noop!(600 TemplateModule::burn_item(origin1.clone(), 1, 1),601 "Item does not exists"602 );603604 assert_eq!(TemplateModule::balance_count(1, 1), 0);605 });606}607608#[test]609fn burn_fungible_item() {610 new_test_ext().execute_with(|| {611 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();612 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();613 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();614 let mode: CollectionMode = CollectionMode::Fungible(3);615616 let origin1 = Origin::signed(1);617 let origin2 = Origin::signed(2);618 assert_ok!(TemplateModule::create_collection(619 origin1.clone(),620 col_name1.clone(),621 col_desc1.clone(),622 token_prefix1.clone(),623 mode624 ));625 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));626 assert_ok!(TemplateModule::create_item(627 origin2.clone(),628 1,629 [].to_vec(),630 1631 ));632633 // check balance (collection with id = 1, user id = 1)634 assert_eq!(TemplateModule::balance_count(1, 1), 1000);635636 // burn item637 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));638 assert_noop!(639 TemplateModule::burn_item(origin1.clone(), 1, 1),640 "Item does not exists"641 );642643 assert_eq!(TemplateModule::balance_count(1, 1), 0);644 });645}646647#[test]648fn burn_refungible_item() {649 new_test_ext().execute_with(|| {650 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();651 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();652 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();653 let mode: CollectionMode = CollectionMode::ReFungible(200, 3);654655 let origin1 = Origin::signed(1);656 let origin2 = Origin::signed(2);657 assert_ok!(TemplateModule::create_collection(658 origin1.clone(),659 col_name1.clone(),660 col_desc1.clone(),661 token_prefix1.clone(),662 mode663 ));664 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));665 assert_ok!(TemplateModule::create_item(666 origin2.clone(),667 1,668 [1, 2, 3].to_vec(),669 1670 ));671672 assert_eq!(673 TemplateModule::refungible_item_id(1, 1).data,674 [1, 2, 3].to_vec()675 );676677 // check balance (collection with id = 1, user id = 2)678 assert_eq!(TemplateModule::balance_count(1, 1), 1000);679680 // burn item681 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));682 assert_noop!(683 TemplateModule::burn_item(origin1.clone(), 1, 1),684 "Item does not exists"685 );686687 assert_eq!(TemplateModule::balance_count(1, 1), 0);688 });689}690691#[test]692fn add_collection_admin() {693 new_test_ext().execute_with(|| {694 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();695 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();696 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();697 let mode: CollectionMode = CollectionMode::NFT(2000);698699 let origin1 = Origin::signed(1);700 let origin2 = Origin::signed(2);701 let origin3 = Origin::signed(3);702 assert_ok!(TemplateModule::create_collection(703 origin1.clone(),704 col_name1.clone(),705 col_desc1.clone(),706 token_prefix1.clone(),707 mode.clone()708 ));709 assert_ok!(TemplateModule::create_collection(710 origin2.clone(),711 col_name1.clone(),712 col_desc1.clone(),713 token_prefix1.clone(),714 mode.clone()715 ));716 assert_ok!(TemplateModule::create_collection(717 origin3.clone(),718 col_name1.clone(),719 col_desc1.clone(),720 token_prefix1.clone(),721 mode.clone()722 ));723724 assert_eq!(TemplateModule::collection(1).owner, 1);725 assert_eq!(TemplateModule::collection(2).owner, 2);726 assert_eq!(TemplateModule::collection(3).owner, 3);727728 // collection admin729 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));730 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 3));731732 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);733 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);734 });735}736737#[test]738fn remove_collection_admin() {739 new_test_ext().execute_with(|| {740 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();741 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();742 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();743 let mode: CollectionMode = CollectionMode::NFT(2000);744745 let origin1 = Origin::signed(1);746 let origin2 = Origin::signed(2);747 let origin3 = Origin::signed(3);748749 assert_ok!(TemplateModule::create_collection(750 origin1.clone(),751 col_name1.clone(),752 col_desc1.clone(),753 token_prefix1.clone(),754 mode.clone()755 ));756 assert_ok!(TemplateModule::create_collection(757 origin2.clone(),758 col_name1.clone(),759 col_desc1.clone(),760 token_prefix1.clone(),761 mode.clone()762 ));763 assert_ok!(TemplateModule::create_collection(764 origin3.clone(),765 col_name1.clone(),766 col_desc1.clone(),767 token_prefix1.clone(),768 mode.clone()769 ));770771 assert_eq!(TemplateModule::collection(1).owner, 1);772 assert_eq!(TemplateModule::collection(2).owner, 2);773 assert_eq!(TemplateModule::collection(3).owner, 3);774775 // collection admin776 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));777 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 3));778779 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);780 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);781782 // remove admin783 assert_ok!(TemplateModule::remove_collection_admin(784 origin2.clone(),785 1,786 3787 ));788 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), false);789 });790}791792#[test]793fn balance_of() {794 new_test_ext().execute_with(|| {795 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();796 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();797 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();798 let nft_mode: CollectionMode = CollectionMode::NFT(2000);799 let furg_mode: CollectionMode = CollectionMode::Fungible(3);800 let refung_mode: CollectionMode = CollectionMode::ReFungible(2000, 3);801802 let origin1 = Origin::signed(1);803804 assert_ok!(TemplateModule::create_collection(805 origin1.clone(),806 col_name1.clone(),807 col_desc1.clone(),808 token_prefix1.clone(),809 nft_mode.clone()810 ));811 assert_ok!(TemplateModule::create_collection(812 origin1.clone(),813 col_name1.clone(),814 col_desc1.clone(),815 token_prefix1.clone(),816 furg_mode.clone()817 ));818 assert_ok!(TemplateModule::create_collection(819 origin1.clone(),820 col_name1.clone(),821 col_desc1.clone(),822 token_prefix1.clone(),823 refung_mode.clone()824 ));825826 assert_eq!(TemplateModule::collection(1).owner, 1);827 assert_eq!(TemplateModule::collection(2).owner, 1);828 assert_eq!(TemplateModule::collection(3).owner, 1);829830 // check balance before831 assert_eq!(TemplateModule::balance_count(1, 1), 0);832 assert_eq!(TemplateModule::balance_count(2, 1), 0);833 assert_eq!(TemplateModule::balance_count(3, 1), 0);834835 // create item836 assert_ok!(TemplateModule::create_item(837 origin1.clone(),838 1,839 [1, 1, 1].to_vec(),840 1841 ));842843 assert_ok!(TemplateModule::create_item(844 origin1.clone(),845 2,846 [].to_vec(),847 1848 ));849850 assert_ok!(TemplateModule::create_item(851 origin1.clone(),852 3,853 [1, 1, 1].to_vec(),854 1855 ));856857 // check balance (collection with id = 1, user id = 1)858 assert_eq!(TemplateModule::balance_count(1, 1), 1);859 assert_eq!(TemplateModule::balance_count(2, 1), 1000);860 assert_eq!(TemplateModule::balance_count(3, 1), 1000);861 assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 1);862 assert_eq!(TemplateModule::fungible_item_id(2, 1).owner, 1);863 assert_eq!(TemplateModule::refungible_item_id(3, 1).owner[0].owner, 1);864 });865}866867#[test]868fn approve() {869 new_test_ext().execute_with(|| {870 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();871 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();872 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();873 let nft_mode: CollectionMode = CollectionMode::NFT(2000);874 let origin1 = Origin::signed(1);875876 assert_ok!(TemplateModule::create_collection(877 origin1.clone(),878 col_name1.clone(),879 col_desc1.clone(),880 token_prefix1.clone(),881 nft_mode.clone()882 ));883884 assert_eq!(TemplateModule::collection(1).owner, 1);885886 // create item887 assert_ok!(TemplateModule::create_item(888 origin1.clone(),889 1,890 [1, 1, 1].to_vec(),891 1892 ));893894 // approve895 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));896 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);897 });898}899900#[test]901fn transfer_from() {902 new_test_ext().execute_with(|| {903 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();904 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();905 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();906 let mode: CollectionMode = CollectionMode::NFT(2000);907 let origin1 = Origin::signed(1);908 let origin2 = Origin::signed(2);909910 assert_ok!(TemplateModule::create_collection(911 origin1.clone(),912 col_name1.clone(),913 col_desc1.clone(),914 token_prefix1.clone(),915 mode916 ));917918 assert_eq!(TemplateModule::collection(1).owner, 1);919920 // create item921 assert_ok!(TemplateModule::create_item(922 origin1.clone(),923 1,924 [1, 1, 1].to_vec(),925 1926 ));927928 // approve929 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));930 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);931 assert_ok!(TemplateModule::transfer_from(932 origin2.clone(),933 1,934 2,935 1,936 1,937 1938 ));939940 // after transfer941 assert_eq!(TemplateModule::balance_count(1, 1), 0);942 assert_eq!(TemplateModule::balance_count(1, 2), 1);943 });944}1// Tests to be written here2use crate::mock::*;3use crate::{ApprovePermissions, CollectionMode, AccessMode, Ownership};4use frame_support::{assert_noop, assert_ok};56// Use cases tests region7// #region8#[test]9fn create_nft_item() {10 new_test_ext().execute_with(|| {11 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();12 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();13 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();14 let mode: CollectionMode = CollectionMode::NFT(2000);1516 let origin1 = Origin::signed(1);17 assert_ok!(TemplateModule::create_collection(18 origin1.clone(),19 col_name1.clone(),20 col_desc1.clone(),21 token_prefix1.clone(),22 mode23 ));24 assert_eq!(TemplateModule::collection(1).owner, 1);2526 assert_ok!(TemplateModule::create_item(27 origin1.clone(),28 1,29 [1, 2, 3].to_vec(),30 131 ));32 assert_eq!(TemplateModule::nft_item_id(1, 1).data, [1, 2, 3].to_vec());33 });34}3536#[test]37fn create_refungible_item() {38 new_test_ext().execute_with(|| {39 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();40 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();41 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();42 let mode: CollectionMode = CollectionMode::ReFungible(2000, 3);4344 let origin1 = Origin::signed(1);45 assert_ok!(TemplateModule::create_collection(46 origin1.clone(),47 col_name1.clone(),48 col_desc1.clone(),49 token_prefix1.clone(),50 mode51 ));52 assert_eq!(TemplateModule::collection(1).owner, 1);5354 assert_ok!(TemplateModule::create_item(55 origin1.clone(),56 1,57 [1, 2, 3].to_vec(),58 159 ));60 assert_eq!(61 TemplateModule::refungible_item_id(1, 1).data,62 [1, 2, 3].to_vec()63 );64 assert_eq!(65 TemplateModule::refungible_item_id(1, 1).owner[0],66 Ownership {67 owner: 1,68 fraction: 100069 }70 );71 });72}7374#[test]75fn create_fungible_item() {76 new_test_ext().execute_with(|| {77 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();78 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();79 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();80 let mode: CollectionMode = CollectionMode::Fungible(3);8182 let origin1 = Origin::signed(1);83 assert_ok!(TemplateModule::create_collection(84 origin1.clone(),85 col_name1.clone(),86 col_desc1.clone(),87 token_prefix1.clone(),88 mode89 ));90 assert_eq!(TemplateModule::collection(1).owner, 1);9192 assert_ok!(TemplateModule::create_item(93 origin1.clone(),94 1,95 [].to_vec(),96 197 ));98 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 1);99 assert_eq!(TemplateModule::balance_count(1, 1), 1000);100 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);101 });102}103104#[test]105fn transfer_fungible_item() {106 new_test_ext().execute_with(|| {107 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();108 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();109 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();110 let mode: CollectionMode = CollectionMode::Fungible(3);111112 let origin1 = Origin::signed(1);113 let origin2 = Origin::signed(2);114 assert_ok!(TemplateModule::create_collection(115 origin1.clone(),116 col_name1.clone(),117 col_desc1.clone(),118 token_prefix1.clone(),119 mode120 ));121 assert_eq!(TemplateModule::collection(1).owner, 1);122123 assert_ok!(TemplateModule::create_item(124 origin1.clone(),125 1,126 [].to_vec(),127 1128 ));129 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 1);130 assert_eq!(TemplateModule::balance_count(1, 1), 1000);131 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);132133 // change owner scenario134 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));135 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);136 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 1000);137 assert_eq!(TemplateModule::balance_count(1, 1), 0);138 assert_eq!(TemplateModule::balance_count(1, 2), 1000);139 assert_eq!(TemplateModule::address_tokens(1, 1), []);140 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);141142 // split item scenario143 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));144 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);145 assert_eq!(TemplateModule::fungible_item_id(1, 2).owner, 3);146 assert_eq!(TemplateModule::balance_count(1, 2), 500);147 assert_eq!(TemplateModule::balance_count(1, 3), 500);148 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);149 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);150151 // split item and new owner has account scenario152 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));153 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 300);154 assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 700);155 assert_eq!(TemplateModule::balance_count(1, 2), 300);156 assert_eq!(TemplateModule::balance_count(1, 3), 700);157 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);158 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);159 });160}161162#[test]163fn transfer_refungible_item() {164 new_test_ext().execute_with(|| {165 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();166 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();167 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();168 let mode: CollectionMode = CollectionMode::ReFungible(2000, 3);169170 let origin1 = Origin::signed(1);171 let origin2 = Origin::signed(2);172 assert_ok!(TemplateModule::create_collection(173 origin1.clone(),174 col_name1.clone(),175 col_desc1.clone(),176 token_prefix1.clone(),177 mode178 ));179 assert_eq!(TemplateModule::collection(1).owner, 1);180181 assert_ok!(TemplateModule::create_item(182 origin1.clone(),183 1,184 [1, 2, 3].to_vec(),185 1186 ));187 assert_eq!(188 TemplateModule::refungible_item_id(1, 1).data,189 [1, 2, 3].to_vec()190 );191 assert_eq!(192 TemplateModule::refungible_item_id(1, 1).owner[0],193 Ownership {194 owner: 1,195 fraction: 1000196 }197 );198 assert_eq!(TemplateModule::balance_count(1, 1), 1000);199 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);200201 // change owner scenario202 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));203 assert_eq!(204 TemplateModule::refungible_item_id(1, 1).owner[0],205 Ownership {206 owner: 2,207 fraction: 1000208 }209 );210 assert_eq!(TemplateModule::balance_count(1, 1), 0);211 assert_eq!(TemplateModule::balance_count(1, 2), 1000);212 assert_eq!(TemplateModule::address_tokens(1, 1), []);213 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);214215 // split item scenario216 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));217 assert_eq!(218 TemplateModule::refungible_item_id(1, 1).owner[0],219 Ownership {220 owner: 2,221 fraction: 500222 }223 );224 assert_eq!(225 TemplateModule::refungible_item_id(1, 1).owner[1],226 Ownership {227 owner: 3,228 fraction: 500229 }230 );231 assert_eq!(TemplateModule::balance_count(1, 2), 500);232 assert_eq!(TemplateModule::balance_count(1, 3), 500);233 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);234 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);235236 // split item and new owner has account scenario237 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));238 assert_eq!(239 TemplateModule::refungible_item_id(1, 1).owner[0],240 Ownership {241 owner: 2,242 fraction: 300243 }244 );245 assert_eq!(246 TemplateModule::refungible_item_id(1, 1).owner[1],247 Ownership {248 owner: 3,249 fraction: 700250 }251 );252 assert_eq!(TemplateModule::balance_count(1, 2), 300);253 assert_eq!(TemplateModule::balance_count(1, 3), 700);254 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);255 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);256 });257}258259#[test]260fn transfer_nft_item() {261 new_test_ext().execute_with(|| {262 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();263 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();264 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();265 let mode: CollectionMode = CollectionMode::NFT(2000);266267 let origin1 = Origin::signed(1);268 assert_ok!(TemplateModule::create_collection(269 origin1.clone(),270 col_name1.clone(),271 col_desc1.clone(),272 token_prefix1.clone(),273 mode274 ));275 assert_eq!(TemplateModule::collection(1).owner, 1);276277 assert_ok!(TemplateModule::create_item(278 origin1.clone(),279 1,280 [1, 2, 3].to_vec(),281 1282 ));283 assert_eq!(TemplateModule::nft_item_id(1, 1).data, [1, 2, 3].to_vec());284 assert_eq!(TemplateModule::balance_count(1, 1), 1);285 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);286287 // default scenario288 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));289 assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2);290 assert_eq!(TemplateModule::balance_count(1, 1), 0);291 assert_eq!(TemplateModule::balance_count(1, 2), 1);292 assert_eq!(TemplateModule::address_tokens(1, 1), []);293 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);294 });295}296297#[test]298fn nft_approve_and_transfer_from() {299 new_test_ext().execute_with(|| {300 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();301 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();302 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();303 let mode: CollectionMode = CollectionMode::NFT(2000);304305 let origin1 = Origin::signed(1);306 let origin2 = Origin::signed(2);307 assert_ok!(TemplateModule::create_collection(308 origin1.clone(),309 col_name1.clone(),310 col_desc1.clone(),311 token_prefix1.clone(),312 mode313 ));314 assert_eq!(TemplateModule::collection(1).owner, 1);315316 assert_ok!(TemplateModule::create_item(317 origin1.clone(),318 1,319 [1, 2, 3].to_vec(),320 1321 ));322 assert_eq!(TemplateModule::nft_item_id(1, 1).data, [1, 2, 3].to_vec());323 assert_eq!(TemplateModule::balance_count(1, 1), 1);324 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);325326 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));327 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));328 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));329 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));330 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));331332 // do approve333 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));334 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);335 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));336 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);337 assert_eq!(338 TemplateModule::approved(1, (1, 1))[0],339 ApprovePermissions {340 approved: 2,341 amount: 100000000342 }343 );344345 assert_ok!(TemplateModule::transfer_from(346 origin2.clone(),347 1,348 3,349 1,350 1,351 1352 ));353 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);354 });355}356357#[test]358fn refungible_approve_and_transfer_from() {359 new_test_ext().execute_with(|| {360 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();361 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();362 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();363 let mode: CollectionMode = CollectionMode::ReFungible(2000, 3);364365 let origin1 = Origin::signed(1);366 let origin2 = Origin::signed(2);367 assert_ok!(TemplateModule::create_collection(368 origin1.clone(),369 col_name1.clone(),370 col_desc1.clone(),371 token_prefix1.clone(),372 mode373 ));374 assert_eq!(TemplateModule::collection(1).owner, 1);375376 assert_ok!(TemplateModule::create_item(377 origin1.clone(),378 1,379 [1, 2, 3].to_vec(),380 1381 ));382 assert_eq!(383 TemplateModule::refungible_item_id(1, 1).data,384 [1, 2, 3].to_vec()385 );386 assert_eq!(387 TemplateModule::refungible_item_id(1, 1).owner[0],388 Ownership {389 owner: 1,390 fraction: 1000391 }392 );393 assert_eq!(TemplateModule::balance_count(1, 1), 1000);394 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);395396 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));397 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));398 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));399 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));400 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));401402 // do approve403 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));404 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);405 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));406 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);407 assert_eq!(408 TemplateModule::approved(1, (1, 1))[0],409 ApprovePermissions {410 approved: 2,411 amount: 100000000412 }413 );414415 assert_ok!(TemplateModule::transfer_from(416 origin2.clone(),417 1,418 3,419 1,420 1,421 100422 ));423 assert_eq!(TemplateModule::balance_count(1, 1), 900);424 assert_eq!(TemplateModule::balance_count(1, 3), 100);425 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);426 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);427428 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);429 assert_eq!(430 TemplateModule::approved(1, (1, 1))[0],431 ApprovePermissions {432 approved: 3,433 amount: 100000000434 }435 );436 });437}438439#[test]440fn fungible_approve_and_transfer_from() {441 new_test_ext().execute_with(|| {442 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();443 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();444 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();445 let mode: CollectionMode = CollectionMode::Fungible(3);446447 let origin1 = Origin::signed(1);448 let origin2 = Origin::signed(2);449 assert_ok!(TemplateModule::create_collection(450 origin1.clone(),451 col_name1.clone(),452 col_desc1.clone(),453 token_prefix1.clone(),454 mode455 ));456 assert_eq!(TemplateModule::collection(1).owner, 1);457458 assert_ok!(TemplateModule::create_item(459 origin1.clone(),460 1,461 [].to_vec(),462 1463 ));464 assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 1);465 assert_eq!(TemplateModule::balance_count(1, 1), 1000);466 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);467468 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));469 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));470 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));471 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));472 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));473474 // do approve475 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));476 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);477 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));478 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);479 assert_eq!(480 TemplateModule::approved(1, (1, 1))[0],481 ApprovePermissions {482 approved: 2,483 amount: 100000000484 }485 );486487 assert_ok!(TemplateModule::transfer_from(488 origin2.clone(),489 1,490 3,491 1,492 1,493 100494 ));495 assert_eq!(TemplateModule::balance_count(1, 1), 900);496 assert_eq!(TemplateModule::balance_count(1, 3), 100);497 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);498 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);499500 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);501 assert_eq!(502 TemplateModule::approved(1, (1, 1))[0],503 ApprovePermissions {504 approved: 3,505 amount: 100000000506 }507 );508509 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));510 assert_ok!(TemplateModule::transfer_from(511 origin2.clone(),512 1,513 3,514 1,515 1,516 900517 ));518 assert_eq!(TemplateModule::balance_count(1, 1), 0);519 assert_eq!(TemplateModule::balance_count(1, 3), 1000);520 assert_eq!(TemplateModule::address_tokens(1, 1), []);521 assert_eq!(TemplateModule::address_tokens(1, 3), [2]);522523 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);524 });525}526527#[test]528fn change_collection_owner() {529 new_test_ext().execute_with(|| {530 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();531 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();532 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();533 let mode: CollectionMode = CollectionMode::NFT(2000);534535 let origin1 = Origin::signed(1);536 assert_ok!(TemplateModule::create_collection(537 origin1.clone(),538 col_name1.clone(),539 col_desc1.clone(),540 token_prefix1.clone(),541 mode542 ));543 assert_ok!(TemplateModule::change_collection_owner(544 origin1.clone(),545 1,546 2547 ));548 assert_eq!(TemplateModule::collection(1).owner, 2);549 });550}551552#[test]553fn destroy_collection() {554 new_test_ext().execute_with(|| {555 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();556 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();557 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();558 let mode: CollectionMode = CollectionMode::NFT(2000);559560 let origin1 = Origin::signed(1);561 assert_ok!(TemplateModule::create_collection(562 origin1.clone(),563 col_name1.clone(),564 col_desc1.clone(),565 token_prefix1.clone(),566 mode567 ));568 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), 1));569 });570}571572#[test]573fn burn_nft_item() {574 new_test_ext().execute_with(|| {575 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();576 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();577 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();578 let mode: CollectionMode = CollectionMode::NFT(2000);579580 let origin1 = Origin::signed(1);581 assert_ok!(TemplateModule::create_collection(582 origin1.clone(),583 col_name1.clone(),584 col_desc1.clone(),585 token_prefix1.clone(),586 mode587 ));588 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));589 assert_ok!(TemplateModule::create_item(590 origin1.clone(),591 1,592 [1, 2, 3].to_vec(),593 1594 ));595596 assert_eq!(TemplateModule::nft_item_id(1, 1).data, [1, 2, 3].to_vec());597598 // check balance (collection with id = 1, user id = 1)599 assert_eq!(TemplateModule::balance_count(1, 1), 1);600601 // burn item602 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));603 assert_noop!(604 TemplateModule::burn_item(origin1.clone(), 1, 1),605 "Item does not exists"606 );607608 assert_eq!(TemplateModule::balance_count(1, 1), 0);609 });610}611612#[test]613fn burn_fungible_item() {614 new_test_ext().execute_with(|| {615 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();616 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();617 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();618 let mode: CollectionMode = CollectionMode::Fungible(3);619620 let origin1 = Origin::signed(1);621 assert_ok!(TemplateModule::create_collection(622 origin1.clone(),623 col_name1.clone(),624 col_desc1.clone(),625 token_prefix1.clone(),626 mode627 ));628 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));629 assert_ok!(TemplateModule::create_item(630 origin1.clone(),631 1,632 [].to_vec(),633 1634 ));635636 // check balance (collection with id = 1, user id = 1)637 assert_eq!(TemplateModule::balance_count(1, 1), 1000);638639 // burn item640 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));641 assert_noop!(642 TemplateModule::burn_item(origin1.clone(), 1, 1),643 "Item does not exists"644 );645646 assert_eq!(TemplateModule::balance_count(1, 1), 0);647 });648}649650#[test]651fn burn_refungible_item() {652 new_test_ext().execute_with(|| {653 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();654 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();655 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();656 let mode: CollectionMode = CollectionMode::ReFungible(200, 3);657658 let origin1 = Origin::signed(1);659 let origin2 = Origin::signed(2);660 assert_ok!(TemplateModule::create_collection(661 origin1.clone(),662 col_name1.clone(),663 col_desc1.clone(),664 token_prefix1.clone(),665 mode666 ));667 668 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));669 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));670 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));671672 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));673 assert_ok!(TemplateModule::create_item(674 origin2.clone(),675 1,676 [1, 2, 3].to_vec(),677 1678 ));679680 assert_eq!(681 TemplateModule::refungible_item_id(1, 1).data,682 [1, 2, 3].to_vec()683 );684685 // check balance (collection with id = 1, user id = 2)686 assert_eq!(TemplateModule::balance_count(1, 1), 1000);687688 // burn item689 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));690 assert_noop!(691 TemplateModule::burn_item(origin1.clone(), 1, 1),692 "Item does not exists"693 );694695 assert_eq!(TemplateModule::balance_count(1, 1), 0);696 });697}698699#[test]700fn add_collection_admin() {701 new_test_ext().execute_with(|| {702 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();703 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();704 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();705 let mode: CollectionMode = CollectionMode::NFT(2000);706707 let origin1 = Origin::signed(1);708 let origin2 = Origin::signed(2);709 let origin3 = Origin::signed(3);710 assert_ok!(TemplateModule::create_collection(711 origin1.clone(),712 col_name1.clone(),713 col_desc1.clone(),714 token_prefix1.clone(),715 mode.clone()716 ));717 assert_ok!(TemplateModule::create_collection(718 origin2.clone(),719 col_name1.clone(),720 col_desc1.clone(),721 token_prefix1.clone(),722 mode.clone()723 ));724 assert_ok!(TemplateModule::create_collection(725 origin3.clone(),726 col_name1.clone(),727 col_desc1.clone(),728 token_prefix1.clone(),729 mode.clone()730 ));731732 assert_eq!(TemplateModule::collection(1).owner, 1);733 assert_eq!(TemplateModule::collection(2).owner, 2);734 assert_eq!(TemplateModule::collection(3).owner, 3);735736 // collection admin737 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));738 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 3));739740 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);741 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);742 });743}744745#[test]746fn remove_collection_admin() {747 new_test_ext().execute_with(|| {748 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();749 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();750 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();751 let mode: CollectionMode = CollectionMode::NFT(2000);752753 let origin1 = Origin::signed(1);754 let origin2 = Origin::signed(2);755 let origin3 = Origin::signed(3);756757 assert_ok!(TemplateModule::create_collection(758 origin1.clone(),759 col_name1.clone(),760 col_desc1.clone(),761 token_prefix1.clone(),762 mode.clone()763 ));764 assert_ok!(TemplateModule::create_collection(765 origin2.clone(),766 col_name1.clone(),767 col_desc1.clone(),768 token_prefix1.clone(),769 mode.clone()770 ));771 assert_ok!(TemplateModule::create_collection(772 origin3.clone(),773 col_name1.clone(),774 col_desc1.clone(),775 token_prefix1.clone(),776 mode.clone()777 ));778779 assert_eq!(TemplateModule::collection(1).owner, 1);780 assert_eq!(TemplateModule::collection(2).owner, 2);781 assert_eq!(TemplateModule::collection(3).owner, 3);782783 // collection admin784 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));785 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 3));786787 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);788 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);789790 // remove admin791 assert_ok!(TemplateModule::remove_collection_admin(792 origin2.clone(),793 1,794 3795 ));796 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), false);797 });798}799800#[test]801fn balance_of() {802 new_test_ext().execute_with(|| {803 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();804 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();805 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();806 let nft_mode: CollectionMode = CollectionMode::NFT(2000);807 let furg_mode: CollectionMode = CollectionMode::Fungible(3);808 let refung_mode: CollectionMode = CollectionMode::ReFungible(2000, 3);809810 let origin1 = Origin::signed(1);811812 assert_ok!(TemplateModule::create_collection(813 origin1.clone(),814 col_name1.clone(),815 col_desc1.clone(),816 token_prefix1.clone(),817 nft_mode.clone()818 ));819 assert_ok!(TemplateModule::create_collection(820 origin1.clone(),821 col_name1.clone(),822 col_desc1.clone(),823 token_prefix1.clone(),824 furg_mode.clone()825 ));826 assert_ok!(TemplateModule::create_collection(827 origin1.clone(),828 col_name1.clone(),829 col_desc1.clone(),830 token_prefix1.clone(),831 refung_mode.clone()832 ));833834 assert_eq!(TemplateModule::collection(1).owner, 1);835 assert_eq!(TemplateModule::collection(2).owner, 1);836 assert_eq!(TemplateModule::collection(3).owner, 1);837838 // check balance before839 assert_eq!(TemplateModule::balance_count(1, 1), 0);840 assert_eq!(TemplateModule::balance_count(2, 1), 0);841 assert_eq!(TemplateModule::balance_count(3, 1), 0);842843 // create item844 assert_ok!(TemplateModule::create_item(845 origin1.clone(),846 1,847 [1, 1, 1].to_vec(),848 1849 ));850851 assert_ok!(TemplateModule::create_item(852 origin1.clone(),853 2,854 [].to_vec(),855 1856 ));857858 assert_ok!(TemplateModule::create_item(859 origin1.clone(),860 3,861 [1, 1, 1].to_vec(),862 1863 ));864865 // check balance (collection with id = 1, user id = 1)866 assert_eq!(TemplateModule::balance_count(1, 1), 1);867 assert_eq!(TemplateModule::balance_count(2, 1), 1000);868 assert_eq!(TemplateModule::balance_count(3, 1), 1000);869 assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 1);870 assert_eq!(TemplateModule::fungible_item_id(2, 1).owner, 1);871 assert_eq!(TemplateModule::refungible_item_id(3, 1).owner[0].owner, 1);872 });873}874875#[test]876fn approve() {877 new_test_ext().execute_with(|| {878 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();879 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();880 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();881 let nft_mode: CollectionMode = CollectionMode::NFT(2000);882 let origin1 = Origin::signed(1);883884 assert_ok!(TemplateModule::create_collection(885 origin1.clone(),886 col_name1.clone(),887 col_desc1.clone(),888 token_prefix1.clone(),889 nft_mode.clone()890 ));891892 assert_eq!(TemplateModule::collection(1).owner, 1);893894 // create item895 assert_ok!(TemplateModule::create_item(896 origin1.clone(),897 1,898 [1, 1, 1].to_vec(),899 1900 ));901902 // approve903 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));904 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);905 });906}907908#[test]909fn transfer_from() {910 new_test_ext().execute_with(|| {911 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();912 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();913 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();914 let mode: CollectionMode = CollectionMode::NFT(2000);915 let origin1 = Origin::signed(1);916 let origin2 = Origin::signed(2);917918 assert_ok!(TemplateModule::create_collection(919 origin1.clone(),920 col_name1.clone(),921 col_desc1.clone(),922 token_prefix1.clone(),923 mode924 ));925926 assert_eq!(TemplateModule::collection(1).owner, 1);927928 // create item929 assert_ok!(TemplateModule::create_item(930 origin1.clone(),931 1,932 [1, 1, 1].to_vec(),933 1934 ));935936 // approve937 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));938 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);939940 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));941 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));942 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));943 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));944 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));945946 assert_ok!(TemplateModule::transfer_from(947 origin2.clone(),948 1,949 2,950 1,951 1,952 1953 ));954955 // after transfer956 assert_eq!(TemplateModule::balance_count(1, 1), 0);957 assert_eq!(TemplateModule::balance_count(1, 2), 1);958 });959}960961// #endregion962963// Coverage tests region964// #region965966#[test]967fn owner_can_add_address_to_white_list() {968 new_test_ext().execute_with(|| {969 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();970 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();971 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();972 let mode: CollectionMode = CollectionMode::NFT(2000);973 let origin1 = Origin::signed(1);974975 assert_ok!(TemplateModule::create_collection(976 origin1.clone(),977 col_name1.clone(),978 col_desc1.clone(),979 token_prefix1.clone(),980 mode981 ));982983 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));984 assert_eq!(TemplateModule::white_list(1)[0], 2);985 });986}987988#[test]989fn admin_can_add_address_to_white_list() {990 new_test_ext().execute_with(|| {991 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();992 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();993 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();994 let mode: CollectionMode = CollectionMode::NFT(2000);995 let origin1 = Origin::signed(1);996 let origin2 = Origin::signed(2);997998 assert_ok!(TemplateModule::create_collection(999 origin1.clone(),1000 col_name1.clone(),1001 col_desc1.clone(),1002 token_prefix1.clone(),1003 mode1004 ));10051006 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));1007 assert_ok!(TemplateModule::add_to_white_list(origin2.clone(), 1, 3));1008 assert_eq!(TemplateModule::white_list(1)[0], 3);1009 });1010}10111012#[test]1013fn nonprivileged_user_cannot_add_address_to_white_list() {1014 new_test_ext().execute_with(|| {1015 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1016 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1017 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1018 let mode: CollectionMode = CollectionMode::NFT(2000);1019 let origin1 = Origin::signed(1);1020 let origin2 = Origin::signed(2);10211022 assert_ok!(TemplateModule::create_collection(1023 origin1.clone(),1024 col_name1.clone(),1025 col_desc1.clone(),1026 token_prefix1.clone(),1027 mode1028 ));10291030 assert_noop!(TemplateModule::add_to_white_list(origin2.clone(), 1, 3), "You do not have permissions to modify this collection");1031 });1032}10331034#[test]1035fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {1036 new_test_ext().execute_with(|| {10371038 let origin1 = Origin::signed(1);1039 assert_noop!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2), "This collection does not exist");1040 });1041}10421043#[test]1044fn nobody_can_add_address_to_white_list_of_deleted_collection() {1045 new_test_ext().execute_with(|| {1046 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1047 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1048 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1049 let mode: CollectionMode = CollectionMode::NFT(2000);1050 let origin1 = Origin::signed(1);10511052 assert_ok!(TemplateModule::create_collection(1053 origin1.clone(),1054 col_name1.clone(),1055 col_desc1.clone(),1056 token_prefix1.clone(),1057 mode1058 ));10591060 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), 1));1061 assert_noop!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2), "This collection does not exist");1062 });1063}10641065// If address is already added to white list, nothing happens1066#[test]1067fn address_is_already_added_to_white_list() {1068 new_test_ext().execute_with(|| {10691070 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1071 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1072 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1073 let mode: CollectionMode = CollectionMode::NFT(2000);1074 let origin1 = Origin::signed(1);10751076 assert_ok!(TemplateModule::create_collection(1077 origin1.clone(),1078 col_name1.clone(),1079 col_desc1.clone(),1080 token_prefix1.clone(),1081 mode1082 ));10831084 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1085 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1086 assert_eq!(TemplateModule::white_list(1)[0], 2);1087 assert_eq!(TemplateModule::white_list(1).len(), 1);1088 });1089}10901091#[test]1092fn owner_can_remove_address_from_white_list() {1093 new_test_ext().execute_with(|| {1094 1095 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1096 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1097 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1098 let mode: CollectionMode = CollectionMode::NFT(2000);1099 let origin1 = Origin::signed(1);11001101 assert_ok!(TemplateModule::create_collection(1102 origin1.clone(),1103 col_name1.clone(),1104 col_desc1.clone(),1105 token_prefix1.clone(),1106 mode1107 ));11081109 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1110 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));1111 assert_eq!(TemplateModule::white_list(1).len(), 0);1112 });1113}11141115#[test]1116fn admin_can_remove_address_from_white_list() {1117 new_test_ext().execute_with(|| {11181119 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1120 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1121 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1122 let mode: CollectionMode = CollectionMode::NFT(2000);1123 let origin1 = Origin::signed(1);1124 let origin2 = Origin::signed(2);11251126 assert_ok!(TemplateModule::create_collection(1127 origin1.clone(),1128 col_name1.clone(),1129 col_desc1.clone(),1130 token_prefix1.clone(),1131 mode1132 ));11331134 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));11351136 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));1137 assert_ok!(TemplateModule::remove_from_white_list(origin2.clone(), 1, 3));1138 assert_eq!(TemplateModule::white_list(1).len(), 0);1139 });1140}11411142#[test]1143fn nonprivileged_user_cannot_remove_address_from_white_list() {1144 new_test_ext().execute_with(|| {11451146 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1147 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1148 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1149 let mode: CollectionMode = CollectionMode::NFT(2000);1150 let origin1 = Origin::signed(1);1151 let origin2 = Origin::signed(2);11521153 assert_ok!(TemplateModule::create_collection(1154 origin1.clone(),1155 col_name1.clone(),1156 col_desc1.clone(),1157 token_prefix1.clone(),1158 mode1159 ));11601161 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1162 assert_noop!(TemplateModule::remove_from_white_list(origin2.clone(), 1, 2), "You do not have permissions to modify this collection");1163 assert_eq!(TemplateModule::white_list(1)[0], 2);1164 });1165}11661167#[test]1168fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1169 new_test_ext().execute_with(|| {11701171 let origin1 = Origin::signed(1);1172 assert_noop!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2), "This collection does not exist");1173 });1174}11751176#[test]1177fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1178 new_test_ext().execute_with(|| {11791180 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1181 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1182 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1183 let mode: CollectionMode = CollectionMode::NFT(2000);1184 let origin1 = Origin::signed(1);1185 let origin2 = Origin::signed(2);11861187 assert_ok!(TemplateModule::create_collection(1188 origin1.clone(),1189 col_name1.clone(),1190 col_desc1.clone(),1191 token_prefix1.clone(),1192 mode1193 ));11941195 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1196 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), 1));1197 assert_noop!(TemplateModule::remove_from_white_list(origin2.clone(), 1, 2), "This collection does not exist");1198 assert_eq!(TemplateModule::white_list(1).len(), 0);1199 });1200}12011202// If address is already removed from white list, nothing happens1203#[test]1204fn address_is_already_removed_from_white_list() {1205 new_test_ext().execute_with(|| {1206 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1207 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1208 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1209 let mode: CollectionMode = CollectionMode::NFT(2000);1210 let origin1 = Origin::signed(1);12111212 assert_ok!(TemplateModule::create_collection(1213 origin1.clone(),1214 col_name1.clone(),1215 col_desc1.clone(),1216 token_prefix1.clone(),1217 mode1218 ));12191220 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));1221 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));1222 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));1223 assert_eq!(TemplateModule::white_list(1).len(), 0);1224 });1225}12261227// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1228#[test]1229fn white_list_test_1() {1230 new_test_ext().execute_with(|| {1231 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1232 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1233 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1234 let mode: CollectionMode = CollectionMode::NFT(2000);12351236 let origin1 = Origin::signed(1);1237 assert_ok!(TemplateModule::create_collection(1238 origin1.clone(),1239 col_name1.clone(),1240 col_desc1.clone(),1241 token_prefix1.clone(),1242 mode1243 ));1244 assert_eq!(TemplateModule::collection(1).owner, 1);12451246 assert_ok!(TemplateModule::create_item(1247 origin1.clone(),1248 1,1249 [1, 2, 3].to_vec(),1250 11251 ));12521253 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1254 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));12551256 assert_noop!(TemplateModule::transfer(1257 origin1.clone(),1258 3,1259 1,1260 1,1261 11262 ), "Address is not in white list");1263 });1264}12651266#[test]1267fn white_list_test_2() {1268 new_test_ext().execute_with(|| {1269 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1270 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1271 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1272 let mode: CollectionMode = CollectionMode::NFT(2000);12731274 let origin1 = Origin::signed(1);1275 assert_ok!(TemplateModule::create_collection(1276 origin1.clone(),1277 col_name1.clone(),1278 col_desc1.clone(),1279 token_prefix1.clone(),1280 mode1281 ));1282 assert_eq!(TemplateModule::collection(1).owner, 1);12831284 assert_ok!(TemplateModule::create_item(1285 origin1.clone(),1286 1,1287 [1, 2, 3].to_vec(),1288 11289 ));12901291 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1292 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1293 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));12941295 // do approve1296 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1297 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);12981299 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 1));13001301 assert_noop!(TemplateModule::transfer_from(1302 origin1.clone(),1303 1,1304 3,1305 1,1306 1,1307 11308 ), "Address is not in white list");1309 });1310}13111312// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1313#[test]1314fn white_list_test_3() {1315 new_test_ext().execute_with(|| {1316 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1317 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1318 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1319 let mode: CollectionMode = CollectionMode::NFT(2000);13201321 let origin1 = Origin::signed(1);1322 assert_ok!(TemplateModule::create_collection(1323 origin1.clone(),1324 col_name1.clone(),1325 col_desc1.clone(),1326 token_prefix1.clone(),1327 mode1328 ));1329 assert_eq!(TemplateModule::collection(1).owner, 1);13301331 assert_ok!(TemplateModule::create_item(1332 origin1.clone(),1333 1,1334 [1, 2, 3].to_vec(),1335 11336 ));13371338 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1339 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));13401341 assert_noop!(TemplateModule::transfer(1342 origin1.clone(),1343 3,1344 1,1345 1,1346 11347 ), "Address is not in white list");1348 });1349}13501351#[test]1352fn white_list_test_4() {1353 new_test_ext().execute_with(|| {1354 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1355 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1356 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1357 let mode: CollectionMode = CollectionMode::NFT(2000);13581359 let origin1 = Origin::signed(1);1360 assert_ok!(TemplateModule::create_collection(1361 origin1.clone(),1362 col_name1.clone(),1363 col_desc1.clone(),1364 token_prefix1.clone(),1365 mode1366 ));1367 assert_eq!(TemplateModule::collection(1).owner, 1);13681369 assert_ok!(TemplateModule::create_item(1370 origin1.clone(),1371 1,1372 [1, 2, 3].to_vec(),1373 11374 ));13751376 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1377 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1378 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));13791380 // do approve1381 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1382 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);13831384 assert_ok!(TemplateModule::remove_from_white_list(origin1.clone(), 1, 2));13851386 assert_noop!(TemplateModule::transfer_from(1387 origin1.clone(),1388 1,1389 3,1390 1,1391 1,1392 11393 ), "Address is not in white list");1394 });1395}13961397// If Public Access mode is set to WhiteList, tokens can’t be destroyed by a non-whitelisted address (even if it owned them before enabling WhiteList mode)1398#[test]1399fn white_list_test_5() {1400 new_test_ext().execute_with(|| {1401 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1402 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1403 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1404 let mode: CollectionMode = CollectionMode::NFT(2000);14051406 let origin1 = Origin::signed(1);1407 assert_ok!(TemplateModule::create_collection(1408 origin1.clone(),1409 col_name1.clone(),1410 col_desc1.clone(),1411 token_prefix1.clone(),1412 mode1413 ));1414 assert_eq!(TemplateModule::collection(1).owner, 1);14151416 assert_ok!(TemplateModule::create_item(1417 origin1.clone(),1418 1,1419 [1, 2, 3].to_vec(),1420 11421 ));14221423 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1424 assert_noop!(TemplateModule::burn_item(origin1.clone(), 1, 1), "Address is not in white list");1425 });1426}14271428// If Public Access mode is set to WhiteList, oken transfers can’t be Approved by a non-whitelisted address (see Approve method).1429#[test]1430fn white_list_test_6() {1431 new_test_ext().execute_with(|| {1432 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1433 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1434 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1435 let mode: CollectionMode = CollectionMode::NFT(2000);14361437 let origin1 = Origin::signed(1);1438 assert_ok!(TemplateModule::create_collection(1439 origin1.clone(),1440 col_name1.clone(),1441 col_desc1.clone(),1442 token_prefix1.clone(),1443 mode1444 ));1445 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));14461447 // do approve1448 assert_noop!(TemplateModule::approve(origin1.clone(), 1, 1, 1), "Address is not in white list");1449 });1450}14511452// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1453// tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1454#[test]1455fn white_list_test_7() {1456 new_test_ext().execute_with(|| {1457 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1458 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1459 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1460 let mode: CollectionMode = CollectionMode::NFT(2000);14611462 let origin1 = Origin::signed(1);1463 assert_ok!(TemplateModule::create_collection(1464 origin1.clone(),1465 col_name1.clone(),1466 col_desc1.clone(),1467 token_prefix1.clone(),1468 mode1469 ));1470 assert_eq!(TemplateModule::collection(1).owner, 1);14711472 assert_ok!(TemplateModule::create_item(1473 origin1.clone(),1474 1,1475 [1, 2, 3].to_vec(),1476 11477 ));14781479 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1480 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1481 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));14821483 assert_ok!(TemplateModule::transfer(1484 origin1.clone(),1485 2,1486 1,1487 1,1488 11489 ));1490 });1491}14921493#[test]1494fn white_list_test_8() {1495 new_test_ext().execute_with(|| {1496 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1497 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1498 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1499 let mode: CollectionMode = CollectionMode::NFT(2000);15001501 let origin1 = Origin::signed(1);1502 assert_ok!(TemplateModule::create_collection(1503 origin1.clone(),1504 col_name1.clone(),1505 col_desc1.clone(),1506 token_prefix1.clone(),1507 mode1508 ));1509 assert_eq!(TemplateModule::collection(1).owner, 1);15101511 assert_ok!(TemplateModule::create_item(1512 origin1.clone(),1513 1,1514 [1, 2, 3].to_vec(),1515 11516 ));15171518 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1519 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1520 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));15211522 // do approve1523 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1524 assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);15251526 assert_ok!(TemplateModule::transfer_from(1527 origin1.clone(),1528 1,1529 2,1530 1,1531 1,1532 11533 ));1534 });1535}15361537// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1538#[test]1539fn white_list_test_9() {1540 new_test_ext().execute_with(|| {1541 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1542 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1543 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1544 let mode: CollectionMode = CollectionMode::NFT(2000);15451546 let origin1 = Origin::signed(1);1547 assert_ok!(TemplateModule::create_collection(1548 origin1.clone(),1549 col_name1.clone(),1550 col_desc1.clone(),1551 token_prefix1.clone(),1552 mode1553 ));15541555 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1556 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));15571558 assert_ok!(TemplateModule::create_item(1559 origin1.clone(),1560 1,1561 [1, 2, 3].to_vec(),1562 11563 ));1564 });1565}15661567// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1568#[test]1569fn white_list_test_10() {1570 new_test_ext().execute_with(|| {1571 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1572 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1573 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1574 let mode: CollectionMode = CollectionMode::NFT(2000);15751576 let origin1 = Origin::signed(1);1577 let origin2 = Origin::signed(2);1578 assert_ok!(TemplateModule::create_collection(1579 origin1.clone(),1580 col_name1.clone(),1581 col_desc1.clone(),1582 token_prefix1.clone(),1583 mode1584 ));15851586 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1587 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));15881589 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));15901591 assert_ok!(TemplateModule::create_item(1592 origin2.clone(),1593 1,1594 [1, 2, 3].to_vec(),1595 21596 ));1597 });1598}15991600// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and white listed address.1601#[test]1602fn white_list_test_11() {1603 new_test_ext().execute_with(|| {1604 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1605 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1606 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1607 let mode: CollectionMode = CollectionMode::NFT(2000);16081609 let origin1 = Origin::signed(1);1610 let origin2 = Origin::signed(2);1611 assert_ok!(TemplateModule::create_collection(1612 origin1.clone(),1613 col_name1.clone(),1614 col_desc1.clone(),1615 token_prefix1.clone(),1616 mode1617 ));16181619 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1620 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));1621 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));16221623 assert_noop!(TemplateModule::create_item(1624 origin2.clone(),1625 1,1626 [1, 2, 3].to_vec(),1627 21628 ), "Collection is not in mint mode");1629 });1630}16311632// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-white listed address.1633#[test]1634fn white_list_test_12() {1635 new_test_ext().execute_with(|| {1636 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1637 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1638 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1639 let mode: CollectionMode = CollectionMode::NFT(2000);16401641 let origin1 = Origin::signed(1);1642 let origin2 = Origin::signed(2);1643 assert_ok!(TemplateModule::create_collection(1644 origin1.clone(),1645 col_name1.clone(),1646 col_desc1.clone(),1647 token_prefix1.clone(),1648 mode1649 ));16501651 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1652 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, false));16531654 assert_noop!(TemplateModule::create_item(1655 origin2.clone(),1656 1,1657 [1, 2, 3].to_vec(),1658 21659 ), "Collection is not in mint mode");1660 });1661}16621663// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1664#[test]1665fn white_list_test_13() {1666 new_test_ext().execute_with(|| {1667 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1668 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1669 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1670 let mode: CollectionMode = CollectionMode::NFT(2000);16711672 let origin1 = Origin::signed(1);1673 assert_ok!(TemplateModule::create_collection(1674 origin1.clone(),1675 col_name1.clone(),1676 col_desc1.clone(),1677 token_prefix1.clone(),1678 mode1679 ));16801681 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1682 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));16831684 assert_ok!(TemplateModule::create_item(1685 origin1.clone(),1686 1,1687 [1, 2, 3].to_vec(),1688 11689 ));1690 });1691}16921693// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1694#[test]1695fn white_list_test_14() {1696 new_test_ext().execute_with(|| {1697 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1698 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1699 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1700 let mode: CollectionMode = CollectionMode::NFT(2000);17011702 let origin1 = Origin::signed(1);1703 let origin2 = Origin::signed(2);1704 assert_ok!(TemplateModule::create_collection(1705 origin1.clone(),1706 col_name1.clone(),1707 col_desc1.clone(),1708 token_prefix1.clone(),1709 mode1710 ));17111712 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1713 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));17141715 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));17161717 assert_ok!(TemplateModule::create_item(1718 origin2.clone(),1719 1,1720 [1, 2, 3].to_vec(),1721 21722 ));1723 });1724}17251726// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-white listed address.1727#[test]1728fn white_list_test_15() {1729 new_test_ext().execute_with(|| {1730 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1731 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1732 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1733 let mode: CollectionMode = CollectionMode::NFT(2000);17341735 let origin1 = Origin::signed(1);1736 let origin2 = Origin::signed(2);1737 assert_ok!(TemplateModule::create_collection(1738 origin1.clone(),1739 col_name1.clone(),1740 col_desc1.clone(),1741 token_prefix1.clone(),1742 mode1743 ));17441745 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1746 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));17471748 assert_noop!(TemplateModule::create_item(1749 origin2.clone(),1750 1,1751 [1, 2, 3].to_vec(),1752 21753 ), "Address is not in white list");1754 });1755}17561757// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by non-privileged and white listed address.1758#[test]1759fn white_list_test_16() {1760 new_test_ext().execute_with(|| {1761 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1762 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1763 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();1764 let mode: CollectionMode = CollectionMode::NFT(2000);17651766 let origin1 = Origin::signed(1);1767 let origin2 = Origin::signed(2);1768 assert_ok!(TemplateModule::create_collection(1769 origin1.clone(),1770 col_name1.clone(),1771 col_desc1.clone(),1772 token_prefix1.clone(),1773 mode1774 ));17751776 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));1777 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));1778 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));17791780 assert_ok!(TemplateModule::create_item(1781 origin2.clone(),1782 1,1783 [1, 2, 3].to_vec(),1784 21785 ));1786 });1787}17881789// #endregionrun-testnet.shdiffbeforeafterboth--- a/run-testnet.sh
+++ b/run-testnet.sh
@@ -49,6 +49,7 @@
--rpc-port $RPCPORT \
--name $NODE \
--ws-external \
+ --ws-max-connections 10000 \
--rpc-cors all \
-lruntime \
$BOOTNODES;
runtime/src/lib.rsdiffbeforeafterboth--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -53,8 +53,10 @@
pub use timestamp::Call as TimestampCall;
-/// Importing a nft pallet
-pub use nft;
+/// Re-export a nft pallet
+/// TODO: Check this re-export. Is this safe and good style?
+extern crate nft;
+pub use nft::*;
/// An index to a block.
pub type BlockNumber = u32;
@@ -111,7 +113,7 @@
spec_name: create_runtime_str!("nft"),
impl_name: create_runtime_str!("nft"),
authoring_version: 1,
- spec_version: 1,
+ spec_version: 2,
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
@@ -318,7 +320,7 @@
Balances: balances::{Module, Call, Storage, Config<T>, Event<T>},
TransactionPayment: transaction_payment::{Module, Storage},
Sudo: sudo::{Module, Call, Config<T>, Storage, Event<T>},
- Nft: nft::{Module, Call, Storage, Event<T>},
+ Nft: nft::{Module, Call, Config<T>, Storage, Event<T>},
}
);
tests/src/blocks-production.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/blocks-production.test.ts
@@ -0,0 +1,48 @@
+import usingApi from "./substrate/substrate-api";
+import promisifySubstrate from "./substrate/promisify-substrate";
+import { expect } from "chai";
+
+describe('Blocks Production', () => {
+ it('Node produces new blocks', async () => {
+ await usingApi(async api => {
+ const blocksPromise = promisifySubstrate(api, () => {
+ return new Promise<number[]>((resolve, reject) => {
+ const blockNumbers: number[] = [];
+ const unsubscribe = api.rpc.chain.subscribeNewHeads(async head => {
+ blockNumbers.push(head.number.toNumber());
+ if(blockNumbers.length >= 2) {
+ (await unsubscribe)();
+ resolve(blockNumbers);
+ }
+ });
+ })
+ })();
+
+ let blocks: number[] | undefined = undefined;
+
+ const timeoutPromise = new Promise<void>((resolve, reject) => {
+ let secondsPassed = 0;
+ let incrementSeconds = () => {
+ secondsPassed++;
+ if(secondsPassed > 5 * 60) {
+ reject('Block production test failed due to timeout.');
+ return;
+ }
+
+ if(blocks) {
+ resolve();
+ return;
+ }
+
+ setTimeout(incrementSeconds, 1000);
+ }
+
+ incrementSeconds();
+ });
+
+ blocks = await Promise.race([blocksPromise, timeoutPromise]) as number[];
+
+ expect(blocks[0]).to.be.lessThan(blocks[1]);
+ });
+ });
+});