git.delta.rocks / unique-network / refs/commits / b278b7e1c230

difftreelog

test(structure) extra nesting + properties refactoring

Fahrrader2022-05-13parent: #0baf86c.patch.diff
in: master

7 files changed

modifiedtests/src/createItem.test.tsdiffbeforeafterboth
--- a/tests/src/createItem.test.ts
+++ b/tests/src/createItem.test.ts
@@ -144,7 +144,6 @@
 
   it('User doesnt have editing rights', async () => {
     await usingApi(async api => {
-      const createMode = 'NFT';
       const newCollectionID = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});
       const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
 
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
before · tests/src/createMultipleItems.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {ApiPromise} from '@polkadot/api';18import {IKeyringPair} from '@polkadot/types/types';19import chai from 'chai';20import chaiAsPromised from 'chai-as-promised';21import privateKey from './substrate/privateKey';22import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync, executeTransaction} from './substrate/substrate-api';23import {24  createCollectionExpectSuccess,25  destroyCollectionExpectSuccess,26  getGenericResult,27  normalizeAccountId,28  setCollectionLimitsExpectSuccess,29  addCollectionAdminExpectSuccess,30  getBalance,31  getTokenOwner,32  getLastTokenId,33  getVariableMetadata,34  getConstMetadata,35  getCreatedCollectionCount,36  createCollectionWithPropsExpectSuccess,37  getCreateItemsResult,38} from './util/helpers';3940chai.use(chaiAsPromised);41const expect = chai.expect;4243describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {44  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {45    await usingApi(async (api: ApiPromise) => {46      const collectionId = await createCollectionExpectSuccess();47      const itemsListIndexBefore = await getLastTokenId(api, collectionId);48      expect(itemsListIndexBefore).to.be.equal(0);49      const alice = privateKey('//Alice');50      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},51        {Nft: {const_data: '0x32', variable_data: '0x32'}},52        {Nft: {const_data: '0x33', variable_data: '0x33'}}];53      const createMultipleItemsTx = api.tx.unique54        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);55      await submitTransactionAsync(alice, createMultipleItemsTx);56      const itemsListIndexAfter = await getLastTokenId(api, collectionId);57      expect(itemsListIndexAfter).to.be.equal(3);5859      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));60      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));61      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));6263      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);64      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);65      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);6667      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);68      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);69      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);70    });71  });7273  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {74    await usingApi(async (api: ApiPromise) => {75      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});76      const itemsListIndexBefore = await getLastTokenId(api, collectionId);77      expect(itemsListIndexBefore).to.be.equal(0);78      const alice = privateKey('//Alice');79      const args = [80        {Fungible: {value: 1}},81        {Fungible: {value: 2}},82        {Fungible: {value: 3}},83      ];84      const createMultipleItemsTx = api.tx.unique85        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);86      await submitTransactionAsync(alice, createMultipleItemsTx);87      const token1Data = await getBalance(api, collectionId, alice.address, 0);8889      expect(token1Data).to.be.equal(6n); // 1 + 2 + 390    });91  });9293  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {94    await usingApi(async (api: ApiPromise) => {95      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});96      const itemsListIndexBefore = await getLastTokenId(api, collectionId);97      expect(itemsListIndexBefore).to.be.equal(0);98      const alice = privateKey('//Alice');99      const args = [100        {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},101        {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},102        {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},103      ];104      const createMultipleItemsTx = api.tx.unique105        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);106      await submitTransactionAsync(alice, createMultipleItemsTx);107      const itemsListIndexAfter = await getLastTokenId(api, collectionId);108      expect(itemsListIndexAfter).to.be.equal(3);109110      expect(await getBalance(api, collectionId, alice.address, 1)).to.be.equal(1n);111      expect(await getBalance(api, collectionId, alice.address, 2)).to.be.equal(1n);112      expect(await getBalance(api, collectionId, alice.address, 3)).to.be.equal(1n);113114      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);115      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);116      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);117118      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);119      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);120      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);121    });122  });123124  it('Can mint amount of items equals to collection limits', async () => {125    await usingApi(async (api) => {126      const alice = privateKey('//Alice');127128      const collectionId = await createCollectionExpectSuccess();129      await setCollectionLimitsExpectSuccess(alice, collectionId, {130        tokenLimit: 2,131      });132      const args = [133        {NFT: {const_data: 'A', variable_data: 'A'}},134        {NFT: {const_data: 'B', variable_data: 'B'}},135      ];136      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);137      const events = await submitTransactionAsync(alice, createMultipleItemsTx);138      const result = getGenericResult(events);139      expect(result.success).to.be.true;140    });141  });142143  it('Create  0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {144    await usingApi(async (api: ApiPromise) => {145      const collectionId = await createCollectionExpectSuccess();146      const itemsListIndexBefore = await getLastTokenId(api, collectionId);147      expect(itemsListIndexBefore).to.be.equal(0);148      const alice = privateKey('//Alice');149      const bob = privateKey('//Bob');150      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},151        {Nft: {const_data: '0x32', variable_data: '0x32'}},152        {Nft: {const_data: '0x33', variable_data: '0x33'}}];153      const createMultipleItemsTx = api.tx.unique154        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);155      await submitTransactionAsync(alice, createMultipleItemsTx);156      const itemsListIndexAfter = await getLastTokenId(api, collectionId);157      expect(itemsListIndexAfter).to.be.equal(3);158159      await expect(executeTransaction(160        api, 161        alice, 162        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]), 163      )).to.not.be.rejected;164165      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));166      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));167      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));168169      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);170      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);171      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);172173      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);174      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);175      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);176    });177  });178179  it('Create  0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {180    await usingApi(async (api: ApiPromise) => {181      const collectionId = await createCollectionExpectSuccess();182      const itemsListIndexBefore = await getLastTokenId(api, collectionId);183      expect(itemsListIndexBefore).to.be.equal(0);184      const alice = privateKey('//Alice');185      const bob = privateKey('//Bob');186      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},187        {Nft: {const_data: '0x32', variable_data: '0x32'}},188        {Nft: {const_data: '0x33', variable_data: '0x33'}}];189      const createMultipleItemsTx = api.tx.unique190        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);191      await submitTransactionAsync(alice, createMultipleItemsTx);192      const itemsListIndexAfter = await getLastTokenId(api, collectionId);193      expect(itemsListIndexAfter).to.be.equal(3);194195      await expect(executeTransaction(196        api, 197        alice, 198        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]), 199      )).to.not.be.rejected;200201      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));202      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));203      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));204205      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);206      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);207      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);208209      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);210      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);211      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);212    });213  });214215  it('Create  0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {216    await usingApi(async (api: ApiPromise) => {217      const collectionId = await createCollectionExpectSuccess();218      const itemsListIndexBefore = await getLastTokenId(api, collectionId);219      expect(itemsListIndexBefore).to.be.equal(0);220      const alice = privateKey('//Alice');221      const bob = privateKey('//Bob');222      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},223        {Nft: {const_data: '0x32', variable_data: '0x32'}},224        {Nft: {const_data: '0x33', variable_data: '0x33'}}];225      const createMultipleItemsTx = api.tx.unique226        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);227      await submitTransactionAsync(alice, createMultipleItemsTx);228      const itemsListIndexAfter = await getLastTokenId(api, collectionId);229      expect(itemsListIndexAfter).to.be.equal(3);230231      await expect(executeTransaction(232        api, 233        alice, 234        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]), 235      )).to.not.be.rejected;236237      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));238      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));239      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));240241      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);242      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);243      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);244245      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);246      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);247      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);248    });249  });250});251252describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {253254  let alice: IKeyringPair;255  let bob: IKeyringPair;256257  before(async () => {258    await usingApi(async () => {259      alice = privateKey('//Alice');260      bob = privateKey('//Bob');261    });262  });263264  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {265    await usingApi(async (api: ApiPromise) => {266      const collectionId = await createCollectionExpectSuccess();267      const itemsListIndexBefore = await getLastTokenId(api, collectionId);268      expect(itemsListIndexBefore).to.be.equal(0);269      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);270      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},271        {Nft: {const_data: '0x32', variable_data: '0x32'}},272        {Nft: {const_data: '0x33', variable_data: '0x33'}}];273      const createMultipleItemsTx = api.tx.unique274        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);275      await submitTransactionAsync(bob, createMultipleItemsTx);276      const itemsListIndexAfter = await getLastTokenId(api, collectionId);277      expect(itemsListIndexAfter).to.be.equal(3);278279      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(bob.address));280      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(bob.address));281      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(bob.address));282283      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);284      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);285      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);286287      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);288      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);289      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);290    });291  });292293  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {294    await usingApi(async (api: ApiPromise) => {295      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});296      const itemsListIndexBefore = await getLastTokenId(api, collectionId);297      expect(itemsListIndexBefore).to.be.equal(0);298      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);299      const args = [300        {Fungible: {value: 1}},301        {Fungible: {value: 2}},302        {Fungible: {value: 3}},303      ];304      const createMultipleItemsTx = api.tx.unique305        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);306      await submitTransactionAsync(bob, createMultipleItemsTx);307      const token1Data = await getBalance(api, collectionId, bob.address, 0);308309      expect(token1Data).to.be.equal(6n); // 1 + 2 + 3310    });311  });312313  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {314    await usingApi(async (api: ApiPromise) => {315      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});316      const itemsListIndexBefore = await getLastTokenId(api, collectionId);317      expect(itemsListIndexBefore).to.be.equal(0);318      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);319      const args = [320        {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},321        {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},322        {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},323      ];324      const createMultipleItemsTx = api.tx.unique325        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);326      await submitTransactionAsync(bob, createMultipleItemsTx);327      const itemsListIndexAfter = await getLastTokenId(api, collectionId);328      expect(itemsListIndexAfter).to.be.equal(3);329330      expect(await getBalance(api, collectionId, bob.address, 1)).to.be.equal(1n);331      expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(1n);332      expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(1n);333334      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);335      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);336      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);337338      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);339      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);340      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);341    });342  });343});344345describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {346347  let alice: IKeyringPair;348  let bob: IKeyringPair;349350  before(async () => {351    await usingApi(async () => {352      alice = privateKey('//Alice');353      bob = privateKey('//Bob');354    });355  });356357  it('Regular user cannot create items in active NFT collection', async () => {358    await usingApi(async (api: ApiPromise) => {359      const collectionId = await createCollectionExpectSuccess();360      const itemsListIndexBefore = await getLastTokenId(api, collectionId);361      expect(itemsListIndexBefore).to.be.equal(0);362      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},363        {Nft: {const_data: '0x32', variable_data: '0x32'}},364        {Nft: {const_data: '0x33', variable_data: '0x33'}}];365      const createMultipleItemsTx = api.tx.unique366        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);367      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;368    });369  });370371  it('Regular user cannot create items in active Fungible collection', async () => {372    await usingApi(async (api: ApiPromise) => {373      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});374      const itemsListIndexBefore = await getLastTokenId(api, collectionId);375      expect(itemsListIndexBefore).to.be.equal(0);376      const args = [377        {Fungible: {value: 1}},378        {Fungible: {value: 2}},379        {Fungible: {value: 3}},380      ];381      const createMultipleItemsTx = api.tx.unique382        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);383      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;384    });385  });386387  it('Regular user cannot create items in active ReFungible collection', async () => {388    await usingApi(async (api: ApiPromise) => {389      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});390      const itemsListIndexBefore = await getLastTokenId(api, collectionId);391      expect(itemsListIndexBefore).to.be.equal(0);392      const args = [393        {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},394        {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},395        {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},396      ];397      const createMultipleItemsTx = api.tx.unique398        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);399      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;400    });401  });402403  it('Create token in not existing collection', async () => {404    await usingApi(async (api: ApiPromise) => {405      const collectionId = await getCreatedCollectionCount(api) + 1;406      const createMultipleItemsTx = api.tx.unique407        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'NFT', 'NFT']);408      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;409    });410  });411412  it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {413    await usingApi(async (api: ApiPromise) => {414      // NFT415      const collectionId = await createCollectionExpectSuccess();416      const alice = privateKey('//Alice');417      const args = [418        {NFT: {const_data: 'A'.repeat(2049), variable_data: 'A'.repeat(2049)}},419        {NFT: {const_data: 'B'.repeat(2049), variable_data: 'B'.repeat(2049)}},420        {NFT: {const_data: 'C'.repeat(2049), variable_data: 'C'.repeat(2049)}},421      ];422      const createMultipleItemsTx = api.tx.unique423        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);424      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;425426      // ReFungible427      const collectionIdReFungible =428        await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});429      const argsReFungible = [430        {ReFungible: ['1'.repeat(2049), '1'.repeat(2049), 10]},431        {ReFungible: ['2'.repeat(2049), '2'.repeat(2049), 10]},432        {ReFungible: ['3'.repeat(2049), '3'.repeat(2049), 10]},433      ];434      const createMultipleItemsTxFungible = api.tx.unique435        .createMultipleItems(collectionIdReFungible, normalizeAccountId(alice.address), argsReFungible);436      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTxFungible)).to.be.rejected;437    });438  });439440  it('Create tokens with different types', async () => {441    await usingApi(async (api: ApiPromise) => {442      const collectionId = await createCollectionExpectSuccess();443      const createMultipleItemsTx = api.tx.unique444        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);445      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;446      // garbage collection :-D447      await destroyCollectionExpectSuccess(collectionId);448    });449  });450451  it('Create tokens with different data limits <> maximum data limit', async () => {452    await usingApi(async (api: ApiPromise) => {453      const collectionId = await createCollectionExpectSuccess();454      const args = [455        {NFT: {const_data: 'A', variable_data: 'A'}},456        {NFT: {const_data: 'B', variable_data: 'B'.repeat(2049)}},457        {NFT: {const_data: 'C'.repeat(2049), variable_data: 'C'}},458      ];459      const createMultipleItemsTx = await api.tx.unique460        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);461      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;462    });463  });464465  it('Fails when minting tokens exceeds collectionLimits amount', async () => {466    await usingApi(async (api) => {467468      const collectionId = await createCollectionExpectSuccess();469      await setCollectionLimitsExpectSuccess(alice, collectionId, {470        tokenLimit: 1,471      });472      const args = [473        {NFT: {const_data: 'A', variable_data: 'A'}},474        {NFT: {const_data: 'B', variable_data: 'B'}},475      ];476      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);477      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;478    });479  });480481  it('No editing rights', async () => {482    await usingApi(async (api: ApiPromise) => {483      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],484        propPerm:   [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});485      const itemsListIndexBefore = await getLastTokenId(api, collectionId);486      expect(itemsListIndexBefore).to.be.equal(0);487      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);488      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},489        {Nft: {const_data: '0x32', variable_data: '0x32'}},490        {Nft: {const_data: '0x33', variable_data: '0x33'}}];491      492      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);493494      const events = await submitTransactionAsync(alice, createMultipleItemsTx);495      const result = getCreateItemsResult(events);496497      for (const elem of result) {498        await expect(executeTransaction(499          api, 500          bob, 501          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 502        )).to.be.rejected;503      }504505      // await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;506    });507  });508509  it('User doesnt have editing rights', async () => {510    await usingApi(async (api: ApiPromise) => {511      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],512        propPerm:   [{key: 'key1', mutable: false, collectionAdmin: false, tokenOwner: false}]});513      const itemsListIndexBefore = await getLastTokenId(api, collectionId);514      expect(itemsListIndexBefore).to.be.equal(0);515      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);516      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},517        {Nft: {const_data: '0x32', variable_data: '0x32'}},518        {Nft: {const_data: '0x33', variable_data: '0x33'}}];519      520      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);521522      const events = await submitTransactionAsync(alice, createMultipleItemsTx);523      const result = getCreateItemsResult(events);524525      for (const elem of result) {526        await expect(executeTransaction(527          api, 528          bob, 529          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 530        )).to.be.rejected;531      }532    });533  });534535  it('Adding property without access rights', async () => {536    await usingApi(async (api: ApiPromise) => {537      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}]});538      const itemsListIndexBefore = await getLastTokenId(api, collectionId);539      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);540      expect(itemsListIndexBefore).to.be.equal(0);541      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},542        {Nft: {const_data: '0x32', variable_data: '0x32'}},543        {Nft: {const_data: '0x33', variable_data: '0x33'}}];544      545      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);546547      const events = await submitTransactionAsync(alice, createMultipleItemsTx);548      const result = getCreateItemsResult(events);549550      for (const elem of result) {551        await expect(executeTransaction(552          api, 553          bob, 554          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 555        )).to.be.rejected;556      }557    });558  });559560  it('Adding more than 64 prps', async () => {561    await usingApi(async (api: ApiPromise) => {562      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],563        propPerm:   [{key: 'key1', mutable: true, collectionAdmin: true, tokenOwner: false}]});564      const itemsListIndexBefore = await getLastTokenId(api, collectionId);565      expect(itemsListIndexBefore).to.be.equal(0);566      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);567568      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},569        {Nft: {const_data: '0x32', variable_data: '0x32'}},570        {Nft: {const_data: '0x33', variable_data: '0x33'}}];571      572      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);573      const events = await submitTransactionAsync(alice, createMultipleItemsTx);574575      const result = getCreateItemsResult(events);576      577      const prps = [];578      579      for (let i = 0; i < 65; i++) {580        prps.push({key: `key${i}`, value: `value${i}`});581      }582583      await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collectionId, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);584      585      for (const elem of result) {586        await expect(executeTransaction(587          api, 588          bob, 589          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps), 590        )).to.be.rejected;591      }592    });593  });594595  it('Trying to add bigger property than allowed', async () => {596    await usingApi(async (api: ApiPromise) => {597      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],598        propPerm:   [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});599      const itemsListIndexBefore = await getLastTokenId(api, collectionId);600      expect(itemsListIndexBefore).to.be.equal(0);601      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},602        {Nft: {const_data: '0x32', variable_data: '0x32'}},603        {Nft: {const_data: '0x33', variable_data: '0x33'}}];604      605      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);606607      const events = await submitTransactionAsync(alice, createMultipleItemsTx);608      const result = getCreateItemsResult(events);609610611      await expect(executeTransaction(api, alice, api.tx.unique.setCollectionProperties(collectionId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]))).to.be.rejectedWith(/common\.NoSpaceForProperty/);612613      for (const elem of result) {614        await expect(executeTransaction(615          api, 616          bob, 617          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]), 618        )).to.be.rejected;619      }620    });621  });622});
after · tests/src/createMultipleItems.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {ApiPromise} from '@polkadot/api';18import {IKeyringPair} from '@polkadot/types/types';19import chai from 'chai';20import chaiAsPromised from 'chai-as-promised';21import privateKey from './substrate/privateKey';22import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync, executeTransaction} from './substrate/substrate-api';23import {24  createCollectionExpectSuccess,25  destroyCollectionExpectSuccess,26  getGenericResult,27  normalizeAccountId,28  setCollectionLimitsExpectSuccess,29  addCollectionAdminExpectSuccess,30  getBalance,31  getTokenOwner,32  getLastTokenId,33  getVariableMetadata,34  getConstMetadata,35  getCreatedCollectionCount,36  createCollectionWithPropsExpectSuccess,37  getCreateItemsResult,38} from './util/helpers';3940chai.use(chaiAsPromised);41const expect = chai.expect;4243describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {44  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {45    await usingApi(async (api: ApiPromise) => {46      const collectionId = await createCollectionExpectSuccess();47      const itemsListIndexBefore = await getLastTokenId(api, collectionId);48      expect(itemsListIndexBefore).to.be.equal(0);49      const alice = privateKey('//Alice');50      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},51        {Nft: {const_data: '0x32', variable_data: '0x32'}},52        {Nft: {const_data: '0x33', variable_data: '0x33'}}];53      const createMultipleItemsTx = api.tx.unique54        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);55      await submitTransactionAsync(alice, createMultipleItemsTx);56      const itemsListIndexAfter = await getLastTokenId(api, collectionId);57      expect(itemsListIndexAfter).to.be.equal(3);5859      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));60      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));61      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));6263      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);64      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);65      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);6667      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);68      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);69      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);70    });71  });7273  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {74    await usingApi(async (api: ApiPromise) => {75      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});76      const itemsListIndexBefore = await getLastTokenId(api, collectionId);77      expect(itemsListIndexBefore).to.be.equal(0);78      const alice = privateKey('//Alice');79      const args = [80        {Fungible: {value: 1}},81        {Fungible: {value: 2}},82        {Fungible: {value: 3}},83      ];84      const createMultipleItemsTx = api.tx.unique85        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);86      await submitTransactionAsync(alice, createMultipleItemsTx);87      const token1Data = await getBalance(api, collectionId, alice.address, 0);8889      expect(token1Data).to.be.equal(6n); // 1 + 2 + 390    });91  });9293  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {94    await usingApi(async (api: ApiPromise) => {95      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});96      const itemsListIndexBefore = await getLastTokenId(api, collectionId);97      expect(itemsListIndexBefore).to.be.equal(0);98      const alice = privateKey('//Alice');99      const args = [100        {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},101        {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},102        {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},103      ];104      const createMultipleItemsTx = api.tx.unique105        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);106      await submitTransactionAsync(alice, createMultipleItemsTx);107      const itemsListIndexAfter = await getLastTokenId(api, collectionId);108      expect(itemsListIndexAfter).to.be.equal(3);109110      expect(await getBalance(api, collectionId, alice.address, 1)).to.be.equal(1n);111      expect(await getBalance(api, collectionId, alice.address, 2)).to.be.equal(1n);112      expect(await getBalance(api, collectionId, alice.address, 3)).to.be.equal(1n);113114      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);115      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);116      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);117118      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);119      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);120      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);121    });122  });123124  it('Can mint amount of items equals to collection limits', async () => {125    await usingApi(async (api) => {126      const alice = privateKey('//Alice');127128      const collectionId = await createCollectionExpectSuccess();129      await setCollectionLimitsExpectSuccess(alice, collectionId, {130        tokenLimit: 2,131      });132      const args = [133        {NFT: {const_data: 'A', variable_data: 'A'}},134        {NFT: {const_data: 'B', variable_data: 'B'}},135      ];136      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);137      const events = await submitTransactionAsync(alice, createMultipleItemsTx);138      const result = getGenericResult(events);139      expect(result.success).to.be.true;140    });141  });142143  it('Create  0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {144    await usingApi(async (api: ApiPromise) => {145      const collectionId = await createCollectionExpectSuccess();146      const itemsListIndexBefore = await getLastTokenId(api, collectionId);147      expect(itemsListIndexBefore).to.be.equal(0);148      const alice = privateKey('//Alice');149      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},150        {Nft: {const_data: '0x32', variable_data: '0x32'}},151        {Nft: {const_data: '0x33', variable_data: '0x33'}}];152      const createMultipleItemsTx = api.tx.unique153        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);154      await submitTransactionAsync(alice, createMultipleItemsTx);155      const itemsListIndexAfter = await getLastTokenId(api, collectionId);156      expect(itemsListIndexAfter).to.be.equal(3);157158      await expect(executeTransaction(159        api, 160        alice, 161        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]), 162      )).to.not.be.rejected;163164      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));165      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));166      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));167168      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);169      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);170      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);171172      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);173      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);174      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);175    });176  });177178  it('Create  0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {179    await usingApi(async (api: ApiPromise) => {180      const collectionId = await createCollectionExpectSuccess();181      const itemsListIndexBefore = await getLastTokenId(api, collectionId);182      expect(itemsListIndexBefore).to.be.equal(0);183      const alice = privateKey('//Alice');184      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},185        {Nft: {const_data: '0x32', variable_data: '0x32'}},186        {Nft: {const_data: '0x33', variable_data: '0x33'}}];187      const createMultipleItemsTx = api.tx.unique188        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);189      await submitTransactionAsync(alice, createMultipleItemsTx);190      const itemsListIndexAfter = await getLastTokenId(api, collectionId);191      expect(itemsListIndexAfter).to.be.equal(3);192193      await expect(executeTransaction(194        api, 195        alice, 196        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]), 197      )).to.not.be.rejected;198199      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));200      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));201      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));202203      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);204      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);205      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);206207      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);208      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);209      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);210    });211  });212213  it('Create  0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {214    await usingApi(async (api: ApiPromise) => {215      const collectionId = await createCollectionExpectSuccess();216      const itemsListIndexBefore = await getLastTokenId(api, collectionId);217      expect(itemsListIndexBefore).to.be.equal(0);218      const alice = privateKey('//Alice');219      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},220        {Nft: {const_data: '0x32', variable_data: '0x32'}},221        {Nft: {const_data: '0x33', variable_data: '0x33'}}];222      const createMultipleItemsTx = api.tx.unique223        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);224      await submitTransactionAsync(alice, createMultipleItemsTx);225      const itemsListIndexAfter = await getLastTokenId(api, collectionId);226      expect(itemsListIndexAfter).to.be.equal(3);227228      await expect(executeTransaction(229        api, 230        alice, 231        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]), 232      )).to.not.be.rejected;233234      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));235      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));236      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));237238      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);239      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);240      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);241242      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);243      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);244      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);245    });246  });247});248249describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {250251  let alice: IKeyringPair;252  let bob: IKeyringPair;253254  before(async () => {255    await usingApi(async () => {256      alice = privateKey('//Alice');257      bob = privateKey('//Bob');258    });259  });260261  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {262    await usingApi(async (api: ApiPromise) => {263      const collectionId = await createCollectionExpectSuccess();264      const itemsListIndexBefore = await getLastTokenId(api, collectionId);265      expect(itemsListIndexBefore).to.be.equal(0);266      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);267      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},268        {Nft: {const_data: '0x32', variable_data: '0x32'}},269        {Nft: {const_data: '0x33', variable_data: '0x33'}}];270      const createMultipleItemsTx = api.tx.unique271        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);272      await submitTransactionAsync(bob, createMultipleItemsTx);273      const itemsListIndexAfter = await getLastTokenId(api, collectionId);274      expect(itemsListIndexAfter).to.be.equal(3);275276      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(bob.address));277      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(bob.address));278      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(bob.address));279280      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);281      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);282      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);283284      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);285      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);286      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);287    });288  });289290  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {291    await usingApi(async (api: ApiPromise) => {292      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});293      const itemsListIndexBefore = await getLastTokenId(api, collectionId);294      expect(itemsListIndexBefore).to.be.equal(0);295      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);296      const args = [297        {Fungible: {value: 1}},298        {Fungible: {value: 2}},299        {Fungible: {value: 3}},300      ];301      const createMultipleItemsTx = api.tx.unique302        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);303      await submitTransactionAsync(bob, createMultipleItemsTx);304      const token1Data = await getBalance(api, collectionId, bob.address, 0);305306      expect(token1Data).to.be.equal(6n); // 1 + 2 + 3307    });308  });309310  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {311    await usingApi(async (api: ApiPromise) => {312      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});313      const itemsListIndexBefore = await getLastTokenId(api, collectionId);314      expect(itemsListIndexBefore).to.be.equal(0);315      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);316      const args = [317        {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},318        {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},319        {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},320      ];321      const createMultipleItemsTx = api.tx.unique322        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);323      await submitTransactionAsync(bob, createMultipleItemsTx);324      const itemsListIndexAfter = await getLastTokenId(api, collectionId);325      expect(itemsListIndexAfter).to.be.equal(3);326327      expect(await getBalance(api, collectionId, bob.address, 1)).to.be.equal(1n);328      expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(1n);329      expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(1n);330331      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);332      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);333      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);334335      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);336      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);337      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);338    });339  });340});341342describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {343344  let alice: IKeyringPair;345  let bob: IKeyringPair;346347  before(async () => {348    await usingApi(async () => {349      alice = privateKey('//Alice');350      bob = privateKey('//Bob');351    });352  });353354  it('Regular user cannot create items in active NFT collection', async () => {355    await usingApi(async (api: ApiPromise) => {356      const collectionId = await createCollectionExpectSuccess();357      const itemsListIndexBefore = await getLastTokenId(api, collectionId);358      expect(itemsListIndexBefore).to.be.equal(0);359      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},360        {Nft: {const_data: '0x32', variable_data: '0x32'}},361        {Nft: {const_data: '0x33', variable_data: '0x33'}}];362      const createMultipleItemsTx = api.tx.unique363        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);364      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;365    });366  });367368  it('Regular user cannot create items in active Fungible collection', async () => {369    await usingApi(async (api: ApiPromise) => {370      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});371      const itemsListIndexBefore = await getLastTokenId(api, collectionId);372      expect(itemsListIndexBefore).to.be.equal(0);373      const args = [374        {Fungible: {value: 1}},375        {Fungible: {value: 2}},376        {Fungible: {value: 3}},377      ];378      const createMultipleItemsTx = api.tx.unique379        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);380      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;381    });382  });383384  it('Regular user cannot create items in active ReFungible collection', async () => {385    await usingApi(async (api: ApiPromise) => {386      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});387      const itemsListIndexBefore = await getLastTokenId(api, collectionId);388      expect(itemsListIndexBefore).to.be.equal(0);389      const args = [390        {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},391        {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},392        {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},393      ];394      const createMultipleItemsTx = api.tx.unique395        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);396      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;397    });398  });399400  it('Create token in not existing collection', async () => {401    await usingApi(async (api: ApiPromise) => {402      const collectionId = await getCreatedCollectionCount(api) + 1;403      const createMultipleItemsTx = api.tx.unique404        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'NFT', 'NFT']);405      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;406    });407  });408409  it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {410    await usingApi(async (api: ApiPromise) => {411      // NFT412      const collectionId = await createCollectionExpectSuccess();413      const alice = privateKey('//Alice');414      const args = [415        {NFT: {const_data: 'A'.repeat(2049), variable_data: 'A'.repeat(2049)}},416        {NFT: {const_data: 'B'.repeat(2049), variable_data: 'B'.repeat(2049)}},417        {NFT: {const_data: 'C'.repeat(2049), variable_data: 'C'.repeat(2049)}},418      ];419      const createMultipleItemsTx = api.tx.unique420        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);421      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;422423      // ReFungible424      const collectionIdReFungible =425        await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});426      const argsReFungible = [427        {ReFungible: ['1'.repeat(2049), '1'.repeat(2049), 10]},428        {ReFungible: ['2'.repeat(2049), '2'.repeat(2049), 10]},429        {ReFungible: ['3'.repeat(2049), '3'.repeat(2049), 10]},430      ];431      const createMultipleItemsTxFungible = api.tx.unique432        .createMultipleItems(collectionIdReFungible, normalizeAccountId(alice.address), argsReFungible);433      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTxFungible)).to.be.rejected;434    });435  });436437  it('Create tokens with different types', async () => {438    await usingApi(async (api: ApiPromise) => {439      const collectionId = await createCollectionExpectSuccess();440      const createMultipleItemsTx = api.tx.unique441        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);442      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;443      // garbage collection :-D444      await destroyCollectionExpectSuccess(collectionId);445    });446  });447448  it('Create tokens with different data limits <> maximum data limit', async () => {449    await usingApi(async (api: ApiPromise) => {450      const collectionId = await createCollectionExpectSuccess();451      const args = [452        {NFT: {const_data: 'A', variable_data: 'A'}},453        {NFT: {const_data: 'B', variable_data: 'B'.repeat(2049)}},454        {NFT: {const_data: 'C'.repeat(2049), variable_data: 'C'}},455      ];456      const createMultipleItemsTx = await api.tx.unique457        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);458      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;459    });460  });461462  it('Fails when minting tokens exceeds collectionLimits amount', async () => {463    await usingApi(async (api) => {464465      const collectionId = await createCollectionExpectSuccess();466      await setCollectionLimitsExpectSuccess(alice, collectionId, {467        tokenLimit: 1,468      });469      const args = [470        {NFT: {const_data: 'A', variable_data: 'A'}},471        {NFT: {const_data: 'B', variable_data: 'B'}},472      ];473      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);474      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;475    });476  });477478  it('No editing rights', async () => {479    await usingApi(async (api: ApiPromise) => {480      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],481        propPerm:   [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});482      const itemsListIndexBefore = await getLastTokenId(api, collectionId);483      expect(itemsListIndexBefore).to.be.equal(0);484      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);485      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},486        {Nft: {const_data: '0x32', variable_data: '0x32'}},487        {Nft: {const_data: '0x33', variable_data: '0x33'}}];488      489      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);490491      const events = await submitTransactionAsync(alice, createMultipleItemsTx);492      const result = getCreateItemsResult(events);493494      for (const elem of result) {495        await expect(executeTransaction(496          api, 497          bob, 498          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 499        )).to.be.rejected;500      }501502      // await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;503    });504  });505506  it('User doesnt have editing rights', async () => {507    await usingApi(async (api: ApiPromise) => {508      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],509        propPerm:   [{key: 'key1', mutable: false, collectionAdmin: false, tokenOwner: false}]});510      const itemsListIndexBefore = await getLastTokenId(api, collectionId);511      expect(itemsListIndexBefore).to.be.equal(0);512      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);513      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},514        {Nft: {const_data: '0x32', variable_data: '0x32'}},515        {Nft: {const_data: '0x33', variable_data: '0x33'}}];516      517      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);518519      const events = await submitTransactionAsync(alice, createMultipleItemsTx);520      const result = getCreateItemsResult(events);521522      for (const elem of result) {523        await expect(executeTransaction(524          api, 525          bob, 526          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 527        )).to.be.rejected;528      }529    });530  });531532  it('Adding property without access rights', async () => {533    await usingApi(async (api: ApiPromise) => {534      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}]});535      const itemsListIndexBefore = await getLastTokenId(api, collectionId);536      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);537      expect(itemsListIndexBefore).to.be.equal(0);538      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},539        {Nft: {const_data: '0x32', variable_data: '0x32'}},540        {Nft: {const_data: '0x33', variable_data: '0x33'}}];541      542      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);543544      const events = await submitTransactionAsync(alice, createMultipleItemsTx);545      const result = getCreateItemsResult(events);546547      for (const elem of result) {548        await expect(executeTransaction(549          api, 550          bob, 551          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 552        )).to.be.rejected;553      }554    });555  });556557  it('Adding more than 64 prps', async () => {558    await usingApi(async (api: ApiPromise) => {559      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],560        propPerm:   [{key: 'key1', mutable: true, collectionAdmin: true, tokenOwner: false}]});561      const itemsListIndexBefore = await getLastTokenId(api, collectionId);562      expect(itemsListIndexBefore).to.be.equal(0);563      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);564565      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},566        {Nft: {const_data: '0x32', variable_data: '0x32'}},567        {Nft: {const_data: '0x33', variable_data: '0x33'}}];568      569      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);570      const events = await submitTransactionAsync(alice, createMultipleItemsTx);571572      const result = getCreateItemsResult(events);573      574      const prps = [];575      576      for (let i = 0; i < 65; i++) {577        prps.push({key: `key${i}`, value: `value${i}`});578      }579580      await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collectionId, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);581      582      for (const elem of result) {583        await expect(executeTransaction(584          api, 585          bob, 586          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps), 587        )).to.be.rejected;588      }589    });590  });591592  it('Trying to add bigger property than allowed', async () => {593    await usingApi(async (api: ApiPromise) => {594      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],595        propPerm:   [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});596      const itemsListIndexBefore = await getLastTokenId(api, collectionId);597      expect(itemsListIndexBefore).to.be.equal(0);598      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},599        {Nft: {const_data: '0x32', variable_data: '0x32'}},600        {Nft: {const_data: '0x33', variable_data: '0x33'}}];601      602      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);603604      const events = await submitTransactionAsync(alice, createMultipleItemsTx);605      const result = getCreateItemsResult(events);606607608      await expect(executeTransaction(api, alice, api.tx.unique.setCollectionProperties(collectionId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]))).to.be.rejectedWith(/common\.NoSpaceForProperty/);609610      for (const elem of result) {611        await expect(executeTransaction(612          api, 613          bob, 614          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]), 615        )).to.be.rejected;616      }617    });618  });619});
modifiedtests/src/nesting/migration-check.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/migration-check.test.ts
+++ b/tests/src/nesting/migration-check.test.ts
@@ -8,8 +8,8 @@
 // Used for polkadot-launch signalling
 import find from 'find-process';
 
-// todo skip
-describe('Migration testing for pallet-common', () => {
+// todo un-skip for migrations
+describe.skip('Migration testing for pallet-common', () => {
   let alice: IKeyringPair;
 
   before(async() => {
@@ -63,16 +63,33 @@
     });
 
     // And wait for the parachain upgrade
-    while (newVersion == oldVersion! && connectionFailCounter < 2) {
-      try {
-        await usingApi(async api => {
-          await waitNewBlocks(api);
-          newVersion = (api.consts.system.version.toJSON() as any).specVersion;
-        });
-      } catch (_) {
-        connectionFailCounter++;
-        console.log(`Still waiting for the parachain upgrade from ${oldVersion!}...`);
-        await new Promise(resolve => setTimeout(resolve, 12000));
+    {
+      // Catch warnings like 'RPC methods not decorated' and keep the 'waiting' message in front
+      const stdlog = console.warn.bind(console);
+      let warnCount = 0;
+      console.warn = function(...args){
+        if (arguments.length <= 2 || !args[2].includes('RPC methods not decorated')) {
+          warnCount++;
+          stdlog.apply(console, args as any);
+        }
+      };
+
+      let oldWarnCount = 0;
+      while (newVersion == oldVersion! && connectionFailCounter < 2) {
+        try {
+          await usingApi(async api => {
+            await waitNewBlocks(api);
+            newVersion = (api.consts.system.version.toJSON() as any).specVersion;
+            if (warnCount > oldWarnCount) {
+              console.log(`Still waiting for the parachain upgrade from ${oldVersion!}...`);
+              oldWarnCount = warnCount;
+            }
+            await new Promise(resolve => setTimeout(resolve, 6000));
+          });
+        } catch (_) {
+          connectionFailCounter++;
+          await new Promise(resolve => setTimeout(resolve, 12000));
+        }
       }
     }
 
modifiedtests/src/nesting/nest.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/nest.test.ts
+++ b/tests/src/nesting/nest.test.ts
@@ -9,8 +9,7 @@
   enableAllowListExpectSuccess,
   enablePublicMintingExpectSuccess,
   getTokenOwner, 
-  getTopmostTokenOwner, 
-  normalizeAccountId, 
+  getTopmostTokenOwner,
   setCollectionLimitsExpectSuccess, 
   transferExpectFailure, 
   transferExpectSuccess, 
@@ -23,7 +22,7 @@
 
 describe('Integration Test: Nesting', () => {
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
     });
@@ -196,7 +195,7 @@
 
 describe('Negative Test: Nesting', async() => {
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
     });
@@ -212,14 +211,11 @@
       const nestedToken1 = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});
       const nestedToken2 = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, nestedToken1)});
       // The nesting depth is limited by 2
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.createItem(
-          collection, 
-          {Ethereum: tokenIdToAddress(collection, nestedToken2)}, 
+      await expect(executeTransaction(api, alice, api.tx.unique.createItem(
+        collection, 
+        {Ethereum: tokenIdToAddress(collection, nestedToken2)}, 
           {nft: {const_data: [], variable_data: []}} as any,
-        ),
-      ), 'while creating nested token').to.be.rejectedWith(/^structure\.DepthLimit$/); // OuroborosDetected?
+      )), 'while creating nested token').to.be.rejectedWith(/^structure\.DepthLimit$/);
 
       expect(await getTopmostTokenOwner(api, collection, nestedToken2)).to.be.deep.equal({Substrate: alice.address});
     });
@@ -234,24 +230,16 @@
       const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');
 
       // Try to create a nested token
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.createItem(
-          collection, 
-          {Ethereum: tokenIdToAddress(collection, targetToken)}, 
+      await expect(executeTransaction(api, alice, api.tx.unique.createItem(
+        collection, 
+        {Ethereum: tokenIdToAddress(collection, targetToken)}, 
           {nft: {const_data: [], variable_data: []}} as any,
-        ),
-      ), 'while creating nested token').to.be.rejectedWith(/^common\.NestingIsDisabled$/);
+      )), 'while creating nested token').to.be.rejectedWith(/^common\.NestingIsDisabled$/);
 
       // Create a token to be nested
       const newToken = await createItemExpectSuccess(alice, collection, 'NFT');
       // Try to nest
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.transfer(
-          normalizeAccountId({Ethereum: tokenIdToAddress(collection, targetToken)}), collection, newToken, 1,
-        ),
-      ), 'while nesting new token').to.be.rejectedWith(/common\.NestingIsDisabled/); // todo to.be.rejected for all
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collection, targetToken)}, collection, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.NestingIsDisabled/);
       expect(await getTopmostTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});
       expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});
     });
@@ -270,23 +258,15 @@
       const targetToken = await createItemExpectSuccess(bob, collection, 'NFT');
 
       // Try to create a nested token in the wrong collection
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.createItem(
-          collection, 
-          {Ethereum: tokenIdToAddress(collection, targetToken)}, 
+      await expect(executeTransaction(api, alice, api.tx.unique.createItem(
+        collection, 
+        {Ethereum: tokenIdToAddress(collection, targetToken)}, 
           {nft: {const_data: [], variable_data: []}} as any,
-        ),
-      ), 'while creating nested token').to.be.rejectedWith(/structure\.DepthLimit/); // todo NestingIsDisabled?
+      )), 'while creating nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
 
       // Try to create and nest a token in the wrong collection
       const newToken = await createItemExpectSuccess(alice, collection, 'NFT');
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.transfer(
-          normalizeAccountId({Ethereum: tokenIdToAddress(collection, targetToken)}), collection, newToken, 1,
-        ),
-      ), 'while nesting new token').to.be.rejectedWith(/common\.AddressNotInAllowlist/);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collection, targetToken)}, collection, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.AddressNotInAllowlist/);
       expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});
     });
   });
@@ -304,23 +284,15 @@
       const targetToken = await createItemExpectSuccess(bob, collection, 'NFT');
 
       // Try to create a nested token in the wrong collection
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.createItem(
-          collection, 
-          {Ethereum: tokenIdToAddress(collection, targetToken)}, 
+      await expect(executeTransaction(api, alice, api.tx.unique.createItem(
+        collection, 
+        {Ethereum: tokenIdToAddress(collection, targetToken)}, 
           {nft: {const_data: [], variable_data: []}} as any,
-        ),
-      ), 'while creating nested token').to.be.rejectedWith(/structure\.DepthLimit/);
+      )), 'while creating nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
 
       // Try to create and nest a token in the wrong collection
       const newToken = await createItemExpectSuccess(alice, collection, 'NFT');
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.transfer(
-          normalizeAccountId({Ethereum: tokenIdToAddress(collection, targetToken)}), collection, newToken, 1,
-        ),
-      ), 'while nesting new token').to.be.rejectedWith(/common\.AddressNotInAllowlist/);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collection, targetToken)}, collection, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.AddressNotInAllowlist/);
       expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});
     });
   });
@@ -334,23 +306,15 @@
       const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');
 
       // Try to create a nested token in the wrong collection
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.createItem(
-          collection, 
-          {Ethereum: tokenIdToAddress(collection, targetToken)}, 
+      await expect(executeTransaction(api, alice, api.tx.unique.createItem(
+        collection, 
+        {Ethereum: tokenIdToAddress(collection, targetToken)}, 
           {nft: {const_data: [], variable_data: []}} as any,
-        ),
-      ), 'while creating nested token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);
+      )), 'while creating nested token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);
 
       // Try to create and nest a token in the wrong collection
       const newToken = await createItemExpectSuccess(alice, collection, 'NFT');
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.transfer(
-          normalizeAccountId({Ethereum: tokenIdToAddress(collection, targetToken)}), collection, newToken, 1,
-        ),
-      ), 'while nesting new token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collection, targetToken)}, collection, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);
       expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});
     });
   });
@@ -367,24 +331,21 @@
       const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
 
       // Try to create a nested token
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.createItem(
-          collectionFT, 
-          targetAddress, 
-          {Fungible: {Value: 10}},
-        )
-      ), 'while creating nested token').to.be.rejectedWith(/^common\.NestingIsDisabled$/);
-
+      await expect(executeTransaction(api, alice, api.tx.unique.createItem(
+        collectionFT, 
+        targetAddress, 
+        {Fungible: {Value: 10}},
+      )), 'while creating nested token').to.be.rejectedWith(/^common\.NestingIsDisabled$/);
+      
       // Create a token to be nested
       const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');
       // Try to nest
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.transfer(
-          normalizeAccountId({Ethereum: tokenIdToAddress(collectionFT, targetToken)}), collectionFT, newToken, 1,
-        ),
-      ), 'while nesting new token').to.be.rejectedWith(/fungible\.FungibleDisallowsNesting/);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.NestingIsDisabled/);
+
+      // Create another token to be nested
+      const newToken2 = await createItemExpectSuccess(alice, collectionFT, 'Fungible');
+      // Try to nest inside a fungible token
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collectionFT, newToken)}, collectionFT, newToken2, 1)), 'while nesting new token inside fungible').to.be.rejectedWith(/fungible\.FungibleDisallowsNesting/);
     });
   });
 
@@ -404,31 +365,21 @@
       const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
 
       // Try to create a nested token in the wrong collection
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.createItem(
-          collectionFT, 
-          targetAddress, 
-          {Fungible: {Value: 10}},
-        )
-      ), 'while creating nested token').to.be.rejectedWith(/structure\.DepthLimit/);
+      await expect(executeTransaction(api, alice, api.tx.unique.createItem(
+        collectionFT, 
+        targetAddress, 
+        {Fungible: {Value: 10}},
+      )), 'while creating nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
 
       // Try to create and nest a token in the wrong collection
       const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');
-      await expect(executeTransaction(
-        api, alice, 
-        api.tx.unique.transfer(
-          normalizeAccountId({Ethereum: tokenIdToAddress(collectionFT, targetToken)}), collectionFT, newToken, 1,
-        ),
-      ), 'while nesting new token').to.be.rejectedWith(/fungible\.FungibleDisallowsNesting/);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
     });
   });
 
   it('Fungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async () => {
     await usingApi(async api => {
       const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await setCollectionLimitsExpectSuccess(alice, collectionNFT, {nestingRule: {OwnerRestricted:[collectionNFT]}}); // todo clear redundant restrictions?
-
       await addToAllowListExpectSuccess(alice, collectionNFT, bob.address);
       await enableAllowListExpectSuccess(alice, collectionNFT);
       await enablePublicMintingExpectSuccess(alice, collectionNFT);
@@ -438,17 +389,18 @@
       const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};
 
       const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+      await setCollectionLimitsExpectSuccess(alice, collectionNFT, {nestingRule: {OwnerRestricted:[collectionFT]}});
 
       // Try to create a nested token in the wrong collection
       await expect(executeTransaction(api, alice, api.tx.unique.createItem(
         collectionFT, 
         targetAddress, 
         {Fungible: {Value: 10}},
-      ))).to.be.rejected;
+      )), 'while creating nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
 
       // Try to create and nest a token in the wrong collection
       const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');
-      await transferExpectFailure(collectionFT, newToken, alice, targetAddress, 1);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
     });
   });
 
@@ -468,11 +420,11 @@
         collectionFT, 
         targetAddress, 
         {Fungible: {Value: 10}},
-      ))).to.be.rejected;
+      )), 'while creating a nested token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);
 
       // Try to create and nest a token in the wrong collection
       const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');
-      await transferExpectFailure(collectionFT, newToken, alice, targetAddress, 1);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);
     });
   });
 
@@ -492,12 +444,19 @@
         collectionRFT, 
         targetAddress, 
         {ReFungible: {const_data: [], pieces: 100}},
-      ))).to.be.rejectedWith(/^common\.NestingIsDisabled$/);
+      )), 'while creating a nested token').to.be.rejectedWith(/^common\.NestingIsDisabled$/);
 
       // Create a token to be nested
       const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');
       // Try to nest
       await transferExpectFailure(collectionRFT, newToken, alice, targetAddress, 100);
+      // Try to nest
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionRFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.NestingIsDisabled/);
+
+      // Create another token to be nested
+      const newToken2 = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');
+      // Try to nest inside a fungible token
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collectionRFT, newToken)}, collectionRFT, newToken2, 1)), 'while nesting new token inside refungible').to.be.rejectedWith(/refungible\.RefungibleDisallowsNesting/);
     });
   });
 
@@ -521,19 +480,17 @@
         collectionRFT, 
         targetAddress, 
         {ReFungible: {const_data: [], pieces: 100}},
-      ))).to.be.rejected;
+      )), 'while creating a nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
 
       // Try to create and nest a token in the wrong collection
       const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');
-      await transferExpectFailure(collectionRFT, newToken, alice, targetAddress, 100);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionRFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
     });
   });
 
   it('ReFungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async () => {
     await usingApi(async api => {
       const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await setCollectionLimitsExpectSuccess(alice, collectionNFT, {nestingRule: {OwnerRestricted:[collectionNFT]}});
-
       await addToAllowListExpectSuccess(alice, collectionNFT, bob.address);
       await enableAllowListExpectSuccess(alice, collectionNFT);
       await enablePublicMintingExpectSuccess(alice, collectionNFT);
@@ -543,17 +500,18 @@
       const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};
 
       const collectionRFT = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+      await setCollectionLimitsExpectSuccess(alice, collectionNFT, {nestingRule: {OwnerRestricted:[collectionRFT]}});
 
       // Try to create a nested token in the wrong collection
       await expect(executeTransaction(api, alice, api.tx.unique.createItem(
         collectionRFT, 
         targetAddress, 
         {ReFungible: {const_data: [], pieces: 100}},
-      ))).to.be.rejected;
+      )), 'while creating a nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
 
       // Try to create and nest a token in the wrong collection
       const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');
-      await transferExpectFailure(collectionRFT, newToken, alice, targetAddress, 100);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionRFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);
     });
   });
 
@@ -573,11 +531,11 @@
         collectionRFT, 
         targetAddress, 
         {ReFungible: {const_data: [], pieces: 100}},
-      ))).to.be.rejected;
+      )), 'while creating a nested token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);
 
       // Try to create and nest a token in the wrong collection
       const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');
-      await transferExpectFailure(collectionRFT, newToken, alice, targetAddress, 100);
+      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionRFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);
     });
   });
 });
modifiedtests/src/nesting/properties.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/properties.test.ts
+++ b/tests/src/nesting/properties.test.ts
@@ -18,7 +18,7 @@
 
 describe('Integration Test: Collection Properties', () => {
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
     });
@@ -113,7 +113,7 @@
 
 describe('Negative Integration Test: Collection Properties', () => {
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
     });
@@ -213,13 +213,13 @@
         api, 
         alice, 
         api.tx.unique.setCollectionProperties(collection, [{key: '', value: 'nothing must not exist'}]), 
-      ), `on rejecting an unnamed property`).to.be.rejectedWith(/common\.EmptyPropertyKey/);
+      ), 'on rejecting an unnamed property').to.be.rejectedWith(/common\.EmptyPropertyKey/);
 
       await expect(executeTransaction(
         api, 
         alice, 
         api.tx.unique.setCollectionProperties(collection, [
-          {key: 'CRISPR-Cas9', value: 'rewriting nature!'}
+          {key: 'CRISPR-Cas9', value: 'rewriting nature!'},
         ]), 
       ), 'on setting the correctly-but-still-badly-named property').to.not.be.rejected;
 
@@ -245,7 +245,7 @@
 
 describe('Integration Test: Access Rights to Token Properties', () => {
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
     });
@@ -311,7 +311,7 @@
 
 describe('Negative Integration Test: Access Rights to Token Properties', () => {
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
     });
@@ -400,7 +400,7 @@
         api, 
         alice, 
         api.tx.unique.setPropertyPermissions(collection, [{key: '', permission: {}}]), 
-      ), `on rejecting an unnamed property`).to.be.rejectedWith(/common\.EmptyPropertyKey/);
+      ), 'on rejecting an unnamed property').to.be.rejectedWith(/common\.EmptyPropertyKey/);
 
       const correctKey = '--0x03116e387820CA05'; // PolkadotJS would parse this as an already encoded hex-string
       await expect(executeTransaction(
@@ -429,7 +429,7 @@
   let permissions: {permission: any, signers: IKeyringPair[]}[];
 
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
       charlie = privateKey('//Charlie');
@@ -446,10 +446,12 @@
   });
 
   beforeEach(async () => {
-    collection = await createCollectionExpectSuccess();
-    token = await createItemExpectSuccess(alice, collection, 'NFT');
-    await addCollectionAdminExpectSuccess(alice, collection, bob.address);
-    await transferExpectSuccess(collection, token, alice, charlie);
+    await usingApi(async () => {
+      collection = await createCollectionExpectSuccess();
+      token = await createItemExpectSuccess(alice, collection, 'NFT');
+      await addCollectionAdminExpectSuccess(alice, collection, bob.address);
+      await transferExpectSuccess(collection, token, alice, charlie);
+    });
   });
   
   it('Reads yet empty properties of a token', async () => {
@@ -592,7 +594,7 @@
   let constitution: {permission: any, signers: IKeyringPair[], sinner: IKeyringPair}[];
 
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
       charlie = privateKey('//Charlie');
modifiedtests/src/nesting/unnest.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/unnest.test.ts
+++ b/tests/src/nesting/unnest.test.ts
@@ -4,11 +4,9 @@
 import usingApi, {executeTransaction} from '../substrate/substrate-api';
 import {
   createCollectionExpectSuccess,
-  createItemExpectFailure,
   createItemExpectSuccess,
   getBalance,
   getTokenOwner,
-  getTopmostTokenOwner,
   normalizeAccountId,
   setCollectionLimitsExpectSuccess,
   transferExpectSuccess,
@@ -21,7 +19,7 @@
 
 describe('Integration Test: Unnesting', () => {
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
     });
@@ -112,7 +110,7 @@
 
 describe('Negative Test: Unnesting', () => {
   before(async () => {
-    await usingApi(async api => {
+    await usingApi(async () => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
     });
@@ -133,7 +131,7 @@
         api,
         bob,
         api.tx.unique.transferFrom(normalizeAccountId(targetAddress), normalizeAccountId(bob), collection, nestedToken, 1),
-      ), 'while unnesting').to.be.rejectedWith(/^structure\.DepthLimit$/); // todo ApprovedValueTooLow?
+      ), 'while unnesting').to.be.rejectedWith(/^common\.ApprovedValueTooLow$/);
       expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});
 
       // Try to burn
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -427,7 +427,6 @@
 export async function createCollectionWithPropsExpectFailure(params: Partial<CreateCollectionParams> = {}) {
   const {name, description, mode, tokenPrefix} = {...defaultCreateCollectionParams, ...params};
 
-  const collectionId = 0;
   await usingApi(async (api) => {
     // Get number of collections before the transaction
     const collectionCountBefore = await getCreatedCollectionCount(api);