git.delta.rocks / unique-network / refs/commits / 9ecb329aa0c0

difftreelog

Merge remote-tracking branch 'origin/develop' into feature/NFTPAR-241

kpozdnikin2021-01-18parents: #f4eeb2e #07025d8.patch.diff
in: master
# Conflicts:
#	tests/package.json

16 files changed

modifiedpallets/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 {
modifiedpallets/nft/src/tests.rsdiffbeforeafterboth
before · pallets/nft/src/tests.rs
1// Tests to be written here2use super::*;3use crate::mock::*;4use crate::{AccessMode, ApprovePermissions, 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 { }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).owner, 1);242    });243}244245#[test]246fn 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).owner, 1);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).owner, 1);285        assert_eq!(TemplateModule::balance_count(1, 1), 1000);286        assert_eq!(TemplateModule::address_tokens(1, 1), [1]);287288        // change owner scenario289        assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));290        assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);291        assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 1000);292        assert_eq!(TemplateModule::balance_count(1, 1), 0);293        assert_eq!(TemplateModule::balance_count(1, 2), 1000);294        // assert_eq!(TemplateModule::address_tokens(1, 1), []);295        assert_eq!(TemplateModule::address_tokens(1, 2), [1]);296297        // split item scenario298        assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));299        assert_eq!(TemplateModule::fungible_item_id(1, 1).owner, 2);300        assert_eq!(TemplateModule::fungible_item_id(1, 2).owner, 3);301        assert_eq!(TemplateModule::balance_count(1, 2), 500);302        assert_eq!(TemplateModule::balance_count(1, 3), 500);303        assert_eq!(TemplateModule::address_tokens(1, 2), [1]);304        assert_eq!(TemplateModule::address_tokens(1, 3), [2]);305306        // split item and new owner has account scenario307        assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));308        assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 300);309        assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 700);310        assert_eq!(TemplateModule::balance_count(1, 2), 300);311        assert_eq!(TemplateModule::balance_count(1, 3), 700);312        assert_eq!(TemplateModule::address_tokens(1, 2), [1]);313        assert_eq!(TemplateModule::address_tokens(1, 3), [2]);314    });315}316317#[test]318fn transfer_refungible_item() {319    new_test_ext().execute_with(|| {320        default_limits();321        322        let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);323324        let data = default_re_fungible_data();325        create_test_item(collection_id, &data.clone().into());326327        let origin1 = Origin::signed(1);328        let origin2 = Origin::signed(2);329        assert_eq!(330            TemplateModule::refungible_item_id(collection_id, 1).const_data,331            data.const_data332        );333        assert_eq!(334            TemplateModule::refungible_item_id(collection_id, 1).variable_data,335            data.variable_data336        );337        assert_eq!(338            TemplateModule::refungible_item_id(collection_id, 1).owner[0],339            Ownership {340                owner: 1,341                fraction: 1000342            }343        );344        assert_eq!(TemplateModule::balance_count(1, 1), 1000);345        assert_eq!(TemplateModule::address_tokens(1, 1), [1]);346347        // change owner scenario348        assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));349        assert_eq!(350            TemplateModule::refungible_item_id(1, 1).owner[0],351            Ownership {352                owner: 2,353                fraction: 1000354            }355        );356        assert_eq!(TemplateModule::balance_count(1, 1), 0);357        assert_eq!(TemplateModule::balance_count(1, 2), 1000);358        // assert_eq!(TemplateModule::address_tokens(1, 1), []);359        assert_eq!(TemplateModule::address_tokens(1, 2), [1]);360361        // split item scenario362        assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500));363        assert_eq!(364            TemplateModule::refungible_item_id(1, 1).owner[0],365            Ownership {366                owner: 2,367                fraction: 500368            }369        );370        assert_eq!(371            TemplateModule::refungible_item_id(1, 1).owner[1],372            Ownership {373                owner: 3,374                fraction: 500375            }376        );377        assert_eq!(TemplateModule::balance_count(1, 2), 500);378        assert_eq!(TemplateModule::balance_count(1, 3), 500);379        assert_eq!(TemplateModule::address_tokens(1, 2), [1]);380        assert_eq!(TemplateModule::address_tokens(1, 3), [1]);381382        // split item and new owner has account scenario383        assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200));384        assert_eq!(385            TemplateModule::refungible_item_id(1, 1).owner[0],386            Ownership {387                owner: 2,388                fraction: 300389            }390        );391        assert_eq!(392            TemplateModule::refungible_item_id(1, 1).owner[1],393            Ownership {394                owner: 3,395                fraction: 700396            }397        );398        assert_eq!(TemplateModule::balance_count(1, 2), 300);399        assert_eq!(TemplateModule::balance_count(1, 3), 700);400        assert_eq!(TemplateModule::address_tokens(1, 2), [1]);401        assert_eq!(TemplateModule::address_tokens(1, 3), [1]);402    });403}404405#[test]406fn transfer_nft_item() {407    new_test_ext().execute_with(|| {408        default_limits();409        410        let collection_id = create_test_collection(&CollectionMode::NFT, 1);411412        let data = default_nft_data();413        create_test_item(collection_id, &data.into());414        assert_eq!(TemplateModule::balance_count(1, 1), 1);415        assert_eq!(TemplateModule::address_tokens(1, 1), [1]);416417        let origin1 = Origin::signed(1);418        // default scenario419        assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000));420        assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2);421        assert_eq!(TemplateModule::balance_count(1, 1), 0);422        assert_eq!(TemplateModule::balance_count(1, 2), 1);423        // assert_eq!(TemplateModule::address_tokens(1, 1), []);424        assert_eq!(TemplateModule::address_tokens(1, 2), [1]);425    });426}427428#[test]429fn nft_approve_and_transfer_from() {430    new_test_ext().execute_with(|| {431        default_limits();432        433        let collection_id = create_test_collection(&CollectionMode::NFT, 1);434435        let data = default_nft_data();436        create_test_item(collection_id, &data.into());437438        let origin1 = Origin::signed(1);439        let origin2 = Origin::signed(2);440441        assert_eq!(TemplateModule::balance_count(1, 1), 1);442        assert_eq!(TemplateModule::address_tokens(1, 1), [1]);443444        // neg transfer445        assert_noop!(TemplateModule::transfer_from(446            origin2.clone(),447            1,448            2,449            1,450            1,451            1), Error::<Test>::NoPermission);452453        // do approve454        assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));455        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);456        assert_eq!(457            TemplateModule::approved(1, (1, 1))[0],458            ApprovePermissions {459                approved: 2,460                amount: 100000000461            }462        );463464        assert_ok!(TemplateModule::transfer_from(465            origin2.clone(),466            1,467            2,468            1,469            1,470            1471        ));472        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);473    });474}475476#[test]477fn nft_approve_and_transfer_from_white_list() {478    new_test_ext().execute_with(|| {479        default_limits();480        481        let collection_id = create_test_collection(&CollectionMode::NFT, 1);482483        let origin1 = Origin::signed(1);484        let origin2 = Origin::signed(2);485486        let data = default_nft_data();487        create_test_item(collection_id, &data.clone().into());488489        assert_eq!(TemplateModule::nft_item_id(1, 1).const_data, data.const_data);490        assert_eq!(TemplateModule::balance_count(1, 1), 1);491        assert_eq!(TemplateModule::address_tokens(1, 1), [1]);492493        assert_ok!(TemplateModule::set_mint_permission(494            origin1.clone(),495            1,496            true497        ));498        assert_ok!(TemplateModule::set_public_access_mode(499            origin1.clone(),500            1,501            AccessMode::WhiteList502        ));503        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));504        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));505        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));506507        // do approve508        assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));509        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);510        assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));511        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);512        assert_eq!(513            TemplateModule::approved(1, (1, 1))[0],514            ApprovePermissions {515                approved: 2,516                amount: 100000000517            }518        );519520        assert_ok!(TemplateModule::transfer_from(521            origin2.clone(),522            1,523            3,524            1,525            1,526            1527        ));528        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);529    });530}531532#[test]533fn refungible_approve_and_transfer_from() {534    new_test_ext().execute_with(|| {535        default_limits();536        537        let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);538        539        let origin1 = Origin::signed(1);540        let origin2 = Origin::signed(2);541542        let data = default_re_fungible_data();543        create_test_item(collection_id, &data.into());544545        assert_eq!(TemplateModule::balance_count(1, 1), 1000);546        assert_eq!(TemplateModule::address_tokens(1, 1), [1]);547548        assert_ok!(TemplateModule::set_mint_permission(549            origin1.clone(),550            1,551            true552        ));553        assert_ok!(TemplateModule::set_public_access_mode(554            origin1.clone(),555            1,556            AccessMode::WhiteList557        ));558        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));559        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));560        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));561562        // do approve563        assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));564        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);565        assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));566        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);567        assert_eq!(568            TemplateModule::approved(1, (1, 1))[0],569            ApprovePermissions {570                approved: 2,571                amount: 100000000572            }573        );574575        assert_ok!(TemplateModule::transfer_from(576            origin2.clone(),577            1,578            3,579            1,580            1,581            100582        ));583        assert_eq!(TemplateModule::balance_count(1, 1), 900);584        assert_eq!(TemplateModule::balance_count(1, 3), 100);585        assert_eq!(TemplateModule::address_tokens(1, 1), [1]);586        assert_eq!(TemplateModule::address_tokens(1, 3), [1]);587588        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);589        assert_eq!(590            TemplateModule::approved(1, (1, 1))[0],591            ApprovePermissions {592                approved: 3,593                amount: 100000000594            }595        );596    });597}598599#[test]600fn fungible_approve_and_transfer_from() {601    new_test_ext().execute_with(|| {602        default_limits();603        604        let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);605        606        let data = default_fungible_data();607        create_test_item(collection_id, &data.into());608609        let origin1 = Origin::signed(1);610        let origin2 = Origin::signed(2);611612        assert_eq!(TemplateModule::balance_count(1, 1), 1000);613        assert_eq!(TemplateModule::address_tokens(1, 1), [1]);614615        assert_ok!(TemplateModule::set_mint_permission(616            origin1.clone(),617            1,618            true619        ));620        assert_ok!(TemplateModule::set_public_access_mode(621            origin1.clone(),622            1,623            AccessMode::WhiteList624        ));625        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));626        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));627        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));628629        // do approve630        assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));631        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);632        assert_ok!(TemplateModule::approve(origin1.clone(), 3, 1, 1));633        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 2);634        assert_eq!(635            TemplateModule::approved(1, (1, 1))[0],636            ApprovePermissions {637                approved: 2,638                amount: 100000000639            }640        );641642        assert_ok!(TemplateModule::transfer_from(643            origin2.clone(),644            1,645            3,646            1,647            1,648            100649        ));650        assert_eq!(TemplateModule::balance_count(1, 1), 900);651        assert_eq!(TemplateModule::balance_count(1, 3), 100);652        assert_eq!(TemplateModule::address_tokens(1, 1), [1]);653        assert_eq!(TemplateModule::address_tokens(1, 3), [2]);654655        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);656        assert_eq!(657            TemplateModule::approved(1, (1, 1))[0],658            ApprovePermissions {659                approved: 3,660                amount: 100000000661            }662        );663664        assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));665        assert_ok!(TemplateModule::transfer_from(666            origin2.clone(),667            1,668            3,669            1,670            1,671            900672        ));673        assert_eq!(TemplateModule::balance_count(1, 1), 0);674        assert_eq!(TemplateModule::balance_count(1, 3), 1000);675        // assert_eq!(TemplateModule::address_tokens(1, 1), []);676        assert_eq!(TemplateModule::address_tokens(1, 3), [2]);677678        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);679    });680}681682#[test]683fn change_collection_owner() {684    new_test_ext().execute_with(|| {685        default_limits();686        687        let collection_id = create_test_collection(&CollectionMode::NFT, 1);688        689        let origin1 = Origin::signed(1);690        assert_ok!(TemplateModule::change_collection_owner(691            origin1.clone(),692            collection_id,693            2694        ));695        assert_eq!(TemplateModule::collection(collection_id).owner, 2);696    });697}698699#[test]700fn destroy_collection() {701    new_test_ext().execute_with(|| {702        default_limits();703        704        let collection_id = create_test_collection(&CollectionMode::NFT, 1);705        706        let origin1 = Origin::signed(1);707        assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));708    });709}710711#[test]712fn burn_nft_item() {713    new_test_ext().execute_with(|| {714        default_limits();715        716        let collection_id = create_test_collection(&CollectionMode::NFT, 1);717718        let origin1 = Origin::signed(1);719        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));720        721        let data = default_nft_data();722        create_test_item(collection_id, &data.into());723724        // check balance (collection with id = 1, user id = 1)725        assert_eq!(TemplateModule::balance_count(1, 1), 1);726727        // burn item728        assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));729        assert_noop!(730            TemplateModule::burn_item(origin1.clone(), 1, 1),731            Error::<Test>::TokenNotFound732        );733734        assert_eq!(TemplateModule::balance_count(1, 1), 0);735    });736}737738#[test]739fn burn_fungible_item() {740    new_test_ext().execute_with(|| {741        default_limits();742        743        let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);744        745        let origin1 = Origin::signed(1);746        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));747        748        let data = default_fungible_data();749        create_test_item(collection_id, &data.into());750751        // check balance (collection with id = 1, user id = 1)752        assert_eq!(TemplateModule::balance_count(1, 1), 1000);753754        // burn item755        assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));756        assert_noop!(757            TemplateModule::burn_item(origin1.clone(), 1, 1),758            Error::<Test>::TokenNotFound759        );760761        assert_eq!(TemplateModule::balance_count(1, 1), 0);762    });763}764765#[test]766fn burn_refungible_item() {767    new_test_ext().execute_with(|| {768        default_limits();769        770        let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);771        let origin1 = Origin::signed(1);772773        assert_ok!(TemplateModule::set_mint_permission(774            origin1.clone(),775            collection_id,776            true777        ));778        assert_ok!(TemplateModule::set_public_access_mode(779            origin1.clone(),780            collection_id,781            AccessMode::WhiteList782        ));783        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));784785        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));786        787        let data = default_re_fungible_data();788        create_test_item(collection_id, &data.into());789790        // check balance (collection with id = 1, user id = 2)791        assert_eq!(TemplateModule::balance_count(1, 1), 1000);792793        // burn item794        assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));795        assert_noop!(796            TemplateModule::burn_item(origin1.clone(), 1, 1),797            Error::<Test>::TokenNotFound798        );799800        assert_eq!(TemplateModule::balance_count(1, 1), 0);801    });802}803804#[test]805fn add_collection_admin() {806    new_test_ext().execute_with(|| {807        default_limits();808        809        let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);810        create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);811        create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);812        813        let origin1 = Origin::signed(1);814815        // collection admin816        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));817        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));818819        assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&2), true);820        assert_eq!(TemplateModule::admin_list_collection(collection1_id).contains(&3), true);821    });822}823824#[test]825fn remove_collection_admin() {826    new_test_ext().execute_with(|| {827        default_limits();828        829        let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);830        create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);831        create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);832833        let origin1 = Origin::signed(1);834        let origin2 = Origin::signed(2);835836        // collection admin837        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 2));838        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection1_id, 3));839840        assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);841        assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);842843        // remove admin844        assert_ok!(TemplateModule::remove_collection_admin(845            origin2.clone(),846            1,847            3848        ));849        assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), false);850    });851}852853#[test]854fn balance_of() {855    new_test_ext().execute_with(|| {856        default_limits();857        858        let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);859        let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);860        let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible(3), 3);861        862        // check balance before863        assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);864        assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);865        assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 0);866867        let nft_data = default_nft_data();868        create_test_item(nft_collection_id, &nft_data.into());869        870        let fungible_data = default_fungible_data();871        create_test_item(fungible_collection_id, &fungible_data.into());872        873        let re_fungible_data = default_re_fungible_data();874        create_test_item(re_fungible_collection_id, &re_fungible_data.into());875876        // check balance (collection with id = 1, user id = 1)877        assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1);878        assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 1000);879        assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 1000);880        assert_eq!(TemplateModule::nft_item_id(nft_collection_id, 1).owner, 1);881        assert_eq!(TemplateModule::fungible_item_id(fungible_collection_id, 1).owner, 1);882        assert_eq!(TemplateModule::refungible_item_id(re_fungible_collection_id, 1).owner[0].owner, 1);883    });884}885886#[test]887fn approve() {888    new_test_ext().execute_with(|| {889        default_limits();890        891        let collection_id = create_test_collection(&CollectionMode::NFT, 1);892        893        let data = default_nft_data();894        create_test_item(collection_id, &data.into());895896        let origin1 = Origin::signed(1);897        898        // approve899        assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));900        assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);901    });902}903904#[test]905fn transfer_from() {906    new_test_ext().execute_with(|| {907        default_limits();908        909        let collection_id = create_test_collection(&CollectionMode::NFT, 1);910        let origin1 = Origin::signed(1);911        let origin2 = Origin::signed(2);912913        let data = default_nft_data();914        create_test_item(collection_id, &data.into());915916        // approve917        assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));918        assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);919920        assert_ok!(TemplateModule::set_mint_permission(921            origin1.clone(),922            1,923            true924        ));925        assert_ok!(TemplateModule::set_public_access_mode(926            origin1.clone(),927            1,928            AccessMode::WhiteList929        ));930        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));931        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));932        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));933934        assert_ok!(TemplateModule::transfer_from(935            origin2.clone(),936            1,937            2,938            1,939            1,940            1941        ));942943        // after transfer944        assert_eq!(TemplateModule::balance_count(1, 1), 0);945        assert_eq!(TemplateModule::balance_count(1, 2), 1);946    });947}948949// #endregion950951// Coverage tests region952// #region953954#[test]955fn owner_can_add_address_to_white_list() {956    new_test_ext().execute_with(|| {957        default_limits();958        959        let collection_id = create_test_collection(&CollectionMode::NFT, 1);960961        let origin1 = Origin::signed(1);962        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));963        assert_eq!(TemplateModule::white_list(collection_id, 2), true);964    });965}966967#[test]968fn admin_can_add_address_to_white_list() {969    new_test_ext().execute_with(|| {970        default_limits();971        972        let collection_id = create_test_collection(&CollectionMode::NFT, 1);973        let origin1 = Origin::signed(1);974        let origin2 = Origin::signed(2);975976        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));977        assert_ok!(TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3));978        assert_eq!(TemplateModule::white_list(collection_id, 3), true);979    });980}981982#[test]983fn nonprivileged_user_cannot_add_address_to_white_list() {984    new_test_ext().execute_with(|| {985        default_limits();986        987        let collection_id = create_test_collection(&CollectionMode::NFT, 1);988989        let origin2 = Origin::signed(2);990        assert_noop!(991            TemplateModule::add_to_white_list(origin2.clone(), collection_id, 3),992            Error::<Test>::NoPermission993        );994    });995}996997#[test]998fn nobody_can_add_address_to_white_list_of_nonexisting_collection() {999    new_test_ext().execute_with(|| {1000        default_limits();10011002        let origin1 = Origin::signed(1);10031004        assert_noop!(1005            TemplateModule::add_to_white_list(origin1.clone(), 1, 2),1006            Error::<Test>::CollectionNotFound1007        );1008    });1009}10101011#[test]1012fn nobody_can_add_address_to_white_list_of_deleted_collection() {1013    new_test_ext().execute_with(|| {1014        default_limits();1015        1016        let collection_id = create_test_collection(&CollectionMode::NFT, 1);10171018        let origin1 = Origin::signed(1);1019        assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1020        assert_noop!(1021            TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2),1022            Error::<Test>::CollectionNotFound1023        );1024    });1025}10261027// If address is already added to white list, nothing happens1028#[test]1029fn address_is_already_added_to_white_list() {1030    new_test_ext().execute_with(|| {1031        default_limits();1032        1033        let collection_id = create_test_collection(&CollectionMode::NFT, 1);1034        let origin1 = Origin::signed(1);1035        1036        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1037        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1038        assert_eq!(TemplateModule::white_list(collection_id, 2), true);1039    });1040}10411042#[test]1043fn owner_can_remove_address_from_white_list() {1044    new_test_ext().execute_with(|| {1045        default_limits();1046        1047        let collection_id = create_test_collection(&CollectionMode::NFT, 1);10481049        let origin1 = Origin::signed(1);1050        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1051        assert_ok!(TemplateModule::remove_from_white_list(1052            origin1.clone(),1053            collection_id,1054            21055        ));1056        assert_eq!(TemplateModule::white_list(collection_id, 2), false);1057    });1058}10591060#[test]1061fn admin_can_remove_address_from_white_list() {1062    new_test_ext().execute_with(|| {1063        default_limits();1064        1065        let collection_id = create_test_collection(&CollectionMode::NFT, 1);1066        let origin1 = Origin::signed(1);1067        let origin2 = Origin::signed(2);10681069        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));10701071        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 3));1072        assert_ok!(TemplateModule::remove_from_white_list(1073            origin2.clone(),1074            collection_id,1075            31076        ));1077        assert_eq!(TemplateModule::white_list(collection_id, 3), false);1078    });1079}10801081#[test]1082fn nonprivileged_user_cannot_remove_address_from_white_list() {1083    new_test_ext().execute_with(|| {1084        default_limits();1085        1086        let collection_id = create_test_collection(&CollectionMode::NFT, 1);1087        let origin1 = Origin::signed(1);1088        let origin2 = Origin::signed(2);10891090        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1091        assert_noop!(1092            TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1093            Error::<Test>::NoPermission1094        );1095        assert_eq!(TemplateModule::white_list(collection_id, 2), true);1096    });1097}10981099#[test]1100fn nobody_can_remove_address_from_white_list_of_nonexisting_collection() {1101    new_test_ext().execute_with(|| {1102        default_limits();1103        let origin1 = Origin::signed(1);11041105        assert_noop!(1106            TemplateModule::remove_from_white_list(origin1.clone(), 1, 2),1107            Error::<Test>::CollectionNotFound1108        );1109    });1110}11111112#[test]1113fn nobody_can_remove_address_from_white_list_of_deleted_collection() {1114    new_test_ext().execute_with(|| {1115        default_limits();1116        1117        let collection_id = create_test_collection(&CollectionMode::NFT, 1);1118        let origin1 = Origin::signed(1);1119        let origin2 = Origin::signed(2);11201121        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1122        assert_ok!(TemplateModule::destroy_collection(origin1.clone(), collection_id));1123        assert_noop!(1124            TemplateModule::remove_from_white_list(origin2.clone(), collection_id, 2),1125            Error::<Test>::CollectionNotFound1126        );1127        assert_eq!(TemplateModule::white_list(collection_id, 2), false);1128    });1129}11301131// If address is already removed from white list, nothing happens1132#[test]1133fn address_is_already_removed_from_white_list() {1134    new_test_ext().execute_with(|| {1135        default_limits();1136        1137        let collection_id = create_test_collection(&CollectionMode::NFT, 1);1138        let origin1 = Origin::signed(1);11391140        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));1141        assert_ok!(TemplateModule::remove_from_white_list(1142            origin1.clone(),1143            collection_id,1144            21145        ));1146        assert_ok!(TemplateModule::remove_from_white_list(1147            origin1.clone(),1148            collection_id,1149            21150        ));1151        assert_eq!(TemplateModule::white_list(collection_id, 2), false);1152    });1153}11541155// If Public Access mode is set to WhiteList, tokens can’t be transferred from a non-whitelisted address with transfer or transferFrom (2 tests)1156#[test]1157fn white_list_test_1() {1158    new_test_ext().execute_with(|| {1159        default_limits();1160        1161        let collection_id = create_test_collection(&CollectionMode::NFT, 1);11621163        let origin1 = Origin::signed(1);1164        1165        let data = default_nft_data();1166        create_test_item(collection_id, &data.into());11671168        assert_ok!(TemplateModule::set_public_access_mode(1169            origin1.clone(),1170            collection_id,1171            AccessMode::WhiteList1172        ));1173        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));11741175        assert_noop!(1176            TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1177            Error::<Test>::AddresNotInWhiteList1178        );1179    });1180}11811182#[test]1183fn white_list_test_2() {1184    new_test_ext().execute_with(|| {1185        default_limits();1186        1187        let collection_id = create_test_collection(&CollectionMode::NFT, 1);1188        let origin1 = Origin::signed(1);1189        1190        let data = default_nft_data();1191        create_test_item(collection_id, &data.into());11921193        assert_ok!(TemplateModule::set_public_access_mode(1194            origin1.clone(),1195            collection_id,1196            AccessMode::WhiteList1197        ));1198        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));1199        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));12001201        // do approve1202        assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1203        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);12041205        assert_ok!(TemplateModule::remove_from_white_list(1206            origin1.clone(),1207            1,1208            11209        ));12101211        assert_noop!(1212            TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1213            Error::<Test>::AddresNotInWhiteList1214        );1215    });1216}12171218// If Public Access mode is set to WhiteList, tokens can’t be transferred to a non-whitelisted address with transfer or transferFrom (2 tests)1219#[test]1220fn white_list_test_3() {1221    new_test_ext().execute_with(|| {1222        default_limits();1223        1224        let collection_id = create_test_collection(&CollectionMode::NFT, 1);12251226        let origin1 = Origin::signed(1);1227        1228        let data = default_nft_data();1229        create_test_item(collection_id, &data.into());12301231        assert_ok!(TemplateModule::set_public_access_mode(1232            origin1.clone(),1233            collection_id,1234            AccessMode::WhiteList1235        ));1236        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));12371238        assert_noop!(1239            TemplateModule::transfer(origin1.clone(), 3, 1, 1, 1),1240            Error::<Test>::AddresNotInWhiteList1241        );1242    });1243}12441245#[test]1246fn white_list_test_4() {1247    new_test_ext().execute_with(|| {1248        default_limits();1249        1250        let collection_id = create_test_collection(&CollectionMode::NFT, 1);12511252        let origin1 = Origin::signed(1);12531254        let data = default_nft_data();1255        create_test_item(collection_id, &data.into());12561257        assert_ok!(TemplateModule::set_public_access_mode(1258            origin1.clone(),1259            collection_id,1260            AccessMode::WhiteList1261        ));1262        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1263        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));12641265        // do approve1266        assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1267        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);12681269        assert_ok!(TemplateModule::remove_from_white_list(1270            origin1.clone(),1271            collection_id,1272            21273        ));12741275        assert_noop!(1276            TemplateModule::transfer_from(origin1.clone(), 1, 3, 1, 1, 1),1277            Error::<Test>::AddresNotInWhiteList1278        );1279    });1280}12811282// 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)1283#[test]1284fn white_list_test_5() {1285    new_test_ext().execute_with(|| {1286        default_limits();1287        1288        let collection_id = create_test_collection(&CollectionMode::NFT, 1);12891290        let origin1 = Origin::signed(1);12911292        let data = default_nft_data();1293        create_test_item(collection_id, &data.into());12941295        assert_ok!(TemplateModule::set_public_access_mode(1296            origin1.clone(),1297            collection_id,1298            AccessMode::WhiteList1299        ));1300        assert_noop!(1301            TemplateModule::burn_item(origin1.clone(), 1, 1),1302            Error::<Test>::AddresNotInWhiteList1303        );1304    });1305}13061307// If Public Access mode is set to WhiteList, oken transfers can’t be Approved by a non-whitelisted address (see Approve method).1308#[test]1309fn white_list_test_6() {1310    new_test_ext().execute_with(|| {1311        default_limits();1312        1313        let collection_id = create_test_collection(&CollectionMode::NFT, 1);13141315        let origin1 = Origin::signed(1);1316        assert_ok!(TemplateModule::set_public_access_mode(1317            origin1.clone(),1318            collection_id,1319            AccessMode::WhiteList1320        ));13211322        // do approve1323        assert_noop!(1324            TemplateModule::approve(origin1.clone(), 1, 1, 1),1325            Error::<Test>::AddresNotInWhiteList1326        );1327    });1328}13291330// If Public Access mode is set to WhiteList, tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests) and1331//          tokens can be transferred from a whitelisted address with transfer or transferFrom (2 tests)1332#[test]1333fn white_list_test_7() {1334    new_test_ext().execute_with(|| {1335        default_limits();1336        1337        let collection_id = create_test_collection(&CollectionMode::NFT, 1);13381339        let data = default_nft_data();1340        create_test_item(collection_id, &data.into());1341        1342        let origin1 = Origin::signed(1);13431344        assert_ok!(TemplateModule::set_public_access_mode(1345            origin1.clone(),1346            collection_id,1347            AccessMode::WhiteList1348        ));1349        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1350        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13511352        assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1));1353    });1354}13551356#[test]1357fn white_list_test_8() {1358    new_test_ext().execute_with(|| {1359        default_limits();1360        1361        let collection_id = create_test_collection(&CollectionMode::NFT, 1);13621363        let data = default_nft_data();1364        create_test_item(collection_id, &data.into());1365        1366        let origin1 = Origin::signed(1);13671368        assert_ok!(TemplateModule::set_public_access_mode(1369            origin1.clone(),1370            collection_id,1371            AccessMode::WhiteList1372        ));1373        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 1));1374        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));13751376        // do approve1377        assert_ok!(TemplateModule::approve(origin1.clone(), 1, 1, 1));1378        assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 1);13791380        assert_ok!(TemplateModule::transfer_from(1381            origin1.clone(),1382            1,1383            2,1384            1,1385            1,1386            11387        ));1388    });1389}13901391// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by owner.1392#[test]1393fn white_list_test_9() {1394    new_test_ext().execute_with(|| {1395        default_limits();1396        1397        let collection_id = create_test_collection(&CollectionMode::NFT, 1);1398        let origin1 = Origin::signed(1);13991400        assert_ok!(TemplateModule::set_public_access_mode(1401            origin1.clone(),1402            collection_id,1403            AccessMode::WhiteList1404        ));1405        assert_ok!(TemplateModule::set_mint_permission(1406            origin1.clone(),1407            collection_id,1408            false1409        ));14101411        let data = default_nft_data();1412        create_test_item(collection_id, &data.into());1413    });1414}14151416// If Public Access mode is set to WhiteList, and Mint Permission is set to false, tokens can be created by admin.1417#[test]1418fn white_list_test_10() {1419    new_test_ext().execute_with(|| {1420        default_limits();1421        1422        let collection_id = create_test_collection(&CollectionMode::NFT, 1);14231424        let origin1 = Origin::signed(1);1425        let origin2 = Origin::signed(2);14261427        assert_ok!(TemplateModule::set_public_access_mode(1428            origin1.clone(),1429            collection_id,1430            AccessMode::WhiteList1431        ));1432        assert_ok!(TemplateModule::set_mint_permission(1433            origin1.clone(),1434            collection_id,1435            false1436        ));14371438        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));14391440        assert_ok!(TemplateModule::create_item(1441            origin2.clone(),1442            collection_id,1443            2,1444            default_nft_data().into()1445        ));1446    });1447}14481449// 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.1450#[test]1451fn white_list_test_11() {1452    new_test_ext().execute_with(|| {1453        default_limits();1454        1455        let collection_id = create_test_collection(&CollectionMode::NFT, 1);14561457        let origin1 = Origin::signed(1);1458        let origin2 = Origin::signed(2);14591460        assert_ok!(TemplateModule::set_public_access_mode(1461            origin1.clone(),1462            collection_id,1463            AccessMode::WhiteList1464        ));1465        assert_ok!(TemplateModule::set_mint_permission(1466            origin1.clone(),1467            collection_id,1468            false1469        ));1470        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));14711472        assert_noop!(1473            TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1474            Error::<Test>::PublicMintingNotAllowed1475        );1476    });1477}14781479// 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.1480#[test]1481fn white_list_test_12() {1482    new_test_ext().execute_with(|| {1483        default_limits();1484        1485        let collection_id = create_test_collection(&CollectionMode::NFT, 1);14861487        let origin1 = Origin::signed(1);1488        let origin2 = Origin::signed(2);14891490        assert_ok!(TemplateModule::set_public_access_mode(1491            origin1.clone(),1492            collection_id,1493            AccessMode::WhiteList1494        ));1495        assert_ok!(TemplateModule::set_mint_permission(1496            origin1.clone(),1497            collection_id,1498            false1499        ));15001501        assert_noop!(1502            TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1503            Error::<Test>::PublicMintingNotAllowed1504        );1505    });1506}15071508// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by owner.1509#[test]1510fn white_list_test_13() {1511    new_test_ext().execute_with(|| {1512        default_limits();1513        1514        let collection_id = create_test_collection(&CollectionMode::NFT, 1);15151516        let origin1 = Origin::signed(1);15171518        assert_ok!(TemplateModule::set_public_access_mode(1519            origin1.clone(),1520            collection_id,1521            AccessMode::WhiteList1522        ));1523        assert_ok!(TemplateModule::set_mint_permission(1524            origin1.clone(),1525            collection_id,1526            true1527        ));15281529        let data = default_nft_data();1530        create_test_item(collection_id, &data.into());1531    });1532}15331534// If Public Access mode is set to WhiteList, and Mint Permission is set to true, tokens can be created by admin.1535#[test]1536fn white_list_test_14() {1537    new_test_ext().execute_with(|| {1538        default_limits();1539        1540        let collection_id = create_test_collection(&CollectionMode::NFT, 1);15411542        let origin1 = Origin::signed(1);1543        let origin2 = Origin::signed(2);15441545        assert_ok!(TemplateModule::set_public_access_mode(1546            origin1.clone(),1547            collection_id,1548            AccessMode::WhiteList1549        ));1550        assert_ok!(TemplateModule::set_mint_permission(1551            origin1.clone(),1552            collection_id,1553            true1554        ));15551556        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));15571558        assert_ok!(TemplateModule::create_item(1559            origin2.clone(),1560            1,1561            2,1562            default_nft_data().into()1563        ));1564    });1565}15661567// 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.1568#[test]1569fn white_list_test_15() {1570    new_test_ext().execute_with(|| {1571        default_limits();1572        1573        let collection_id = create_test_collection(&CollectionMode::NFT, 1);15741575        let origin1 = Origin::signed(1);1576        let origin2 = Origin::signed(2);15771578        assert_ok!(TemplateModule::set_public_access_mode(1579            origin1.clone(),1580            collection_id,1581            AccessMode::WhiteList1582        ));1583        assert_ok!(TemplateModule::set_mint_permission(1584            origin1.clone(),1585            collection_id,1586            true1587        ));15881589        assert_noop!(1590            TemplateModule::create_item(origin2.clone(), 1, 2, default_nft_data().into()),1591            Error::<Test>::AddresNotInWhiteList1592        );1593    });1594}15951596// 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.1597#[test]1598fn white_list_test_16() {1599    new_test_ext().execute_with(|| {1600        default_limits();1601        1602        let collection_id = create_test_collection(&CollectionMode::NFT, 1);16031604        let origin1 = Origin::signed(1);1605        let origin2 = Origin::signed(2);16061607        assert_ok!(TemplateModule::set_public_access_mode(1608            origin1.clone(),1609            collection_id,1610            AccessMode::WhiteList1611        ));1612        assert_ok!(TemplateModule::set_mint_permission(1613            origin1.clone(),1614            collection_id,1615            true1616        ));1617        assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), collection_id, 2));16181619        assert_ok!(TemplateModule::create_item(1620            origin2.clone(),1621            1,1622            2,1623            default_nft_data().into()1624        ));1625    });1626}16271628// Total number of collections. Positive test1629#[test]1630fn total_number_collections_bound() {1631    new_test_ext().execute_with(|| {1632        default_limits();1633        1634        create_test_collection(&CollectionMode::NFT, 1);1635    });1636}16371638// Total number of collections. Negotive test1639#[test]1640fn total_number_collections_bound_neg() {1641    new_test_ext().execute_with(|| {1642        default_limits();16431644        let origin1 = Origin::signed(1);16451646        for i in 0..default_collection_numbers_limit() {1647            create_test_collection(&CollectionMode::NFT, i + 1);1648        }16491650        let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();1651        let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();1652        let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();16531654        // 11-th collection in chain. Expects error1655        assert_noop!(TemplateModule::create_collection(1656            origin1.clone(),1657            col_name1.clone(),1658            col_desc1.clone(),1659            token_prefix1.clone(),1660            CollectionMode::NFT1661        ), Error::<Test>::TotalCollectionsLimitExceeded);1662    });1663}16641665// Owned tokens by a single address. Positive test1666#[test]1667fn owned_tokens_bound() {1668    new_test_ext().execute_with(|| {1669        default_limits();1670        1671        let collection_id = create_test_collection(&CollectionMode::NFT, 1);16721673        let data = default_nft_data();1674        create_test_item(collection_id, &data.clone().into());1675        create_test_item(collection_id, &data.into());1676    });1677}16781679// Owned tokens by a single address. Negotive test1680#[test]1681fn owned_tokens_bound_neg() {1682    new_test_ext().execute_with(|| {1683        assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1684            collection_numbers_limit: 10,1685            account_token_ownership_limit: 1,1686            collections_admins_limit: 5,1687            custom_data_limit: 2048,1688            nft_sponsor_transfer_timeout: 15,1689            fungible_sponsor_transfer_timeout: 15,1690            refungible_sponsor_transfer_timeout: 15,          1691        }));1692        1693        let collection_id = create_test_collection(&CollectionMode::NFT, 1);16941695        let origin1 = Origin::signed(1);1696        let data = default_nft_data();1697        create_test_item(collection_id, &data.clone().into());16981699        assert_noop!(TemplateModule::create_item(1700            origin1.clone(),1701            1,1702            1,1703            data.into()1704        ),  Error::<Test>::AddressOwnershipLimitExceeded);1705    });1706}17071708// Number of collection admins. Positive test1709#[test]1710fn collection_admins_bound() {1711    new_test_ext().execute_with(|| {1712        assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1713            collection_numbers_limit: 10,1714            account_token_ownership_limit: 10,1715            collections_admins_limit: 2,1716            custom_data_limit: 2048,1717            nft_sponsor_transfer_timeout: 15,1718            fungible_sponsor_transfer_timeout: 15,1719            refungible_sponsor_transfer_timeout: 15,          1720        }));1721        1722        let collection_id = create_test_collection(&CollectionMode::NFT, 1);17231724        let origin1 = Origin::signed(1);1725        1726        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1727        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3));1728    });1729}17301731// Number of collection admins. Negotive test1732#[test]1733fn collection_admins_bound_neg() {1734    new_test_ext().execute_with(|| {1735        assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1736            collection_numbers_limit: 10,1737            account_token_ownership_limit: 1,1738            collections_admins_limit: 1,1739            custom_data_limit: 2048,1740            nft_sponsor_transfer_timeout: 15,1741            fungible_sponsor_transfer_timeout: 15,1742            refungible_sponsor_transfer_timeout: 15,          1743        }));1744        1745        let collection_id = create_test_collection(&CollectionMode::NFT, 1);17461747        let origin1 = Origin::signed(1);17481749        assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 2));1750        assert_noop!(TemplateModule::add_collection_admin(origin1.clone(), collection_id, 3), Error::<Test>::CollectionAdminsLimitExceeded);1751    });1752}17531754// NFT custom data size. Negative test const_data.1755#[test]1756fn custom_data_size_nft_const_data_bound_neg() {1757    new_test_ext().execute_with(|| {1758        assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1759            collection_numbers_limit: 10,1760            account_token_ownership_limit: 10,1761            collections_admins_limit: 5,1762            custom_data_limit: 2,1763            nft_sponsor_transfer_timeout: 15,1764            fungible_sponsor_transfer_timeout: 15,1765            refungible_sponsor_transfer_timeout: 15,          1766        }));1767        1768        let collection_id = create_test_collection(&CollectionMode::NFT, 1);17691770        let origin1 = Origin::signed(1);1771        let too_big_const_data = CreateItemData::NFT(CreateNftData{1772            const_data: vec![1, 2, 3, 4],1773            variable_data: vec![]1774        });17751776        assert_noop!(TemplateModule::create_item(1777            origin1.clone(),1778            collection_id,1779            1,1780            too_big_const_data1781        ), Error::<Test>::TokenConstDataLimitExceeded);1782    });1783}17841785// NFT custom data size. Negative test variable_data.1786#[test]1787fn custom_data_size_nft_variable_data_bound_neg() {1788    new_test_ext().execute_with(|| {1789        assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1790            collection_numbers_limit: 10,1791            account_token_ownership_limit: 10,1792            collections_admins_limit: 5,1793            custom_data_limit: 2,1794            nft_sponsor_transfer_timeout: 15,1795            fungible_sponsor_transfer_timeout: 15,1796            refungible_sponsor_transfer_timeout: 15,          1797        }));17981799        let collection_id = create_test_collection(&CollectionMode::NFT, 1);18001801        let origin1 = Origin::signed(1);1802        let too_big_const_data = CreateItemData::NFT(CreateNftData{1803            const_data: vec![],1804            variable_data: vec![1, 2, 3, 4]1805        });18061807        assert_noop!(TemplateModule::create_item(1808            origin1.clone(),1809            collection_id,1810            1,1811            too_big_const_data1812        ), Error::<Test>::TokenVariableDataLimitExceeded);1813    });1814}18151816// Re fungible custom data size. Negative test const_data.1817#[test]1818fn custom_data_size_re_fungible_const_data_bound_neg() {1819    new_test_ext().execute_with(|| {1820        assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1821            collection_numbers_limit: 10,1822            account_token_ownership_limit: 10,1823            collections_admins_limit: 5,1824            custom_data_limit: 2,1825            nft_sponsor_transfer_timeout: 15,1826            fungible_sponsor_transfer_timeout: 15,1827            refungible_sponsor_transfer_timeout: 15,          1828        }));18291830        let collection_id = create_test_collection(&CollectionMode::NFT, 1);18311832        let origin1 = Origin::signed(1);1833        let too_big_const_data = CreateItemData::NFT(CreateNftData{1834            const_data: vec![1, 2, 3, 4],1835            variable_data: vec![]1836        });18371838        assert_noop!(TemplateModule::create_item(1839            origin1.clone(),1840            collection_id,1841            1,1842            too_big_const_data1843        ), Error::<Test>::TokenConstDataLimitExceeded);1844    });1845}18461847// Re fungible custom data size. Negative test variable_data.1848#[test]1849fn custom_data_size_re_fungible_variable_data_bound_neg() {1850    new_test_ext().execute_with(|| {1851        assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1852            collection_numbers_limit: 10,1853            account_token_ownership_limit: 10,1854            collections_admins_limit: 5,1855            custom_data_limit: 2,1856            nft_sponsor_transfer_timeout: 15,1857            fungible_sponsor_transfer_timeout: 15,1858            refungible_sponsor_transfer_timeout: 15,          1859        }));18601861        let collection_id = create_test_collection(&CollectionMode::NFT, 1);18621863        let origin1 = Origin::signed(1);1864        let too_big_const_data = CreateItemData::NFT(CreateNftData{1865            const_data: vec![],1866            variable_data: vec![1, 2, 3, 4]1867        });18681869        assert_noop!(TemplateModule::create_item(1870            origin1.clone(),1871            collection_id,1872            1,1873            too_big_const_data1874        ), Error::<Test>::TokenVariableDataLimitExceeded);1875    });1876}1877// #endregion18781879#[test]1880fn set_const_on_chain_schema() {1881    new_test_ext().execute_with(|| {1882        default_limits();18831884        let collection_id = create_test_collection(&CollectionMode::NFT, 1);18851886        let origin1 = Origin::signed(1);1887        assert_ok!(TemplateModule::set_const_on_chain_schema(origin1, collection_id, b"test const on chain schema".to_vec()));18881889        assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"test const on chain schema".to_vec());1890        assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"".to_vec());1891    });1892}18931894#[test]1895fn set_variable_on_chain_schema() {1896    new_test_ext().execute_with(|| {1897        default_limits();1898        1899        let collection_id = create_test_collection(&CollectionMode::NFT, 1);19001901        let origin1 = Origin::signed(1);1902        assert_ok!(TemplateModule::set_variable_on_chain_schema(origin1, collection_id, b"test variable on chain schema".to_vec()));19031904        assert_eq!(TemplateModule::collection(collection_id).const_on_chain_schema, b"".to_vec());1905        assert_eq!(TemplateModule::collection(collection_id).variable_on_chain_schema, b"test variable on chain schema".to_vec());1906    });1907}19081909#[test]1910fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {1911    new_test_ext().execute_with(|| {1912        default_limits();19131914        let collection_id = create_test_collection(&CollectionMode::NFT, 1);19151916        let origin1 = Origin::signed(1);1917        1918        let data = default_nft_data();1919        create_test_item(1, &data.into());1920        1921        let variable_data = b"test set_variable_meta_data method.".to_vec();1922        assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));19231924        assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, variable_data);1925    });1926}19271928#[test]1929fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {1930    new_test_ext().execute_with(|| {1931        default_limits();19321933        let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);19341935        let origin1 = Origin::signed(1);19361937        let data = default_re_fungible_data();1938        create_test_item(1, &data.into());19391940        let variable_data = b"test set_variable_meta_data method.".to_vec();1941        assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()));19421943        assert_eq!(TemplateModule::refungible_item_id(collection_id, 1).variable_data, variable_data);1944    });1945}194619471948#[test]1949fn set_variable_meta_data_on_fungible_token_fails() {1950    new_test_ext().execute_with(|| {1951        default_limits();19521953        let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);19541955        let origin1 = Origin::signed(1);19561957        let data = default_fungible_data();1958        create_test_item(1, &data.into());19591960        let variable_data = b"test set_variable_meta_data method.".to_vec();1961        assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone()), Error::<Test>::CantStoreMetadataInFungibleTokens);1962    });1963}19641965#[test]1966fn set_variable_meta_data_on_nft_token_fails_for_big_data() {1967    new_test_ext().execute_with(|| {1968        assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1969            collection_numbers_limit: default_collection_numbers_limit(),1970            account_token_ownership_limit: 10,1971            collections_admins_limit: 5,1972            custom_data_limit: 10,1973            nft_sponsor_transfer_timeout: 15,1974            fungible_sponsor_transfer_timeout: 15,1975            refungible_sponsor_transfer_timeout: 15,          1976        }));19771978        let collection_id = create_test_collection(&CollectionMode::NFT, 1);19791980        let origin1 = Origin::signed(1);19811982        let data = default_nft_data();1983        create_test_item(1, &data.into());19841985        let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();1986        assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);1987    });1988}19891990#[test]1991fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {1992    new_test_ext().execute_with(|| {1993        assert_ok!(TemplateModule::set_chain_limits(RawOrigin::Root.into(), ChainLimits { 1994            collection_numbers_limit: default_collection_numbers_limit(),1995            account_token_ownership_limit: 10,1996            collections_admins_limit: 5,1997            custom_data_limit: 10,1998            nft_sponsor_transfer_timeout: 15,1999            fungible_sponsor_transfer_timeout: 15,2000            refungible_sponsor_transfer_timeout: 15,          2001        }));200220032004        let collection_id = create_test_collection(&CollectionMode::ReFungible(3), 1);20052006        let origin1 = Origin::signed(1);20072008        let data = default_re_fungible_data();2009        create_test_item(1, &data.into());20102011        let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();2012        assert_noop!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data), Error::<Test>::TokenVariableDataLimitExceeded);2013    });2014}
after · pallets/nft/src/tests.rs
1// 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}
modifiedtests/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",
addedtests/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);
+    });
+  });
+});
addedtests/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);
+    });
+
+  });
+
+});
modifiedtests/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');
 
modifiedtests/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'}});
   });
 });
modifiedtests/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);
   });
 });
modifiedtests/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);
   });
 });
addedtests/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;
+    });
+  });
+});
modifiedtests/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'}});
     });
   });
 });
modifiedtests/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);
   });
 
modifiedtests/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;
-      }*/
     });
   });
 });
modifiedtests/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
+}
addedtests/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;
+      }
+    });
+  });
+});
modifiedtests/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