difftreelog
Merge branch 'develop' into release/v2.0.0
in: master
34 files changed
Dockerfilediffbeforeafterboth--- a/Dockerfile
+++ b/Dockerfile
@@ -1,9 +1,9 @@
# ===== BUILD ======
-FROM phusion/baseimage:0.10.2 as builder
+FROM phusion/baseimage:18.04-1.0.0 as builder
LABEL maintainer="gz@usetech.com"
-ENV WASM_TOOLCHAIN=nightly-2020-10-01
+ENV WASM_TOOLCHAIN=nightly-2021-01-27
ARG PROFILE=release
@@ -37,7 +37,7 @@
# ===== RUN ======
-FROM phusion/baseimage:0.10.2
+FROM phusion/baseimage:18.04-1.0.0
ARG PROFILE=release
COPY --from=builder /nft_parachain/target/$PROFILE/nft /usr/local/bin
pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -54,6 +54,7 @@
mod default_weights;
pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;
+pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;
pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;
pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;
@@ -71,8 +72,7 @@
NFT,
// decimal points
Fungible(DecimalPoints),
- // decimal points
- ReFungible(DecimalPoints),
+ ReFungible,
}
impl Default for CollectionMode {
@@ -87,7 +87,7 @@
CollectionMode::Invalid => 0,
CollectionMode::NFT => 1,
CollectionMode::Fungible(_) => 2,
- CollectionMode::ReFungible(_) => 3,
+ CollectionMode::ReFungible => 3,
}
}
}
@@ -185,6 +185,8 @@
// Timeouts for item types in passed blocks
pub sponsor_transfer_timeout: u32,
+ pub owner_can_transfer: bool,
+ pub owner_can_destroy: bool,
}
impl Default for CollectionLimits {
@@ -193,7 +195,10 @@
account_token_ownership_limit: 10_000_000,
token_limit: u32::max_value(),
sponsored_data_size: u32::max_value(),
- sponsor_transfer_timeout: 14400 }
+ sponsor_transfer_timeout: 14400,
+ owner_can_transfer: true,
+ owner_can_destroy: true
+ }
}
}
@@ -266,6 +271,7 @@
pub struct CreateReFungibleData {
pub const_data: Vec<u8>,
pub variable_data: Vec<u8>,
+ pub pieces: u128,
}
#[derive(Encode, Decode, Debug, Clone, PartialEq)]
@@ -377,7 +383,9 @@
/// Collection limit bounds per collection exceeded
CollectionLimitBoundsExceeded,
/// Schema data size limit bound exceeded
- SchemaDataLimitExceeded
+ SchemaDataLimitExceeded,
+ /// Maximum refungibility exceeded
+ WrongRefungiblePieces
}
}
@@ -548,7 +556,6 @@
let decimal_points = match mode {
CollectionMode::Fungible(points) => points,
- CollectionMode::ReFungible(points) => points,
_ => 0
};
@@ -590,7 +597,7 @@
sponsor_confirmed: false,
variable_on_chain_schema: Vec::new(),
const_on_chain_schema: Vec::new(),
- limits: CollectionLimits::default(),
+ limits: CollectionLimits::default()
};
// Add new collection to map
@@ -933,7 +940,7 @@
Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;
Self::validate_create_item_args(&target_collection, &data)?;
- Self::create_item_no_validation(collection_id, &target_collection, owner, data)?;
+ Self::create_item_no_validation(collection_id, owner, data)?;
Ok(())
}
@@ -973,7 +980,7 @@
Self::validate_create_item_args(&target_collection, data)?;
}
for data in &items_data {
- Self::create_item_no_validation(collection_id, &target_collection, owner.clone(), data.clone())?;
+ Self::create_item_no_validation(collection_id, owner.clone(), data.clone())?;
}
Ok(())
@@ -1012,7 +1019,7 @@
{
CollectionMode::NFT => Self::burn_nft_item(collection_id, item_id)?,
CollectionMode::Fungible(_) => Self::burn_fungible_item(&sender, collection_id, value)?,
- CollectionMode::ReFungible(_) => Self::burn_refungible_item(collection_id, item_id, &sender)?,
+ CollectionMode::ReFungible => Self::burn_refungible_item(collection_id, item_id, &sender)?,
_ => ()
};
@@ -1154,7 +1161,7 @@
{
CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, from, recipient)?,
CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, value, &from, &recipient)?,
- CollectionMode::ReFungible(_) => Self::transfer_refungible(collection_id, item_id, value, from.clone(), recipient)?,
+ CollectionMode::ReFungible => Self::transfer_refungible(collection_id, item_id, value, from.clone(), recipient)?,
_ => ()
};
@@ -1211,7 +1218,7 @@
match target_collection.mode
{
CollectionMode::NFT => Self::set_nft_variable_data(collection_id, item_id, data)?,
- CollectionMode::ReFungible(_) => Self::set_re_fungible_variable_data(collection_id, item_id, data)?,
+ CollectionMode::ReFungible => Self::set_re_fungible_variable_data(collection_id, item_id, data)?,
CollectionMode::Fungible(_) => fail!(Error::<T>::CantStoreMetadataInFungibleTokens),
_ => fail!(Error::<T>::UnexpectedCollectionType)
};
@@ -1551,7 +1558,7 @@
{
CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient)?,
CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, value, &sender, &recipient)?,
- CollectionMode::ReFungible(_) => Self::transfer_refungible(collection_id, item_id, value, sender.clone(), recipient)?,
+ CollectionMode::ReFungible => Self::transfer_refungible(collection_id, item_id, value, sender.clone(), recipient)?,
_ => ()
};
@@ -1603,12 +1610,16 @@
fail!(Error::<T>::NotFungibleDataUsedToMintFungibleCollectionToken);
}
},
- CollectionMode::ReFungible(_) => {
+ CollectionMode::ReFungible => {
if let CreateItemData::ReFungible(data) = data {
// check sizes
ensure!(ChainLimit::get().custom_data_limit >= data.const_data.len() as u32, Error::<T>::TokenConstDataLimitExceeded);
ensure!(ChainLimit::get().custom_data_limit >= data.variable_data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);
+
+ // Check refungibility limits
+ ensure!(data.pieces <= MAX_REFUNGIBLE_PIECES, Error::<T>::WrongRefungiblePieces);
+ ensure!(data.pieces > 0, Error::<T>::WrongRefungiblePieces);
} else {
fail!(Error::<T>::NotReFungibleDataUsedToMintReFungibleCollectionToken);
}
@@ -1619,7 +1630,7 @@
Ok(())
}
- fn create_item_no_validation(collection_id: CollectionId, collection: &CollectionType<T::AccountId>, owner: T::AccountId, data: CreateItemData) -> DispatchResult {
+ fn create_item_no_validation(collection_id: CollectionId, owner: T::AccountId, data: CreateItemData) -> DispatchResult {
match data
{
CreateItemData::NFT(data) => {
@@ -1636,8 +1647,7 @@
},
CreateItemData::ReFungible(data) => {
let mut owner_list = Vec::new();
- let value = (10 as u128).pow(collection.decimal_points as u32);
- owner_list.push(Ownership {owner: owner.clone(), fraction: value});
+ owner_list.push(Ownership {owner: owner.clone(), fraction: data.pieces});
let item = ReFungibleItemType {
owner: owner_list,
@@ -1866,7 +1876,7 @@
CollectionMode::Fungible(_) => {
<FungibleItemList<T>>::contains_key(collection_id, &subject)
}
- CollectionMode::ReFungible(_) => {
+ CollectionMode::ReFungible => {
<ReFungibleItemList<T>>::get(collection_id, item_id)
.owner
.iter()
@@ -1895,7 +1905,7 @@
{
CollectionMode::NFT => <NftItemList<T>>::contains_key(collection_id, item_id),
CollectionMode::Fungible(_) => <FungibleItemList<T>>::contains_key(collection_id, owner),
- CollectionMode::ReFungible(_) => <ReFungibleItemList<T>>::contains_key(collection_id, item_id),
+ CollectionMode::ReFungible => <ReFungibleItemList<T>>::contains_key(collection_id, item_id),
_ => false
};
@@ -2421,7 +2431,7 @@
sponsored
}
- CollectionMode::ReFungible(_) => {
+ CollectionMode::ReFungible => {
// get correct limit
let limit: u32 = if collection_limits.sponsor_transfer_timeout > 0 {
pallets/nft/src/tests.rsdiffbeforeafterboth1// Tests to be written here2use super::*;3use crate::mock::*;4use crate::{AccessMode, CollectionMode,5 Ownership, ChainLimits, CreateItemData, CreateNftData, CreateFungibleData, CreateReFungibleData,6 CollectionId, TokenId, MAX_DECIMAL_POINTS};7use frame_support::{assert_noop, assert_ok};8use frame_system::{ RawOrigin };910fn default_collection_numbers_limit() -> u32 {11 1012}1314fn default_limits() {15 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits {16 collection_numbers_limit: default_collection_numbers_limit(),17 account_token_ownership_limit: 10,18 collections_admins_limit: 5,19 custom_data_limit: 2048,20 nft_sponsor_transfer_timeout: 15,21 fungible_sponsor_transfer_timeout: 15,22 refungible_sponsor_transfer_timeout: 15,23 const_on_chain_schema_limit: 1024,24 offchain_schema_limit: 1024,25 variable_on_chain_schema_limit: 1024,26 }));27}2829fn default_nft_data() -> CreateNftData {30 CreateNftData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] }31}3233fn default_fungible_data () -> CreateFungibleData {34 CreateFungibleData { value: 5 }35}3637fn default_re_fungible_data () -> CreateReFungibleData {38 CreateReFungibleData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] }39}4041fn create_test_collection_for_owner(mode: &CollectionMode, owner: u64, id: CollectionId) -> CollectionId {42 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();43 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();44 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();4546 let origin1 = Origin::signed(owner);47 assert_ok!(TemplateModule::create_collection(48 origin1.clone(),49 col_name1.clone(),50 col_desc1.clone(),51 token_prefix1.clone(),52 mode.clone()53 ));5455 let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();56 let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();57 let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();58 assert_eq!(TemplateModule::collection(id).owner, owner);59 assert_eq!(TemplateModule::collection(id).name, saved_col_name);60 assert_eq!(TemplateModule::collection(id).mode, *mode);61 assert_eq!(TemplateModule::collection(id).description, saved_description);62 assert_eq!(TemplateModule::collection(id).token_prefix, saved_prefix);63 id64}6566fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {67 create_test_collection_for_owner(&mode, 1, id)68}6970fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {71 let origin1 = Origin::signed(1);72 assert_ok!(TemplateModule::create_item(73 origin1.clone(),74 collection_id,75 1,76 data.clone()77 ));7879}8081// Use cases tests region82// #region8384#[test]85fn set_version_schema() {86 new_test_ext().execute_with(|| {87 default_limits();88 let origin1 = Origin::signed(1);89 let collection_id = create_test_collection(&CollectionMode::NFT, 1);90 91 assert_ok!(TemplateModule::set_schema_version(origin1, collection_id, SchemaVersion::Unique));92 assert_eq!(TemplateModule::collection(collection_id).schema_version, SchemaVersion::Unique);93 });94}9596#[test]97fn create_fungible_collection_fails_with_large_decimal_numbers() {98 new_test_ext().execute_with(|| {99 default_limits();100101 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();102 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();103 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();104105 let origin1 = Origin::signed(1);106 assert_noop!(TemplateModule::create_collection(107 origin1,108 col_name1,109 col_desc1,110 token_prefix1,111 CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1)112 ), Error::<Test>::CollectionDecimalPointLimitExceeded);113 }); 114}115116#[test]117fn create_re_fungible_collection_fails_with_large_decimal_numbers() {118 new_test_ext().execute_with(|| {119 default_limits();120121 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();122 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();123 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();124125 let origin1 = Origin::signed(1);126 assert_noop!(TemplateModule::create_collection(127 origin1,128 col_name1,129 col_desc1,130 token_prefix1,131 CollectionMode::ReFungible(MAX_DECIMAL_POINTS + 1)132 ), Error::<Test>::CollectionDecimalPointLimitExceeded);133 });134}135136#[test]137fn create_nft_item() {138 new_test_ext().execute_with(|| {139 default_limits();140 let collection_id = create_test_collection(&CollectionMode::NFT, 1);141 142 let data = default_nft_data();143 create_test_item(collection_id, &data.clone().into());144 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).const_data, data.const_data);145 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, data.variable_data);146 });147}148149// Use cases tests region150// #region151#[test]152fn create_nft_multiple_items() {153 new_test_ext().execute_with(|| {154 default_limits();155 156 create_test_collection(&CollectionMode::NFT, 1);157158 let origin1 = Origin::signed(1);159160 let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];161162 assert_ok!(TemplateModule::create_multiple_items(163 origin1.clone(),164 1,165 1,166 items_data.clone().into_iter().map(|d| { d.into() }).collect()167 ));168 for (index, data) in items_data.iter().enumerate() {169 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).const_data.to_vec(), data.const_data);170 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).variable_data.to_vec(), data.variable_data);171 }172 });173}174175#[test]176fn create_refungible_item() {177 new_test_ext().execute_with(|| {178 default_limits();179 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);180181 let data = default_re_fungible_data();182 create_test_item(collection_id, &data.clone().into());183 assert_eq!(184 TemplateModule::refungible_item_id(collection_id, 1).const_data,185 data.const_data186 );187 assert_eq!(188 TemplateModule::refungible_item_id(collection_id, 1).variable_data,189 data.variable_data190 );191 assert_eq!(192 TemplateModule::refungible_item_id(collection_id, 1).owner[0],193 Ownership {194 owner: 1,195 fraction: 1000196 }197 );198 });199}200201#[test]202fn create_multiple_refungible_items() {203 new_test_ext().execute_with(|| {204 default_limits();205 206 create_test_collection(&CollectionMode::ReFungible(3), 1);207208 let origin1 = Origin::signed(1);209210 let items_data = vec![default_re_fungible_data(), default_re_fungible_data(), default_re_fungible_data()];211212 assert_ok!(TemplateModule::create_multiple_items(213 origin1.clone(),214 1,215 1,216 items_data.clone().into_iter().map(|d| { d.into() }).collect()217 ));218 for (index, data) in items_data.iter().enumerate() {219220 let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId);221 assert_eq!(item.const_data.to_vec(), data.const_data);222 assert_eq!(item.variable_data.to_vec(), data.variable_data);223 assert_eq!(224 item.owner[0],225 Ownership {226 owner: 1,227 fraction: 1000228 }229 );230 }231 });232}233234#[test]235fn create_fungible_item() {236 new_test_ext().execute_with(|| {237 default_limits();238 239 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);240241 let data = default_fungible_data();242 create_test_item(collection_id, &data.into());243244 assert_eq!(TemplateModule::fungible_item_id(collection_id, 1).value, 5);245 });246}247248//#[test]249// fn create_multiple_fungible_items() {250// new_test_ext().execute_with(|| {251// default_limits();252253// create_test_collection(&CollectionMode::Fungible(3), 1);254255// let origin1 = Origin::signed(1);256257// let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];258259// assert_ok!(TemplateModule::create_multiple_items(260// origin1.clone(),261// 1,262// 1,263// items_data.clone().into_iter().map(|d| { d.into() }).collect()264// ));265 266// for (index, _) in items_data.iter().enumerate() {267// assert_eq!(TemplateModule::fungible_item_id(1, (index + 1) as TokenId).value, 5);268// }269// assert_eq!(TemplateModule::balance_count(1, 1), 3000);270// assert_eq!(TemplateModule::address_tokens(1, 1), [1, 2, 3]);271// });272// }273274#[test]275fn transfer_fungible_item() {276 new_test_ext().execute_with(|| {277 default_limits();278 279 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);280281 let origin1 = Origin::signed(1);282 let origin2 = Origin::signed(2);283284 let data = default_fungible_data();285 create_test_item(collection_id, &data.into());286287 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 5);288 assert_eq!(TemplateModule::balance_count(1, 1), 5);289290 // change owner scenario291 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 5));292 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 0);293 assert_eq!(TemplateModule::balance_count(1, 1), 0);294 assert_eq!(TemplateModule::balance_count(1, 2), 5);295296 // split item scenario297 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 3));298 assert_eq!(TemplateModule::balance_count(1, 2), 2);299 assert_eq!(TemplateModule::balance_count(1, 3), 3);300301 // split item and new owner has account scenario302 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 1));303 assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 1);304 assert_eq!(TemplateModule::fungible_item_id(1, 3).value, 4);305 assert_eq!(TemplateModule::balance_count(1, 2), 1);306 assert_eq!(TemplateModule::balance_count(1, 3), 4);307 });308}309310#[test]311fn transfer_refungible_item() {312 new_test_ext().execute_with(|| {313 default_limits();314 315 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);316317 let data = default_re_fungible_data();318 create_test_item(collection_id, &data.clone().into());319320 let origin1 = Origin::signed(1);321 let origin2 = Origin::signed(2);322 assert_eq!(323 TemplateModule::refungible_item_id(collection_id, 1).const_data,324 data.const_data325 );326 assert_eq!(327 TemplateModule::refungible_item_id(collection_id, 1).variable_data,328 data.variable_data329 );330 assert_eq!(331 TemplateModule::refungible_item_id(collection_id, 1).owner[0],332 Ownership {333 owner: 1,334 fraction: 1000335 }336 );337 assert_eq!(TemplateModule::balance_count(1, 1), 1000);338 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);339340 // change owner scenario341 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));342 assert_eq!(343 TemplateModule::refungible_item_id(1, 1).owner[0],344 Ownership {345 owner: 2,346 fraction: 1000347 }348 );349 assert_eq!(TemplateModule::balance_count(1, 1), 0);350 assert_eq!(TemplateModule::balance_count(1, 2), 1000);351 // assert_eq!(TemplateModule::address_tokens(1, 1), []);352 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);353354 // split item scenario355 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));356 assert_eq!(357 TemplateModule::refungible_item_id(1, 1).owner[0],358 Ownership {359 owner: 2,360 fraction: 500361 }362 );363 assert_eq!(364 TemplateModule::refungible_item_id(1, 1).owner[1],365 Ownership {366 owner: 3,367 fraction: 500368 }369 );370 assert_eq!(TemplateModule::balance_count(1, 2), 500);371 assert_eq!(TemplateModule::balance_count(1, 3), 500);372 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);373 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);374375 // split item and new owner has account scenario376 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));377 assert_eq!(378 TemplateModule::refungible_item_id(1, 1).owner[0],379 Ownership {380 owner: 2,381 fraction: 300382 }383 );384 assert_eq!(385 TemplateModule::refungible_item_id(1, 1).owner[1],386 Ownership {387 owner: 3,388 fraction: 700389 }390 );391 assert_eq!(TemplateModule::balance_count(1, 2), 300);392 assert_eq!(TemplateModule::balance_count(1, 3), 700);393 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);394 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);395 });396}397398#[test]399fn transfer_nft_item() {400 new_test_ext().execute_with(|| {401 default_limits();402 403 let collection_id = create_test_collection(&CollectionMode::NFT, 1);404405 let data = default_nft_data();406 create_test_item(collection_id, &data.into());407 assert_eq!(TemplateModule::balance_count(1, 1), 1);408 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);409410 let origin1 = Origin::signed(1);411 // default scenario412 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));413 assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2);414 assert_eq!(TemplateModule::balance_count(1, 1), 0);415 assert_eq!(TemplateModule::balance_count(1, 2), 1);416 // assert_eq!(TemplateModule::address_tokens(1, 1), []);417 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);418 });419}420421#[test]422fn nft_approve_and_transfer_from() {423 new_test_ext().execute_with(|| {424 default_limits();425 426 let collection_id = create_test_collection(&CollectionMode::NFT, 1);427428 let data = default_nft_data();429 create_test_item(collection_id, &data.into());430431 let origin1 = Origin::signed(1);432 let origin2 = Origin::signed(2);433434 assert_eq!(TemplateModule::balance_count(1, 1), 1);435 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);436437 // neg transfer438 assert_noop!(TemplateModule::transfer_from(439 origin2.clone(),440 1,441 2,442 1,443 1,444 1), Error::<Test>::NoPermission);445446 // do approve447 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));448 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);449 assert_eq!(450 TemplateModule::approved(1, (1, 1, 2)),451 5452 );453454 assert_ok!(TemplateModule::transfer_from(455 origin2.clone(),456 1,457 3,458 1,459 1,460 1461 ));462 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);463 });464}465466#[test]467fn nft_approve_and_transfer_from_white_list() {468 new_test_ext().execute_with(|| {469 default_limits();470 471 let collection_id = create_test_collection(&CollectionMode::NFT, 1);472473 let origin1 = Origin::signed(1);474 let origin2 = Origin::signed(2);475476 let data = default_nft_data();477 create_test_item(collection_id, &data.clone().into());478479 assert_eq!(TemplateModule::nft_item_id(1, 1).const_data, data.const_data);480 assert_eq!(TemplateModule::balance_count(1, 1), 1);481 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);482483 assert_ok!(TemplateModule::set_mint_permission(484 origin1.clone(),485 1,486 true487 ));488 assert_ok!(TemplateModule::set_public_access_mode(489 origin1.clone(),490 1,491 AccessMode::WhiteList492 ));493 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));494 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));495 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));496497 // do approve498 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));499 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);500 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1, 5));501 assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);502503 assert_ok!(TemplateModule::transfer_from(504 origin2.clone(),505 1,506 3,507 1,508 1,509 1510 ));511 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);512 });513}514515#[test]516fn refungible_approve_and_transfer_from() {517 new_test_ext().execute_with(|| {518 default_limits();519 520 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);521 522 let origin1 = Origin::signed(1);523 let origin2 = Origin::signed(2);524525 let data = default_re_fungible_data();526 create_test_item(collection_id, &data.into());527528 assert_eq!(TemplateModule::balance_count(1, 1), 1000);529 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);530531 assert_ok!(TemplateModule::set_mint_permission(532 origin1.clone(),533 1,534 true535 ));536 assert_ok!(TemplateModule::set_public_access_mode(537 origin1.clone(),538 1,539 AccessMode::WhiteList540 ));541 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));542 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));543 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));544545 // do approve546 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 1000));547 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1000);548549 assert_ok!(TemplateModule::transfer_from(550 origin2.clone(),551 1,552 3,553 1,554 1,555 100556 ));557 assert_eq!(TemplateModule::balance_count(1, 1), 900);558 assert_eq!(TemplateModule::balance_count(1, 3), 100);559 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);560 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);561562 assert_eq!(563 TemplateModule::approved(1, (1, 1, 2)),564 900565 );566 });567}568569#[test]570fn fungible_approve_and_transfer_from() {571 new_test_ext().execute_with(|| {572 default_limits();573 574 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);575 576 let data = default_fungible_data();577 create_test_item(collection_id, &data.into());578579 let origin1 = Origin::signed(1);580 let origin2 = Origin::signed(2);581582 assert_eq!(TemplateModule::balance_count(1, 1), 5);583584 assert_ok!(TemplateModule::set_mint_permission(585 origin1.clone(),586 1,587 true588 ));589 assert_ok!(TemplateModule::set_public_access_mode(590 origin1.clone(),591 1,592 AccessMode::WhiteList593 ));594 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));595 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));596 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));597598 // do approve599 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));600 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);601 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1, 5));602 assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);603 assert_eq!(604 TemplateModule::approved(1, (1, 1, 2)),605 5606 );607608 assert_ok!(TemplateModule::transfer_from(609 origin2.clone(),610 1,611 3,612 1,613 1,614 4615 ));616 assert_eq!(TemplateModule::balance_count(1, 1), 1);617 assert_eq!(TemplateModule::balance_count(1, 3), 4);618619 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);620621 assert_noop!(TemplateModule::transfer_from(622 origin2.clone(),623 1,624 3,625 1,626 1,627 4628 ), Error::<Test>::TokenValueNotEnough);629 });630}631632#[test]633fn change_collection_owner() {634 new_test_ext().execute_with(|| {635 default_limits();636 637 let collection_id = create_test_collection(&CollectionMode::NFT, 1);638 639 let origin1 = Origin::signed(1);640 assert_ok!(TemplateModule::change_collection_owner(641 origin1.clone(),642 collection_id,643 2644 ));645 assert_eq!(TemplateModule::collection(collection_id).owner, 2);646 });647}648649#[test]650fn destroy_collection() {651 new_test_ext().execute_with(|| {652 default_limits();653 654 let collection_id = create_test_collection(&CollectionMode::NFT, 1);655 656 let origin1 = Origin::signed(1);657 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));658 });659}660661#[test]662fn burn_nft_item() {663 new_test_ext().execute_with(|| {664 default_limits();665 666 let collection_id = create_test_collection(&CollectionMode::NFT, 1);667668 let origin1 = Origin::signed(1);669 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));670 671 let data = default_nft_data();672 create_test_item(collection_id, &data.into());673674 // check balance (collection with id = 1, user id = 1)675 assert_eq!(TemplateModule::balance_count(1, 1), 1);676677 // burn item678 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));679 assert_noop!(680 TemplateModule::burn_item(origin1.clone(), 1, 1, 5),681 Error::<Test>::TokenNotFound682 );683684 assert_eq!(TemplateModule::balance_count(1, 1), 0);685 });686}687688#[test]689fn burn_fungible_item() {690 new_test_ext().execute_with(|| {691 default_limits();692 693 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);694 695 let origin1 = Origin::signed(1);696 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));697 698 let data = default_fungible_data();699 create_test_item(collection_id, &data.into());700701 // check balance (collection with id = 1, user id = 1)702 assert_eq!(TemplateModule::balance_count(1, 1), 5);703704 // burn item705 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));706 assert_noop!(707 TemplateModule::burn_item(origin1.clone(), 1, 1, 5),708 Error::<Test>::TokenNotFound709 );710711 assert_eq!(TemplateModule::balance_count(1, 1), 0);712 });713}714715#[test]716fn burn_refungible_item() {717 new_test_ext().execute_with(|| {718 default_limits();719 720 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);721 let origin1 = Origin::signed(1);722723 assert_ok!(TemplateModule::set_mint_permission(724 origin1.clone(),725 collection_id,726 true727 ));728 assert_ok!(TemplateModule::set_public_access_mode(729 origin1.clone(),730 collection_id,731 AccessMode::WhiteList732 ));733 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));734735 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));736 737 let data = default_re_fungible_data();738 create_test_item(collection_id, &data.into());739740 // check balance (collection with id = 1, user id = 2)741 assert_eq!(TemplateModule::balance_count(1, 1), 1000);742743 // burn item744 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 1000));745 assert_noop!(746 TemplateModule::burn_item(origin1.clone(), 1, 1, 1000),747 Error::<Test>::TokenNotFound748 );749750 assert_eq!(TemplateModule::balance_count(1, 1), 0);751 });752}753754#[test]755fn add_collection_admin() {756 new_test_ext().execute_with(|| {757 default_limits();758 759 let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);760 create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);761 create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);762 763 let origin1 = Origin::signed(1);764765 // collection admin766 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));767 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));768769 assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&2), true);770 assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&3), true);771 });772}773774#[test]775fn remove_collection_admin() {776 new_test_ext().execute_with(|| {777 default_limits();778 779 let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);780 create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);781 create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);782783 let origin1 = Origin::signed(1);784 let origin2 = Origin::signed(2);785786 // collection admin787 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));788 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));789790 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);791 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);792793 // remove admin794 assert_ok!(TemplateModule::remove_collection_admin(795 origin2.clone(),796 1,797 3798 ));799 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), false);800 });801}802803#[test]804fn balance_of() {805 new_test_ext().execute_with(|| {806 default_limits();807 808 let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);809 let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);810 let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible(3), 3);811 812 // check balance before813 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);814 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);815 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 0);816817 let nft_data = default_nft_data();818 create_test_item(nft_collection_id, &nft_data.into());819 820 let fungible_data = default_fungible_data();821 create_test_item(fungible_collection_id, &fungible_data.into());822 823 let re_fungible_data = default_re_fungible_data();824 create_test_item(re_fungible_collection_id, &re_fungible_data.into());825826 // check balance (collection with id = 1, user id = 1)827 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1);828 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 5);829 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 1000);830 assert_eq!(TemplateModule::nft_item_id(nft_collection_id, 1).owner, 1);831 assert_eq!(TemplateModule::fungible_item_id(fungible_collection_id, 1).value, 5);832 assert_eq!(TemplateModule::refungible_item_id(re_fungible_collection_id, 1).owner[0].owner, 1);833 });834}835836#[test]837fn approve() {838 new_test_ext().execute_with(|| {839 default_limits();840 841 let collection_id = create_test_collection(&CollectionMode::NFT, 1);842 843 let data = default_nft_data();844 create_test_item(collection_id, &data.into());845846 let origin1 = Origin::signed(1);847 848 // approve849 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 1));850 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);851 });852}853854#[test]855fn transfer_from() {856 new_test_ext().execute_with(|| {857 default_limits();858 859 let collection_id = create_test_collection(&CollectionMode::NFT, 1);860 let origin1 = Origin::signed(1);861 let origin2 = Origin::signed(2);862863 let data = default_nft_data();864 create_test_item(collection_id, &data.into());865866 // approve867 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 1));868 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);869870 assert_ok!(TemplateModule::set_mint_permission(871 origin1.clone(),872 1,873 true874 ));875 assert_ok!(TemplateModule::set_public_access_mode(876 origin1.clone(),877 1,878 AccessMode::WhiteList879 ));880 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));881 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));882 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));883884 assert_ok!(TemplateModule::transfer_from(885 origin2.clone(),886 1,887 2,888 1,889 1,890 1891 ));892893 // after transfer894 assert_eq!(TemplateModule::balance_count(1, 1), 0);895 assert_eq!(TemplateModule::balance_count(1, 2), 1);896 });897}898899// #endregion900901// Coverage tests region902// #region903904#[test]905fn owner_can_add_address_to_white_list() {906 new_test_ext().execute_with(|| {907 default_limits();908 909 let collection_id = create_test_collection(&CollectionMode::NFT, 1);910911 let origin1 = Origin::signed(1);912 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));913 assert_eq!(TemplateModule::white_list(collection_id, 2), true);914 });915}916917#[test]918fn admin_can_add_address_to_white_list() {919 new_test_ext().execute_with(|| {920 default_limits();921 922 let collection_id = create_test_collection(&CollectionMode::NFT, 1);923 let origin1 = Origin::signed(1);924 let origin2 = Origin::signed(2);925926 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));927 assert_ok!(TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3));928 assert_eq!(TemplateModule::white_list(collection_id, 3), true);929 });930}931932#[test]933fn nonprivileged_user_cannot_add_address_to_white_list() {934 new_test_ext().execute_with(|| {935 default_limits();936 937 let collection_id = create_test_collection(&CollectionMode::NFT, 1);938939 let origin2 = Origin::signed(2);940 assert_noop!(941 TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3),942 Error::<Test>::NoPermission943 );944 });945}946947#[test]948fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {949 new_test_ext().execute_with(|| {950 default_limits();951952 let origin1 = Origin::signed(1);953954 assert_noop!(955 TemplateModule::add_to_white_list(origin1.clone(), 1, 2),956 Error::<Test>::CollectionNotFound957 );958 });959}960961#[test]962fn nobody_can_add_address_to_white_list_of_deleted_collection() {963 new_test_ext().execute_with(|| {964 default_limits();965 966 let collection_id = create_test_collection(&CollectionMode::NFT, 1);967968 let origin1 = Origin::signed(1);969 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));970 assert_noop!(971 TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2),972 Error::<Test>::CollectionNotFound973 );974 });975}976977// If address is already added to white list, nothing happens978#[test]979fn address_is_already_added_to_white_list() {980 new_test_ext().execute_with(|| {981 default_limits();982 983 let collection_id = create_test_collection(&CollectionMode::NFT, 1);984 let origin1 = Origin::signed(1);985 986 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));987 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));988 assert_eq!(TemplateModule::white_list(collection_id, 2), true);989 });990}991992#[test]993fn owner_can_remove_address_from_white_list() {994 new_test_ext().execute_with(|| {995 default_limits();996 997 let collection_id = create_test_collection(&CollectionMode::NFT, 1);998999 let origin1 = Origin::signed(1);1000 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1001 assert_ok!(TemplateModule::remove_from_white_list(1002 origin1.clone(),1003 collection_id,1004 21005 ));1006 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1007 });1008}10091010#[test]1011fn admin_can_remove_address_from_white_list() {1012 new_test_ext().execute_with(|| {1013 default_limits();1014 1015 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1016 let origin1 = Origin::signed(1);1017 let origin2 = Origin::signed(2);10181019 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));10201021 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 3));1022 assert_ok!(TemplateModule::remove_from_white_list(1023 origin2.clone(),1024 collection_id,1025 31026 ));1027 assert_eq!(TemplateModule::white_list(collection_id, 3), false);1028 });1029}10301031#[test]1032fn nonprivileged_user_cannot_remove_address_from_white_list() {1033 new_test_ext().execute_with(|| {1034 default_limits();1035 1036 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1037 let origin1 = Origin::signed(1);1038 let origin2 = Origin::signed(2);10391040 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1041 assert_noop!(1042 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1043 Error::<Test>::NoPermission1044 );1045 assert_eq!(TemplateModule::white_list(collection_id, 2), true);1046 });1047}10481049#[test]1050fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1051 new_test_ext().execute_with(|| {1052 default_limits();1053 let origin1 = Origin::signed(1);10541055 assert_noop!(1056 TemplateModule::remove_from_white_list(origin1.clone(), 1, 2),1057 Error::<Test>::CollectionNotFound1058 );1059 });1060}10611062#[test]1063fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1064 new_test_ext().execute_with(|| {1065 default_limits();1066 1067 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1068 let origin1 = Origin::signed(1);1069 let origin2 = Origin::signed(2);10701071 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1072 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1073 assert_noop!(1074 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1075 Error::<Test>::CollectionNotFound1076 );1077 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1078 });1079}10801081// If address is already removed from white list, nothing happens1082#[test]1083fn address_is_already_removed_from_white_list() {1084 new_test_ext().execute_with(|| {1085 default_limits();1086 1087 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1088 let origin1 = Origin::signed(1);10891090 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1091 assert_ok!(TemplateModule::remove_from_white_list(1092 origin1.clone(),1093 collection_id,1094 21095 ));1096 assert_ok!(TemplateModule::remove_from_white_list(1097 origin1.clone(),1098 collection_id,1099 21100 ));1101 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1102 });1103}11041105// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1106#[test]1107fn white_list_test_1() {1108 new_test_ext().execute_with(|| {1109 default_limits();1110 1111 let collection_id = create_test_collection(&CollectionMode::NFT, 1);11121113 let origin1 = Origin::signed(1);1114 1115 let data = default_nft_data();1116 create_test_item(collection_id, &data.into());11171118 assert_ok!(TemplateModule::set_public_access_mode(1119 origin1.clone(),1120 collection_id,1121 AccessMode::WhiteList1122 ));1123 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));11241125 assert_noop!(1126 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1127 Error::<Test>::AddresNotInWhiteList1128 );1129 });1130}11311132#[test]1133fn white_list_test_2() {1134 new_test_ext().execute_with(|| {1135 default_limits();1136 1137 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1138 let origin1 = Origin::signed(1);1139 1140 let data = default_nft_data();1141 create_test_item(collection_id, &data.into());11421143 assert_ok!(TemplateModule::set_public_access_mode(1144 origin1.clone(),1145 collection_id,1146 AccessMode::WhiteList1147 ));1148 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1149 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));11501151 // do approve1152 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1, 1));1153 assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);11541155 assert_ok!(TemplateModule::remove_from_white_list(1156 origin1.clone(),1157 1,1158 11159 ));11601161 assert_noop!(1162 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1163 Error::<Test>::AddresNotInWhiteList1164 );1165 });1166}11671168// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1169#[test]1170fn white_list_test_3() {1171 new_test_ext().execute_with(|| {1172 default_limits();1173 1174 let collection_id = create_test_collection(&CollectionMode::NFT, 1);11751176 let origin1 = Origin::signed(1);1177 1178 let data = default_nft_data();1179 create_test_item(collection_id, &data.into());11801181 assert_ok!(TemplateModule::set_public_access_mode(1182 origin1.clone(),1183 collection_id,1184 AccessMode::WhiteList1185 ));1186 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));11871188 assert_noop!(1189 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1190 Error::<Test>::AddresNotInWhiteList1191 );1192 });1193}11941195#[test]1196fn white_list_test_4() {1197 new_test_ext().execute_with(|| {1198 default_limits();1199 1200 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12011202 let origin1 = Origin::signed(1);12031204 let data = default_nft_data();1205 create_test_item(collection_id, &data.into());12061207 assert_ok!(TemplateModule::set_public_access_mode(1208 origin1.clone(),1209 collection_id,1210 AccessMode::WhiteList1211 ));1212 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1213 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));12141215 // do approve1216 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1, 1));1217 assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);12181219 assert_ok!(TemplateModule::remove_from_white_list(1220 origin1.clone(),1221 collection_id,1222 21223 ));12241225 assert_noop!(1226 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1227 Error::<Test>::AddresNotInWhiteList1228 );1229 });1230}12311232// 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)1233#[test]1234fn white_list_test_5() {1235 new_test_ext().execute_with(|| {1236 default_limits();1237 1238 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12391240 let origin1 = Origin::signed(1);12411242 let data = default_nft_data();1243 create_test_item(collection_id, &data.into());12441245 assert_ok!(TemplateModule::set_public_access_mode(1246 origin1.clone(),1247 collection_id,1248 AccessMode::WhiteList1249 ));1250 assert_noop!(1251 TemplateModule::burn_item(origin1.clone(), 1, 1, 5),1252 Error::<Test>::AddresNotInWhiteList1253 );1254 });1255}12561257// If Public Access mode is set to WhiteList, token transfers can’t be Approved by a non-whitelisted address (see Approve method).1258#[test]1259fn white_list_test_6() {1260 new_test_ext().execute_with(|| {1261 default_limits();1262 1263 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12641265 let origin1 = Origin::signed(1);12661267 let data = default_nft_data();1268 create_test_item(collection_id, &data.into());12691270 assert_ok!(TemplateModule::set_public_access_mode(1271 origin1.clone(),1272 collection_id,1273 AccessMode::WhiteList1274 ));12751276 // do approve1277 assert_noop!(1278 TemplateModule::approve(origin1.clone(), 1, 1, 1, 5),1279 Error::<Test>::AddresNotInWhiteList1280 );1281 });1282}12831284// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1285// tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1286#[test]1287fn white_list_test_7() {1288 new_test_ext().execute_with(|| {1289 default_limits();1290 1291 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12921293 let data = default_nft_data();1294 create_test_item(collection_id, &data.into());1295 1296 let origin1 = Origin::signed(1);12971298 assert_ok!(TemplateModule::set_public_access_mode(1299 origin1.clone(),1300 collection_id,1301 AccessMode::WhiteList1302 ));1303 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1304 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13051306 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1));1307 });1308}13091310#[test]1311fn white_list_test_8() {1312 new_test_ext().execute_with(|| {1313 default_limits();1314 1315 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13161317 let data = default_nft_data();1318 create_test_item(collection_id, &data.into());1319 1320 let origin1 = Origin::signed(1);13211322 assert_ok!(TemplateModule::set_public_access_mode(1323 origin1.clone(),1324 collection_id,1325 AccessMode::WhiteList1326 ));1327 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1328 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13291330 // do approve1331 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1, 5));1332 assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 5);13331334 assert_ok!(TemplateModule::transfer_from(1335 origin1.clone(),1336 1,1337 2,1338 1,1339 1,1340 11341 ));1342 });1343}13441345// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1346#[test]1347fn white_list_test_9() {1348 new_test_ext().execute_with(|| {1349 default_limits();1350 1351 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1352 let origin1 = Origin::signed(1);13531354 assert_ok!(TemplateModule::set_public_access_mode(1355 origin1.clone(),1356 collection_id,1357 AccessMode::WhiteList1358 ));1359 assert_ok!(TemplateModule::set_mint_permission(1360 origin1.clone(),1361 collection_id,1362 false1363 ));13641365 let data = default_nft_data();1366 create_test_item(collection_id, &data.into());1367 });1368}13691370// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1371#[test]1372fn white_list_test_10() {1373 new_test_ext().execute_with(|| {1374 default_limits();1375 1376 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13771378 let origin1 = Origin::signed(1);1379 let origin2 = Origin::signed(2);13801381 assert_ok!(TemplateModule::set_public_access_mode(1382 origin1.clone(),1383 collection_id,1384 AccessMode::WhiteList1385 ));1386 assert_ok!(TemplateModule::set_mint_permission(1387 origin1.clone(),1388 collection_id,1389 false1390 ));13911392 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));13931394 assert_ok!(TemplateModule::create_item(1395 origin2.clone(),1396 collection_id,1397 2,1398 default_nft_data().into()1399 ));1400 });1401}14021403// 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.1404#[test]1405fn white_list_test_11() {1406 new_test_ext().execute_with(|| {1407 default_limits();1408 1409 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14101411 let origin1 = Origin::signed(1);1412 let origin2 = Origin::signed(2);14131414 assert_ok!(TemplateModule::set_public_access_mode(1415 origin1.clone(),1416 collection_id,1417 AccessMode::WhiteList1418 ));1419 assert_ok!(TemplateModule::set_mint_permission(1420 origin1.clone(),1421 collection_id,1422 false1423 ));1424 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));14251426 assert_noop!(1427 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1428 Error::<Test>::PublicMintingNotAllowed1429 );1430 });1431}14321433// 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.1434#[test]1435fn white_list_test_12() {1436 new_test_ext().execute_with(|| {1437 default_limits();1438 1439 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14401441 let origin1 = Origin::signed(1);1442 let origin2 = Origin::signed(2);14431444 assert_ok!(TemplateModule::set_public_access_mode(1445 origin1.clone(),1446 collection_id,1447 AccessMode::WhiteList1448 ));1449 assert_ok!(TemplateModule::set_mint_permission(1450 origin1.clone(),1451 collection_id,1452 false1453 ));14541455 assert_noop!(1456 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1457 Error::<Test>::PublicMintingNotAllowed1458 );1459 });1460}14611462// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1463#[test]1464fn white_list_test_13() {1465 new_test_ext().execute_with(|| {1466 default_limits();1467 1468 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14691470 let origin1 = Origin::signed(1);14711472 assert_ok!(TemplateModule::set_public_access_mode(1473 origin1.clone(),1474 collection_id,1475 AccessMode::WhiteList1476 ));1477 assert_ok!(TemplateModule::set_mint_permission(1478 origin1.clone(),1479 collection_id,1480 true1481 ));14821483 let data = default_nft_data();1484 create_test_item(collection_id, &data.into());1485 });1486}14871488// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1489#[test]1490fn white_list_test_14() {1491 new_test_ext().execute_with(|| {1492 default_limits();1493 1494 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14951496 let origin1 = Origin::signed(1);1497 let origin2 = Origin::signed(2);14981499 assert_ok!(TemplateModule::set_public_access_mode(1500 origin1.clone(),1501 collection_id,1502 AccessMode::WhiteList1503 ));1504 assert_ok!(TemplateModule::set_mint_permission(1505 origin1.clone(),1506 collection_id,1507 true1508 ));15091510 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));15111512 assert_ok!(TemplateModule::create_item(1513 origin2.clone(),1514 1,1515 2,1516 default_nft_data().into()1517 ));1518 });1519}15201521// 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.1522#[test]1523fn white_list_test_15() {1524 new_test_ext().execute_with(|| {1525 default_limits();1526 1527 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15281529 let origin1 = Origin::signed(1);1530 let origin2 = Origin::signed(2);15311532 assert_ok!(TemplateModule::set_public_access_mode(1533 origin1.clone(),1534 collection_id,1535 AccessMode::WhiteList1536 ));1537 assert_ok!(TemplateModule::set_mint_permission(1538 origin1.clone(),1539 collection_id,1540 true1541 ));15421543 assert_noop!(1544 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1545 Error::<Test>::AddresNotInWhiteList1546 );1547 });1548}15491550// 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.1551#[test]1552fn white_list_test_16() {1553 new_test_ext().execute_with(|| {1554 default_limits();1555 1556 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15571558 let origin1 = Origin::signed(1);1559 let origin2 = Origin::signed(2);15601561 assert_ok!(TemplateModule::set_public_access_mode(1562 origin1.clone(),1563 collection_id,1564 AccessMode::WhiteList1565 ));1566 assert_ok!(TemplateModule::set_mint_permission(1567 origin1.clone(),1568 collection_id,1569 true1570 ));1571 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));15721573 assert_ok!(TemplateModule::create_item(1574 origin2.clone(),1575 1,1576 2,1577 default_nft_data().into()1578 ));1579 });1580}15811582// Total number of collections. Positive test1583#[test]1584fn total_number_collections_bound() {1585 new_test_ext().execute_with(|| {1586 default_limits();1587 1588 create_test_collection(&CollectionMode::NFT, 1);1589 });1590}15911592// Total number of collections. Negotive test1593#[test]1594fn total_number_collections_bound_neg() {1595 new_test_ext().execute_with(|| {1596 default_limits();15971598 let origin1 = Origin::signed(1);15991600 for i in 0..default_collection_numbers_limit() {1601 create_test_collection(&CollectionMode::NFT, i + 1);1602 }16031604 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();16071608 // 11-th collection in chain. Expects error1609 assert_noop!(TemplateModule::create_collection(1610 origin1.clone(),1611 col_name1.clone(),1612 col_desc1.clone(),1613 token_prefix1.clone(),1614 CollectionMode::NFT1615 ), Error::<Test>::TotalCollectionsLimitExceeded);1616 });1617}16181619// Owned tokens by a single address. Positive test1620#[test]1621fn owned_tokens_bound() {1622 new_test_ext().execute_with(|| {1623 default_limits();1624 1625 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16261627 let data = default_nft_data();1628 create_test_item(collection_id, &data.clone().into());1629 create_test_item(collection_id, &data.into());1630 });1631}16321633// Owned tokens by a single address. Negotive test1634#[test]1635fn owned_tokens_bound_neg() {1636 new_test_ext().execute_with(|| {1637 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1638 collection_numbers_limit: 10,1639 account_token_ownership_limit: 1,1640 collections_admins_limit: 5,1641 custom_data_limit: 2048,1642 nft_sponsor_transfer_timeout: 15,1643 fungible_sponsor_transfer_timeout: 15,1644 refungible_sponsor_transfer_timeout: 15,1645 const_on_chain_schema_limit: 1024,1646 offchain_schema_limit: 1024,1647 variable_on_chain_schema_limit: 1024,1648 }));1649 1650 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16511652 let origin1 = Origin::signed(1);1653 let data = default_nft_data();1654 create_test_item(collection_id, &data.clone().into());16551656 assert_noop!(TemplateModule::create_item(1657 origin1.clone(),1658 1,1659 1,1660 data.into()1661 ), Error::<Test>::AddressOwnershipLimitExceeded);1662 });1663}16641665// Number of collection admins. Positive test1666#[test]1667fn collection_admins_bound() {1668 new_test_ext().execute_with(|| {1669 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1670 collection_numbers_limit: 10,1671 account_token_ownership_limit: 10,1672 collections_admins_limit: 2,1673 custom_data_limit: 2048,1674 nft_sponsor_transfer_timeout: 15,1675 fungible_sponsor_transfer_timeout: 15,1676 refungible_sponsor_transfer_timeout: 15,1677 const_on_chain_schema_limit: 1024,1678 offchain_schema_limit: 1024,1679 variable_on_chain_schema_limit: 1024,1680 }));1681 1682 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16831684 let origin1 = Origin::signed(1);1685 1686 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1687 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3));1688 });1689}16901691// Number of collection admins. Negotive test1692#[test]1693fn collection_admins_bound_neg() {1694 new_test_ext().execute_with(|| {1695 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1696 collection_numbers_limit: 10,1697 account_token_ownership_limit: 1,1698 collections_admins_limit: 1,1699 custom_data_limit: 2048,1700 nft_sponsor_transfer_timeout: 15,1701 fungible_sponsor_transfer_timeout: 15,1702 refungible_sponsor_transfer_timeout: 15,1703 const_on_chain_schema_limit: 1024,1704 offchain_schema_limit: 1024,1705 variable_on_chain_schema_limit: 1024,1706 }));1707 1708 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17091710 let origin1 = Origin::signed(1);17111712 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1713 assert_noop!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3), Error::<Test>::CollectionAdminsLimitExceeded);1714 });1715}17161717// NFT custom data size. Negative test const_data.1718#[test]1719fn custom_data_size_nft_const_data_bound_neg() {1720 new_test_ext().execute_with(|| {1721 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1722 collection_numbers_limit: 10,1723 account_token_ownership_limit: 10,1724 collections_admins_limit: 5,1725 custom_data_limit: 2,1726 nft_sponsor_transfer_timeout: 15,1727 fungible_sponsor_transfer_timeout: 15,1728 refungible_sponsor_transfer_timeout: 15,1729 const_on_chain_schema_limit: 1024,1730 offchain_schema_limit: 1024,1731 variable_on_chain_schema_limit: 1024,1732 }));1733 1734 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17351736 let origin1 = Origin::signed(1);1737 let too_big_const_data = CreateItemData::NFT(CreateNftData{1738 const_data: vec![1, 2, 3, 4],1739 variable_data: vec![]1740 });17411742 assert_noop!(TemplateModule::create_item(1743 origin1.clone(),1744 collection_id,1745 1,1746 too_big_const_data1747 ), Error::<Test>::TokenConstDataLimitExceeded);1748 });1749}17501751// NFT custom data size. Negative test variable_data.1752#[test]1753fn custom_data_size_nft_variable_data_bound_neg() {1754 new_test_ext().execute_with(|| {1755 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1756 collection_numbers_limit: 10,1757 account_token_ownership_limit: 10,1758 collections_admins_limit: 5,1759 custom_data_limit: 2,1760 nft_sponsor_transfer_timeout: 15,1761 fungible_sponsor_transfer_timeout: 15,1762 refungible_sponsor_transfer_timeout: 15,1763 const_on_chain_schema_limit: 1024,1764 offchain_schema_limit: 1024,1765 variable_on_chain_schema_limit: 1024,1766 }));17671768 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17691770 let origin1 = Origin::signed(1);1771 let too_big_const_data = CreateItemData::NFT(CreateNftData{1772 const_data: vec![],1773 variable_data: vec![1, 2, 3, 4]1774 });17751776 assert_noop!(TemplateModule::create_item(1777 origin1.clone(),1778 collection_id,1779 1,1780 too_big_const_data1781 ), Error::<Test>::TokenVariableDataLimitExceeded);1782 });1783}17841785// Re fungible custom data size. Negative test const_data.1786#[test]1787fn custom_data_size_re_fungible_const_data_bound_neg() {1788 new_test_ext().execute_with(|| {1789 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1790 collection_numbers_limit: 10,1791 account_token_ownership_limit: 10,1792 collections_admins_limit: 5,1793 custom_data_limit: 2,1794 nft_sponsor_transfer_timeout: 15,1795 fungible_sponsor_transfer_timeout: 15,1796 refungible_sponsor_transfer_timeout: 15,1797 const_on_chain_schema_limit: 1024,1798 offchain_schema_limit: 1024,1799 variable_on_chain_schema_limit: 1024,1800 }));18011802 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18031804 let origin1 = Origin::signed(1);1805 let too_big_const_data = CreateItemData::NFT(CreateNftData{1806 const_data: vec![1, 2, 3, 4],1807 variable_data: vec![]1808 });18091810 assert_noop!(TemplateModule::create_item(1811 origin1.clone(),1812 collection_id,1813 1,1814 too_big_const_data1815 ), Error::<Test>::TokenConstDataLimitExceeded);1816 });1817}18181819// Re fungible custom data size. Negative test variable_data.1820#[test]1821fn custom_data_size_re_fungible_variable_data_bound_neg() {1822 new_test_ext().execute_with(|| {1823 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1824 collection_numbers_limit: 10,1825 account_token_ownership_limit: 10,1826 collections_admins_limit: 5,1827 custom_data_limit: 2,1828 nft_sponsor_transfer_timeout: 15,1829 fungible_sponsor_transfer_timeout: 15,1830 refungible_sponsor_transfer_timeout: 15,1831 const_on_chain_schema_limit: 1024,1832 offchain_schema_limit: 1024,1833 variable_on_chain_schema_limit: 1024,1834 }));18351836 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18371838 let origin1 = Origin::signed(1);1839 let too_big_const_data = CreateItemData::NFT(CreateNftData{1840 const_data: vec![],1841 variable_data: vec![1, 2, 3, 4]1842 });18431844 assert_noop!(TemplateModule::create_item(1845 origin1.clone(),1846 collection_id,1847 1,1848 too_big_const_data1849 ), Error::<Test>::TokenVariableDataLimitExceeded);1850 });1851}1852// #endregion18531854#[test]1855fn set_const_on_chain_schema() {1856 new_test_ext().execute_with(|| {1857 default_limits();18581859 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18601861 let origin1 = Origin::signed(1);1862 assert_ok!(TemplateModule::set_const_on_chain_schema(origin1, collection_id, b"test const on chain schema".to_vec()));18631864 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"test const on chain schema".to_vec());1865 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"".to_vec());1866 });1867}18681869#[test]1870fn set_variable_on_chain_schema() {1871 new_test_ext().execute_with(|| {1872 default_limits();1873 1874 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18751876 let origin1 = Origin::signed(1);1877 assert_ok!(TemplateModule::set_variable_on_chain_schema(origin1, collection_id, b"test variable on chain schema".to_vec()));18781879 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"".to_vec());1880 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"test variable on chain schema".to_vec());1881 });1882}18831884#[test]1885fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {1886 new_test_ext().execute_with(|| {1887 default_limits();18881889 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18901891 let origin1 = Origin::signed(1);1892 1893 let data = default_nft_data();1894 create_test_item(1, &data.into());1895 1896 let variable_data = b"test set_variable_meta_data method.".to_vec();1897 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));18981899 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, variable_data);1900 });1901}19021903#[test]1904fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {1905 new_test_ext().execute_with(|| {1906 default_limits();19071908 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);19091910 let origin1 = Origin::signed(1);19111912 let data = default_re_fungible_data();1913 create_test_item(1, &data.into());19141915 let variable_data = b"test set_variable_meta_data method.".to_vec();1916 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));19171918 assert_eq!(TemplateModule::refungible_item_id(collection_id, 1).variable_data, variable_data);1919 });1920}192119221923#[test]1924fn set_variable_meta_data_on_fungible_token_fails() {1925 new_test_ext().execute_with(|| {1926 default_limits();19271928 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);19291930 let origin1 = Origin::signed(1);19311932 let data = default_fungible_data();1933 create_test_item(1, &data.into());19341935 let variable_data = b"test set_variable_meta_data method.".to_vec();1936 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()), Error::<Test>::CantStoreMetadataInFungibleTokens);1937 });1938}19391940#[test]1941fn set_variable_meta_data_on_nft_token_fails_for_big_data() {1942 new_test_ext().execute_with(|| {1943 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1944 collection_numbers_limit: default_collection_numbers_limit(),1945 account_token_ownership_limit: 10,1946 collections_admins_limit: 5,1947 custom_data_limit: 10,1948 nft_sponsor_transfer_timeout: 15,1949 fungible_sponsor_transfer_timeout: 15,1950 refungible_sponsor_transfer_timeout: 15,1951 const_on_chain_schema_limit: 1024,1952 offchain_schema_limit: 1024,1953 variable_on_chain_schema_limit: 1024,1954 }));19551956 let collection_id = create_test_collection(&CollectionMode::NFT, 1);19571958 let origin1 = Origin::signed(1);19591960 let data = default_nft_data();1961 create_test_item(1, &data.into());19621963 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1964 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);1965 });1966}19671968#[test]1969fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {1970 new_test_ext().execute_with(|| {1971 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1972 collection_numbers_limit: default_collection_numbers_limit(),1973 account_token_ownership_limit: 10,1974 collections_admins_limit: 5,1975 custom_data_limit: 10,1976 nft_sponsor_transfer_timeout: 15,1977 fungible_sponsor_transfer_timeout: 15,1978 refungible_sponsor_transfer_timeout: 15,1979 const_on_chain_schema_limit: 1024,1980 offchain_schema_limit: 1024,1981 variable_on_chain_schema_limit: 1024,1982 }));198319841985 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);19861987 let origin1 = Origin::signed(1);19881989 let data = default_re_fungible_data();1990 create_test_item(1, &data.into());19911992 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1993 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);1994 });1995}runtime_types.jsondiffbeforeafterboth--- a/runtime_types.json
+++ b/runtime_types.json
@@ -1,27 +1,4 @@
{
- "Schedule": {
- "version": "u32",
- "put_code_per_byte_cost": "Gas",
- "grow_mem_cost": "Gas",
- "regular_op_cost": "Gas",
- "return_data_per_byte_cost": "Gas",
- "event_data_per_byte_cost": "Gas",
- "event_per_topic_cost": "Gas",
- "event_base_cost": "Gas",
- "call_base_cost": "Gas",
- "instantiate_base_cost": "Gas",
- "dispatch_base_cost": "Gas",
- "sandbox_data_read_cost": "Gas",
- "sandbox_data_write_cost": "Gas",
- "transfer_cost": "Gas",
- "instantiate_cost": "Gas",
- "max_event_topics": "u32",
- "max_stack_height": "u32",
- "max_memory_pages": "u32",
- "max_table_size": "u32",
- "enable_println": "bool",
- "max_subject_len": "u32"
- },
"AccessMode": {
"_enum": [
"Normal",
@@ -34,7 +11,7 @@
"Invalid": null,
"NFT": null,
"Fungible": "DecimalPoints",
- "ReFungible": "DecimalPoints"
+ "ReFungible": null
}
},
"Ownership": {
@@ -84,7 +61,8 @@
},
"CreateReFungibleData": {
"const_data": "Vec<u8>",
- "variable_data": "Vec<u8>"
+ "variable_data": "Vec<u8>",
+ "pieces": "u128"
},
"CreateItemData": {
"_enum": {
@@ -117,15 +95,8 @@
"AccountTokenOwnershipLimit": "u32",
"SponsoredMintSize": "u32",
"TokenLimit": "u32",
- "SponsorTimeout": "u32"
- },
- "AccountInfo": "AccountInfoWithProviders",
- "AccountInfoWithProviders": {
- "nonce": "Index",
- "consumers": "RefCount",
- "providers": "RefCount",
- "data": "AccountData"
+ "SponsorTimeout": "u32",
+ "OwnerCanTransfer": "bool",
+ "OwnerCanDestroy": "bool"
}
-
- }
-
\ No newline at end of file
+}
\ No newline at end of file
tests/src/addCollectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/addCollectionAdmin.test.ts
+++ b/tests/src/addCollectionAdmin.test.ts
@@ -1,4 +1,9 @@
-import { ApiPromise } from '@polkadot/api';
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import { ApiPromise } from '@polkadot/api';
import BN from 'bn.js';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
@@ -98,7 +103,7 @@
});
});
- it('Add an admin to a collection that has reached the maximum number of admins limit', async () => {
+ it.only('Add an admin to a collection that has reached the maximum number of admins limit', async () => {
await usingApi(async (api: ApiPromise) => {
const Alice = privateKey('//Alice');
const accounts = [
@@ -112,18 +117,18 @@
];
const collectionId = await createCollectionExpectSuccess();
- const chainLimit = await api.query.nft.chainLimit() as unknown as { collections_admins_limit: BN };
- const chainLimitNumber = chainLimit.collections_admins_limit.toNumber();
- expect(chainLimitNumber).to.be.equal(5);
+ const chainLimit = await api.query.nft.chainLimit() as unknown as { CollectionAdminsLimit: BN };
+ const chainAdminLimit = chainLimit.CollectionAdminsLimit.toNumber();
+ expect(chainAdminLimit).to.be.equal(5);
- for (let i = 0; i < chainLimitNumber; i++) {
+ for (let i = 0; i < chainAdminLimit; i++) {
const changeAdminTx = api.tx.nft.addCollectionAdmin(collectionId, accounts[i]);
await submitTransactionAsync(Alice, changeAdminTx);
const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId));
expect(adminListAfterAddAdmin).to.be.contains(accounts[i]);
}
- const tx = api.tx.nft.addCollectionAdmin(collectionId, accounts[chainLimitNumber]);
+ const tx = api.tx.nft.addCollectionAdmin(collectionId, accounts[chainAdminLimit]);
await expect(submitTransactionExpectFailAsync(Alice, tx)).to.be.rejected;
});
});
tests/src/addToContractWhiteList.test.tsdiffbeforeafterboth--- a/tests/src/addToContractWhiteList.test.ts
+++ b/tests/src/addToContractWhiteList.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import chai from "chai";
import chaiAsPromised from 'chai-as-promised';
import usingApi, { submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api";
tests/src/addToWhiteList.test.tsdiffbeforeafterboth--- a/tests/src/addToWhiteList.test.ts
+++ b/tests/src/addToWhiteList.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { IKeyringPair } from '@polkadot/types/types';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
tests/src/approve.test.tsdiffbeforeafterboth--- a/tests/src/approve.test.ts
+++ b/tests/src/approve.test.ts
@@ -34,7 +34,7 @@
await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob);
// reFungible
const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);
});
@@ -56,7 +56,7 @@
await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 0);
// reFungible
const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 1);
await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 0);
@@ -95,7 +95,7 @@
await approveExpectFail(fungibleCollectionId, 1, Alice, Bob);
// reFungible
const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await destroyCollectionExpectSuccess(reFungibleCollectionId);
await approveExpectFail(reFungibleCollectionId, 1, Alice, Bob);
});
@@ -113,7 +113,7 @@
await approveExpectFail(fungibleCollectionId, 2, Alice, Bob);
// reFungible
const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await approveExpectFail(reFungibleCollectionId, 2, Alice, Bob);
});
});
@@ -132,7 +132,7 @@
await approveExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice);
// reFungible
const reFungibleCollectionId =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Bob, Alice);
});
tests/src/burnItem.test.tsdiffbeforeafterboth--- a/tests/src/burnItem.test.ts
+++ b/tests/src/burnItem.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api';
import { Keyring } from "@polkadot/api";
import { IKeyringPair } from "@polkadot/types/types";
@@ -70,7 +75,7 @@
});
it('Burn item in ReFungible collection', async () => {
const createMode = 'ReFungible';
- const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 2 }});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode }});
const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
await usingApi(async (api) => {
@@ -91,7 +96,7 @@
it('Burn owned portion of item in ReFungible collection', async () => {
const createMode = 'ReFungible';
- const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 2 }});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
await usingApi(async (api) => {
@@ -107,7 +112,7 @@
const tx = api.tx.nft.burnItem(collectionId, tokenId, 0);
const events2 = await submitTransactionAsync(bob, tx);
const result2 = getGenericResult(events2);
-
+
// Get balances
const balance: any = (await api.query.nft.reFungibleItemList(collectionId, tokenId)).toJSON();
// console.log(balance);
tests/src/change-collection-owner.test.tsdiffbeforeafterboth--- a/tests/src/change-collection-owner.test.ts
+++ b/tests/src/change-collection-owner.test.ts
@@ -1,4 +1,9 @@
-import chai from 'chai';
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
+import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import privateKey from './substrate/privateKey';
import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api";
tests/src/confirmSponsorship.test.tsdiffbeforeafterboth--- a/tests/src/confirmSponsorship.test.ts
+++ b/tests/src/confirmSponsorship.test.ts
@@ -115,7 +115,7 @@
});
it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async () => {
- const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0 }});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
@@ -247,7 +247,7 @@
});
it('ReFungible: Sponsoring is rate limited', async () => {
- const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0 }});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
tests/src/contracts.test.tsdiffbeforeafterboth--- a/tests/src/contracts.test.ts
+++ b/tests/src/contracts.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import chai from "chai";
import chaiAsPromised from 'chai-as-promised';
import usingApi, { submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api";
tests/src/createCollection.test.tsdiffbeforeafterboth--- a/tests/src/createCollection.test.ts
+++ b/tests/src/createCollection.test.ts
@@ -28,7 +28,7 @@
await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
});
it('Create new ReFungible collection', async () => {
- await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
});
});
tests/src/createItem.test.tsdiffbeforeafterboth--- a/tests/src/createItem.test.ts
+++ b/tests/src/createItem.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { default as usingApi } from './substrate/substrate-api';
import { Keyring } from "@polkadot/api";
import { IKeyringPair } from "@polkadot/types/types";
@@ -28,7 +33,7 @@
});
it('Create new item in ReFungible collection', async () => {
const createMode = 'ReFungible';
- const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
+ const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
await createItemExpectSuccess(alice, newCollectionID, createMode);
});
});
tests/src/createMultipleItems.test.tsdiffbeforeafterboth--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -56,14 +56,14 @@
it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
await usingApi(async (api: ApiPromise) => {
- const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const itemsListIndexBefore = await api.query.nft.itemListIndex(collectionId) as unknown as BN;
expect(itemsListIndexBefore.toNumber()).to.be.equal(0);
const Alice = privateKey('//Alice');
const args = [
- { Refungible: ['0x31', '0x31'] },
- { Refungible: ['0x32', '0x32'] },
- { Refungible: ['0x33', '0x33'] },
+ {refungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},
+ {refungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},
+ {refungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},
];
const createMultipleItemsTx = await api.tx.nft
.createMultipleItems(collectionId, Alice.address, args);
@@ -137,7 +137,7 @@
// ReFungible
const collectionIdReFungible =
- await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const argsReFungible = [
{ ReFungible: ['1'.repeat(2049), '1'.repeat(2049)] },
{ ReFungible: ['2'.repeat(2049), '2'.repeat(2049)] },
tests/src/destroyCollection.test.tsdiffbeforeafterboth--- a/tests/src/destroyCollection.test.ts
+++ b/tests/src/destroyCollection.test.ts
@@ -1,12 +1,14 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
-import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api";
-import { createCollectionExpectSuccess, createCollectionExpectFailure, destroyCollectionExpectSuccess, destroyCollectionExpectFailure } from "./util/helpers";
-import type { AccountId, EventRecord } from '@polkadot/types/interfaces';
-import privateKey from './substrate/privateKey';
+import { default as usingApi } from "./substrate/substrate-api";
+import { createCollectionExpectSuccess, destroyCollectionExpectSuccess, destroyCollectionExpectFailure } from "./util/helpers";
chai.use(chaiAsPromised);
-const expect = chai.expect;
describe('integration test: ext. destroyCollection():', () => {
it('NFT collection can be destroyed', async () => {
@@ -18,7 +20,7 @@
await destroyCollectionExpectSuccess(collectionId);
});
it('ReFungible collection can be destroyed', async () => {
- const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await destroyCollectionExpectSuccess(collectionId);
});
});
tests/src/enableContractSponsoring.test.tsdiffbeforeafterboth--- a/tests/src/enableContractSponsoring.test.ts
+++ b/tests/src/enableContractSponsoring.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { IKeyringPair } from '@polkadot/types/types';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
tests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/removeCollectionAdmin.test.ts
+++ b/tests/src/removeCollectionAdmin.test.ts
@@ -1,5 +1,9 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { ApiPromise } from '@polkadot/api';
-import BN from 'bn.js';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import privateKey from './substrate/privateKey';
tests/src/removeFromContractWhiteList.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/removeFromContractWhiteList.test.ts
@@ -0,0 +1,72 @@
+import privateKey from "./substrate/privateKey";
+import usingApi from "./substrate/substrate-api";
+import { deployFlipper, toggleFlipValueExpectFailure, toggleFlipValueExpectSuccess } from "./util/contracthelpers";
+import { addToContractWhiteListExpectSuccess, isWhitelistedInContract, removeFromContractWhiteListExpectFailure, removeFromContractWhiteListExpectSuccess, toggleContractWhitelistExpectSuccess } from "./util/helpers";
+import { IKeyringPair } from '@polkadot/types/types';
+import { expect } from "chai";
+
+describe('Integration Test removeFromContractWhiteList', () => {
+ let bob: IKeyringPair;
+
+ before(() => {
+ bob = privateKey('//Bob');
+ });
+
+ it('user is no longer whitelisted after removal', async () => {
+ await usingApi(async (api) => {
+ const [flipper, deployer] = await deployFlipper(api);
+
+ await addToContractWhiteListExpectSuccess(deployer, flipper.address, bob.address);
+ await removeFromContractWhiteListExpectSuccess(deployer, flipper.address, bob.address);
+
+ expect(await isWhitelistedInContract(flipper.address, bob.address)).to.be.false;
+ });
+ });
+
+ it('user can\'t execute contract after removal', async () => {
+ await usingApi(async (api) => {
+ const [flipper, deployer] = await deployFlipper(api);
+ await toggleContractWhitelistExpectSuccess(deployer, flipper.address, true);
+
+ await addToContractWhiteListExpectSuccess(deployer, flipper.address, bob.address);
+ await toggleFlipValueExpectSuccess(bob, flipper);
+
+ await removeFromContractWhiteListExpectSuccess(deployer, flipper.address, bob.address);
+ await toggleFlipValueExpectFailure(bob, flipper);
+ });
+ });
+
+ it('can be called twice', async () => {
+ await usingApi(async (api) => {
+ const [flipper, deployer] = await deployFlipper(api);
+
+ await addToContractWhiteListExpectSuccess(deployer, flipper.address, bob.address);
+ await removeFromContractWhiteListExpectSuccess(deployer, flipper.address, bob.address);
+ await removeFromContractWhiteListExpectSuccess(deployer, flipper.address, bob.address);
+ });
+ });
+});
+
+describe('Negative Integration Test removeFromContractWhiteList', () => {
+ let alice: IKeyringPair;
+ let bob: IKeyringPair;
+
+ before(() => {
+ alice = privateKey('//Alice');
+ bob = privateKey('//Bob');
+ });
+
+ it('fails when called with non-contract address', async () => {
+ await usingApi(async () => {
+ await removeFromContractWhiteListExpectFailure(alice, alice.address, bob.address);
+ });
+ });
+
+ it('fails when executed by non owner', async () => {
+ await usingApi(async (api) => {
+ const [flipper, _] = await deployFlipper(api);
+
+ await removeFromContractWhiteListExpectFailure(alice, flipper.address, bob.address);
+ });
+ });
+});
tests/src/removeFromWhiteList.test.tsdiffbeforeafterboth--- a/tests/src/removeFromWhiteList.test.ts
+++ b/tests/src/removeFromWhiteList.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import { default as usingApi } from './substrate/substrate-api';
tests/src/setCollectionLimits.test.tsdiffbeforeafterboth--- a/tests/src/setCollectionLimits.test.ts
+++ b/tests/src/setCollectionLimits.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
// https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits
import { ApiPromise, Keyring } from '@polkadot/api';
import { IKeyringPair } from '@polkadot/types/types';
tests/src/setCollectionSponsor.test.tsdiffbeforeafterboth--- a/tests/src/setCollectionSponsor.test.ts
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -9,7 +9,6 @@
import { createCollectionExpectSuccess, setCollectionSponsorExpectSuccess, destroyCollectionExpectSuccess, setCollectionSponsorExpectFailure } from "./util/helpers";
import { Keyring } from "@polkadot/api";
import { IKeyringPair } from "@polkadot/types/types";
-import type { AccountId } from '@polkadot/types/interfaces';
chai.use(chaiAsPromised);
const expect = chai.expect;
@@ -34,7 +33,7 @@
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
});
it('Set ReFungible collection sponsor', async () => {
- const collectionId = await createCollectionExpectSuccess({ mode: {type: 'ReFungible', decimalPoints: 0} });
+ const collectionId = await createCollectionExpectSuccess({ mode: {type: 'ReFungible'} });
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
});
tests/src/setConstOnChainSchema.test.tsdiffbeforeafterboth--- a/tests/src/setConstOnChainSchema.test.ts
+++ b/tests/src/setConstOnChainSchema.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { Keyring } from '@polkadot/api';
import { IKeyringPair } from '@polkadot/types/types';
import chai from 'chai';
tests/src/setContractSponsoringRateLimit.test.tsdiffbeforeafterboth--- a/tests/src/setContractSponsoringRateLimit.test.ts
+++ b/tests/src/setContractSponsoringRateLimit.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { IKeyringPair } from '@polkadot/types/types';
import privateKey from './substrate/privateKey';
import usingApi from './substrate/substrate-api';
tests/src/setMintPermission.test.tsdiffbeforeafterboth--- a/tests/src/setMintPermission.test.ts
+++ b/tests/src/setMintPermission.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { IKeyringPair } from '@polkadot/types/types';
import privateKey from './substrate/privateKey';
import usingApi from './substrate/substrate-api';
tests/src/setPublicAccessMode.test.tsdiffbeforeafterboth--- a/tests/src/setPublicAccessMode.test.ts
+++ b/tests/src/setPublicAccessMode.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
// https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion
import { ApiPromise, Keyring } from '@polkadot/api';
import { IKeyringPair } from '@polkadot/types/types';
tests/src/setSchemaVersion.test.tsdiffbeforeafterboth--- a/tests/src/setSchemaVersion.test.ts
+++ b/tests/src/setSchemaVersion.test.ts
@@ -1,7 +1,11 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
// https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion
import { ApiPromise, Keyring } from '@polkadot/api';
import { IKeyringPair } from '@polkadot/types/types';
-import BN from 'bn.js';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import usingApi, {submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
tests/src/setVariableMetaData.test.tsdiffbeforeafterboth--- a/tests/src/setVariableMetaData.test.ts
+++ b/tests/src/setVariableMetaData.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { IKeyringPair } from '@polkadot/types/types';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
tests/src/setVariableOnChainSchema.test.tsdiffbeforeafterboth--- a/tests/src/setVariableOnChainSchema.test.ts
+++ b/tests/src/setVariableOnChainSchema.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import { Keyring } from '@polkadot/api';
import { IKeyringPair } from '@polkadot/types/types';
import chai from 'chai';
tests/src/toggleContractWhiteList.test.tsdiffbeforeafterboth--- a/tests/src/toggleContractWhiteList.test.ts
+++ b/tests/src/toggleContractWhiteList.test.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import chai from "chai";
import chaiAsPromised from 'chai-as-promised';
import usingApi, { submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api";
tests/src/transfer.test.tsdiffbeforeafterboth--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -63,7 +63,7 @@
});
});
- it('Create collection, balance transfers and check balance', async () => {
+ it('User can transfer owned token', async () => {
await usingApi(async (api) => {
const Alice = privateKey('//Alice');
const Bob = privateKey('//Bob');
@@ -77,10 +77,10 @@
await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1, 'Fungible');
// reFungible
const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
await transferExpectSuccess(reFungibleCollectionId,
- newReFungibleTokenId, Alice, Bob, 1, 'ReFungible');
+ newReFungibleTokenId, Alice, Bob, 100, 'ReFungible');
});
});
});
@@ -119,7 +119,7 @@
await transferExpectFail(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1, 'Fungible');
// reFungible
const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
await destroyCollectionExpectSuccess(reFungibleCollectionId);
await transferExpectFail(reFungibleCollectionId,
@@ -134,7 +134,7 @@
await transferExpectFail(fungibleCollectionId, 2, Alice, Bob, 1, 'Fungible');
// reFungible
const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
await transferExpectFail(reFungibleCollectionId,
2, Alice, Bob, 1, 'ReFungible');
});
@@ -151,7 +151,7 @@
await transferExpectFail(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1, 'Fungible');
// reFungible
const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
await burnItemExpectSuccess(Alice, reFungibleCollectionId, newReFungibleTokenId, 1);
await transferExpectFail(reFungibleCollectionId,
@@ -168,7 +168,7 @@
await transferExpectFail(fungibleCollectionId, newFungibleTokenId, Charlie, Bob, 1, 'Fungible');
// reFungible
const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
await transferExpectFail(reFungibleCollectionId,
newReFungibleTokenId, Charlie, Bob, 1, 'ReFungible');
tests/src/transferFrom.test.tsdiffbeforeafterboth--- a/tests/src/transferFrom.test.ts
+++ b/tests/src/transferFrom.test.ts
@@ -25,7 +25,7 @@
await usingApi(async (api: ApiPromise) => {
const Alice = privateKey('//Alice');
const Bob = privateKey('//Bob');
- const Charlie = privateKey('//CHARLIE');
+ const Charlie = privateKey('//Charlie');
// nft
const nftCollectionId = await createCollectionExpectSuccess();
const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
@@ -40,11 +40,11 @@
await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 1, 'Fungible');
// reFungible
const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
- await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);
+ await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 100);
await transferFromExpectSuccess(reFungibleCollectionId,
- newReFungibleTokenId, Bob, Alice, Charlie, 1, 'ReFungible');
+ newReFungibleTokenId, Bob, Alice, Charlie, 100, 'ReFungible');
});
});
});
@@ -54,7 +54,7 @@
await usingApi(async (api: ApiPromise) => {
const Alice = privateKey('//Alice');
const Bob = privateKey('//Bob');
- const Charlie = privateKey('//CHARLIE');
+ const Charlie = privateKey('//Charlie');
// nft
const nftCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
await approveExpectFail(nftCollectionCount + 1, 1, Alice, Bob);
@@ -96,7 +96,7 @@
await usingApi(async (api: ApiPromise) => {
const Alice = privateKey('//Alice');
const Bob = privateKey('//Bob');
- const Charlie = privateKey('//CHARLIE');
+ const Charlie = privateKey('//Charlie');
// nft
const nftCollectionId = await createCollectionExpectSuccess();
const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
@@ -109,7 +109,7 @@
await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 1);
// reFungible
const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
await transferFromExpectFail(reFungibleCollectionId,
newReFungibleTokenId, Bob, Alice, Charlie, 1);
@@ -120,7 +120,7 @@
await usingApi(async (api: ApiPromise) => {
const Alice = privateKey('//Alice');
const Bob = privateKey('//Bob');
- const Charlie = privateKey('//CHARLIE');
+ const Charlie = privateKey('//Charlie');
// nft
const nftCollectionId = await createCollectionExpectSuccess();
const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
@@ -135,7 +135,7 @@
await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 2);
// reFungible
const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);
await transferFromExpectFail(reFungibleCollectionId,
@@ -147,8 +147,8 @@
await usingApi(async (api: ApiPromise) => {
const Alice = privateKey('//Alice');
const Bob = privateKey('//Bob');
- const Charlie = privateKey('//CHARLIE');
- const Dave = privateKey('//DAVE');
+ const Charlie = privateKey('//Charlie');
+ const Dave = privateKey('//Dave');
// nft
const nftCollectionId = await createCollectionExpectSuccess();
const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
@@ -174,7 +174,7 @@
}
// reFungible
const reFungibleCollectionId = await
- createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
try {
await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Dave, Bob);
tests/src/types.tsdiffbeforeafterboth--- a/tests/src/types.ts
+++ b/tests/src/types.ts
@@ -1,3 +1,8 @@
+//
+// This file is subject to the terms and conditions defined in
+// file 'LICENSE', which is part of this source code package.
+//
+
import BN from 'bn.js';
export interface ICollectionInterface {
tests/src/util/helpers.tsdiffbeforeafterboth--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -124,23 +124,8 @@
interface ReFungible {
type: 'ReFungible';
- decimalPoints: number;
-}
-
-interface Nft {
- type: 'NFT'
-}
-
-interface Fungible {
- type: 'Fungible',
- decimalPoints: number
}
-interface ReFungible {
- type: 'ReFungible',
- decimalPoints: number
-}
-
type CollectionMode = Nft | Fungible | ReFungible | Invalid;
export type CreateCollectionParams = {
@@ -174,7 +159,7 @@
} else if (mode.type === 'Fungible') {
modeprm = {fungible: mode.decimalPoints};
} else if (mode.type === 'ReFungible') {
- modeprm = {refungible: mode.decimalPoints};
+ modeprm = {refungible: null};
} else if (mode.type === 'Invalid') {
modeprm = {invalid: null};
}
@@ -216,7 +201,7 @@
} else if (mode.type === 'Fungible') {
modeprm = {fungible: mode.decimalPoints};
} else if (mode.type === 'ReFungible') {
- modeprm = {refungible: mode.decimalPoints};
+ modeprm = {refungible: null};
} else if (mode.type === 'Invalid') {
modeprm = {invalid: null};
}
@@ -424,6 +409,54 @@
});
}
+export async function toggleContractWhitelistExpectSuccess(sender: IKeyringPair, contractAddress: AccountId | string, enabled: boolean) {
+ await usingApi(async (api) => {
+ const tx = api.tx.nft.toggleContractWhiteList(contractAddress, true);
+ const events = await submitTransactionAsync(sender, tx);
+ const result = getGenericResult(events);
+
+ expect(result.success).to.be.true;
+ });
+}
+
+export async function isWhitelistedInContract(contractAddress: AccountId | string, user: string) {
+ let whitelisted: boolean = false;
+ await usingApi(async (api) => {
+ whitelisted = (await api.query.nft.contractWhiteList(contractAddress, user)).toJSON() as boolean;
+ });
+ return whitelisted;
+}
+
+export async function addToContractWhiteListExpectSuccess(sender: IKeyringPair, contractAddress: AccountId | string, user: string) {
+ await usingApi(async (api) => {
+ const tx = api.tx.nft.addToContractWhiteList(contractAddress, user);
+ const events = await submitTransactionAsync(sender, tx);
+ const result = getGenericResult(events);
+
+ expect(result.success).to.be.true;
+ });
+}
+
+export async function removeFromContractWhiteListExpectSuccess(sender: IKeyringPair, contractAddress: AccountId | string, user: string) {
+ await usingApi(async (api) => {
+ const tx = api.tx.nft.removeFromContractWhiteList(contractAddress, user);
+ const events = await submitTransactionAsync(sender, tx);
+ const result = getGenericResult(events);
+
+ expect(result.success).to.be.true;
+ });
+}
+
+export async function removeFromContractWhiteListExpectFailure(sender: IKeyringPair, contractAddress: AccountId | string, user: string) {
+ await usingApi(async (api) => {
+ const tx = api.tx.nft.removeFromContractWhiteList(contractAddress, user);
+ const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
+ const result = getGenericResult(events);
+
+ expect(result.success).to.be.false;
+ });
+}
+
export async function setVariableMetaDataExpectSuccess(sender: IKeyringPair, collectionId: number, itemId: number, data: number[]) {
await usingApi(async (api) => {
const tx = api.tx.nft.setVariableMetaData(collectionId, itemId, '0x' + Buffer.from(data).toString('hex'));
@@ -620,6 +653,9 @@
if (createMode === 'Fungible') {
const createData = {fungible: {value: 10}};
tx = api.tx.nft.createItem(collectionId, owner, createData);
+ } else if (createMode === 'ReFungible') {
+ const createData = {refungible: {const_data: [], variable_data: [], pieces: 100}};
+ tx = api.tx.nft.createItem(collectionId, owner, createData);
} else {
tx = api.tx.nft.createItem(collectionId, owner, createMode);
}