difftreelog
Merge remote-tracking branch 'origin/develop' into feature/NFTPAR-241
in: master
# Conflicts: # tests/package.json
16 files changed
pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -1153,7 +1153,7 @@
}
// Reduce approval by transferred amount or remove if remaining approval drops to 0
- if approval - value > 0 {
+ if approval.checked_sub(value).unwrap_or(0) > 0 {
<Allowances<T>>::insert(collection_id, (item_id, &from, &recipient), approval - value);
}
else {
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 }));24}2526fn default_nft_data() -> CreateNftData {27 CreateNftData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] }28}2930fn default_fungible_data () -> CreateFungibleData {31 CreateFungibleData { value: 5 }32}3334fn default_re_fungible_data () -> CreateReFungibleData {35 CreateReFungibleData { const_data: vec![1, 2, 3], variable_data: vec![3, 2, 1] }36}3738fn create_test_collection_for_owner(mode: &CollectionMode, owner: u64, id: CollectionId) -> CollectionId {39 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();40 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();41 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();4243 let origin1 = Origin::signed(owner);44 assert_ok!(TemplateModule::create_collection(45 origin1.clone(),46 col_name1.clone(),47 col_desc1.clone(),48 token_prefix1.clone(),49 mode.clone()50 ));5152 let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();53 let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();54 let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();55 assert_eq!(TemplateModule::collection(id).owner, owner);56 assert_eq!(TemplateModule::collection(id).name, saved_col_name);57 assert_eq!(TemplateModule::collection(id).mode, *mode);58 assert_eq!(TemplateModule::collection(id).description, saved_description);59 assert_eq!(TemplateModule::collection(id).token_prefix, saved_prefix);60 id61}6263fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {64 create_test_collection_for_owner(&mode, 1, id)65}6667fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {68 let origin1 = Origin::signed(1);69 assert_ok!(TemplateModule::create_item(70 origin1.clone(),71 collection_id,72 1,73 data.clone()74 ));7576}7778// Use cases tests region79// #region8081#[test]82fn set_version_schema() {83 new_test_ext().execute_with(|| {84 default_limits();85 let origin1 = Origin::signed(1);86 let collection_id = create_test_collection(&CollectionMode::NFT, 1);87 88 assert_ok!(TemplateModule::set_schema_version(origin1, collection_id, SchemaVersion::Unique));89 assert_eq!(TemplateModule::collection(collection_id).schema_version, SchemaVersion::Unique);90 });91}9293#[test]94fn create_fungible_collection_fails_with_large_decimal_numbers() {95 new_test_ext().execute_with(|| {96 default_limits();9798 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();99 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();100 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();101102 let origin1 = Origin::signed(1);103 assert_noop!(TemplateModule::create_collection(104 origin1,105 col_name1,106 col_desc1,107 token_prefix1,108 CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1)109 ), Error::<Test>::CollectionDecimalPointLimitExceeded);110 }); 111}112113#[test]114fn create_re_fungible_collection_fails_with_large_decimal_numbers() {115 new_test_ext().execute_with(|| {116 default_limits();117118 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();119 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();120 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();121122 let origin1 = Origin::signed(1);123 assert_noop!(TemplateModule::create_collection(124 origin1,125 col_name1,126 col_desc1,127 token_prefix1,128 CollectionMode::ReFungible(MAX_DECIMAL_POINTS + 1)129 ), Error::<Test>::CollectionDecimalPointLimitExceeded);130 });131}132133#[test]134fn create_nft_item() {135 new_test_ext().execute_with(|| {136 default_limits();137 let collection_id = create_test_collection(&CollectionMode::NFT, 1);138 139 let data = default_nft_data();140 create_test_item(collection_id, &data.clone().into());141 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).const_data, data.const_data);142 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, data.variable_data);143 });144}145146// Use cases tests region147// #region148#[test]149fn create_nft_multiple_items() {150 new_test_ext().execute_with(|| {151 default_limits();152 153 create_test_collection(&CollectionMode::NFT, 1);154155 let origin1 = Origin::signed(1);156157 let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];158159 assert_ok!(TemplateModule::create_multiple_items(160 origin1.clone(),161 1,162 1,163 items_data.clone().into_iter().map(|d| { d.into() }).collect()164 ));165 for (index, data) in items_data.iter().enumerate() {166 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).const_data.to_vec(), data.const_data);167 assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).variable_data.to_vec(), data.variable_data);168 }169 });170}171172#[test]173fn create_refungible_item() {174 new_test_ext().execute_with(|| {175 default_limits();176 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);177178 let data = default_re_fungible_data();179 create_test_item(collection_id, &data.clone().into());180 assert_eq!(181 TemplateModule::refungible_item_id(collection_id, 1).const_data,182 data.const_data183 );184 assert_eq!(185 TemplateModule::refungible_item_id(collection_id, 1).variable_data,186 data.variable_data187 );188 assert_eq!(189 TemplateModule::refungible_item_id(collection_id, 1).owner[0],190 Ownership {191 owner: 1,192 fraction: 1000193 }194 );195 });196}197198#[test]199fn create_multiple_refungible_items() {200 new_test_ext().execute_with(|| {201 default_limits();202 203 create_test_collection(&CollectionMode::ReFungible(3), 1);204205 let origin1 = Origin::signed(1);206207 let items_data = vec![default_re_fungible_data(), default_re_fungible_data(), default_re_fungible_data()];208209 assert_ok!(TemplateModule::create_multiple_items(210 origin1.clone(),211 1,212 1,213 items_data.clone().into_iter().map(|d| { d.into() }).collect()214 ));215 for (index, data) in items_data.iter().enumerate() {216217 let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId);218 assert_eq!(item.const_data.to_vec(), data.const_data);219 assert_eq!(item.variable_data.to_vec(), data.variable_data);220 assert_eq!(221 item.owner[0],222 Ownership {223 owner: 1,224 fraction: 1000225 }226 );227 }228 });229}230231#[test]232fn create_fungible_item() {233 new_test_ext().execute_with(|| {234 default_limits();235 236 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);237238 let data = default_fungible_data();239 create_test_item(collection_id, &data.into());240241 assert_eq!(TemplateModule::fungible_item_id(collection_id, 1).value, 5);242 });243}244245//#[test]246// fn create_multiple_fungible_items() {247// new_test_ext().execute_with(|| {248// default_limits();249250// create_test_collection(&CollectionMode::Fungible(3), 1);251252// let origin1 = Origin::signed(1);253254// let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];255256// assert_ok!(TemplateModule::create_multiple_items(257// origin1.clone(),258// 1,259// 1,260// items_data.clone().into_iter().map(|d| { d.into() }).collect()261// ));262 263// for (index, _) in items_data.iter().enumerate() {264// assert_eq!(TemplateModule::fungible_item_id(1, (index + 1) as TokenId).value, 5);265// }266// assert_eq!(TemplateModule::balance_count(1, 1), 3000);267// assert_eq!(TemplateModule::address_tokens(1, 1), [1, 2, 3]);268// });269// }270271#[test]272fn transfer_fungible_item() {273 new_test_ext().execute_with(|| {274 default_limits();275 276 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);277278 let origin1 = Origin::signed(1);279 let origin2 = Origin::signed(2);280281 let data = default_fungible_data();282 create_test_item(collection_id, &data.into());283284 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 5);285 assert_eq!(TemplateModule::balance_count(1, 1), 5);286287 // change owner scenario288 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 5));289 assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 0);290 assert_eq!(TemplateModule::balance_count(1, 1), 0);291 assert_eq!(TemplateModule::balance_count(1, 2), 5);292293 // split item scenario294 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 3));295 assert_eq!(TemplateModule::balance_count(1, 2), 2);296 assert_eq!(TemplateModule::balance_count(1, 3), 3);297298 // split item and new owner has account scenario299 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 1));300 assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 1);301 assert_eq!(TemplateModule::fungible_item_id(1, 3).value, 4);302 assert_eq!(TemplateModule::balance_count(1, 2), 1);303 assert_eq!(TemplateModule::balance_count(1, 3), 4);304 });305}306307#[test]308fn transfer_refungible_item() {309 new_test_ext().execute_with(|| {310 default_limits();311 312 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);313314 let data = default_re_fungible_data();315 create_test_item(collection_id, &data.clone().into());316317 let origin1 = Origin::signed(1);318 let origin2 = Origin::signed(2);319 assert_eq!(320 TemplateModule::refungible_item_id(collection_id, 1).const_data,321 data.const_data322 );323 assert_eq!(324 TemplateModule::refungible_item_id(collection_id, 1).variable_data,325 data.variable_data326 );327 assert_eq!(328 TemplateModule::refungible_item_id(collection_id, 1).owner[0],329 Ownership {330 owner: 1,331 fraction: 1000332 }333 );334 assert_eq!(TemplateModule::balance_count(1, 1), 1000);335 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);336337 // change owner scenario338 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));339 assert_eq!(340 TemplateModule::refungible_item_id(1, 1).owner[0],341 Ownership {342 owner: 2,343 fraction: 1000344 }345 );346 assert_eq!(TemplateModule::balance_count(1, 1), 0);347 assert_eq!(TemplateModule::balance_count(1, 2), 1000);348 // assert_eq!(TemplateModule::address_tokens(1, 1), []);349 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);350351 // split item scenario352 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));353 assert_eq!(354 TemplateModule::refungible_item_id(1, 1).owner[0],355 Ownership {356 owner: 2,357 fraction: 500358 }359 );360 assert_eq!(361 TemplateModule::refungible_item_id(1, 1).owner[1],362 Ownership {363 owner: 3,364 fraction: 500365 }366 );367 assert_eq!(TemplateModule::balance_count(1, 2), 500);368 assert_eq!(TemplateModule::balance_count(1, 3), 500);369 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);370 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);371372 // split item and new owner has account scenario373 assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));374 assert_eq!(375 TemplateModule::refungible_item_id(1, 1).owner[0],376 Ownership {377 owner: 2,378 fraction: 300379 }380 );381 assert_eq!(382 TemplateModule::refungible_item_id(1, 1).owner[1],383 Ownership {384 owner: 3,385 fraction: 700386 }387 );388 assert_eq!(TemplateModule::balance_count(1, 2), 300);389 assert_eq!(TemplateModule::balance_count(1, 3), 700);390 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);391 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);392 });393}394395#[test]396fn transfer_nft_item() {397 new_test_ext().execute_with(|| {398 default_limits();399 400 let collection_id = create_test_collection(&CollectionMode::NFT, 1);401402 let data = default_nft_data();403 create_test_item(collection_id, &data.into());404 assert_eq!(TemplateModule::balance_count(1, 1), 1);405 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);406407 let origin1 = Origin::signed(1);408 // default scenario409 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));410 assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2);411 assert_eq!(TemplateModule::balance_count(1, 1), 0);412 assert_eq!(TemplateModule::balance_count(1, 2), 1);413 // assert_eq!(TemplateModule::address_tokens(1, 1), []);414 assert_eq!(TemplateModule::address_tokens(1, 2), [1]);415 });416}417418#[test]419fn nft_approve_and_transfer_from() {420 new_test_ext().execute_with(|| {421 default_limits();422 423 let collection_id = create_test_collection(&CollectionMode::NFT, 1);424425 let data = default_nft_data();426 create_test_item(collection_id, &data.into());427428 let origin1 = Origin::signed(1);429 let origin2 = Origin::signed(2);430431 assert_eq!(TemplateModule::balance_count(1, 1), 1);432 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);433434 // neg transfer435 assert_noop!(TemplateModule::transfer_from(436 origin2.clone(),437 1,438 2,439 1,440 1,441 1), Error::<Test>::NoPermission);442443 // do approve444 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));445 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);446 assert_eq!(447 TemplateModule::approved(1, (1, 1, 2)),448 5449 );450451 assert_ok!(TemplateModule::transfer_from(452 origin2.clone(),453 1,454 2,455 1,456 1,457 1458 ));459 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);460 });461}462463#[test]464fn nft_approve_and_transfer_from_white_list() {465 new_test_ext().execute_with(|| {466 default_limits();467 468 let collection_id = create_test_collection(&CollectionMode::NFT, 1);469470 let origin1 = Origin::signed(1);471 let origin2 = Origin::signed(2);472473 let data = default_nft_data();474 create_test_item(collection_id, &data.clone().into());475476 assert_eq!(TemplateModule::nft_item_id(1, 1).const_data, data.const_data);477 assert_eq!(TemplateModule::balance_count(1, 1), 1);478 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);479480 assert_ok!(TemplateModule::set_mint_permission(481 origin1.clone(),482 1,483 true484 ));485 assert_ok!(TemplateModule::set_public_access_mode(486 origin1.clone(),487 1,488 AccessMode::WhiteList489 ));490 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));491 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));492 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));493494 // do approve495 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));496 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);497 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1, 5));498 assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);499500 assert_ok!(TemplateModule::transfer_from(501 origin2.clone(),502 1,503 3,504 1,505 1,506 1507 ));508 assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 4);509 });510}511512#[test]513fn refungible_approve_and_transfer_from() {514 new_test_ext().execute_with(|| {515 default_limits();516 517 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);518 519 let origin1 = Origin::signed(1);520 let origin2 = Origin::signed(2);521522 let data = default_re_fungible_data();523 create_test_item(collection_id, &data.into());524525 assert_eq!(TemplateModule::balance_count(1, 1), 1000);526 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);527528 assert_ok!(TemplateModule::set_mint_permission(529 origin1.clone(),530 1,531 true532 ));533 assert_ok!(TemplateModule::set_public_access_mode(534 origin1.clone(),535 1,536 AccessMode::WhiteList537 ));538 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));539 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));540 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));541542 // do approve543 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));544 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);545 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1, 1000));546 assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 1000);547548 assert_ok!(TemplateModule::transfer_from(549 origin2.clone(),550 1,551 3,552 1,553 1,554 100555 ));556 assert_eq!(TemplateModule::balance_count(1, 1), 900);557 assert_eq!(TemplateModule::balance_count(1, 3), 100);558 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);559 assert_eq!(TemplateModule::address_tokens(1, 3), [1]);560561 assert_eq!(562 TemplateModule::approved(1, (1, 1, 3)),563 900564 );565 });566}567568#[test]569fn fungible_approve_and_transfer_from() {570 new_test_ext().execute_with(|| {571 default_limits();572 573 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);574 575 let data = default_fungible_data();576 create_test_item(collection_id, &data.into());577578 let origin1 = Origin::signed(1);579 let origin2 = Origin::signed(2);580581 assert_eq!(TemplateModule::balance_count(1, 1), 5);582583 assert_ok!(TemplateModule::set_mint_permission(584 origin1.clone(),585 1,586 true587 ));588 assert_ok!(TemplateModule::set_public_access_mode(589 origin1.clone(),590 1,591 AccessMode::WhiteList592 ));593 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));594 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));595 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));596597 // do approve598 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));599 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);600 assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1, 5));601 assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);602 assert_eq!(603 TemplateModule::approved(1, (1, 1, 2)),604 5605 );606607 assert_ok!(TemplateModule::transfer_from(608 origin2.clone(),609 1,610 3,611 1,612 1,613 4614 ));615 assert_eq!(TemplateModule::balance_count(1, 1), 1);616 assert_eq!(TemplateModule::balance_count(1, 3), 4);617618 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);619 assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 1);620621 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 5));622 assert_noop!(TemplateModule::transfer_from(623 origin2.clone(),624 1,625 3,626 1,627 1,628 4629 ), Error::<Test>::TokenValueNotEnough);630 });631}632633#[test]634fn change_collection_owner() {635 new_test_ext().execute_with(|| {636 default_limits();637 638 let collection_id = create_test_collection(&CollectionMode::NFT, 1);639 640 let origin1 = Origin::signed(1);641 assert_ok!(TemplateModule::change_collection_owner(642 origin1.clone(),643 collection_id,644 2645 ));646 assert_eq!(TemplateModule::collection(collection_id).owner, 2);647 });648}649650#[test]651fn destroy_collection() {652 new_test_ext().execute_with(|| {653 default_limits();654 655 let collection_id = create_test_collection(&CollectionMode::NFT, 1);656 657 let origin1 = Origin::signed(1);658 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));659 });660}661662#[test]663fn burn_nft_item() {664 new_test_ext().execute_with(|| {665 default_limits();666 667 let collection_id = create_test_collection(&CollectionMode::NFT, 1);668669 let origin1 = Origin::signed(1);670 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));671 672 let data = default_nft_data();673 create_test_item(collection_id, &data.into());674675 // check balance (collection with id = 1, user id = 1)676 assert_eq!(TemplateModule::balance_count(1, 1), 1);677678 // burn item679 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));680 assert_noop!(681 TemplateModule::burn_item(origin1.clone(), 1, 1, 5),682 Error::<Test>::TokenNotFound683 );684685 assert_eq!(TemplateModule::balance_count(1, 1), 0);686 });687}688689#[test]690fn burn_fungible_item() {691 new_test_ext().execute_with(|| {692 default_limits();693 694 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);695 696 let origin1 = Origin::signed(1);697 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));698 699 let data = default_fungible_data();700 create_test_item(collection_id, &data.into());701702 // check balance (collection with id = 1, user id = 1)703 assert_eq!(TemplateModule::balance_count(1, 1), 5);704705 // burn item706 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));707 assert_noop!(708 TemplateModule::burn_item(origin1.clone(), 1, 1, 5),709 Error::<Test>::TokenNotFound710 );711712 assert_eq!(TemplateModule::balance_count(1, 1), 0);713 });714}715716#[test]717fn burn_refungible_item() {718 new_test_ext().execute_with(|| {719 default_limits();720 721 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);722 let origin1 = Origin::signed(1);723724 assert_ok!(TemplateModule::set_mint_permission(725 origin1.clone(),726 collection_id,727 true728 ));729 assert_ok!(TemplateModule::set_public_access_mode(730 origin1.clone(),731 collection_id,732 AccessMode::WhiteList733 ));734 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));735736 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));737 738 let data = default_re_fungible_data();739 create_test_item(collection_id, &data.into());740741 // check balance (collection with id = 1, user id = 2)742 assert_eq!(TemplateModule::balance_count(1, 1), 1000);743744 // burn item745 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 1000));746 assert_noop!(747 TemplateModule::burn_item(origin1.clone(), 1, 1, 1000),748 Error::<Test>::TokenNotFound749 );750751 assert_eq!(TemplateModule::balance_count(1, 1), 0);752 });753}754755#[test]756fn add_collection_admin() {757 new_test_ext().execute_with(|| {758 default_limits();759 760 let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);761 create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);762 create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);763 764 let origin1 = Origin::signed(1);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(collection1_id).contains(&2), true);771 assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&3), true);772 });773}774775#[test]776fn remove_collection_admin() {777 new_test_ext().execute_with(|| {778 default_limits();779 780 let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);781 create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);782 create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);783784 let origin1 = Origin::signed(1);785 let origin2 = Origin::signed(2);786787 // collection admin788 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));789 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));790791 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);792 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);793794 // remove admin795 assert_ok!(TemplateModule::remove_collection_admin(796 origin2.clone(),797 1,798 3799 ));800 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), false);801 });802}803804#[test]805fn balance_of() {806 new_test_ext().execute_with(|| {807 default_limits();808 809 let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);810 let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);811 let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible(3), 3);812 813 // check balance before814 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);815 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);816 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 0);817818 let nft_data = default_nft_data();819 create_test_item(nft_collection_id, &nft_data.into());820 821 let fungible_data = default_fungible_data();822 create_test_item(fungible_collection_id, &fungible_data.into());823 824 let re_fungible_data = default_re_fungible_data();825 create_test_item(re_fungible_collection_id, &re_fungible_data.into());826827 // check balance (collection with id = 1, user id = 1)828 assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1);829 assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 5);830 assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 1000);831 assert_eq!(TemplateModule::nft_item_id(nft_collection_id, 1).owner, 1);832 assert_eq!(TemplateModule::fungible_item_id(fungible_collection_id, 1).value, 5);833 assert_eq!(TemplateModule::refungible_item_id(re_fungible_collection_id, 1).owner[0].owner, 1);834 });835}836837#[test]838fn approve() {839 new_test_ext().execute_with(|| {840 default_limits();841 842 let collection_id = create_test_collection(&CollectionMode::NFT, 1);843 844 let data = default_nft_data();845 create_test_item(collection_id, &data.into());846847 let origin1 = Origin::signed(1);848 849 // approve850 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 1));851 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);852 });853}854855#[test]856fn transfer_from() {857 new_test_ext().execute_with(|| {858 default_limits();859 860 let collection_id = create_test_collection(&CollectionMode::NFT, 1);861 let origin1 = Origin::signed(1);862 let origin2 = Origin::signed(2);863864 let data = default_nft_data();865 create_test_item(collection_id, &data.into());866867 // approve868 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1, 1));869 assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);870871 assert_ok!(TemplateModule::set_mint_permission(872 origin1.clone(),873 1,874 true875 ));876 assert_ok!(TemplateModule::set_public_access_mode(877 origin1.clone(),878 1,879 AccessMode::WhiteList880 ));881 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));882 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));883 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));884885 assert_ok!(TemplateModule::transfer_from(886 origin2.clone(),887 1,888 2,889 1,890 1,891 1892 ));893894 // after transfer895 assert_eq!(TemplateModule::balance_count(1, 1), 0);896 assert_eq!(TemplateModule::balance_count(1, 2), 1);897 });898}899900// #endregion901902// Coverage tests region903// #region904905#[test]906fn owner_can_add_address_to_white_list() {907 new_test_ext().execute_with(|| {908 default_limits();909 910 let collection_id = create_test_collection(&CollectionMode::NFT, 1);911912 let origin1 = Origin::signed(1);913 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));914 assert_eq!(TemplateModule::white_list(collection_id, 2), true);915 });916}917918#[test]919fn admin_can_add_address_to_white_list() {920 new_test_ext().execute_with(|| {921 default_limits();922 923 let collection_id = create_test_collection(&CollectionMode::NFT, 1);924 let origin1 = Origin::signed(1);925 let origin2 = Origin::signed(2);926927 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));928 assert_ok!(TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3));929 assert_eq!(TemplateModule::white_list(collection_id, 3), true);930 });931}932933#[test]934fn nonprivileged_user_cannot_add_address_to_white_list() {935 new_test_ext().execute_with(|| {936 default_limits();937 938 let collection_id = create_test_collection(&CollectionMode::NFT, 1);939940 let origin2 = Origin::signed(2);941 assert_noop!(942 TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3),943 Error::<Test>::NoPermission944 );945 });946}947948#[test]949fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {950 new_test_ext().execute_with(|| {951 default_limits();952953 let origin1 = Origin::signed(1);954955 assert_noop!(956 TemplateModule::add_to_white_list(origin1.clone(), 1, 2),957 Error::<Test>::CollectionNotFound958 );959 });960}961962#[test]963fn nobody_can_add_address_to_white_list_of_deleted_collection() {964 new_test_ext().execute_with(|| {965 default_limits();966 967 let collection_id = create_test_collection(&CollectionMode::NFT, 1);968969 let origin1 = Origin::signed(1);970 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));971 assert_noop!(972 TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2),973 Error::<Test>::CollectionNotFound974 );975 });976}977978// If address is already added to white list, nothing happens979#[test]980fn address_is_already_added_to_white_list() {981 new_test_ext().execute_with(|| {982 default_limits();983 984 let collection_id = create_test_collection(&CollectionMode::NFT, 1);985 let origin1 = Origin::signed(1);986 987 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));988 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));989 assert_eq!(TemplateModule::white_list(collection_id, 2), true);990 });991}992993#[test]994fn owner_can_remove_address_from_white_list() {995 new_test_ext().execute_with(|| {996 default_limits();997 998 let collection_id = create_test_collection(&CollectionMode::NFT, 1);9991000 let origin1 = Origin::signed(1);1001 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1002 assert_ok!(TemplateModule::remove_from_white_list(1003 origin1.clone(),1004 collection_id,1005 21006 ));1007 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1008 });1009}10101011#[test]1012fn admin_can_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_collection_admin(origin1.clone(), collection_id, 2));10211022 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 3));1023 assert_ok!(TemplateModule::remove_from_white_list(1024 origin2.clone(),1025 collection_id,1026 31027 ));1028 assert_eq!(TemplateModule::white_list(collection_id, 3), false);1029 });1030}10311032#[test]1033fn nonprivileged_user_cannot_remove_address_from_white_list() {1034 new_test_ext().execute_with(|| {1035 default_limits();1036 1037 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1038 let origin1 = Origin::signed(1);1039 let origin2 = Origin::signed(2);10401041 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1042 assert_noop!(1043 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1044 Error::<Test>::NoPermission1045 );1046 assert_eq!(TemplateModule::white_list(collection_id, 2), true);1047 });1048}10491050#[test]1051fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1052 new_test_ext().execute_with(|| {1053 default_limits();1054 let origin1 = Origin::signed(1);10551056 assert_noop!(1057 TemplateModule::remove_from_white_list(origin1.clone(), 1, 2),1058 Error::<Test>::CollectionNotFound1059 );1060 });1061}10621063#[test]1064fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1065 new_test_ext().execute_with(|| {1066 default_limits();1067 1068 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1069 let origin1 = Origin::signed(1);1070 let origin2 = Origin::signed(2);10711072 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1073 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1074 assert_noop!(1075 TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1076 Error::<Test>::CollectionNotFound1077 );1078 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1079 });1080}10811082// If address is already removed from white list, nothing happens1083#[test]1084fn address_is_already_removed_from_white_list() {1085 new_test_ext().execute_with(|| {1086 default_limits();1087 1088 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1089 let origin1 = Origin::signed(1);10901091 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1092 assert_ok!(TemplateModule::remove_from_white_list(1093 origin1.clone(),1094 collection_id,1095 21096 ));1097 assert_ok!(TemplateModule::remove_from_white_list(1098 origin1.clone(),1099 collection_id,1100 21101 ));1102 assert_eq!(TemplateModule::white_list(collection_id, 2), false);1103 });1104}11051106// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1107#[test]1108fn white_list_test_1() {1109 new_test_ext().execute_with(|| {1110 default_limits();1111 1112 let collection_id = create_test_collection(&CollectionMode::NFT, 1);11131114 let origin1 = Origin::signed(1);1115 1116 let data = default_nft_data();1117 create_test_item(collection_id, &data.into());11181119 assert_ok!(TemplateModule::set_public_access_mode(1120 origin1.clone(),1121 collection_id,1122 AccessMode::WhiteList1123 ));1124 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));11251126 assert_noop!(1127 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1128 Error::<Test>::AddresNotInWhiteList1129 );1130 });1131}11321133#[test]1134fn white_list_test_2() {1135 new_test_ext().execute_with(|| {1136 default_limits();1137 1138 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1139 let origin1 = Origin::signed(1);1140 1141 let data = default_nft_data();1142 create_test_item(collection_id, &data.into());11431144 assert_ok!(TemplateModule::set_public_access_mode(1145 origin1.clone(),1146 collection_id,1147 AccessMode::WhiteList1148 ));1149 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1150 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));11511152 // do approve1153 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1, 1));1154 assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);11551156 assert_ok!(TemplateModule::remove_from_white_list(1157 origin1.clone(),1158 1,1159 11160 ));11611162 assert_noop!(1163 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1164 Error::<Test>::AddresNotInWhiteList1165 );1166 });1167}11681169// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1170#[test]1171fn white_list_test_3() {1172 new_test_ext().execute_with(|| {1173 default_limits();1174 1175 let collection_id = create_test_collection(&CollectionMode::NFT, 1);11761177 let origin1 = Origin::signed(1);1178 1179 let data = default_nft_data();1180 create_test_item(collection_id, &data.into());11811182 assert_ok!(TemplateModule::set_public_access_mode(1183 origin1.clone(),1184 collection_id,1185 AccessMode::WhiteList1186 ));1187 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));11881189 assert_noop!(1190 TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1191 Error::<Test>::AddresNotInWhiteList1192 );1193 });1194}11951196#[test]1197fn white_list_test_4() {1198 new_test_ext().execute_with(|| {1199 default_limits();1200 1201 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12021203 let origin1 = Origin::signed(1);12041205 let data = default_nft_data();1206 create_test_item(collection_id, &data.into());12071208 assert_ok!(TemplateModule::set_public_access_mode(1209 origin1.clone(),1210 collection_id,1211 AccessMode::WhiteList1212 ));1213 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1214 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));12151216 // do approve1217 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1, 1));1218 assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);12191220 assert_ok!(TemplateModule::remove_from_white_list(1221 origin1.clone(),1222 collection_id,1223 21224 ));12251226 assert_noop!(1227 TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1228 Error::<Test>::AddresNotInWhiteList1229 );1230 });1231}12321233// 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)1234#[test]1235fn white_list_test_5() {1236 new_test_ext().execute_with(|| {1237 default_limits();1238 1239 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12401241 let origin1 = Origin::signed(1);12421243 let data = default_nft_data();1244 create_test_item(collection_id, &data.into());12451246 assert_ok!(TemplateModule::set_public_access_mode(1247 origin1.clone(),1248 collection_id,1249 AccessMode::WhiteList1250 ));1251 assert_noop!(1252 TemplateModule::burn_item(origin1.clone(), 1, 1, 5),1253 Error::<Test>::AddresNotInWhiteList1254 );1255 });1256}12571258// If Public Access mode is set to WhiteList, oken transfers can’t be Approved by a non-whitelisted address (see Approve method).1259#[test]1260fn white_list_test_6() {1261 new_test_ext().execute_with(|| {1262 default_limits();1263 1264 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12651266 let origin1 = Origin::signed(1);1267 assert_ok!(TemplateModule::set_public_access_mode(1268 origin1.clone(),1269 collection_id,1270 AccessMode::WhiteList1271 ));12721273 // do approve1274 assert_noop!(1275 TemplateModule::approve(origin1.clone(), 1, 1, 1, 5),1276 Error::<Test>::AddresNotInWhiteList1277 );1278 });1279}12801281// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1282// tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1283#[test]1284fn white_list_test_7() {1285 new_test_ext().execute_with(|| {1286 default_limits();1287 1288 let collection_id = create_test_collection(&CollectionMode::NFT, 1);12891290 let data = default_nft_data();1291 create_test_item(collection_id, &data.into());1292 1293 let origin1 = Origin::signed(1);12941295 assert_ok!(TemplateModule::set_public_access_mode(1296 origin1.clone(),1297 collection_id,1298 AccessMode::WhiteList1299 ));1300 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1301 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13021303 assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1));1304 });1305}13061307#[test]1308fn white_list_test_8() {1309 new_test_ext().execute_with(|| {1310 default_limits();1311 1312 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13131314 let data = default_nft_data();1315 create_test_item(collection_id, &data.into());1316 1317 let origin1 = Origin::signed(1);13181319 assert_ok!(TemplateModule::set_public_access_mode(1320 origin1.clone(),1321 collection_id,1322 AccessMode::WhiteList1323 ));1324 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1325 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13261327 // do approve1328 assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1, 5));1329 assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 5);13301331 assert_ok!(TemplateModule::transfer_from(1332 origin1.clone(),1333 1,1334 2,1335 1,1336 1,1337 11338 ));1339 });1340}13411342// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1343#[test]1344fn white_list_test_9() {1345 new_test_ext().execute_with(|| {1346 default_limits();1347 1348 let collection_id = create_test_collection(&CollectionMode::NFT, 1);1349 let origin1 = Origin::signed(1);13501351 assert_ok!(TemplateModule::set_public_access_mode(1352 origin1.clone(),1353 collection_id,1354 AccessMode::WhiteList1355 ));1356 assert_ok!(TemplateModule::set_mint_permission(1357 origin1.clone(),1358 collection_id,1359 false1360 ));13611362 let data = default_nft_data();1363 create_test_item(collection_id, &data.into());1364 });1365}13661367// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1368#[test]1369fn white_list_test_10() {1370 new_test_ext().execute_with(|| {1371 default_limits();1372 1373 let collection_id = create_test_collection(&CollectionMode::NFT, 1);13741375 let origin1 = Origin::signed(1);1376 let origin2 = Origin::signed(2);13771378 assert_ok!(TemplateModule::set_public_access_mode(1379 origin1.clone(),1380 collection_id,1381 AccessMode::WhiteList1382 ));1383 assert_ok!(TemplateModule::set_mint_permission(1384 origin1.clone(),1385 collection_id,1386 false1387 ));13881389 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));13901391 assert_ok!(TemplateModule::create_item(1392 origin2.clone(),1393 collection_id,1394 2,1395 default_nft_data().into()1396 ));1397 });1398}13991400// 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.1401#[test]1402fn white_list_test_11() {1403 new_test_ext().execute_with(|| {1404 default_limits();1405 1406 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14071408 let origin1 = Origin::signed(1);1409 let origin2 = Origin::signed(2);14101411 assert_ok!(TemplateModule::set_public_access_mode(1412 origin1.clone(),1413 collection_id,1414 AccessMode::WhiteList1415 ));1416 assert_ok!(TemplateModule::set_mint_permission(1417 origin1.clone(),1418 collection_id,1419 false1420 ));1421 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));14221423 assert_noop!(1424 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1425 Error::<Test>::PublicMintingNotAllowed1426 );1427 });1428}14291430// 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.1431#[test]1432fn white_list_test_12() {1433 new_test_ext().execute_with(|| {1434 default_limits();1435 1436 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14371438 let origin1 = Origin::signed(1);1439 let origin2 = Origin::signed(2);14401441 assert_ok!(TemplateModule::set_public_access_mode(1442 origin1.clone(),1443 collection_id,1444 AccessMode::WhiteList1445 ));1446 assert_ok!(TemplateModule::set_mint_permission(1447 origin1.clone(),1448 collection_id,1449 false1450 ));14511452 assert_noop!(1453 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1454 Error::<Test>::PublicMintingNotAllowed1455 );1456 });1457}14581459// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1460#[test]1461fn white_list_test_13() {1462 new_test_ext().execute_with(|| {1463 default_limits();1464 1465 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14661467 let origin1 = Origin::signed(1);14681469 assert_ok!(TemplateModule::set_public_access_mode(1470 origin1.clone(),1471 collection_id,1472 AccessMode::WhiteList1473 ));1474 assert_ok!(TemplateModule::set_mint_permission(1475 origin1.clone(),1476 collection_id,1477 true1478 ));14791480 let data = default_nft_data();1481 create_test_item(collection_id, &data.into());1482 });1483}14841485// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1486#[test]1487fn white_list_test_14() {1488 new_test_ext().execute_with(|| {1489 default_limits();1490 1491 let collection_id = create_test_collection(&CollectionMode::NFT, 1);14921493 let origin1 = Origin::signed(1);1494 let origin2 = Origin::signed(2);14951496 assert_ok!(TemplateModule::set_public_access_mode(1497 origin1.clone(),1498 collection_id,1499 AccessMode::WhiteList1500 ));1501 assert_ok!(TemplateModule::set_mint_permission(1502 origin1.clone(),1503 collection_id,1504 true1505 ));15061507 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));15081509 assert_ok!(TemplateModule::create_item(1510 origin2.clone(),1511 1,1512 2,1513 default_nft_data().into()1514 ));1515 });1516}15171518// 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.1519#[test]1520fn white_list_test_15() {1521 new_test_ext().execute_with(|| {1522 default_limits();1523 1524 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15251526 let origin1 = Origin::signed(1);1527 let origin2 = Origin::signed(2);15281529 assert_ok!(TemplateModule::set_public_access_mode(1530 origin1.clone(),1531 collection_id,1532 AccessMode::WhiteList1533 ));1534 assert_ok!(TemplateModule::set_mint_permission(1535 origin1.clone(),1536 collection_id,1537 true1538 ));15391540 assert_noop!(1541 TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1542 Error::<Test>::AddresNotInWhiteList1543 );1544 });1545}15461547// 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.1548#[test]1549fn white_list_test_16() {1550 new_test_ext().execute_with(|| {1551 default_limits();1552 1553 let collection_id = create_test_collection(&CollectionMode::NFT, 1);15541555 let origin1 = Origin::signed(1);1556 let origin2 = Origin::signed(2);15571558 assert_ok!(TemplateModule::set_public_access_mode(1559 origin1.clone(),1560 collection_id,1561 AccessMode::WhiteList1562 ));1563 assert_ok!(TemplateModule::set_mint_permission(1564 origin1.clone(),1565 collection_id,1566 true1567 ));1568 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));15691570 assert_ok!(TemplateModule::create_item(1571 origin2.clone(),1572 1,1573 2,1574 default_nft_data().into()1575 ));1576 });1577}15781579// Total number of collections. Positive test1580#[test]1581fn total_number_collections_bound() {1582 new_test_ext().execute_with(|| {1583 default_limits();1584 1585 create_test_collection(&CollectionMode::NFT, 1);1586 });1587}15881589// Total number of collections. Negotive test1590#[test]1591fn total_number_collections_bound_neg() {1592 new_test_ext().execute_with(|| {1593 default_limits();15941595 let origin1 = Origin::signed(1);15961597 for i in 0..default_collection_numbers_limit() {1598 create_test_collection(&CollectionMode::NFT, i + 1);1599 }16001601 let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1602 let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1603 let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();16041605 // 11-th collection in chain. Expects error1606 assert_noop!(TemplateModule::create_collection(1607 origin1.clone(),1608 col_name1.clone(),1609 col_desc1.clone(),1610 token_prefix1.clone(),1611 CollectionMode::NFT1612 ), Error::<Test>::TotalCollectionsLimitExceeded);1613 });1614}16151616// Owned tokens by a single address. Positive test1617#[test]1618fn owned_tokens_bound() {1619 new_test_ext().execute_with(|| {1620 default_limits();1621 1622 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16231624 let data = default_nft_data();1625 create_test_item(collection_id, &data.clone().into());1626 create_test_item(collection_id, &data.into());1627 });1628}16291630// Owned tokens by a single address. Negotive test1631#[test]1632fn owned_tokens_bound_neg() {1633 new_test_ext().execute_with(|| {1634 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1635 collection_numbers_limit: 10,1636 account_token_ownership_limit: 1,1637 collections_admins_limit: 5,1638 custom_data_limit: 2048,1639 nft_sponsor_transfer_timeout: 15,1640 fungible_sponsor_transfer_timeout: 15,1641 refungible_sponsor_transfer_timeout: 15, 1642 }));1643 1644 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16451646 let origin1 = Origin::signed(1);1647 let data = default_nft_data();1648 create_test_item(collection_id, &data.clone().into());16491650 assert_noop!(TemplateModule::create_item(1651 origin1.clone(),1652 1,1653 1,1654 data.into()1655 ), Error::<Test>::AddressOwnershipLimitExceeded);1656 });1657}16581659// Number of collection admins. Positive test1660#[test]1661fn collection_admins_bound() {1662 new_test_ext().execute_with(|| {1663 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1664 collection_numbers_limit: 10,1665 account_token_ownership_limit: 10,1666 collections_admins_limit: 2,1667 custom_data_limit: 2048,1668 nft_sponsor_transfer_timeout: 15,1669 fungible_sponsor_transfer_timeout: 15,1670 refungible_sponsor_transfer_timeout: 15, 1671 }));1672 1673 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16741675 let origin1 = Origin::signed(1);1676 1677 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1678 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3));1679 });1680}16811682// Number of collection admins. Negotive test1683#[test]1684fn collection_admins_bound_neg() {1685 new_test_ext().execute_with(|| {1686 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1687 collection_numbers_limit: 10,1688 account_token_ownership_limit: 1,1689 collections_admins_limit: 1,1690 custom_data_limit: 2048,1691 nft_sponsor_transfer_timeout: 15,1692 fungible_sponsor_transfer_timeout: 15,1693 refungible_sponsor_transfer_timeout: 15, 1694 }));1695 1696 let collection_id = create_test_collection(&CollectionMode::NFT, 1);16971698 let origin1 = Origin::signed(1);16991700 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1701 assert_noop!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3), Error::<Test>::CollectionAdminsLimitExceeded);1702 });1703}17041705// NFT custom data size. Negative test const_data.1706#[test]1707fn custom_data_size_nft_const_data_bound_neg() {1708 new_test_ext().execute_with(|| {1709 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1710 collection_numbers_limit: 10,1711 account_token_ownership_limit: 10,1712 collections_admins_limit: 5,1713 custom_data_limit: 2,1714 nft_sponsor_transfer_timeout: 15,1715 fungible_sponsor_transfer_timeout: 15,1716 refungible_sponsor_transfer_timeout: 15, 1717 }));1718 1719 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17201721 let origin1 = Origin::signed(1);1722 let too_big_const_data = CreateItemData::NFT(CreateNftData{1723 const_data: vec![1, 2, 3, 4],1724 variable_data: vec![]1725 });17261727 assert_noop!(TemplateModule::create_item(1728 origin1.clone(),1729 collection_id,1730 1,1731 too_big_const_data1732 ), Error::<Test>::TokenConstDataLimitExceeded);1733 });1734}17351736// NFT custom data size. Negative test variable_data.1737#[test]1738fn custom_data_size_nft_variable_data_bound_neg() {1739 new_test_ext().execute_with(|| {1740 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1741 collection_numbers_limit: 10,1742 account_token_ownership_limit: 10,1743 collections_admins_limit: 5,1744 custom_data_limit: 2,1745 nft_sponsor_transfer_timeout: 15,1746 fungible_sponsor_transfer_timeout: 15,1747 refungible_sponsor_transfer_timeout: 15, 1748 }));17491750 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17511752 let origin1 = Origin::signed(1);1753 let too_big_const_data = CreateItemData::NFT(CreateNftData{1754 const_data: vec![],1755 variable_data: vec![1, 2, 3, 4]1756 });17571758 assert_noop!(TemplateModule::create_item(1759 origin1.clone(),1760 collection_id,1761 1,1762 too_big_const_data1763 ), Error::<Test>::TokenVariableDataLimitExceeded);1764 });1765}17661767// Re fungible custom data size. Negative test const_data.1768#[test]1769fn custom_data_size_re_fungible_const_data_bound_neg() {1770 new_test_ext().execute_with(|| {1771 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1772 collection_numbers_limit: 10,1773 account_token_ownership_limit: 10,1774 collections_admins_limit: 5,1775 custom_data_limit: 2,1776 nft_sponsor_transfer_timeout: 15,1777 fungible_sponsor_transfer_timeout: 15,1778 refungible_sponsor_transfer_timeout: 15, 1779 }));17801781 let collection_id = create_test_collection(&CollectionMode::NFT, 1);17821783 let origin1 = Origin::signed(1);1784 let too_big_const_data = CreateItemData::NFT(CreateNftData{1785 const_data: vec![1, 2, 3, 4],1786 variable_data: vec![]1787 });17881789 assert_noop!(TemplateModule::create_item(1790 origin1.clone(),1791 collection_id,1792 1,1793 too_big_const_data1794 ), Error::<Test>::TokenConstDataLimitExceeded);1795 });1796}17971798// Re fungible custom data size. Negative test variable_data.1799#[test]1800fn custom_data_size_re_fungible_variable_data_bound_neg() {1801 new_test_ext().execute_with(|| {1802 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1803 collection_numbers_limit: 10,1804 account_token_ownership_limit: 10,1805 collections_admins_limit: 5,1806 custom_data_limit: 2,1807 nft_sponsor_transfer_timeout: 15,1808 fungible_sponsor_transfer_timeout: 15,1809 refungible_sponsor_transfer_timeout: 15, 1810 }));18111812 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18131814 let origin1 = Origin::signed(1);1815 let too_big_const_data = CreateItemData::NFT(CreateNftData{1816 const_data: vec![],1817 variable_data: vec![1, 2, 3, 4]1818 });18191820 assert_noop!(TemplateModule::create_item(1821 origin1.clone(),1822 collection_id,1823 1,1824 too_big_const_data1825 ), Error::<Test>::TokenVariableDataLimitExceeded);1826 });1827}1828// #endregion18291830#[test]1831fn set_const_on_chain_schema() {1832 new_test_ext().execute_with(|| {1833 default_limits();18341835 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18361837 let origin1 = Origin::signed(1);1838 assert_ok!(TemplateModule::set_const_on_chain_schema(origin1, collection_id, b"test const on chain schema".to_vec()));18391840 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"test const on chain schema".to_vec());1841 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"".to_vec());1842 });1843}18441845#[test]1846fn set_variable_on_chain_schema() {1847 new_test_ext().execute_with(|| {1848 default_limits();1849 1850 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18511852 let origin1 = Origin::signed(1);1853 assert_ok!(TemplateModule::set_variable_on_chain_schema(origin1, collection_id, b"test variable on chain schema".to_vec()));18541855 assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"".to_vec());1856 assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"test variable on chain schema".to_vec());1857 });1858}18591860#[test]1861fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {1862 new_test_ext().execute_with(|| {1863 default_limits();18641865 let collection_id = create_test_collection(&CollectionMode::NFT, 1);18661867 let origin1 = Origin::signed(1);1868 1869 let data = default_nft_data();1870 create_test_item(1, &data.into());1871 1872 let variable_data = b"test set_variable_meta_data method.".to_vec();1873 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));18741875 assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, variable_data);1876 });1877}18781879#[test]1880fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {1881 new_test_ext().execute_with(|| {1882 default_limits();18831884 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);18851886 let origin1 = Origin::signed(1);18871888 let data = default_re_fungible_data();1889 create_test_item(1, &data.into());18901891 let variable_data = b"test set_variable_meta_data method.".to_vec();1892 assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));18931894 assert_eq!(TemplateModule::refungible_item_id(collection_id, 1).variable_data, variable_data);1895 });1896}189718981899#[test]1900fn set_variable_meta_data_on_fungible_token_fails() {1901 new_test_ext().execute_with(|| {1902 default_limits();19031904 let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);19051906 let origin1 = Origin::signed(1);19071908 let data = default_fungible_data();1909 create_test_item(1, &data.into());19101911 let variable_data = b"test set_variable_meta_data method.".to_vec();1912 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()), Error::<Test>::CantStoreMetadataInFungibleTokens);1913 });1914}19151916#[test]1917fn set_variable_meta_data_on_nft_token_fails_for_big_data() {1918 new_test_ext().execute_with(|| {1919 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1920 collection_numbers_limit: default_collection_numbers_limit(),1921 account_token_ownership_limit: 10,1922 collections_admins_limit: 5,1923 custom_data_limit: 10,1924 nft_sponsor_transfer_timeout: 15,1925 fungible_sponsor_transfer_timeout: 15,1926 refungible_sponsor_transfer_timeout: 15, 1927 }));19281929 let collection_id = create_test_collection(&CollectionMode::NFT, 1);19301931 let origin1 = Origin::signed(1);19321933 let data = default_nft_data();1934 create_test_item(1, &data.into());19351936 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1937 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);1938 });1939}19401941#[test]1942fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {1943 new_test_ext().execute_with(|| {1944 assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1945 collection_numbers_limit: default_collection_numbers_limit(),1946 account_token_ownership_limit: 10,1947 collections_admins_limit: 5,1948 custom_data_limit: 10,1949 nft_sponsor_transfer_timeout: 15,1950 fungible_sponsor_transfer_timeout: 15,1951 refungible_sponsor_transfer_timeout: 15, 1952 }));195319541955 let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);19561957 let origin1 = Origin::signed(1);19581959 let data = default_re_fungible_data();1960 create_test_item(1, &data.into());19611962 let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1963 assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);1964 });1965}tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -20,9 +20,13 @@
"load": "mocha --timeout 9999999 -r ts-node/register ./**/*.load.ts",
"testSetSchemaVersion": "mocha --timeout 9999999 -r ts-node/register ./**/setSchemaVersion.test.ts",
"testSetCollectionLimits": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionLimits.test.ts",
+ "testRemoveCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionAdmin.test.ts",
"testConnection": "mocha --timeout 9999999 -r ts-node/register ./**/connection.test.ts",
"testCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts",
- "testCreateMultipleItems": "mocha --timeout 9999999 -r ts-node/register ./**/createMultipleItems.test.ts"
+ "testCreateMultipleItems": "mocha --timeout 9999999 -r ts-node/register ./**/createMultipleItems.test.ts",
+ "testApprove": "mocha --timeout 9999999 -r ts-node/register ./**/approve.test.ts",
+ "testTransferFrom": "mocha --timeout 9999999 -r ts-node/register ./**/transferFrom.test.ts",
+ "testCreateCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts"
},
"author": "",
"license": "Apache 2.0",
tests/src/approve.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/approve.test.ts
@@ -0,0 +1,140 @@
+//
+// 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';
+import { default as usingApi } from './substrate/substrate-api';
+import {
+ approveExpectFail,
+ approveExpectSuccess,
+ createCollectionExpectSuccess,
+ createItemExpectSuccess,
+ destroyCollectionExpectSuccess,
+} from './util/helpers';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+describe('Integration Test approve(spender, collection_id, item_id, amount):', () => {
+ it('Execute the extrinsic and check approvedList', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ const nftCollectionId = await createCollectionExpectSuccess();
+ // nft
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob);
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob);
+ // reFungible
+ const reFungibleCollectionId =
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);
+ });
+ });
+
+ it('Remove approval by using 0 amount', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ const nftCollectionId = await createCollectionExpectSuccess();
+ // nft
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 1);
+ await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 0);
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1);
+ await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 0);
+ // reFungible
+ const reFungibleCollectionId =
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 1);
+ await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 0);
+ });
+ });
+});
+
+describe('Negative Integration Test approve(spender, collection_id, item_id, amount):', () => {
+ it('Approve for a collection that does not exist', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ // nft
+ const nftCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
+ await approveExpectFail(nftCollectionCount + 1, 1, Alice, Bob);
+ // fungible
+ const fungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
+ await approveExpectFail(fungibleCollectionCount + 1, 1, Alice, Bob);
+ // reFungible
+ const reFungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
+ await approveExpectFail(reFungibleCollectionCount + 1, 1, Alice, Bob);
+ });
+ });
+
+ it('Approve for a collection that was destroyed', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ await destroyCollectionExpectSuccess(nftCollectionId);
+ await approveExpectFail(nftCollectionId, 1, Alice, Bob);
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ await destroyCollectionExpectSuccess(fungibleCollectionId);
+ await approveExpectFail(fungibleCollectionId, 1, Alice, Bob);
+ // reFungible
+ const reFungibleCollectionId =
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await destroyCollectionExpectSuccess(reFungibleCollectionId);
+ await approveExpectFail(reFungibleCollectionId, 1, Alice, Bob);
+ });
+ });
+
+ it('Approve transfer of a token that does not exist', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ await approveExpectFail(nftCollectionId, 2, Alice, Bob);
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ await approveExpectFail(fungibleCollectionId, 2, Alice, Bob);
+ // reFungible
+ const reFungibleCollectionId =
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await approveExpectFail(reFungibleCollectionId, 2, Alice, Bob);
+ });
+ });
+
+ it('Approve using the address that does not own the approved token', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ const nftCollectionId = await createCollectionExpectSuccess();
+ // nft
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ await approveExpectFail(nftCollectionId, newNftTokenId, Bob, Alice);
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await approveExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice);
+ // reFungible
+ const reFungibleCollectionId =
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Bob, Alice);
+ });
+ });
+});
tests/src/burnItem.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/burnItem.test.ts
@@ -0,0 +1,237 @@
+import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api';
+import { Keyring } from "@polkadot/api";
+import { IKeyringPair } from "@polkadot/types/types";
+import {
+ createCollectionExpectSuccess,
+ createItemExpectSuccess,
+ getGenericResult,
+ destroyCollectionExpectSuccess
+} from './util/helpers';
+import { nullPublicKey } from "./accounts";
+
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+let alice: IKeyringPair;
+let bob: IKeyringPair;
+
+describe('integration test: ext. burnItem():', () => {
+ before(async () => {
+ await usingApi(async (api) => {
+ const keyring = new Keyring({ type: 'sr25519' });
+ alice = keyring.addFromUri(`//Alice`);
+ bob = keyring.addFromUri(`//Bob`);
+ });
+ });
+
+ it('Burn item in NFT collection', async () => {
+ const createMode = 'NFT';
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
+ const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
+
+ await usingApi(async (api) => {
+ const tx = api.tx.nft.burnItem(collectionId, tokenId, 0);
+ const events = await submitTransactionAsync(alice, tx);
+ const result = getGenericResult(events);
+
+ // Get the item
+ const item: any = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(item).to.be.not.null;
+ expect(item.Owner).to.be.equal(nullPublicKey);
+ });
+
+ });
+ it('Burn item in Fungible collection', async () => {
+ const createMode = 'Fungible';
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0 }});
+ await createItemExpectSuccess(alice, collectionId, createMode); // Helper creates 10 fungible tokens
+ const tokenId = 0; // ignored
+
+ await usingApi(async (api) => {
+ // Destroy 1 of 10
+ const tx = api.tx.nft.burnItem(collectionId, tokenId, 1);
+ const events = await submitTransactionAsync(alice, tx);
+ const result = getGenericResult(events);
+
+ // Get alice balance
+ const balance: any = (await api.query.nft.fungibleItemList(collectionId, alice.address)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(balance).to.be.not.null;
+ expect(balance.Value).to.be.equal(9);
+ });
+
+ });
+ it('Burn item in ReFungible collection', async () => {
+ const createMode = 'ReFungible';
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 2 }});
+ const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
+
+ await usingApi(async (api) => {
+ const tx = api.tx.nft.burnItem(collectionId, tokenId, 1);
+ const events = await submitTransactionAsync(alice, tx);
+ const result = getGenericResult(events);
+
+ // Get alice balance
+ const balance: any = (await api.query.nft.reFungibleItemList(collectionId, tokenId)).toJSON();
+
+ // What to expect
+ expect(result.success).to.be.true;
+ expect(balance).to.be.not.null;
+ expect(balance.Owner.length).to.be.equal(0);
+ });
+
+ });
+
+ it('Burn owned portion of item in ReFungible collection', async () => {
+ const createMode = 'ReFungible';
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 2 }});
+ const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
+
+ await usingApi(async (api) => {
+ // Transfer 1/100 of the token to Bob
+ const transfertx = api.tx.nft.transfer(bob.address, collectionId, tokenId, 1);
+ const events1 = await submitTransactionAsync(alice, transfertx);
+ const result1 = getGenericResult(events1);
+
+ // Get balances
+ const balanceBefore: any = (await api.query.nft.reFungibleItemList(collectionId, tokenId)).toJSON();
+
+ // Bob burns his portion
+ 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);
+
+ // What to expect before burning
+ expect(result1.success).to.be.true;
+ expect(balanceBefore).to.be.not.null;
+ expect(balanceBefore.Owner.length).to.be.equal(2);
+ expect(balanceBefore.Owner[0].Owner).to.be.equal(alice.address);
+ expect(balanceBefore.Owner[0].Fraction).to.be.equal(99);
+ expect(balanceBefore.Owner[1].Owner).to.be.equal(bob.address);
+ expect(balanceBefore.Owner[1].Fraction).to.be.equal(1);
+
+ // What to expect after burning
+ expect(result2.success).to.be.true;
+ expect(balance).to.be.not.null;
+ expect(balance.Owner.length).to.be.equal(1);
+ expect(balance.Owner[0].Fraction).to.be.equal(99);
+ expect(balance.Owner[0].Owner).to.be.equal(alice.address);
+ });
+
+ });
+
+});
+
+describe('Negative integration test: ext. burnItem():', () => {
+ before(async () => {
+ await usingApi(async (api) => {
+ const keyring = new Keyring({ type: 'sr25519' });
+ alice = keyring.addFromUri(`//Alice`);
+ bob = keyring.addFromUri(`//Bob`);
+ });
+ });
+
+ it('Burn a token in a destroyed collection', async () => {
+ const createMode = 'NFT';
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode }});
+ const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
+ await destroyCollectionExpectSuccess(collectionId);
+
+ await usingApi(async (api) => {
+ const tx = api.tx.nft.burnItem(collectionId, tokenId, 0);
+ const badTransaction = async function () {
+ await submitTransactionExpectFailAsync(alice, tx);
+ };
+ await expect(badTransaction()).to.be.rejected;
+ });
+
+ });
+
+ it('Burn a token that was never created', async () => {
+ const createMode = 'NFT';
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode }});
+ const tokenId = 10;
+
+ await usingApi(async (api) => {
+ const tx = api.tx.nft.burnItem(collectionId, tokenId, 0);
+ const badTransaction = async function () {
+ await submitTransactionExpectFailAsync(alice, tx);
+ };
+ await expect(badTransaction()).to.be.rejected;
+ });
+
+ });
+
+ it('Burn a token using the address that does not own it', async () => {
+ const createMode = 'NFT';
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode }});
+ const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
+
+ await usingApi(async (api) => {
+ const tx = api.tx.nft.burnItem(collectionId, tokenId, 0);
+ const badTransaction = async function () {
+ await submitTransactionExpectFailAsync(bob, tx);
+ };
+ await expect(badTransaction()).to.be.rejected;
+ });
+
+ });
+
+ it('Transfer a burned a token', async () => {
+ const createMode = 'NFT';
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode }});
+ const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
+
+ await usingApi(async (api) => {
+
+ const burntx = api.tx.nft.burnItem(collectionId, tokenId, 0);
+ const events1 = await submitTransactionAsync(alice, burntx);
+ const result1 = getGenericResult(events1);
+ expect(result1.success).to.be.true;
+
+ const tx = api.tx.nft.transfer(bob.address, collectionId, tokenId, 0);
+ const badTransaction = async function () {
+ await submitTransactionExpectFailAsync(alice, tx);
+ };
+ await expect(badTransaction()).to.be.rejected;
+ });
+
+ });
+
+ it('Burn more than owned in Fungible collection', async () => {
+ const createMode = 'Fungible';
+ const collectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0 }});
+ // Helper creates 10 fungible tokens
+ await createItemExpectSuccess(alice, collectionId, createMode);
+ const tokenId = 0; // ignored
+
+ await usingApi(async (api) => {
+ // Destroy 11 of 10
+ const tx = api.tx.nft.burnItem(collectionId, tokenId, 11);
+ const badTransaction = async function () {
+ await submitTransactionExpectFailAsync(alice, tx);
+ };
+ await expect(badTransaction()).to.be.rejected;
+
+ // Get alice balance
+ const balance: any = (await api.query.nft.fungibleItemList(collectionId, alice.address)).toJSON();
+
+ // What to expect
+ expect(balance).to.be.not.null;
+ expect(balance.Value).to.be.equal(10);
+ });
+
+ });
+
+});
tests/src/confirmSponsorship.test.tsdiffbeforeafterboth--- a/tests/src/confirmSponsorship.test.ts
+++ b/tests/src/confirmSponsorship.test.ts
@@ -89,7 +89,7 @@
});
it('Fungible: Transfer fees are paid by the sponsor after confirmation', async () => {
- const collectionId = await createCollectionExpectSuccess({mode: 'Fungible'});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0 }});
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
@@ -115,7 +115,7 @@
});
it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async () => {
- const collectionId = await createCollectionExpectSuccess({mode: 'ReFungible'});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0 }});
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
@@ -210,7 +210,7 @@
});
it('Fungible: Sponsoring is rate limited', async () => {
- const collectionId = await createCollectionExpectSuccess({mode: 'Fungible'});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0 }});
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: 'ReFungible'});
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0 }});
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
tests/src/createCollection.test.tsdiffbeforeafterboth--- a/tests/src/createCollection.test.ts
+++ b/tests/src/createCollection.test.ts
@@ -5,15 +5,15 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
-import { default as usingApi } from "./substrate/substrate-api";
-import { createCollectionExpectSuccess, createCollectionExpectFailure, CollectionMode } from "./util/helpers";
+import { default as usingApi } from './substrate/substrate-api';
+import { createCollectionExpectFailure, createCollectionExpectSuccess } from './util/helpers';
chai.use(chaiAsPromised);
const expect = chai.expect;
describe('integration test: ext. createCollection():', () => {
it('Create new NFT collection', async () => {
- await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: 'NFT'});
+ await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
});
it('Create new NFT collection whith collection_name of maximum length (64 bytes)', async () => {
await createCollectionExpectSuccess({name: 'A'.repeat(64)});
@@ -25,34 +25,35 @@
await createCollectionExpectSuccess({tokenPrefix: 'A'.repeat(16)});
});
it('Create new Fungible collection', async () => {
- await createCollectionExpectSuccess({mode: 'Fungible'});
+ await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
});
it('Create new ReFungible collection', async () => {
- await createCollectionExpectSuccess({mode: 'ReFungible'});
+ await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
});
});
describe('(!negative test!) integration test: ext. createCollection():', () => {
it('(!negative test!) create new NFT collection whith incorrect data (mode)', async () => {
await usingApi(async (api) => {
- const AcollectionCount = parseInt((await api.query.nft.collectionCount()).toString());
+ const AcollectionCount = parseInt((await api.query.nft.collectionCount()).toString(), 10);
- const badTransaction = async function () {
- await createCollectionExpectSuccess({mode: 'BadMode' as CollectionMode});
+ const badTransaction = async () => {
+ await createCollectionExpectSuccess({mode: {type: 'Invalid'}});
};
+ // tslint:disable-next-line:no-unused-expression
expect(badTransaction()).to.be.rejected;
- const BcollectionCount = parseInt((await api.query.nft.collectionCount()).toString());
+ const BcollectionCount = parseInt((await api.query.nft.collectionCount()).toString(), 10);
expect(BcollectionCount).to.be.equal(AcollectionCount, 'Error: Incorrect collection created.');
});
});
it('(!negative test!) create new NFT collection whith incorrect data (collection_name)', async () => {
- await createCollectionExpectFailure({name: 'A'.repeat(65)});
+ await createCollectionExpectFailure({ name: 'A'.repeat(65), mode: {type: 'NFT'}});
});
it('(!negative test!) create new NFT collection whith incorrect data (collection_description)', async () => {
- await createCollectionExpectFailure({description: 'A'.repeat(257)});
+ await createCollectionExpectFailure({ description: 'A'.repeat(257), mode: { type: 'NFT' }});
});
it('(!negative test!) create new NFT collection whith incorrect data (token_prefix)', async () => {
- await createCollectionExpectFailure({tokenPrefix: 'A'.repeat(17)});
+ await createCollectionExpectFailure({tokenPrefix: 'A'.repeat(17), mode: {type: 'NFT'}});
});
});
tests/src/createItem.test.tsdiffbeforeafterboth--- a/tests/src/createItem.test.ts
+++ b/tests/src/createItem.test.ts
@@ -18,17 +18,17 @@
it('Create new item in NFT collection', async () => {
const createMode = 'NFT';
- const newCollectionID = await createCollectionExpectSuccess({mode: createMode});
+ const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
await createItemExpectSuccess(alice, newCollectionID, createMode);
});
it('Create new item in Fungible collection', async () => {
const createMode = 'Fungible';
- const newCollectionID = await createCollectionExpectSuccess({mode: createMode});
+ const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
await createItemExpectSuccess(alice, newCollectionID, createMode);
});
it('Create new item in ReFungible collection', async () => {
const createMode = 'ReFungible';
- const newCollectionID = await createCollectionExpectSuccess({mode: createMode});
+ const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
await createItemExpectSuccess(alice, newCollectionID, createMode);
});
});
tests/src/destroyCollection.test.tsdiffbeforeafterboth--- a/tests/src/destroyCollection.test.ts
+++ b/tests/src/destroyCollection.test.ts
@@ -14,11 +14,11 @@
await destroyCollectionExpectSuccess(collectionId);
});
it('Fungible collection can be destroyed', async () => {
- const collectionId = await createCollectionExpectSuccess({ mode: 'Fungible' });
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
await destroyCollectionExpectSuccess(collectionId);
});
it('ReFungible collection can be destroyed', async () => {
- const collectionId = await createCollectionExpectSuccess({ mode: 'ReFungible' });
+ const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
await destroyCollectionExpectSuccess(collectionId);
});
});
tests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/removeCollectionAdmin.test.ts
@@ -0,0 +1,82 @@
+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';
+import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api';
+import {createCollectionExpectSuccess, destroyCollectionExpectSuccess} from './util/helpers';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
+ it('Remove collection admin.', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const collectionId = await createCollectionExpectSuccess();
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ const collection: any = (await api.query.nft.collection(collectionId));
+ expect(collection.Owner.toString()).to.be.eq(Alice.address);
+ // first - add collection admin Bob
+ const addAdminTx = api.tx.nft.addCollectionAdmin(collectionId, Bob.address);
+ await submitTransactionAsync(Alice, addAdminTx);
+
+ const adminListAfterAddAdmin: any = (await api.query.nft.adminList(collectionId));
+ expect(adminListAfterAddAdmin).to.be.contains(Bob.address);
+
+ // then remove bob from admins of collection
+ const removeAdminTx = api.tx.nft.removeCollectionAdmin(collectionId, Bob.address);
+ await submitTransactionAsync(Alice, removeAdminTx);
+
+ const adminListAfterRemoveAdmin: any = (await api.query.nft.adminList(collectionId));
+ expect(adminListAfterRemoveAdmin).not.to.be.contains(Bob.address);
+ });
+ });
+});
+
+describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
+ it('Can\'t remove collection admin from not existing collection', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ // tslint:disable-next-line: no-bitwise
+ const collectionId = (1 << 32) - 1;
+ const alice = privateKey('//Alice');
+ const bob = privateKey('//Bob');
+
+ const changeOwnerTx = api.tx.nft.removeCollectionAdmin(collectionId, bob.address);
+ await expect(submitTransactionExpectFailAsync(alice, changeOwnerTx)).to.be.rejected;
+
+ // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
+ await createCollectionExpectSuccess();
+ });
+ });
+
+ it('Can\'t remove collection admin from deleted collection', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ // tslint:disable-next-line: no-bitwise
+ const collectionId = await createCollectionExpectSuccess();
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+
+ await destroyCollectionExpectSuccess(collectionId);
+
+ const changeOwnerTx = api.tx.nft.removeCollectionAdmin(collectionId, Bob.address);
+ await expect(submitTransactionExpectFailAsync(Alice, changeOwnerTx)).to.be.rejected;
+
+ // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
+ await createCollectionExpectSuccess();
+ });
+ });
+
+ it('Remove admin from collection that has no admins', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const collectionId = await createCollectionExpectSuccess();
+
+ const adminListBeforeAddAdmin: any = (await api.query.nft.adminList(collectionId));
+ expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
+
+ const tx = api.tx.nft.removeCollectionAdmin(collectionId, Alice.address);
+ await expect(submitTransactionExpectFailAsync(Alice, tx)).to.be.rejected;
+ });
+ });
+});
tests/src/setCollectionLimits.test.tsdiffbeforeafterboth--- a/tests/src/setCollectionLimits.test.ts
+++ b/tests/src/setCollectionLimits.test.ts
@@ -32,7 +32,7 @@
});
it('choose or create collection for testing', async () => {
await usingApi(async () => {
- collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: 'NFT'});
+ collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
});
});
});
tests/src/setCollectionSponsor.test.tsdiffbeforeafterboth--- a/tests/src/setCollectionSponsor.test.ts
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -30,11 +30,11 @@
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
});
it('Set Fungible collection sponsor', async () => {
- const collectionId = await createCollectionExpectSuccess({ mode: 'Fungible' });
+ const collectionId = await createCollectionExpectSuccess({ mode: {type: 'Fungible', decimalPoints: 0} });
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
});
it('Set ReFungible collection sponsor', async () => {
- const collectionId = await createCollectionExpectSuccess({ mode: 'ReFungible' });
+ const collectionId = await createCollectionExpectSuccess({ mode: {type: 'ReFungible', decimalPoints: 0} });
await setCollectionSponsorExpectSuccess(collectionId, bob.address);
});
tests/src/setSchemaVersion.test.tsdiffbeforeafterboth--- a/tests/src/setSchemaVersion.test.ts
+++ b/tests/src/setSchemaVersion.test.ts
@@ -35,7 +35,7 @@
});
it('choose or create collection for testing', async () => {
await usingApi(async () => {
- collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: 'NFT'});
+ collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
});
});
});
@@ -93,12 +93,6 @@
const nonExistedCollectionId = collectionCount + 1;
tx = api.tx.nft.setSchemaVersion(nonExistedCollectionId, 'ImageURL');
await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
- /*try {
- await submitTransactionAsync(alice, tx);
- } catch (e) {
- // tslint:disable-next-line:no-unused-expression
- expect(e).to.be.exist;
- }*/
});
});
@@ -119,13 +113,6 @@
await destroyCollectionExpectSuccess(collectionIdForTesting);
tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'ImageURL');
await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
- /*try {
- tx = api.tx.nft.setSchemaVersion(collectionIdForTesting, 'ImageURL');
- await submitTransactionAsync(alice, tx);
- } catch (e) {
- // tslint:disable-next-line:no-unused-expression
- expect(e).to.be.exist;
- }*/
});
});
});
tests/src/substrate/substrate-api.tsdiffbeforeafterboth--- a/tests/src/substrate/substrate-api.ts
+++ b/tests/src/substrate/substrate-api.ts
@@ -90,7 +90,6 @@
res(rec);
console.error = consoleError;
console.log = consoleLog;
-
});
};
const reject = (errror: any) => {
@@ -104,6 +103,8 @@
await transaction.signAndSend(sender, ({ events = [], status }) => {
const transactionStatus = getTransactionStatus(events, status);
+ console.log('transactionStatus', transactionStatus, 'events', events);
+
if (transactionStatus == TransactionStatus.Success) {
resolve(events);
} else if (transactionStatus == TransactionStatus.Fail) {
@@ -114,4 +115,4 @@
reject(e);
}
});
-}
\ No newline at end of file
+}
tests/src/transferFrom.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/transferFrom.test.ts
@@ -0,0 +1,188 @@
+//
+// 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 chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import privateKey from './substrate/privateKey';
+import { default as usingApi } from './substrate/substrate-api';
+import {
+ approveExpectFail,
+ approveExpectSuccess,
+ createCollectionExpectSuccess,
+ createItemExpectSuccess,
+ destroyCollectionExpectSuccess,
+ transferFromExpectFail,
+ transferFromExpectSuccess,
+} from './util/helpers';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
+describe('Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {
+ it('Execute the extrinsic and check nftItemList - owner of token', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ const Charlie = privateKey('//CHARLIE');
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob);
+
+ await transferFromExpectSuccess(nftCollectionId, newNftTokenId, Bob, Alice, Charlie, 1, 'NFT');
+
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob);
+ await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 1, 'Fungible');
+ // reFungible
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);
+ await transferFromExpectSuccess(reFungibleCollectionId,
+ newReFungibleTokenId, Bob, Alice, Charlie, 1, 'ReFungible');
+ });
+ });
+});
+
+describe('Negative Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {
+ it('transferFrom for a collection that does not exist', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ const Charlie = privateKey('//CHARLIE');
+ // nft
+ const nftCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
+ await approveExpectFail(nftCollectionCount + 1, 1, Alice, Bob);
+
+ await transferFromExpectFail(nftCollectionCount + 1, 1, Bob, Alice, Charlie, 1);
+
+ // fungible
+ const fungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
+ await approveExpectFail(fungibleCollectionCount + 1, 1, Alice, Bob);
+
+ await transferFromExpectFail(fungibleCollectionCount + 1, 1, Bob, Alice, Charlie, 1);
+ // reFungible
+ const reFungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
+ await approveExpectFail(reFungibleCollectionCount + 1, 1, Alice, Bob);
+
+ await transferFromExpectFail(reFungibleCollectionCount + 1, 1, Bob, Alice, Charlie, 1);
+ });
+ });
+
+ /* it('transferFrom for a collection that was destroyed', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ this test copies approve negative test
+ });
+ }); */
+
+ /* it('transferFrom a token that does not exist', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ this test copies approve negative test
+ });
+ }); */
+
+ /* it('transferFrom a token that was deleted', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ this test copies approve negative test
+ });
+ }); */
+
+ it('transferFrom for not approved address', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ const Charlie = privateKey('//CHARLIE');
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+
+ await transferFromExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, Charlie, 1);
+
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 1);
+ // reFungible
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await transferFromExpectFail(reFungibleCollectionId,
+ newReFungibleTokenId, Bob, Alice, Charlie, 1);
+ });
+ });
+
+ it('transferFrom incorrect token count', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ const Charlie = privateKey('//CHARLIE');
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob);
+
+ await transferFromExpectFail(nftCollectionId, newNftTokenId, Bob, Alice, Charlie, 2);
+
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob);
+ await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice, Charlie, 2);
+ // reFungible
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);
+ await transferFromExpectFail(reFungibleCollectionId,
+ newReFungibleTokenId, Bob, Alice, Charlie, 2);
+ });
+ });
+
+ it('execute transferFrom from account that is not owner of collection', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ const Charlie = privateKey('//CHARLIE');
+ const Dave = privateKey('//DAVE');
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ try {
+ await approveExpectFail(nftCollectionId, newNftTokenId, Dave, Bob);
+ await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);
+ } catch (e) {
+ // tslint:disable-next-line:no-unused-expression
+ expect(e).to.be.exist;
+ }
+
+ // await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);
+
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ try {
+ await approveExpectFail(fungibleCollectionId, newFungibleTokenId, Dave, Bob);
+ await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, Dave, Alice, Charlie, 1);
+ } catch (e) {
+ // tslint:disable-next-line:no-unused-expression
+ expect(e).to.be.exist;
+ }
+ // reFungible
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ try {
+ await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Dave, Bob);
+ await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, Dave, Alice, Charlie, 1);
+ } catch (e) {
+ // tslint:disable-next-line:no-unused-expression
+ expect(e).to.be.exist;
+ }
+ });
+ });
+});
tests/src/util/helpers.tsdiffbeforeafterboth--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -3,20 +3,20 @@
// file 'LICENSE', which is part of this source code package.
//
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
+import { ApiPromise, Keyring } from '@polkadot/api';
+import { Enum, Struct } from '@polkadot/types/codec';
import type { AccountId, EventRecord } from '@polkadot/types/interfaces';
-import { ApiPromise, Keyring } from "@polkadot/api";
-import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from "../substrate/substrate-api";
-import privateKey from '../substrate/privateKey';
-import { alicesPublicKey, nullPublicKey } from "../accounts";
-import { strToUTF16, utf16ToStr, hexToStr } from './util';
+import { u128 } from '@polkadot/types/primitive';
import { IKeyringPair } from '@polkadot/types/types';
import { BigNumber } from 'bignumber.js';
-import { Struct, Enum } from '@polkadot/types/codec';
-import { u128 } from '@polkadot/types/primitive';
+import BN from 'bn.js';
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import { alicesPublicKey, nullPublicKey } from '../accounts';
+import privateKey from '../substrate/privateKey';
+import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from '../substrate/substrate-api';
import { ICollectionInterface } from '../types';
-import BN from "bn.js";
+import { hexToStr, strToUTF16, utf16ToStr } from './util';
chai.use(chaiAsPromised);
const expect = chai.expect;
@@ -25,24 +25,45 @@
success: boolean,
};
-type CreateCollectionResult = {
- success: boolean,
- collectionId: number
-};
+interface CreateCollectionResult {
+ success: boolean;
+ collectionId: number;
+}
+
+interface CreateItemResult {
+ success: boolean;
+ collectionId: number;
+ itemId: number;
+}
+
+interface IReFungibleOwner {
+ Fraction: BN;
+ Owner: number[];
+}
+
+interface ITokenDataType {
+ Owner: number[];
+ ConstData: number[];
+ VariableData: number[];
+}
+
+interface IFungibleTokenDataType {
+ Value: BN;
+}
-type CreateItemResult = {
- success: boolean,
- collectionId: number,
- itemId: number
-};
+interface IReFungibleTokenDataType {
+ Owner: IReFungibleOwner[];
+ ConstData: number[];
+ VariableData: number[];
+}
export function getGenericResult(events: EventRecord[]): GenericResult {
- let result: GenericResult = {
- success: false
- }
+ const result: GenericResult = {
+ success: false,
+ };
events.forEach(({ phase, event: { data, method, section } }) => {
// console.log(` ${phase}: ${section}.${method}:: ${data}`);
- if (method == 'ExtrinsicSuccess') {
+ if (method === 'ExtrinsicSuccess') {
result.success = true;
}
});
@@ -60,10 +81,10 @@
collectionId = parseInt(data[0].toString());
}
});
- let result: CreateCollectionResult = {
+ const result: CreateCollectionResult = {
success,
- collectionId
- }
+ collectionId,
+ };
return result;
}
@@ -80,27 +101,60 @@
itemId = parseInt(data[1].toString());
}
});
- let result: CreateItemResult = {
+ const result: CreateItemResult = {
success,
collectionId,
- itemId
- }
+ itemId,
+ };
return result;
}
-export type CollectionMode = 'NFT' | 'Fungible' | 'ReFungible';
+interface Invalid {
+ type: 'Invalid';
+}
+
+interface Nft {
+ type: 'NFT';
+}
+
+interface Fungible {
+ type: 'Fungible';
+ decimalPoints: number;
+}
+
+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 = {
mode: CollectionMode,
name: string,
description: string,
- tokenPrefix: string
+ tokenPrefix: string,
};
const defaultCreateCollectionParams: CreateCollectionParams = {
+ description: 'description',
+ mode: { type: 'NFT' },
name: 'name',
- description: 'description',
- mode: 'NFT',
- tokenPrefix: 'prefix'
+ tokenPrefix: 'prefix',
}
export async function createCollectionExpectSuccess(params: Partial<CreateCollectionParams> = {}): Promise<number> {
@@ -109,25 +163,39 @@
let collectionId: number = 0;
await usingApi(async (api) => {
// Get number of collections before the transaction
- const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());
+ const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString(), 10);
// Run the CreateCollection transaction
const alicePrivateKey = privateKey('//Alice');
- const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), mode);
+
+ let modeprm = {};
+ if (mode.type === 'NFT') {
+ modeprm = {nft: null};
+ } else if (mode.type === 'Fungible') {
+ modeprm = {fungible: mode.decimalPoints};
+ } else if (mode.type === 'ReFungible') {
+ modeprm = {refungible: mode.decimalPoints};
+ } else if (mode.type === 'Invalid') {
+ modeprm = {invalid: null};
+ }
+
+ const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm);
const events = await submitTransactionAsync(alicePrivateKey, tx);
const result = getCreateCollectionResult(events);
// Get number of collections after the transaction
- const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());
+ const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString(), 10);
- // Get the collection
+ // Get the collection
const collection: any = (await api.query.nft.collection(result.collectionId)).toJSON();
// What to expect
+ // tslint:disable-next-line:no-unused-expression
expect(result.success).to.be.true;
expect(result.collectionId).to.be.equal(BcollectionCount);
+ // tslint:disable-next-line:no-unused-expression
expect(collection).to.be.not.null;
- expect(BcollectionCount).to.be.equal(AcollectionCount+1, 'Error: NFT collection NOT created.');
+ expect(BcollectionCount).to.be.equal(AcollectionCount + 1, 'Error: NFT collection NOT created.');
expect(collection.Owner).to.be.equal(alicesPublicKey);
expect(utf16ToStr(collection.Name)).to.be.equal(name);
expect(utf16ToStr(collection.Description)).to.be.equal(description);
@@ -138,17 +206,28 @@
return collectionId;
}
-
+
export async function createCollectionExpectFailure(params: Partial<CreateCollectionParams> = {}) {
const {name, description, mode, tokenPrefix } = {...defaultCreateCollectionParams, ...params};
+ let modeprm = {};
+ if (mode.type === 'NFT') {
+ modeprm = {nft: null};
+ } else if (mode.type === 'Fungible') {
+ modeprm = {fungible: mode.decimalPoints};
+ } else if (mode.type === 'ReFungible') {
+ modeprm = {refungible: mode.decimalPoints};
+ } else if (mode.type === 'Invalid') {
+ modeprm = {invalid: null};
+ }
+
await usingApi(async (api) => {
// Get number of collections before the transaction
const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());
// Run the CreateCollection transaction
const alicePrivateKey = privateKey('//Alice');
- const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), mode);
+ const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm);
const events = await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected;
const result = getCreateCollectionResult(events);
@@ -156,11 +235,12 @@
const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString());
// What to expect
+ // tslint:disable-next-line:no-unused-expression
expect(result.success).to.be.false;
expect(BcollectionCount).to.be.equal(AcollectionCount, 'Error: Collection with incorrect data created.');
});
}
-
+
export async function findUnusedAddress(api: ApiPromise): Promise<IKeyringPair> {
let bal = new BigNumber(0);
let unused;
@@ -170,7 +250,7 @@
unused = keyring.addFromUri(`//${randomSeed}`);
bal = new BigNumber((await api.query.system.account(unused.address)).data.free.toString());
} while (bal.toFixed() != '0');
- return unused;
+ return unused;
}
function getDestroyResult(events: EventRecord[]): boolean {
@@ -201,7 +281,7 @@
const events = await submitTransactionAsync(alicePrivateKey, tx);
const result = getDestroyResult(events);
- // Get the collection
+ // Get the collection
const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
// What to expect
@@ -220,7 +300,7 @@
const events = await submitTransactionAsync(alicePrivateKey, tx);
const result = getGenericResult(events);
- // Get the collection
+ // Get the collection
const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
// What to expect
@@ -239,7 +319,7 @@
const events = await submitTransactionAsync(alicePrivateKey, tx);
const result = getGenericResult(events);
- // Get the collection
+ // Get the collection
const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
// What to expect
@@ -278,7 +358,7 @@
const events = await submitTransactionAsync(sender, tx);
const result = getGenericResult(events);
- // Get the collection
+ // Get the collection
const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
// What to expect
@@ -300,49 +380,132 @@
export interface CreateFungibleData extends Struct {
readonly value: u128;
-};
+}
-export interface CreateReFungibleData extends Struct {};
-export interface CreateNftData extends Struct {};
+export interface CreateReFungibleData extends Struct {}
+export interface CreateNftData extends Struct {}
export interface CreateItemData extends Enum {
- NFT: CreateNftData,
- Fungible: CreateFungibleData,
- ReFungible: CreateReFungibleData
-};
+ NFT: CreateNftData;
+ Fungible: CreateFungibleData;
+ ReFungible: CreateReFungibleData;
+}
+
+export async function
+approveExpectSuccess(collectionId: number,
+ tokenId: number, owner: IKeyringPair, approved: IKeyringPair, amount: number = 1) {
+ await usingApi(async (api: ApiPromise) => {
+ const allowanceBefore =
+ await api.query.nft.allowances(collectionId, [tokenId, owner.address, approved.address]) as unknown as BN;
+ const approveNftTx = await api.tx.nft.approve(approved.address, collectionId, tokenId, amount);
+ const events = await submitTransactionAsync(owner, approveNftTx);
+ const result = getCreateItemResult(events);
+ // tslint:disable-next-line:no-unused-expression
+ expect(result.success).to.be.true;
+ const allowanceAfter =
+ await api.query.nft.allowances(collectionId, [tokenId, owner.address, approved.address]) as unknown as BN;
+ expect(allowanceAfter.toNumber() - allowanceBefore.toNumber()).to.be.equal(amount);
+ });
+}
+export async function
+transferFromExpectSuccess(collectionId: number,
+ tokenId: number,
+ accountApproved: IKeyringPair,
+ accountFrom: IKeyringPair,
+ accountTo: IKeyringPair,
+ value: number = 1,
+ type: string = 'NFT') {
+ await usingApi(async (api: ApiPromise) => {
+ let balanceBefore = new BN(0);
+ if (type === 'Fungible') {
+ balanceBefore = await api.query.nft.balance(collectionId, accountTo.address) as unknown as BN;
+ }
+ const transferFromTx = await api.tx.nft.transferFrom(
+ accountFrom.address, accountTo.address, collectionId, tokenId, value);
+ const events = await submitTransactionAsync(accountFrom, transferFromTx);
+ const result = getCreateItemResult(events);
+ // tslint:disable-next-line:no-unused-expression
+ expect(result.success).to.be.true;
+ if (type === 'NFT') {
+ const nftItemData = await api.query.nft.nftItemList(collectionId, tokenId) as unknown as ITokenDataType;
+ expect(nftItemData.Owner.toString()).to.be.equal(accountTo.address);
+ }
+ if (type === 'Fungible') {
+ const balanceAfter = await api.query.nft.balance(collectionId, accountTo.address) as unknown as BN;
+ expect(balanceAfter.sub(balanceBefore).toNumber()).to.be.equal(value);
+ }
+ if (type === 'ReFungible') {
+ const nftItemData =
+ await api.query.nft.reFungibleItemList(collectionId, tokenId) as unknown as IReFungibleTokenDataType;
+ expect(nftItemData.Owner[0].Owner.toString()).to.be.equal(accountTo.address);
+ expect(nftItemData.Owner[0].Fraction.toNumber()).to.be.equal(value);
+ }
+ });
+}
+
+export async function
+transferFromExpectFail(collectionId: number,
+ tokenId: number,
+ accountApproved: IKeyringPair,
+ accountFrom: IKeyringPair,
+ accountTo: IKeyringPair,
+ value: number = 1) {
+ await usingApi(async (api: ApiPromise) => {
+ const transferFromTx = await api.tx.nft.transferFrom(
+ accountFrom.address, accountTo.address, collectionId, tokenId, value);
+ const events = await expect(submitTransactionExpectFailAsync(accountApproved, transferFromTx)).to.be.rejected;
+ const result = getCreateCollectionResult(events);
+ // tslint:disable-next-line:no-unused-expression
+ expect(result.success).to.be.false;
+ });
+}
+
+export async function
+approveExpectFail(collectionId: number,
+ tokenId: number, owner: IKeyringPair, approved: IKeyringPair, amount: number = 1) {
+ await usingApi(async (api: ApiPromise) => {
+ const approveNftTx = await api.tx.nft.approve(approved.address, collectionId, tokenId, amount);
+ const events = await expect(submitTransactionExpectFailAsync(owner, approveNftTx)).to.be.rejected;
+ const result = getCreateCollectionResult(events);
+ // tslint:disable-next-line:no-unused-expression
+ expect(result.success).to.be.false;
+ });
+}
+
export async function createItemExpectSuccess(sender: IKeyringPair, collectionId: number, createMode: string, owner: string = '') {
let newItemId: number = 0;
await usingApi(async (api) => {
- const AItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString());
- const Aitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON();
+ const AItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString(), 10);
+ const Aitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON();
const AItemBalance = new BigNumber(Aitem.Value);
- if (owner === '') owner = sender.address;
+ if (owner === '') {
+ owner = sender.address;
+ }
let tx;
- if (createMode == 'Fungible') {
- let createData = {fungible: {value: 10}};
+ if (createMode === 'Fungible') {
+ const createData = {fungible: {value: 10}};
tx = api.tx.nft.createItem(collectionId, owner, createData);
- }
- else {
+ } else {
tx = api.tx.nft.createItem(collectionId, owner, createMode);
}
const events = await submitTransactionAsync(sender, tx);
const result = getCreateItemResult(events);
- const BItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString());
- const Bitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON();
+ const BItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString(), 10);
+ const Bitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON();
const BItemBalance = new BigNumber(Bitem.Value);
// What to expect
+ // tslint:disable-next-line:no-unused-expression
expect(result.success).to.be.true;
- if (createMode == 'Fungible') {
+ if (createMode === 'Fungible') {
expect(BItemBalance.minus(AItemBalance).toNumber()).to.be.equal(10);
+ } else {
+ expect(BItemCount).to.be.equal(AItemCount + 1);
}
- else {
- expect(BItemCount).to.be.equal(AItemCount+1);
- }
expect(collectionId).to.be.equal(result.collectionId);
expect(BItemCount).to.be.equal(result.itemId);
newItemId = result.itemId;
@@ -358,7 +521,7 @@
const events = await submitTransactionAsync(sender, tx);
const result = getGenericResult(events);
- // Get the collection
+ // Get the collection
const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
// What to expect
@@ -375,7 +538,7 @@
const events = await submitTransactionAsync(sender, tx);
const result = getGenericResult(events);
- // Get the collection
+ // Get the collection
const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
// What to expect
@@ -392,7 +555,7 @@
const events = await submitTransactionAsync(sender, tx);
const result = getGenericResult(events);
- // Get the collection
+ // Get the collection
const collection: any = (await api.query.nft.collection(collectionId)).toJSON();
// What to expect