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], pieces: 1023 }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_nft_item() {118 new_test_ext().execute_with(|| {119 default_limits();120 let collection_id = create_test_collection(&CollectionMode::NFT, 1);121 122 let data = default_nft_data();123 create_test_item(collection_id, &data.clone().into());124 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).const_data, data.const_data);125 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, data.variable_data);126 });127}128129// Use cases tests region130// #region131#[test]132fn create_nft_multiple_items() {133 new_test_ext().execute_with(|| {134 default_limits();135 136 create_test_collection(&CollectionMode::NFT, 1);137138 let origin1 = Origin::signed(1);139140 let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];141142 assert_ok!(TemplateModule::create_multiple_items(143 origin1.clone(),144 1,145 1,146 items_data.clone().into_iter().map(|d| { d.into() }).collect()147 ));148 for (index, data) in items_data.iter().enumerate() {149 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).const_data.to_vec(), data.const_data);150 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).variable_data.to_vec(), data.variable_data);151 }152 });153}154155#[test]156fn create_refungible_item() {157 new_test_ext().execute_with(|| {158 default_limits();159 let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);160161 let data = default_re_fungible_data();162 create_test_item(collection_id, &data.clone().into());163 assert_eq!(164 TemplateModule::refungible_item_id(collection_id, 1).const_data,165 data.const_data166 );167 assert_eq!(168 TemplateModule::refungible_item_id(collection_id, 1).variable_data,169 data.variable_data170 );171 assert_eq!(172 TemplateModule::refungible_item_id(collection_id, 1).owner[0],173 Ownership {174 owner: 1,175 fraction: 1023176 }177 );178 });179}180181#[test]182fn create_multiple_refungible_items() {183 new_test_ext().execute_with(|| {184 default_limits();185 186 create_test_collection(&CollectionMode::ReFungible, 1);187188 let origin1 = Origin::signed(1);189190 let items_data = vec![default_re_fungible_data(), default_re_fungible_data(), default_re_fungible_data()];191192 assert_ok!(TemplateModule::create_multiple_items(193 origin1.clone(),194 1,195 1,196 items_data.clone().into_iter().map(|d| { d.into() }).collect()197 ));198 for (index, data) in items_data.iter().enumerate() {199200 let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId);201 assert_eq!(item.const_data.to_vec(), data.const_data);202 assert_eq!(item.variable_data.to_vec(), data.variable_data);203 assert_eq!(204 item.owner[0],205 Ownership {206 owner: 1,207 fraction: 1023208 }209 );210 }211 });212}213214#[test]215fn create_fungible_item() {216 new_test_ext().execute_with(|| {217 default_limits();218 219 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);220221 let data = default_fungible_data();222 create_test_item(collection_id, &data.into());223224 assert_eq!(TemplateModule::fungible_item_id(collection_id, 1).value, 5);225 });226}227228//#[test]229// fn create_multiple_fungible_items() {230// new_test_ext().execute_with(|| {231// default_limits();232233// create_test_collection(&CollectionMode::Fungible(3), 1);234235// let origin1 = Origin::signed(1);236237// let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];238239// assert_ok!(TemplateModule::create_multiple_items(240// origin1.clone(),241// 1,242// 1,243// items_data.clone().into_iter().map(|d| { d.into() }).collect()244// ));245 246// for (index, _) in items_data.iter().enumerate() {247// assert_eq!(TemplateModule::fungible_item_id(1, (index + 1) as TokenId).value, 5);248// }249// assert_eq!(TemplateModule::balance_count(1, 1), 3000);250// assert_eq!(TemplateModule::address_tokens(1, 1), [1, 2, 3]);251// });252// }253254#[test]255fn transfer_fungible_item() {256 new_test_ext().execute_with(|| {257 default_limits();258 259 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);260261 let origin1 = Origin::signed(1);262 let origin2 = Origin::signed(2);263264 let data = default_fungible_data();265 create_test_item(collection_id, &data.into());266267 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 5);268 assert_eq!(TemplateModule::balance_count(1, 1), 5);269270 // change owner scenario271 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 5));272 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 0);273 assert_eq!(TemplateModule::balance_count(1, 1), 0);274 assert_eq!(TemplateModule::balance_count(1, 2), 5);275276 // split item scenario277 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 3));278 assert_eq!(TemplateModule::balance_count(1, 2), 2);279 assert_eq!(TemplateModule::balance_count(1, 3), 3);280281 // split item and new owner has account scenario282 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 1));283 assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 1);284 assert_eq!(TemplateModule::fungible_item_id(1, 3).value, 4);285 assert_eq!(TemplateModule::balance_count(1, 2), 1);286 assert_eq!(TemplateModule::balance_count(1, 3), 4);287 });288}289290#[test]291fn transfer_refungible_item() {292 new_test_ext().execute_with(|| {293 default_limits();294 295 let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);296297 let data = default_re_fungible_data();298 create_test_item(collection_id, &data.clone().into());299300 let origin1 = Origin::signed(1);301 let origin2 = Origin::signed(2);302 assert_eq!(303 TemplateModule::refungible_item_id(collection_id, 1).const_data,304 data.const_data305 );306 assert_eq!(307 TemplateModule::refungible_item_id(collection_id, 1).variable_data,308 data.variable_data309 );310 assert_eq!(311 TemplateModule::refungible_item_id(collection_id, 1).owner[0],312 Ownership {313 owner: 1,314 fraction: 1023315 }316 );317 assert_eq!(TemplateModule::balance_count(1, 1), 1023);318 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);319320 // change owner scenario321 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1023));322 assert_eq!(323 TemplateModule::refungible_item_id(1, 1).owner[0],324 Ownership {325 owner: 2,326 fraction: 1023327 }328 );329 assert_eq!(TemplateModule::balance_count(1, 1), 0);330 assert_eq!(TemplateModule::balance_count(1, 2), 1023);331 // assert_eq!(TemplateModule::address_tokens(1, 1), []);332 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);333334 // split item scenario335 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));336 assert_eq!(337 TemplateModule::refungible_item_id(1, 1).owner[0],338 Ownership {339 owner: 2,340 fraction: 523341 }342 );343 assert_eq!(344 TemplateModule::refungible_item_id(1, 1).owner[1],345 Ownership {346 owner: 3,347 fraction: 500348 }349 );350 assert_eq!(TemplateModule::balance_count(1, 2), 523);351 assert_eq!(TemplateModule::balance_count(1, 3), 500);352 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);353 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);354355 // split item and new owner has account scenario356 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));357 assert_eq!(358 TemplateModule::refungible_item_id(1, 1).owner[0],359 Ownership {360 owner: 2,361 fraction: 323362 }363 );364 assert_eq!(365 TemplateModule::refungible_item_id(1, 1).owner[1],366 Ownership {367 owner: 3,368 fraction: 700369 }370 );371 assert_eq!(TemplateModule::balance_count(1, 2), 323);372 assert_eq!(TemplateModule::balance_count(1, 3), 700);373 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);374 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);375 });376}377378#[test]379fn transfer_nft_item() {380 new_test_ext().execute_with(|| {381 default_limits();382 383 let collection_id = create_test_collection(&CollectionMode::NFT, 1);384385 let data = default_nft_data();386 create_test_item(collection_id, &data.into());387 assert_eq!(TemplateModule::balance_count(1, 1), 1);388 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);389390 let origin1 = Origin::signed(1);391 // default scenario392 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));393 assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2);394 assert_eq!(TemplateModule::balance_count(1, 1), 0);395 assert_eq!(TemplateModule::balance_count(1, 2), 1);396 // assert_eq!(TemplateModule::address_tokens(1, 1), []);397 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);398 });399}400401#[test]402fn nft_approve_and_transfer_from() {403 new_test_ext().execute_with(|| {404 default_limits();405 406 let collection_id = create_test_collection(&CollectionMode::NFT, 1);407408 let data = default_nft_data();409 create_test_item(collection_id, &data.into());410411 let origin1 = Origin::signed(1);412 let origin2 = Origin::signed(2);413414 assert_eq!(TemplateModule::balance_count(1, 1), 1);415 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);416417 // neg transfer418 assert_noop!(TemplateModule::transfer_from(419 origin2.clone(),420 1,421 2,422 1,423 1,424 1), Error::<Test>::NoPermission);425426 // do approve427 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));428 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);429 assert_eq!(430 TemplateModule::approved(1, (1, 1, 2)),431 5432 );433434 assert_ok!(TemplateModule::transfer_from(435 origin2.clone(),436 1,437 3,438 1,439 1,440 1441 ));442 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);443 });444}445446#[test]447fn nft_approve_and_transfer_from_white_list() {448 new_test_ext().execute_with(|| {449 default_limits();450 451 let collection_id = create_test_collection(&CollectionMode::NFT, 1);452453 let origin1 = Origin::signed(1);454 let origin2 = Origin::signed(2);455456 let data = default_nft_data();457 create_test_item(collection_id, &data.clone().into());458459 assert_eq!(TemplateModule::nft_item_id(1, 1).const_data, data.const_data);460 assert_eq!(TemplateModule::balance_count(1, 1), 1);461 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);462463 assert_ok!(TemplateModule::set_mint_permission(464 origin1.clone(),465 1,466 true467 ));468 assert_ok!(TemplateModule::set_public_access_mode(469 origin1.clone(),470 1,471 AccessMode::WhiteList472 ));473 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));474 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));475 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));476477 // do approve478 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));479 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);480 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1, 5));481 assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);482483 assert_ok!(TemplateModule::transfer_from(484 origin2.clone(),485 1,486 3,487 1,488 1,489 1490 ));491 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);492 });493}494495#[test]496fn refungible_approve_and_transfer_from() {497 new_test_ext().execute_with(|| {498 default_limits();499 500 let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);501 502 let origin1 = Origin::signed(1);503 let origin2 = Origin::signed(2);504505 let data = default_re_fungible_data();506 create_test_item(collection_id, &data.into());507508 assert_eq!(TemplateModule::balance_count(1, 1), 1023);509 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);510511 assert_ok!(TemplateModule::set_mint_permission(512 origin1.clone(),513 1,514 true515 ));516 assert_ok!(TemplateModule::set_public_access_mode(517 origin1.clone(),518 1,519 AccessMode::WhiteList520 ));521 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));522 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));523 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));524525 // do approve526 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 1023));527 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1023);528529 assert_ok!(TemplateModule::transfer_from(530 origin2.clone(),531 1,532 3,533 1,534 1,535 100536 ));537 assert_eq!(TemplateModule::balance_count(1, 1), 923);538 assert_eq!(TemplateModule::balance_count(1, 3), 100);539 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);540 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);541542 assert_eq!(543 TemplateModule::approved(1, (1, 1, 2)),544 923545 );546 });547}548549#[test]550fn fungible_approve_and_transfer_from() {551 new_test_ext().execute_with(|| {552 default_limits();553 554 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);555 556 let data = default_fungible_data();557 create_test_item(collection_id, &data.into());558559 let origin1 = Origin::signed(1);560 let origin2 = Origin::signed(2);561562 assert_eq!(TemplateModule::balance_count(1, 1), 5);563564 assert_ok!(TemplateModule::set_mint_permission(565 origin1.clone(),566 1,567 true568 ));569 assert_ok!(TemplateModule::set_public_access_mode(570 origin1.clone(),571 1,572 AccessMode::WhiteList573 ));574 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));575 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));576 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));577578 // do approve579 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));580 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);581 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1, 5));582 assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);583 assert_eq!(584 TemplateModule::approved(1, (1, 1, 2)),585 5586 );587588 assert_ok!(TemplateModule::transfer_from(589 origin2.clone(),590 1,591 3,592 1,593 1,594 4595 ));596 assert_eq!(TemplateModule::balance_count(1, 1), 1);597 assert_eq!(TemplateModule::balance_count(1, 3), 4);598599 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);600601 assert_noop!(TemplateModule::transfer_from(602 origin2.clone(),603 1,604 3,605 1,606 1,607 4608 ), Error::<Test>::TokenValueNotEnough);609 });610}611612#[test]613fn change_collection_owner() {614 new_test_ext().execute_with(|| {615 default_limits();616 617 let collection_id = create_test_collection(&CollectionMode::NFT, 1);618 619 let origin1 = Origin::signed(1);620 assert_ok!(TemplateModule::change_collection_owner(621 origin1.clone(),622 collection_id,623 2624 ));625 assert_eq!(TemplateModule::collection(collection_id).owner, 2);626 });627}628629#[test]630fn destroy_collection() {631 new_test_ext().execute_with(|| {632 default_limits();633 634 let collection_id = create_test_collection(&CollectionMode::NFT, 1);635 636 let origin1 = Origin::signed(1);637 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));638 });639}640641#[test]642fn burn_nft_item() {643 new_test_ext().execute_with(|| {644 default_limits();645 646 let collection_id = create_test_collection(&CollectionMode::NFT, 1);647648 let origin1 = Origin::signed(1);649 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));650 651 let data = default_nft_data();652 create_test_item(collection_id, &data.into());653654 // check balance (collection with id = 1, user id = 1)655 assert_eq!(TemplateModule::balance_count(1, 1), 1);656657 // burn item658 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));659 assert_noop!(660 TemplateModule::burn_item(origin1.clone(), 1, 1, 5),661 Error::<Test>::TokenNotFound662 );663664 assert_eq!(TemplateModule::balance_count(1, 1), 0);665 });666}667668#[test]669fn burn_fungible_item() {670 new_test_ext().execute_with(|| {671 default_limits();672 673 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);674 675 let origin1 = Origin::signed(1);676 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));677 678 let data = default_fungible_data();679 create_test_item(collection_id, &data.into());680681 // check balance (collection with id = 1, user id = 1)682 assert_eq!(TemplateModule::balance_count(1, 1), 5);683684 // burn item685 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));686 assert_noop!(687 TemplateModule::burn_item(origin1.clone(), 1, 1, 5),688 Error::<Test>::TokenNotFound689 );690691 assert_eq!(TemplateModule::balance_count(1, 1), 0);692 });693}694695#[test]696fn burn_refungible_item() {697 new_test_ext().execute_with(|| {698 default_limits();699 700 let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);701 let origin1 = Origin::signed(1);702703 assert_ok!(TemplateModule::set_mint_permission(704 origin1.clone(),705 collection_id,706 true707 ));708 assert_ok!(TemplateModule::set_public_access_mode(709 origin1.clone(),710 collection_id,711 AccessMode::WhiteList712 ));713 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));714715 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));716 717 let data = default_re_fungible_data();718 create_test_item(collection_id, &data.into());719720 // check balance (collection with id = 1, user id = 2)721 assert_eq!(TemplateModule::balance_count(1, 1), 1023);722723 // burn item724 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 1023));725 assert_noop!(726 TemplateModule::burn_item(origin1.clone(), 1, 1, 1023),727 Error::<Test>::TokenNotFound728 );729730 assert_eq!(TemplateModule::balance_count(1, 1), 0);731 });732}733734#[test]735fn add_collection_admin() {736 new_test_ext().execute_with(|| {737 default_limits();738 739 let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);740 create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);741 create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);742 743 let origin1 = Origin::signed(1);744745 // collection admin746 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));747 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));748749 assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&2), true);750 assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&3), true);751 });752}753754#[test]755fn remove_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);762763 let origin1 = Origin::signed(1);764 let origin2 = Origin::signed(2);765766 // collection admin767 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));768 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));769770 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);771 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);772773 // remove admin774 assert_ok!(TemplateModule::remove_collection_admin(775 origin2.clone(),776 1,777 3778 ));779 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), false);780 });781}782783#[test]784fn balance_of() {785 new_test_ext().execute_with(|| {786 default_limits();787 788 let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);789 let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);790 let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible, 3);791 792 // check balance before793 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);794 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);795 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 0);796797 let nft_data = default_nft_data();798 create_test_item(nft_collection_id, &nft_data.into());799 800 let fungible_data = default_fungible_data();801 create_test_item(fungible_collection_id, &fungible_data.into());802 803 let re_fungible_data = default_re_fungible_data();804 create_test_item(re_fungible_collection_id, &re_fungible_data.into());805806 // check balance (collection with id = 1, user id = 1)807 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1);808 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 5);809 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 1023);810 assert_eq!(TemplateModule::nft_item_id(nft_collection_id, 1).owner, 1);811 assert_eq!(TemplateModule::fungible_item_id(fungible_collection_id, 1).value, 5);812 assert_eq!(TemplateModule::refungible_item_id(re_fungible_collection_id, 1).owner[0].owner, 1);813 });814}815816#[test]817fn approve() {818 new_test_ext().execute_with(|| {819 default_limits();820 821 let collection_id = create_test_collection(&CollectionMode::NFT, 1);822 823 let data = default_nft_data();824 create_test_item(collection_id, &data.into());825826 let origin1 = Origin::signed(1);827 828 // approve829 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 1));830 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);831 });832}833834#[test]835fn transfer_from() {836 new_test_ext().execute_with(|| {837 default_limits();838 839 let collection_id = create_test_collection(&CollectionMode::NFT, 1);840 let origin1 = Origin::signed(1);841 let origin2 = Origin::signed(2);842843 let data = default_nft_data();844 create_test_item(collection_id, &data.into());845846 // approve847 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 1));848 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);849850 assert_ok!(TemplateModule::set_mint_permission(851 origin1.clone(),852 1,853 true854 ));855 assert_ok!(TemplateModule::set_public_access_mode(856 origin1.clone(),857 1,858 AccessMode::WhiteList859 ));860 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));861 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));862 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));863864 assert_ok!(TemplateModule::transfer_from(865 origin2.clone(),866 1,867 2,868 1,869 1,870 1871 ));872873 // after transfer874 assert_eq!(TemplateModule::balance_count(1, 1), 0);875 assert_eq!(TemplateModule::balance_count(1, 2), 1);876 });877}878879// #endregion880881// Coverage tests region882// #region883884#[test]885fn owner_can_add_address_to_white_list() {886 new_test_ext().execute_with(|| {887 default_limits();888 889 let collection_id = create_test_collection(&CollectionMode::NFT, 1);890891 let origin1 = Origin::signed(1);892 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));893 assert_eq!(TemplateModule::white_list(collection_id, 2), true);894 });895}896897#[test]898fn admin_can_add_address_to_white_list() {899 new_test_ext().execute_with(|| {900 default_limits();901 902 let collection_id = create_test_collection(&CollectionMode::NFT, 1);903 let origin1 = Origin::signed(1);904 let origin2 = Origin::signed(2);905906 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));907 assert_ok!(TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3));908 assert_eq!(TemplateModule::white_list(collection_id, 3), true);909 });910}911912#[test]913fn nonprivileged_user_cannot_add_address_to_white_list() {914 new_test_ext().execute_with(|| {915 default_limits();916 917 let collection_id = create_test_collection(&CollectionMode::NFT, 1);918919 let origin2 = Origin::signed(2);920 assert_noop!(921 TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3),922 Error::<Test>::NoPermission923 );924 });925}926927#[test]928fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {929 new_test_ext().execute_with(|| {930 default_limits();931932 let origin1 = Origin::signed(1);933934 assert_noop!(935 TemplateModule::add_to_white_list(origin1.clone(), 1, 2),936 Error::<Test>::CollectionNotFound937 );938 });939}940941#[test]942fn nobody_can_add_address_to_white_list_of_deleted_collection() {943 new_test_ext().execute_with(|| {944 default_limits();945 946 let collection_id = create_test_collection(&CollectionMode::NFT, 1);947948 let origin1 = Origin::signed(1);949 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));950 assert_noop!(951 TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2),952 Error::<Test>::CollectionNotFound953 );954 });955}956957// If address is already added to white list, nothing happens958#[test]959fn address_is_already_added_to_white_list() {960 new_test_ext().execute_with(|| {961 default_limits();962 963 let collection_id = create_test_collection(&CollectionMode::NFT, 1);964 let origin1 = Origin::signed(1);965 966 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));967 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));968 assert_eq!(TemplateModule::white_list(collection_id, 2), true);969 });970}971972#[test]973fn owner_can_remove_address_from_white_list() {974 new_test_ext().execute_with(|| {975 default_limits();976 977 let collection_id = create_test_collection(&CollectionMode::NFT, 1);978979 let origin1 = Origin::signed(1);980 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));981 assert_ok!(TemplateModule::remove_from_white_list(982 origin1.clone(),983 collection_id,984 2985 ));986 assert_eq!(TemplateModule::white_list(collection_id, 2), false);987 });988}989990#[test]991fn admin_can_remove_address_from_white_list() {992 new_test_ext().execute_with(|| {993 default_limits();994 995 let collection_id = create_test_collection(&CollectionMode::NFT, 1);996 let origin1 = Origin::signed(1);997 let origin2 = Origin::signed(2);998999 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));10001001 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 3));1002 assert_ok!(TemplateModule::remove_from_white_list(1003 origin2.clone(),1004 collection_id,1005 31006 ));1007 assert_eq!(TemplateModule::white_list(collection_id, 3), false);1008 });1009}10101011#[test]1012fn nonprivileged_user_cannot_remove_address_from_white_list() {1013 new_test_ext().execute_with(|| {1014 default_limits();1015 1016 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1017 let origin1 = Origin::signed(1);1018 let origin2 = Origin::signed(2);10191020 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1021 assert_noop!(1022 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1023 Error::<Test>::NoPermission1024 );1025 assert_eq!(TemplateModule::white_list(collection_id, 2), true);1026 });1027}10281029#[test]1030fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1031 new_test_ext().execute_with(|| {1032 default_limits();1033 let origin1 = Origin::signed(1);10341035 assert_noop!(1036 TemplateModule::remove_from_white_list(origin1.clone(), 1, 2),1037 Error::<Test>::CollectionNotFound1038 );1039 });1040}10411042#[test]1043fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1044 new_test_ext().execute_with(|| {1045 default_limits();1046 1047 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1048 let origin1 = Origin::signed(1);1049 let origin2 = Origin::signed(2);10501051 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1052 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1053 assert_noop!(1054 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1055 Error::<Test>::CollectionNotFound1056 );1057 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1058 });1059}10601061// If address is already removed from white list, nothing happens1062#[test]1063fn address_is_already_removed_from_white_list() {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);10691070 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1071 assert_ok!(TemplateModule::remove_from_white_list(1072 origin1.clone(),1073 collection_id,1074 21075 ));1076 assert_ok!(TemplateModule::remove_from_white_list(1077 origin1.clone(),1078 collection_id,1079 21080 ));1081 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1082 });1083}10841085// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1086#[test]1087fn white_list_test_1() {1088 new_test_ext().execute_with(|| {1089 default_limits();1090 1091 let collection_id = create_test_collection(&CollectionMode::NFT, 1);10921093 let origin1 = Origin::signed(1);1094 1095 let data = default_nft_data();1096 create_test_item(collection_id, &data.into());10971098 assert_ok!(TemplateModule::set_public_access_mode(1099 origin1.clone(),1100 collection_id,1101 AccessMode::WhiteList1102 ));1103 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));11041105 assert_noop!(1106 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1107 Error::<Test>::AddresNotInWhiteList1108 );1109 });1110}11111112#[test]1113fn white_list_test_2() {1114 new_test_ext().execute_with(|| {1115 default_limits();1116 1117 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1118 let origin1 = Origin::signed(1);1119 1120 let data = default_nft_data();1121 create_test_item(collection_id, &data.into());11221123 assert_ok!(TemplateModule::set_public_access_mode(1124 origin1.clone(),1125 collection_id,1126 AccessMode::WhiteList1127 ));1128 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1129 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));11301131 // do approve1132 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1, 1));1133 assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);11341135 assert_ok!(TemplateModule::remove_from_white_list(1136 origin1.clone(),1137 1,1138 11139 ));11401141 assert_noop!(1142 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1143 Error::<Test>::AddresNotInWhiteList1144 );1145 });1146}11471148// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1149#[test]1150fn white_list_test_3() {1151 new_test_ext().execute_with(|| {1152 default_limits();1153 1154 let collection_id = create_test_collection(&CollectionMode::NFT, 1);11551156 let origin1 = Origin::signed(1);1157 1158 let data = default_nft_data();1159 create_test_item(collection_id, &data.into());11601161 assert_ok!(TemplateModule::set_public_access_mode(1162 origin1.clone(),1163 collection_id,1164 AccessMode::WhiteList1165 ));1166 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));11671168 assert_noop!(1169 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1170 Error::<Test>::AddresNotInWhiteList1171 );1172 });1173}11741175#[test]1176fn white_list_test_4() {1177 new_test_ext().execute_with(|| {1178 default_limits();1179 1180 let collection_id = create_test_collection(&CollectionMode::NFT, 1);11811182 let origin1 = Origin::signed(1);11831184 let data = default_nft_data();1185 create_test_item(collection_id, &data.into());11861187 assert_ok!(TemplateModule::set_public_access_mode(1188 origin1.clone(),1189 collection_id,1190 AccessMode::WhiteList1191 ));1192 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1193 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));11941195 // do approve1196 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1, 1));1197 assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);11981199 assert_ok!(TemplateModule::remove_from_white_list(1200 origin1.clone(),1201 collection_id,1202 21203 ));12041205 assert_noop!(1206 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1207 Error::<Test>::AddresNotInWhiteList1208 );1209 });1210}12111212// 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)1213#[test]1214fn white_list_test_5() {1215 new_test_ext().execute_with(|| {1216 default_limits();1217 1218 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12191220 let origin1 = Origin::signed(1);12211222 let data = default_nft_data();1223 create_test_item(collection_id, &data.into());12241225 assert_ok!(TemplateModule::set_public_access_mode(1226 origin1.clone(),1227 collection_id,1228 AccessMode::WhiteList1229 ));1230 assert_noop!(1231 TemplateModule::burn_item(origin1.clone(), 1, 1, 5),1232 Error::<Test>::AddresNotInWhiteList1233 );1234 });1235}12361237// If Public Access mode is set to WhiteList, token transfers can’t be Approved by a non-whitelisted address (see Approve method).1238#[test]1239fn white_list_test_6() {1240 new_test_ext().execute_with(|| {1241 default_limits();1242 1243 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12441245 let origin1 = Origin::signed(1);12461247 let data = default_nft_data();1248 create_test_item(collection_id, &data.into());12491250 assert_ok!(TemplateModule::set_public_access_mode(1251 origin1.clone(),1252 collection_id,1253 AccessMode::WhiteList1254 ));12551256 // do approve1257 assert_noop!(1258 TemplateModule::approve(origin1.clone(), 1, 1, 1, 5),1259 Error::<Test>::AddresNotInWhiteList1260 );1261 });1262}12631264// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1265// tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1266#[test]1267fn white_list_test_7() {1268 new_test_ext().execute_with(|| {1269 default_limits();1270 1271 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12721273 let data = default_nft_data();1274 create_test_item(collection_id, &data.into());1275 1276 let origin1 = Origin::signed(1);12771278 assert_ok!(TemplateModule::set_public_access_mode(1279 origin1.clone(),1280 collection_id,1281 AccessMode::WhiteList1282 ));1283 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1284 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));12851286 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1));1287 });1288}12891290#[test]1291fn white_list_test_8() {1292 new_test_ext().execute_with(|| {1293 default_limits();1294 1295 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12961297 let data = default_nft_data();1298 create_test_item(collection_id, &data.into());1299 1300 let origin1 = Origin::signed(1);13011302 assert_ok!(TemplateModule::set_public_access_mode(1303 origin1.clone(),1304 collection_id,1305 AccessMode::WhiteList1306 ));1307 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1308 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13091310 // do approve1311 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1, 5));1312 assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 5);13131314 assert_ok!(TemplateModule::transfer_from(1315 origin1.clone(),1316 1,1317 2,1318 1,1319 1,1320 11321 ));1322 });1323}13241325// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1326#[test]1327fn white_list_test_9() {1328 new_test_ext().execute_with(|| {1329 default_limits();1330 1331 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1332 let origin1 = Origin::signed(1);13331334 assert_ok!(TemplateModule::set_public_access_mode(1335 origin1.clone(),1336 collection_id,1337 AccessMode::WhiteList1338 ));1339 assert_ok!(TemplateModule::set_mint_permission(1340 origin1.clone(),1341 collection_id,1342 false1343 ));13441345 let data = default_nft_data();1346 create_test_item(collection_id, &data.into());1347 });1348}13491350// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1351#[test]1352fn white_list_test_10() {1353 new_test_ext().execute_with(|| {1354 default_limits();1355 1356 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13571358 let origin1 = Origin::signed(1);1359 let origin2 = Origin::signed(2);13601361 assert_ok!(TemplateModule::set_public_access_mode(1362 origin1.clone(),1363 collection_id,1364 AccessMode::WhiteList1365 ));1366 assert_ok!(TemplateModule::set_mint_permission(1367 origin1.clone(),1368 collection_id,1369 false1370 ));13711372 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));13731374 assert_ok!(TemplateModule::create_item(1375 origin2.clone(),1376 collection_id,1377 2,1378 default_nft_data().into()1379 ));1380 });1381}13821383// 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.1384#[test]1385fn white_list_test_11() {1386 new_test_ext().execute_with(|| {1387 default_limits();1388 1389 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13901391 let origin1 = Origin::signed(1);1392 let origin2 = Origin::signed(2);13931394 assert_ok!(TemplateModule::set_public_access_mode(1395 origin1.clone(),1396 collection_id,1397 AccessMode::WhiteList1398 ));1399 assert_ok!(TemplateModule::set_mint_permission(1400 origin1.clone(),1401 collection_id,1402 false1403 ));1404 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));14051406 assert_noop!(1407 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1408 Error::<Test>::PublicMintingNotAllowed1409 );1410 });1411}14121413// 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.1414#[test]1415fn white_list_test_12() {1416 new_test_ext().execute_with(|| {1417 default_limits();1418 1419 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14201421 let origin1 = Origin::signed(1);1422 let origin2 = Origin::signed(2);14231424 assert_ok!(TemplateModule::set_public_access_mode(1425 origin1.clone(),1426 collection_id,1427 AccessMode::WhiteList1428 ));1429 assert_ok!(TemplateModule::set_mint_permission(1430 origin1.clone(),1431 collection_id,1432 false1433 ));14341435 assert_noop!(1436 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1437 Error::<Test>::PublicMintingNotAllowed1438 );1439 });1440}14411442// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1443#[test]1444fn white_list_test_13() {1445 new_test_ext().execute_with(|| {1446 default_limits();1447 1448 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14491450 let origin1 = Origin::signed(1);14511452 assert_ok!(TemplateModule::set_public_access_mode(1453 origin1.clone(),1454 collection_id,1455 AccessMode::WhiteList1456 ));1457 assert_ok!(TemplateModule::set_mint_permission(1458 origin1.clone(),1459 collection_id,1460 true1461 ));14621463 let data = default_nft_data();1464 create_test_item(collection_id, &data.into());1465 });1466}14671468// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1469#[test]1470fn white_list_test_14() {1471 new_test_ext().execute_with(|| {1472 default_limits();1473 1474 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14751476 let origin1 = Origin::signed(1);1477 let origin2 = Origin::signed(2);14781479 assert_ok!(TemplateModule::set_public_access_mode(1480 origin1.clone(),1481 collection_id,1482 AccessMode::WhiteList1483 ));1484 assert_ok!(TemplateModule::set_mint_permission(1485 origin1.clone(),1486 collection_id,1487 true1488 ));14891490 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));14911492 assert_ok!(TemplateModule::create_item(1493 origin2.clone(),1494 1,1495 2,1496 default_nft_data().into()1497 ));1498 });1499}15001501// 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.1502#[test]1503fn white_list_test_15() {1504 new_test_ext().execute_with(|| {1505 default_limits();1506 1507 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15081509 let origin1 = Origin::signed(1);1510 let origin2 = Origin::signed(2);15111512 assert_ok!(TemplateModule::set_public_access_mode(1513 origin1.clone(),1514 collection_id,1515 AccessMode::WhiteList1516 ));1517 assert_ok!(TemplateModule::set_mint_permission(1518 origin1.clone(),1519 collection_id,1520 true1521 ));15221523 assert_noop!(1524 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1525 Error::<Test>::AddresNotInWhiteList1526 );1527 });1528}15291530// 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.1531#[test]1532fn white_list_test_16() {1533 new_test_ext().execute_with(|| {1534 default_limits();1535 1536 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15371538 let origin1 = Origin::signed(1);1539 let origin2 = Origin::signed(2);15401541 assert_ok!(TemplateModule::set_public_access_mode(1542 origin1.clone(),1543 collection_id,1544 AccessMode::WhiteList1545 ));1546 assert_ok!(TemplateModule::set_mint_permission(1547 origin1.clone(),1548 collection_id,1549 true1550 ));1551 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));15521553 assert_ok!(TemplateModule::create_item(1554 origin2.clone(),1555 1,1556 2,1557 default_nft_data().into()1558 ));1559 });1560}15611562// Total number of collections. Positive test1563#[test]1564fn total_number_collections_bound() {1565 new_test_ext().execute_with(|| {1566 default_limits();1567 1568 create_test_collection(&CollectionMode::NFT, 1);1569 });1570}15711572// Total number of collections. Negotive test1573#[test]1574fn total_number_collections_bound_neg() {1575 new_test_ext().execute_with(|| {1576 default_limits();15771578 let origin1 = Origin::signed(1);15791580 for i in 0..default_collection_numbers_limit() {1581 create_test_collection(&CollectionMode::NFT, i + 1);1582 }15831584 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1585 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1586 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();15871588 // 11-th collection in chain. Expects error1589 assert_noop!(TemplateModule::create_collection(1590 origin1.clone(),1591 col_name1.clone(),1592 col_desc1.clone(),1593 token_prefix1.clone(),1594 CollectionMode::NFT1595 ), Error::<Test>::TotalCollectionsLimitExceeded);1596 });1597}15981599// Owned tokens by a single address. Positive test1600#[test]1601fn owned_tokens_bound() {1602 new_test_ext().execute_with(|| {1603 default_limits();1604 1605 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16061607 let data = default_nft_data();1608 create_test_item(collection_id, &data.clone().into());1609 create_test_item(collection_id, &data.into());1610 });1611}16121613// Owned tokens by a single address. Negotive test1614#[test]1615fn owned_tokens_bound_neg() {1616 new_test_ext().execute_with(|| {1617 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1618 collection_numbers_limit: 10,1619 account_token_ownership_limit: 1,1620 collections_admins_limit: 5,1621 custom_data_limit: 2048,1622 nft_sponsor_transfer_timeout: 15,1623 fungible_sponsor_transfer_timeout: 15,1624 refungible_sponsor_transfer_timeout: 15,1625 const_on_chain_schema_limit: 1024,1626 offchain_schema_limit: 1024,1627 variable_on_chain_schema_limit: 1024,1628 }));1629 1630 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16311632 let origin1 = Origin::signed(1);1633 let data = default_nft_data();1634 create_test_item(collection_id, &data.clone().into());16351636 assert_noop!(TemplateModule::create_item(1637 origin1.clone(),1638 1,1639 1,1640 data.into()1641 ), Error::<Test>::AddressOwnershipLimitExceeded);1642 });1643}16441645// Number of collection admins. Positive test1646#[test]1647fn collection_admins_bound() {1648 new_test_ext().execute_with(|| {1649 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1650 collection_numbers_limit: 10,1651 account_token_ownership_limit: 10,1652 collections_admins_limit: 2,1653 custom_data_limit: 2048,1654 nft_sponsor_transfer_timeout: 15,1655 fungible_sponsor_transfer_timeout: 15,1656 refungible_sponsor_transfer_timeout: 15,1657 const_on_chain_schema_limit: 1024,1658 offchain_schema_limit: 1024,1659 variable_on_chain_schema_limit: 1024,1660 }));1661 1662 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16631664 let origin1 = Origin::signed(1);1665 1666 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1667 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3));1668 });1669}16701671// Number of collection admins. Negotive test1672#[test]1673fn collection_admins_bound_neg() {1674 new_test_ext().execute_with(|| {1675 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1676 collection_numbers_limit: 10,1677 account_token_ownership_limit: 1,1678 collections_admins_limit: 1,1679 custom_data_limit: 2048,1680 nft_sponsor_transfer_timeout: 15,1681 fungible_sponsor_transfer_timeout: 15,1682 refungible_sponsor_transfer_timeout: 15,1683 const_on_chain_schema_limit: 1024,1684 offchain_schema_limit: 1024,1685 variable_on_chain_schema_limit: 1024,1686 }));1687 1688 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16891690 let origin1 = Origin::signed(1);16911692 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1693 assert_noop!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3), Error::<Test>::CollectionAdminsLimitExceeded);1694 });1695}16961697// NFT custom data size. Negative test const_data.1698#[test]1699fn custom_data_size_nft_const_data_bound_neg() {1700 new_test_ext().execute_with(|| {1701 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1702 collection_numbers_limit: 10,1703 account_token_ownership_limit: 10,1704 collections_admins_limit: 5,1705 custom_data_limit: 2,1706 nft_sponsor_transfer_timeout: 15,1707 fungible_sponsor_transfer_timeout: 15,1708 refungible_sponsor_transfer_timeout: 15,1709 const_on_chain_schema_limit: 1024,1710 offchain_schema_limit: 1024,1711 variable_on_chain_schema_limit: 1024,1712 }));1713 1714 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17151716 let origin1 = Origin::signed(1);1717 let too_big_const_data = CreateItemData::NFT(CreateNftData{1718 const_data: vec![1, 2, 3, 4],1719 variable_data: vec![]1720 });17211722 assert_noop!(TemplateModule::create_item(1723 origin1.clone(),1724 collection_id,1725 1,1726 too_big_const_data1727 ), Error::<Test>::TokenConstDataLimitExceeded);1728 });1729}17301731// NFT custom data size. Negative test variable_data.1732#[test]1733fn custom_data_size_nft_variable_data_bound_neg() {1734 new_test_ext().execute_with(|| {1735 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1736 collection_numbers_limit: 10,1737 account_token_ownership_limit: 10,1738 collections_admins_limit: 5,1739 custom_data_limit: 2,1740 nft_sponsor_transfer_timeout: 15,1741 fungible_sponsor_transfer_timeout: 15,1742 refungible_sponsor_transfer_timeout: 15,1743 const_on_chain_schema_limit: 1024,1744 offchain_schema_limit: 1024,1745 variable_on_chain_schema_limit: 1024,1746 }));17471748 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17491750 let origin1 = Origin::signed(1);1751 let too_big_const_data = CreateItemData::NFT(CreateNftData{1752 const_data: vec![],1753 variable_data: vec![1, 2, 3, 4]1754 });17551756 assert_noop!(TemplateModule::create_item(1757 origin1.clone(),1758 collection_id,1759 1,1760 too_big_const_data1761 ), Error::<Test>::TokenVariableDataLimitExceeded);1762 });1763}17641765// Re fungible custom data size. Negative test const_data.1766#[test]1767fn custom_data_size_re_fungible_const_data_bound_neg() {1768 new_test_ext().execute_with(|| {1769 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1770 collection_numbers_limit: 10,1771 account_token_ownership_limit: 10,1772 collections_admins_limit: 5,1773 custom_data_limit: 2,1774 nft_sponsor_transfer_timeout: 15,1775 fungible_sponsor_transfer_timeout: 15,1776 refungible_sponsor_transfer_timeout: 15,1777 const_on_chain_schema_limit: 1024,1778 offchain_schema_limit: 1024,1779 variable_on_chain_schema_limit: 1024,1780 }));17811782 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17831784 let origin1 = Origin::signed(1);1785 let too_big_const_data = CreateItemData::NFT(CreateNftData{1786 const_data: vec![1, 2, 3, 4],1787 variable_data: vec![]1788 });17891790 assert_noop!(TemplateModule::create_item(1791 origin1.clone(),1792 collection_id,1793 1,1794 too_big_const_data1795 ), Error::<Test>::TokenConstDataLimitExceeded);1796 });1797}17981799// Re fungible custom data size. Negative test variable_data.1800#[test]1801fn custom_data_size_re_fungible_variable_data_bound_neg() {1802 new_test_ext().execute_with(|| {1803 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1804 collection_numbers_limit: 10,1805 account_token_ownership_limit: 10,1806 collections_admins_limit: 5,1807 custom_data_limit: 2,1808 nft_sponsor_transfer_timeout: 15,1809 fungible_sponsor_transfer_timeout: 15,1810 refungible_sponsor_transfer_timeout: 15,1811 const_on_chain_schema_limit: 1024,1812 offchain_schema_limit: 1024,1813 variable_on_chain_schema_limit: 1024,1814 }));18151816 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18171818 let origin1 = Origin::signed(1);1819 let too_big_const_data = CreateItemData::NFT(CreateNftData{1820 const_data: vec![],1821 variable_data: vec![1, 2, 3, 4]1822 });18231824 assert_noop!(TemplateModule::create_item(1825 origin1.clone(),1826 collection_id,1827 1,1828 too_big_const_data1829 ), Error::<Test>::TokenVariableDataLimitExceeded);1830 });1831}1832// #endregion18331834#[test]1835fn set_const_on_chain_schema() {1836 new_test_ext().execute_with(|| {1837 default_limits();18381839 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18401841 let origin1 = Origin::signed(1);1842 assert_ok!(TemplateModule::set_const_on_chain_schema(origin1, collection_id, b"test const on chain schema".to_vec()));18431844 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"test const on chain schema".to_vec());1845 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"".to_vec());1846 });1847}18481849#[test]1850fn set_variable_on_chain_schema() {1851 new_test_ext().execute_with(|| {1852 default_limits();1853 1854 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18551856 let origin1 = Origin::signed(1);1857 assert_ok!(TemplateModule::set_variable_on_chain_schema(origin1, collection_id, b"test variable on chain schema".to_vec()));18581859 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"".to_vec());1860 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"test variable on chain schema".to_vec());1861 });1862}18631864#[test]1865fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {1866 new_test_ext().execute_with(|| {1867 default_limits();18681869 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18701871 let origin1 = Origin::signed(1);1872 1873 let data = default_nft_data();1874 create_test_item(1, &data.into());1875 1876 let variable_data = b"test set_variable_meta_data method.".to_vec();1877 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));18781879 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, variable_data);1880 });1881}18821883#[test]1884fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {1885 new_test_ext().execute_with(|| {1886 default_limits();18871888 let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);18891890 let origin1 = Origin::signed(1);18911892 let data = default_re_fungible_data();1893 create_test_item(1, &data.into());18941895 let variable_data = b"test set_variable_meta_data method.".to_vec();1896 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));18971898 assert_eq!(TemplateModule::refungible_item_id(collection_id, 1).variable_data, variable_data);1899 });1900}190119021903#[test]1904fn set_variable_meta_data_on_fungible_token_fails() {1905 new_test_ext().execute_with(|| {1906 default_limits();19071908 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);19091910 let origin1 = Origin::signed(1);19111912 let data = default_fungible_data();1913 create_test_item(1, &data.into());19141915 let variable_data = b"test set_variable_meta_data method.".to_vec();1916 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()), Error::<Test>::CantStoreMetadataInFungibleTokens);1917 });1918}19191920#[test]1921fn set_variable_meta_data_on_nft_token_fails_for_big_data() {1922 new_test_ext().execute_with(|| {1923 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1924 collection_numbers_limit: default_collection_numbers_limit(),1925 account_token_ownership_limit: 10,1926 collections_admins_limit: 5,1927 custom_data_limit: 10,1928 nft_sponsor_transfer_timeout: 15,1929 fungible_sponsor_transfer_timeout: 15,1930 refungible_sponsor_transfer_timeout: 15,1931 const_on_chain_schema_limit: 1024,1932 offchain_schema_limit: 1024,1933 variable_on_chain_schema_limit: 1024,1934 }));19351936 let collection_id = create_test_collection(&CollectionMode::NFT, 1);19371938 let origin1 = Origin::signed(1);19391940 let data = default_nft_data();1941 create_test_item(1, &data.into());19421943 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1944 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);1945 });1946}19471948#[test]1949fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {1950 new_test_ext().execute_with(|| {1951 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1952 collection_numbers_limit: default_collection_numbers_limit(),1953 account_token_ownership_limit: 10,1954 collections_admins_limit: 5,1955 custom_data_limit: 10,1956 nft_sponsor_transfer_timeout: 15,1957 fungible_sponsor_transfer_timeout: 15,1958 refungible_sponsor_transfer_timeout: 15,1959 const_on_chain_schema_limit: 1024,1960 offchain_schema_limit: 1024,1961 variable_on_chain_schema_limit: 1024,1962 }));196319641965 let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);19661967 let origin1 = Origin::signed(1);19681969 let data = default_re_fungible_data();1970 create_test_item(1, &data.into());19711972 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1973 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);1974 });1975}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);
}