git.delta.rocks / unique-network / refs/commits / 464a3c1ac005

difftreelog

fix properties have been moved in creation functions

kryadinskii2022-05-20parent: #fc4f875.patch.diff
in: master

5 files changed

modifiedtests/src/createItem.test.tsdiffbeforeafterboth
--- a/tests/src/createItem.test.ts
+++ b/tests/src/createItem.test.ts
@@ -24,6 +24,7 @@
   addCollectionAdminExpectSuccess,
   createCollectionWithPropsExpectSuccess,
   createItemWithPropsExpectSuccess,
+  createItemWithPropsExpectFailure,
 } from './util/helpers';
 
 const expect = chai.expect;
@@ -128,69 +129,47 @@
       const createMode = 'NFT';
       const newCollectionID = await createCollectionWithPropsExpectSuccess({mode: {type: createMode}, 
         propPerm:   [{key: 'key1', permission: {mutable: false, collectionAdmin: false, tokenOwner: false}}]});
-
-      const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
       await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
 
-      await expect(executeTransaction(
-        api, 
-        alice, 
-        api.tx.unique.setTokenProperties(newCollectionID, token, [{key: 'key1', value: 'v2'}]), 
-      )).to.be.rejected;
+      await createItemWithPropsExpectFailure(bob, newCollectionID, 'NFT', [{key: 'key1', value: 'v'}]);
     });
   });
 
   it('User doesnt have editing rights', async () => {
     await usingApi(async api => {
       const newCollectionID = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}]});
-      const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
-
-      await expect(executeTransaction(
-        api, 
-        bob, 
-        api.tx.unique.setTokenProperties(newCollectionID, token, [{key: 'key1', value: 'v2'}]), 
-      )).to.be.rejected;
+      await createItemWithPropsExpectFailure(bob, newCollectionID, 'NFT', [{key: 'key1', value: 'v'}]);
     });
   });
 
   it('Adding property without access rights', async () => {
     await usingApi(async api => {
-      const createMode = 'NFT';
-      const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
-
-      const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
+      const newCollectionID = await createCollectionWithPropsExpectSuccess();
       await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
-      
-      await expect(executeTransaction(
-        api, 
-        bob, 
-        api.tx.unique.setTokenProperties(newCollectionID, token, [{key: 'key1', value: 'v2'}]), 
-      )).to.be.rejected;
+
+      await createItemWithPropsExpectFailure(bob, newCollectionID, 'NFT', [{key: 'k', value: 'v'}]);
     });
   });
 
   it('Adding more than 64 prps', async () => {
     await usingApi(async api => {
-      const createMode = 'NFT';
-
       const prps = [];
 
       for (let i = 0; i < 65; i++) {
         prps.push({key: `key${i}`, value: `value${i}`});
       }
 
-      const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
+      const newCollectionID = await createCollectionWithPropsExpectSuccess();
       
-      await expect(executeTransaction(api, alice, api.tx.unique.setCollectionProperties(newCollectionID, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);
+      createItemWithPropsExpectFailure(alice, newCollectionID, 'NFT', prps);
     });
   });
 
   it('Trying to add bigger property than allowed', async () => {
     await usingApi(async api => {
-      const createMode = 'NFT';
-      const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
+      const newCollectionID = await createCollectionWithPropsExpectSuccess();
       
-      await expect(executeTransaction(api, alice, api.tx.unique.setCollectionProperties(newCollectionID, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]))).to.be.rejectedWith(/common\.NoSpaceForProperty/);
+      createItemWithPropsExpectFailure(alice, newCollectionID, 'NFT', [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]);
     });
   });
 });
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  getConstMetadata,34  getCreatedCollectionCount,35  createCollectionWithPropsExpectSuccess,36  getCreateItemsResult,37  createMultipleItemsWithPropsExpectSuccess38} 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'}},51        {Nft: {const_data: '0x32'}},52        {Nft: {const_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]);66    });67  });6869  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {70    await usingApi(async (api: ApiPromise) => {71      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});72      const itemsListIndexBefore = await getLastTokenId(api, collectionId);73      expect(itemsListIndexBefore).to.be.equal(0);74      const alice = privateKey('//Alice');75      const args = [76        {Fungible: {value: 1}},77        {Fungible: {value: 2}},78        {Fungible: {value: 3}},79      ];80      const createMultipleItemsTx = api.tx.unique81        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);82      await submitTransactionAsync(alice, createMultipleItemsTx);83      const token1Data = await getBalance(api, collectionId, alice.address, 0);8485      expect(token1Data).to.be.equal(6n); // 1 + 2 + 386    });87  });8889  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {90    await usingApi(async (api: ApiPromise) => {91      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});92      const itemsListIndexBefore = await getLastTokenId(api, collectionId);93      expect(itemsListIndexBefore).to.be.equal(0);94      const alice = privateKey('//Alice');95      const args = [96        {ReFungible: {const_data: [0x31], pieces: 1}},97        {ReFungible: {const_data: [0x32], pieces: 1}},98        {ReFungible: {const_data: [0x33], pieces: 1}},99      ];100      const createMultipleItemsTx = api.tx.unique101        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);102      await submitTransactionAsync(alice, createMultipleItemsTx);103      const itemsListIndexAfter = await getLastTokenId(api, collectionId);104      expect(itemsListIndexAfter).to.be.equal(3);105106      expect(await getBalance(api, collectionId, alice.address, 1)).to.be.equal(1n);107      expect(await getBalance(api, collectionId, alice.address, 2)).to.be.equal(1n);108      expect(await getBalance(api, collectionId, alice.address, 3)).to.be.equal(1n);109110      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);111      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);112      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);113    });114  });115116  it('Can mint amount of items equals to collection limits', async () => {117    await usingApi(async (api) => {118      const alice = privateKey('//Alice');119120      const collectionId = await createCollectionExpectSuccess();121      await setCollectionLimitsExpectSuccess(alice, collectionId, {122        tokenLimit: 2,123      });124      const args = [125        {NFT: {const_data: 'A'}},126        {NFT: {const_data: 'B'}},127      ];128      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);129      const events = await submitTransactionAsync(alice, createMultipleItemsTx);130      const result = getGenericResult(events);131      expect(result.success).to.be.true;132    });133  });134135  it('Create  0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {136    await usingApi(async (api: ApiPromise) => {137      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});138      const itemsListIndexBefore = await getLastTokenId(api, collectionId);139      expect(itemsListIndexBefore).to.be.equal(0);140      const alice = privateKey('//Alice');141      const bob = privateKey('//Bob');142      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v1'}]}},143        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'v2'}]}},144        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'v3'}]}}];145146      await createMultipleItemsWithPropsExpectSuccess(alice, collectionId, args);147      const itemsListIndexAfter = await getLastTokenId(api, collectionId);148      expect(itemsListIndexAfter).to.be.equal(3);149150      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));151      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));152      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));153154      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);155      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);156      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);157    });158  });159160  it('Create  0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {161    await usingApi(async (api: ApiPromise) => {162      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]});163      const itemsListIndexBefore = await getLastTokenId(api, collectionId);164      expect(itemsListIndexBefore).to.be.equal(0);165      const alice = privateKey('//Alice');166      const bob = privateKey('//Bob');167      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);168      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v1'}]}},169        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'v2'}]}},170        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'v3'}]}}];171172      await createMultipleItemsWithPropsExpectSuccess(alice, collectionId, args);173      const itemsListIndexAfter = await getLastTokenId(api, collectionId);174      expect(itemsListIndexAfter).to.be.equal(3);175176      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));177      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));178      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));179180      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);181      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);182      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);183    });184  });185186  it('Create  0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {187    await usingApi(async (api: ApiPromise) => {188      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});189      const itemsListIndexBefore = await getLastTokenId(api, collectionId);190      expect(itemsListIndexBefore).to.be.equal(0);191      const alice = privateKey('//Alice');192      const bob = privateKey('//Bob');193      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v1'}]}},194        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'v2'}]}},195        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'v3'}]}}];196197      await createMultipleItemsWithPropsExpectSuccess(alice, collectionId, args);198      const itemsListIndexAfter = await getLastTokenId(api, collectionId);199      expect(itemsListIndexAfter).to.be.equal(3);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]);208    });209  });210});211212describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {213214  let alice: IKeyringPair;215  let bob: IKeyringPair;216217  before(async () => {218    await usingApi(async () => {219      alice = privateKey('//Alice');220      bob = privateKey('//Bob');221    });222  });223224  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {225    await usingApi(async (api: ApiPromise) => {226      const collectionId = await createCollectionExpectSuccess();227      const itemsListIndexBefore = await getLastTokenId(api, collectionId);228      expect(itemsListIndexBefore).to.be.equal(0);229      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);230      const args = [{Nft: {const_data: '0x31'}},231        {Nft: {const_data: '0x32'}},232        {Nft: {const_data: '0x33'}}];233      const createMultipleItemsTx = api.tx.unique234        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);235      await submitTransactionAsync(bob, createMultipleItemsTx);236      const itemsListIndexAfter = await getLastTokenId(api, collectionId);237      expect(itemsListIndexAfter).to.be.equal(3);238239      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(bob.address));240      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(bob.address));241      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(bob.address));242243      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);244      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);245      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);246    });247  });248249  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {250    await usingApi(async (api: ApiPromise) => {251      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});252      const itemsListIndexBefore = await getLastTokenId(api, collectionId);253      expect(itemsListIndexBefore).to.be.equal(0);254      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);255      const args = [256        {Fungible: {value: 1}},257        {Fungible: {value: 2}},258        {Fungible: {value: 3}},259      ];260      const createMultipleItemsTx = api.tx.unique261        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);262      await submitTransactionAsync(bob, createMultipleItemsTx);263      const token1Data = await getBalance(api, collectionId, bob.address, 0);264265      expect(token1Data).to.be.equal(6n); // 1 + 2 + 3266    });267  });268269  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {270    await usingApi(async (api: ApiPromise) => {271      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});272      const itemsListIndexBefore = await getLastTokenId(api, collectionId);273      expect(itemsListIndexBefore).to.be.equal(0);274      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);275      const args = [276        {ReFungible: {const_data: [0x31], pieces: 1}},277        {ReFungible: {const_data: [0x32], pieces: 1}},278        {ReFungible: {const_data: [0x33], pieces: 1}},279      ];280      const createMultipleItemsTx = api.tx.unique281        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);282      await submitTransactionAsync(bob, createMultipleItemsTx);283      const itemsListIndexAfter = await getLastTokenId(api, collectionId);284      expect(itemsListIndexAfter).to.be.equal(3);285286      expect(await getBalance(api, collectionId, bob.address, 1)).to.be.equal(1n);287      expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(1n);288      expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(1n);289290      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);291      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);292      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);293    });294  });295});296297describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {298299  let alice: IKeyringPair;300  let bob: IKeyringPair;301302  before(async () => {303    await usingApi(async () => {304      alice = privateKey('//Alice');305      bob = privateKey('//Bob');306    });307  });308309  it('Regular user cannot create items in active NFT collection', async () => {310    await usingApi(async (api: ApiPromise) => {311      const collectionId = await createCollectionExpectSuccess();312      const itemsListIndexBefore = await getLastTokenId(api, collectionId);313      expect(itemsListIndexBefore).to.be.equal(0);314      const args = [{Nft: {const_data: '0x31'}},315        {Nft: {const_data: '0x32'}},316        {Nft: {const_data: '0x33'}}];317      const createMultipleItemsTx = api.tx.unique318        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);319      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;320    });321  });322323  it('Regular user cannot create items in active Fungible collection', async () => {324    await usingApi(async (api: ApiPromise) => {325      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});326      const itemsListIndexBefore = await getLastTokenId(api, collectionId);327      expect(itemsListIndexBefore).to.be.equal(0);328      const args = [329        {Fungible: {value: 1}},330        {Fungible: {value: 2}},331        {Fungible: {value: 3}},332      ];333      const createMultipleItemsTx = api.tx.unique334        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);335      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;336    });337  });338339  it('Regular user cannot create items in active ReFungible collection', async () => {340    await usingApi(async (api: ApiPromise) => {341      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});342      const itemsListIndexBefore = await getLastTokenId(api, collectionId);343      expect(itemsListIndexBefore).to.be.equal(0);344      const args = [345        {ReFungible: {const_data: [0x31], pieces: 1}},346        {ReFungible: {const_data: [0x32], pieces: 1}},347        {ReFungible: {const_data: [0x33], pieces: 1}},348      ];349      const createMultipleItemsTx = api.tx.unique350        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);351      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;352    });353  });354355  it('Create token in not existing collection', async () => {356    await usingApi(async (api: ApiPromise) => {357      const collectionId = await getCreatedCollectionCount(api) + 1;358      const createMultipleItemsTx = api.tx.unique359        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'NFT', 'NFT']);360      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;361    });362  });363364  it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {365    await usingApi(async (api: ApiPromise) => {366      // NFT367      const collectionId = await createCollectionExpectSuccess();368      const alice = privateKey('//Alice');369      const args = [370        {NFT: {const_data: 'A'.repeat(2049)}},371        {NFT: {const_data: 'B'.repeat(2049)}},372        {NFT: {const_data: 'C'.repeat(2049)}},373      ];374      const createMultipleItemsTx = api.tx.unique375        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);376      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;377378      // ReFungible379      const collectionIdReFungible =380        await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});381      const argsReFungible = [382        {ReFungible: ['1'.repeat(2049), 10]},383        {ReFungible: ['2'.repeat(2049), 10]},384        {ReFungible: ['3'.repeat(2049), 10]},385      ];386      const createMultipleItemsTxFungible = api.tx.unique387        .createMultipleItems(collectionIdReFungible, normalizeAccountId(alice.address), argsReFungible);388      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTxFungible)).to.be.rejected;389    });390  });391392  it('Create tokens with different types', async () => {393    await usingApi(async (api: ApiPromise) => {394      const collectionId = await createCollectionExpectSuccess();395      const createMultipleItemsTx = api.tx.unique396        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);397      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;398      // garbage collection :-D399      await destroyCollectionExpectSuccess(collectionId);400    });401  });402403  it('Create tokens with different data limits <> maximum data limit', async () => {404    await usingApi(async (api: ApiPromise) => {405      const collectionId = await createCollectionExpectSuccess();406      const args = [407        {NFT: {const_data: 'A'}},408        {NFT: {const_data: 'B'.repeat(2049)}},409      ];410      const createMultipleItemsTx = await api.tx.unique411        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);412      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;413    });414  });415416  it('Fails when minting tokens exceeds collectionLimits amount', async () => {417    await usingApi(async (api) => {418419      const collectionId = await createCollectionExpectSuccess();420      await setCollectionLimitsExpectSuccess(alice, collectionId, {421        tokenLimit: 1,422      });423      const args = [424        {NFT: {const_data: 'A'}},425        {NFT: {const_data: 'B'}},426      ];427      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);428      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;429    });430  });431432  it('No editing rights', async () => {433    await usingApi(async (api: ApiPromise) => {434      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],435        propPerm:   [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}]});436      const itemsListIndexBefore = await getLastTokenId(api, collectionId);437      expect(itemsListIndexBefore).to.be.equal(0);438      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);439      const args = [{Nft: {const_data: '0x31'}},440        {Nft: {const_data: '0x32'}},441        {Nft: {const_data: '0x33'}}];442443      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);444445      const events = await submitTransactionAsync(alice, createMultipleItemsTx);446      const result = getCreateItemsResult(events);447448      for (const elem of result) {449        await expect(executeTransaction(450          api,451          bob,452          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),453        )).to.be.rejected;454      }455456      // await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;457    });458  });459460  it('User doesnt have editing rights', async () => {461    await usingApi(async (api: ApiPromise) => {462      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],463        propPerm:   [{key: 'key1', permission: {mutable: false, collectionAdmin: false, tokenOwner: false}}]});464      const itemsListIndexBefore = await getLastTokenId(api, collectionId);465      expect(itemsListIndexBefore).to.be.equal(0);466      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);467      const args = [{Nft: {const_data: '0x31'}},468        {Nft: {const_data: '0x32'}},469        {Nft: {const_data: '0x33'}}];470471      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);472473      const events = await submitTransactionAsync(alice, createMultipleItemsTx);474      const result = getCreateItemsResult(events);475476      for (const elem of result) {477        await expect(executeTransaction(478          api,479          bob,480          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),481        )).to.be.rejected;482      }483    });484  });485486  it('Adding property without access rights', async () => {487    await usingApi(async (api: ApiPromise) => {488      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}]});489      const itemsListIndexBefore = await getLastTokenId(api, collectionId);490      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);491      expect(itemsListIndexBefore).to.be.equal(0);492      const args = [{Nft: {const_data: '0x31'}},493        {Nft: {const_data: '0x32'}},494        {Nft: {const_data: '0x33'}}];495496      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);497498      const events = await submitTransactionAsync(alice, createMultipleItemsTx);499      const result = getCreateItemsResult(events);500501      for (const elem of result) {502        await expect(executeTransaction(503          api,504          bob,505          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),506        )).to.be.rejected;507      }508    });509  });510511  it('Adding more than 64 prps', async () => {512    await usingApi(async (api: ApiPromise) => {513      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],514        propPerm:   [{key: 'key1', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});515      const itemsListIndexBefore = await getLastTokenId(api, collectionId);516      expect(itemsListIndexBefore).to.be.equal(0);517      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);518519      const args = [{Nft: {const_data: '0x31'}},520        {Nft: {const_data: '0x32'}},521        {Nft: {const_data: '0x33'}}];522523      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);524      const events = await submitTransactionAsync(alice, createMultipleItemsTx);525526      const result = getCreateItemsResult(events);527528      const prps = [];529530      for (let i = 0; i < 65; i++) {531        prps.push({key: `key${i}`, value: `value${i}`});532      }533534      await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collectionId, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);535536      for (const elem of result) {537        await expect(executeTransaction(538          api,539          bob,540          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps),541        )).to.be.rejected;542      }543    });544  });545546  it('Trying to add bigger property than allowed', async () => {547    await usingApi(async (api: ApiPromise) => {548      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],549        propPerm:   [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}]});550      const itemsListIndexBefore = await getLastTokenId(api, collectionId);551      expect(itemsListIndexBefore).to.be.equal(0);552      const args = [{Nft: {const_data: '0x31'}},553        {Nft: {const_data: '0x32'}},554        {Nft: {const_data: '0x33'}}];555556      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);557558      const events = await submitTransactionAsync(alice, createMultipleItemsTx);559      const result = getCreateItemsResult(events);560561562      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/);563564      for (const elem of result) {565        await expect(executeTransaction(566          api,567          bob,568          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]),569        )).to.be.rejected;570      }571    });572  });573});
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  getConstMetadata,34  getCreatedCollectionCount,35  createCollectionWithPropsExpectSuccess,36  getCreateItemsResult,37  createMultipleItemsWithPropsExpectSuccess,38  createMultipleItemsWithPropsExpectFailure,39} from './util/helpers';4041chai.use(chaiAsPromised);42const expect = chai.expect;4344describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {45  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {46    await usingApi(async (api: ApiPromise) => {47      const collectionId = await createCollectionExpectSuccess();48      const itemsListIndexBefore = await getLastTokenId(api, collectionId);49      expect(itemsListIndexBefore).to.be.equal(0);50      const alice = privateKey('//Alice');51      const args = [{Nft: {const_data: '0x31'}},52        {Nft: {const_data: '0x32'}},53        {Nft: {const_data: '0x33'}}];54      const createMultipleItemsTx = api.tx.unique55        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);56      await submitTransactionAsync(alice, createMultipleItemsTx);57      const itemsListIndexAfter = await getLastTokenId(api, collectionId);58      expect(itemsListIndexAfter).to.be.equal(3);5960      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));61      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));62      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));6364      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);65      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);66      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);67    });68  });6970  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {71    await usingApi(async (api: ApiPromise) => {72      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});73      const itemsListIndexBefore = await getLastTokenId(api, collectionId);74      expect(itemsListIndexBefore).to.be.equal(0);75      const alice = privateKey('//Alice');76      const args = [77        {Fungible: {value: 1}},78        {Fungible: {value: 2}},79        {Fungible: {value: 3}},80      ];81      const createMultipleItemsTx = api.tx.unique82        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);83      await submitTransactionAsync(alice, createMultipleItemsTx);84      const token1Data = await getBalance(api, collectionId, alice.address, 0);8586      expect(token1Data).to.be.equal(6n); // 1 + 2 + 387    });88  });8990  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {91    await usingApi(async (api: ApiPromise) => {92      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});93      const itemsListIndexBefore = await getLastTokenId(api, collectionId);94      expect(itemsListIndexBefore).to.be.equal(0);95      const alice = privateKey('//Alice');96      const args = [97        {ReFungible: {const_data: [0x31], pieces: 1}},98        {ReFungible: {const_data: [0x32], pieces: 1}},99        {ReFungible: {const_data: [0x33], pieces: 1}},100      ];101      const createMultipleItemsTx = api.tx.unique102        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);103      await submitTransactionAsync(alice, createMultipleItemsTx);104      const itemsListIndexAfter = await getLastTokenId(api, collectionId);105      expect(itemsListIndexAfter).to.be.equal(3);106107      expect(await getBalance(api, collectionId, alice.address, 1)).to.be.equal(1n);108      expect(await getBalance(api, collectionId, alice.address, 2)).to.be.equal(1n);109      expect(await getBalance(api, collectionId, alice.address, 3)).to.be.equal(1n);110111      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);112      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);113      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);114    });115  });116117  it('Can mint amount of items equals to collection limits', async () => {118    await usingApi(async (api) => {119      const alice = privateKey('//Alice');120121      const collectionId = await createCollectionExpectSuccess();122      await setCollectionLimitsExpectSuccess(alice, collectionId, {123        tokenLimit: 2,124      });125      const args = [126        {NFT: {const_data: 'A'}},127        {NFT: {const_data: 'B'}},128      ];129      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);130      const events = await submitTransactionAsync(alice, createMultipleItemsTx);131      const result = getGenericResult(events);132      expect(result.success).to.be.true;133    });134  });135136  it('Create  0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {137    await usingApi(async (api: ApiPromise) => {138      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});139      const itemsListIndexBefore = await getLastTokenId(api, collectionId);140      expect(itemsListIndexBefore).to.be.equal(0);141      const alice = privateKey('//Alice');142      const bob = privateKey('//Bob');143      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v1'}]}},144        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'v2'}]}},145        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'v3'}]}}];146147      await createMultipleItemsWithPropsExpectSuccess(alice, collectionId, args);148      const itemsListIndexAfter = await getLastTokenId(api, collectionId);149      expect(itemsListIndexAfter).to.be.equal(3);150151      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));152      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));153      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));154155      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);156      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);157      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);158    });159  });160161  it('Create  0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {162    await usingApi(async (api: ApiPromise) => {163      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]});164      const itemsListIndexBefore = await getLastTokenId(api, collectionId);165      expect(itemsListIndexBefore).to.be.equal(0);166      const alice = privateKey('//Alice');167      const bob = privateKey('//Bob');168      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);169      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v1'}]}},170        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'v2'}]}},171        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'v3'}]}}];172173      await createMultipleItemsWithPropsExpectSuccess(alice, collectionId, args);174      const itemsListIndexAfter = await getLastTokenId(api, collectionId);175      expect(itemsListIndexAfter).to.be.equal(3);176177      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));178      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));179      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));180181      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);182      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);183      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);184    });185  });186187  it('Create  0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {188    await usingApi(async (api: ApiPromise) => {189      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});190      const itemsListIndexBefore = await getLastTokenId(api, collectionId);191      expect(itemsListIndexBefore).to.be.equal(0);192      const alice = privateKey('//Alice');193      const bob = privateKey('//Bob');194      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v1'}]}},195        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'v2'}]}},196        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'v3'}]}}];197198      await createMultipleItemsWithPropsExpectSuccess(alice, collectionId, args);199      const itemsListIndexAfter = await getLastTokenId(api, collectionId);200      expect(itemsListIndexAfter).to.be.equal(3);201202      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));203      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));204      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));205206      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);207      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);208      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);209    });210  });211});212213describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {214215  let alice: IKeyringPair;216  let bob: IKeyringPair;217218  before(async () => {219    await usingApi(async () => {220      alice = privateKey('//Alice');221      bob = privateKey('//Bob');222    });223  });224225  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {226    await usingApi(async (api: ApiPromise) => {227      const collectionId = await createCollectionExpectSuccess();228      const itemsListIndexBefore = await getLastTokenId(api, collectionId);229      expect(itemsListIndexBefore).to.be.equal(0);230      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);231      const args = [{Nft: {const_data: '0x31'}},232        {Nft: {const_data: '0x32'}},233        {Nft: {const_data: '0x33'}}];234      const createMultipleItemsTx = api.tx.unique235        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);236      await submitTransactionAsync(bob, createMultipleItemsTx);237      const itemsListIndexAfter = await getLastTokenId(api, collectionId);238      expect(itemsListIndexAfter).to.be.equal(3);239240      expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(bob.address));241      expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(bob.address));242      expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(bob.address));243244      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);245      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);246      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);247    });248  });249250  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {251    await usingApi(async (api: ApiPromise) => {252      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});253      const itemsListIndexBefore = await getLastTokenId(api, collectionId);254      expect(itemsListIndexBefore).to.be.equal(0);255      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);256      const args = [257        {Fungible: {value: 1}},258        {Fungible: {value: 2}},259        {Fungible: {value: 3}},260      ];261      const createMultipleItemsTx = api.tx.unique262        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);263      await submitTransactionAsync(bob, createMultipleItemsTx);264      const token1Data = await getBalance(api, collectionId, bob.address, 0);265266      expect(token1Data).to.be.equal(6n); // 1 + 2 + 3267    });268  });269270  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {271    await usingApi(async (api: ApiPromise) => {272      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});273      const itemsListIndexBefore = await getLastTokenId(api, collectionId);274      expect(itemsListIndexBefore).to.be.equal(0);275      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);276      const args = [277        {ReFungible: {const_data: [0x31], pieces: 1}},278        {ReFungible: {const_data: [0x32], pieces: 1}},279        {ReFungible: {const_data: [0x33], pieces: 1}},280      ];281      const createMultipleItemsTx = api.tx.unique282        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);283      await submitTransactionAsync(bob, createMultipleItemsTx);284      const itemsListIndexAfter = await getLastTokenId(api, collectionId);285      expect(itemsListIndexAfter).to.be.equal(3);286287      expect(await getBalance(api, collectionId, bob.address, 1)).to.be.equal(1n);288      expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(1n);289      expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(1n);290291      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);292      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);293      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);294    });295  });296});297298describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {299300  let alice: IKeyringPair;301  let bob: IKeyringPair;302303  before(async () => {304    await usingApi(async () => {305      alice = privateKey('//Alice');306      bob = privateKey('//Bob');307    });308  });309310  it('Regular user cannot create items in active NFT collection', async () => {311    await usingApi(async (api: ApiPromise) => {312      const collectionId = await createCollectionExpectSuccess();313      const itemsListIndexBefore = await getLastTokenId(api, collectionId);314      expect(itemsListIndexBefore).to.be.equal(0);315      const args = [{Nft: {const_data: '0x31'}},316        {Nft: {const_data: '0x32'}},317        {Nft: {const_data: '0x33'}}];318      const createMultipleItemsTx = api.tx.unique319        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);320      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;321    });322  });323324  it('Regular user cannot create items in active Fungible collection', async () => {325    await usingApi(async (api: ApiPromise) => {326      const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});327      const itemsListIndexBefore = await getLastTokenId(api, collectionId);328      expect(itemsListIndexBefore).to.be.equal(0);329      const args = [330        {Fungible: {value: 1}},331        {Fungible: {value: 2}},332        {Fungible: {value: 3}},333      ];334      const createMultipleItemsTx = api.tx.unique335        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);336      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;337    });338  });339340  it('Regular user cannot create items in active ReFungible collection', async () => {341    await usingApi(async (api: ApiPromise) => {342      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});343      const itemsListIndexBefore = await getLastTokenId(api, collectionId);344      expect(itemsListIndexBefore).to.be.equal(0);345      const args = [346        {ReFungible: {const_data: [0x31], pieces: 1}},347        {ReFungible: {const_data: [0x32], pieces: 1}},348        {ReFungible: {const_data: [0x33], pieces: 1}},349      ];350      const createMultipleItemsTx = api.tx.unique351        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);352      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;353    });354  });355356  it('Create token in not existing collection', async () => {357    await usingApi(async (api: ApiPromise) => {358      const collectionId = await getCreatedCollectionCount(api) + 1;359      const createMultipleItemsTx = api.tx.unique360        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'NFT', 'NFT']);361      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;362    });363  });364365  it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {366    await usingApi(async (api: ApiPromise) => {367      // NFT368      const collectionId = await createCollectionExpectSuccess();369      const alice = privateKey('//Alice');370      const args = [371        {NFT: {const_data: 'A'.repeat(2049)}},372        {NFT: {const_data: 'B'.repeat(2049)}},373        {NFT: {const_data: 'C'.repeat(2049)}},374      ];375      const createMultipleItemsTx = api.tx.unique376        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);377      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;378379      // ReFungible380      const collectionIdReFungible =381        await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});382      const argsReFungible = [383        {ReFungible: ['1'.repeat(2049), 10]},384        {ReFungible: ['2'.repeat(2049), 10]},385        {ReFungible: ['3'.repeat(2049), 10]},386      ];387      const createMultipleItemsTxFungible = api.tx.unique388        .createMultipleItems(collectionIdReFungible, normalizeAccountId(alice.address), argsReFungible);389      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTxFungible)).to.be.rejected;390    });391  });392393  it('Create tokens with different types', async () => {394    await usingApi(async (api: ApiPromise) => {395      const collectionId = await createCollectionExpectSuccess();396      const createMultipleItemsTx = api.tx.unique397        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);398      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;399      // garbage collection :-D400      await destroyCollectionExpectSuccess(collectionId);401    });402  });403404  it('Create tokens with different data limits <> maximum data limit', async () => {405    await usingApi(async (api: ApiPromise) => {406      const collectionId = await createCollectionExpectSuccess();407      const args = [408        {NFT: {const_data: 'A'}},409        {NFT: {const_data: 'B'.repeat(2049)}},410      ];411      const createMultipleItemsTx = await api.tx.unique412        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);413      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;414    });415  });416417  it('Fails when minting tokens exceeds collectionLimits amount', async () => {418    await usingApi(async (api) => {419420      const collectionId = await createCollectionExpectSuccess();421      await setCollectionLimitsExpectSuccess(alice, collectionId, {422        tokenLimit: 1,423      });424      const args = [425        {NFT: {const_data: 'A'}},426        {NFT: {const_data: 'B'}},427      ];428      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);429      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;430    });431  });432433  it('No editing rights', async () => {434    await usingApi(async (api: ApiPromise) => {435      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],436        propPerm:   [{key: 'key1', permission: {mutable: false, collectionAdmin: false, tokenOwner: true}}]});437      const itemsListIndexBefore = await getLastTokenId(api, collectionId);438      expect(itemsListIndexBefore).to.be.equal(0);439      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);440      const args = [{Nft: {const_data: '0x31', properties: [{key: 'key1', value: 'v2'}]}},441        {Nft: {const_data: '0x32'}},442        {Nft: {const_data: '0x33'}}];443444      await createMultipleItemsWithPropsExpectFailure(bob, collectionId, args);445    });446  });447448  it('User doesnt have editing rights', async () => {449    await usingApi(async (api: ApiPromise) => {450      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],451        propPerm:   [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}]});452      const itemsListIndexBefore = await getLastTokenId(api, collectionId);453      expect(itemsListIndexBefore).to.be.equal(0);454      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);455      const args = [{Nft: {const_data: '0x31', properties: [{key: 'key1', value: 'v2'}]}},456        {Nft: {const_data: '0x32'}},457        {Nft: {const_data: '0x33'}}];458459      await createMultipleItemsWithPropsExpectFailure(bob, collectionId, args);460    });461  });462463  it('Adding property without access rights', async () => {464    await usingApi(async (api: ApiPromise) => {465      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'k', value: 'v1'}]});466      const itemsListIndexBefore = await getLastTokenId(api, collectionId);467      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);468      expect(itemsListIndexBefore).to.be.equal(0);469      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v'}]}},470        {Nft: {const_data: '0x32'}},471        {Nft: {const_data: '0x33'}}];472473      await createMultipleItemsWithPropsExpectFailure(bob, collectionId, args);474    });475  });476477  it('Adding more than 64 prps', async () => {478    await usingApi(async (api: ApiPromise) => {479      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],480        propPerm:   [{key: 'key1', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});481      const itemsListIndexBefore = await getLastTokenId(api, collectionId);482      expect(itemsListIndexBefore).to.be.equal(0);483      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);484485      const prps = [];486487      for (let i = 0; i < 65; i++) {488        prps.push({key: `key${i}`, value: `value${i}`});489      }490491      const args = [{Nft: {const_data: '0x31', properties: prps}},492        {Nft: {const_data: '0x32', properties: prps}},493        {Nft: {const_data: '0x33', properties: prps}}];494495      createMultipleItemsWithPropsExpectFailure(alice, collectionId, args);496    });497  });498499  it('Trying to add bigger property than allowed', async () => {500    await usingApi(async (api: ApiPromise) => {501      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm:   [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});502      const itemsListIndexBefore = await getLastTokenId(api, collectionId);503      expect(itemsListIndexBefore).to.be.equal(0);504      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}},505        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}},506        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}}];507508      createMultipleItemsWithPropsExpectFailure(alice, collectionId, args);509    });510  });511});
modifiedtests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItemsEx.test.ts
+++ b/tests/src/createMultipleItemsEx.test.ts
@@ -16,7 +16,7 @@
 
 import {expect} from 'chai';
 import privateKey from './substrate/privateKey';
-import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';
+import usingApi, {executeTransaction, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
 import {createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, addCollectionAdminExpectSuccess, getCreateItemsResult} from './util/helpers';
 
 describe('createMultipleItemsEx', () => {
@@ -48,7 +48,7 @@
     });
   });
 
-  it.only('createMultipleItemsEx with property Admin', async () => {
+  it('createMultipleItemsEx with property Admin', async () => {
     const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});
     const alice = privateKey('//Alice');
     const bob = privateKey('//Bob');
@@ -152,26 +152,20 @@
       const data = [
         {
           owner: {substrate: alice.address},
+          properties: [{key: 'key1', value: 'v2'}],
         }, {
-          owner: {substrate: bob.address},
+          owner: {substrate: alice.address},
+          properties: [{key: 'key1', value: 'v2'}],
         }, {
-          owner: {substrate: charlie.address},
+          owner: {substrate: alice.address},
+          properties: [{key: 'key1', value: 'v2'}],
         },
       ];
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
-      await executeTransaction(api, alice, tx);
-
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateItemsResult(events);
+      // await executeTransaction(api, alice, tx);
 
-      for (const elem of result) {
-        await expect(executeTransaction(
-          api,
-          bob,
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
-        )).to.be.rejected;
-      }
+      await submitTransactionExpectFailAsync(alice, tx);
     });
   });
 
@@ -186,26 +180,20 @@
       const data = [
         {
           owner: {substrate: alice.address},
+          properties: [{key: 'key1', value: 'v2'}],
         }, {
-          owner: {substrate: bob.address},
+          owner: {substrate: alice.address},
+          properties: [{key: 'key1', value: 'v2'}],
         }, {
-          owner: {substrate: charlie.address},
+          owner: {substrate: alice.address},
+          properties: [{key: 'key1', value: 'v2'}],
         },
       ];
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
-      await executeTransaction(api, alice, tx);
-
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateItemsResult(events);
+      // await executeTransaction(api, alice, tx);
 
-      for (const elem of result) {
-        await expect(executeTransaction(
-          api,
-          bob,
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
-        )).to.be.rejected;
-      }
+      await submitTransactionExpectFailAsync(alice, tx);
     });
   });
 
@@ -219,31 +207,32 @@
       const data = [
         {
           owner: {substrate: alice.address},
+          properties: [{key: 'key1', value: 'v2'}],
         }, {
           owner: {substrate: bob.address},
+          properties: [{key: 'key1', value: 'v2'}],
         }, {
           owner: {substrate: charlie.address},
+          properties: [{key: 'key1', value: 'v2'}],
         },
       ];
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
-      await executeTransaction(api, alice, tx);
-
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateItemsResult(events);
 
-      for (const elem of result) {
-        await expect(executeTransaction(
-          api,
-          bob,
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
-        )).to.be.rejected;
-      }
+      await submitTransactionExpectFailAsync(alice, tx);
     });
   });
 
   it('Adding more than 64 prps', async () => {
-    const collection = await createCollectionWithPropsExpectSuccess();
+    const prps = [{key: 'key', value: 'v'}];
+    const propPerm = [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}];
+
+    for (let i = 0; i < 65; i++) {
+      prps.push({key: `key${i}`, value: `value${i}`});
+      propPerm.push({key: `key${i}`, permission: {mutable: true, collectionAdmin: true, tokenOwner: true}});
+    }
+
+    const collection = await createCollectionWithPropsExpectSuccess({propPerm: propPerm});
     const alice = privateKey('//Alice');
     const bob = privateKey('//Bob');
     const charlie = privateKey('//Charlie');
@@ -252,40 +241,24 @@
       const data = [
         {
           owner: {substrate: alice.address},
+          properties: prps,
         }, {
-          owner: {substrate: bob.address},
+          owner: {substrate: alice.address},
+          properties: prps,
         }, {
-          owner: {substrate: charlie.address},
+          owner: {substrate: alice.address},
+          properties: prps,
         },
       ];
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
-      await executeTransaction(api, alice, tx);
 
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateItemsResult(events);
-
-      const prps = [];
-
-      for (let i = 0; i < 65; i++) {
-        prps.push({key: `key${i}`, value: `value${i}`});
-      }
-
-      await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collection, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);
-
-
-      for (const elem of result) {
-        await expect(executeTransaction(
-          api,
-          bob,
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps),
-        )).to.be.rejected;
-      }
+      await submitTransactionExpectFailAsync(alice, tx);
     });
   });
 
   it('Trying to add bigger property than allowed', async () => {
-    const collection = await createCollectionWithPropsExpectSuccess();
+    const collection = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});
     const alice = privateKey('//Alice');
     const bob = privateKey('//Bob');
     const charlie = privateKey('//Charlie');
@@ -293,32 +266,17 @@
     await usingApi(async (api) => {
       const data = [
         {
-          owner: {substrate: alice.address},
+          owner: {substrate: alice.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],
         }, {
-          owner: {substrate: bob.address},
+          owner: {substrate: bob.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],
         }, {
-          owner: {substrate: charlie.address},
+          owner: {substrate: charlie.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],
         },
       ];
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
-      await executeTransaction(api, alice, tx);
 
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateItemsResult(events);
-
-      const prps = [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}];
-
-      await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collection, prps))).to.be.rejectedWith(/common\.NoSpaceForProperty/);
-
-
-      for (const elem of result) {
-        await expect(executeTransaction(
-          api,
-          bob,
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps),
-        )).to.be.rejected;
-      }
+      await submitTransactionExpectFailAsync(alice, tx);
     });
   });
 
modifiedtests/src/interfaces/rmrk/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/rmrk/definitions.ts
+++ b/tests/src/interfaces/rmrk/definitions.ts
@@ -24,92 +24,92 @@
 
 const atParam = {name: 'at', type: 'Hash', isOptional: true};
 const fn = (description: string, params: RpcParam[], type: string) => ({
-    description,
-    params: [...params, atParam],
-    type,
+  description,
+  params: [...params, atParam],
+  type,
 });
 
 export default {
-    types,
-    rpc: {
-        lastCollectionIdx: fn('Get the latest created collection id', [], 'u32'),
-        collectionById: fn('Get collection by id', [{name: 'id', type: 'u32'}], 'Option<RmrkTypesCollectionInfo>'),
-        nftById: fn(
-            'Get NFT by collection id and NFT id',
-            [
-                {name: 'collectionId', type: 'u32'},
-                {name: 'nftId', type: 'u32'},
-            ],
-            'Option<RmrkTypesNftInfo>'
-        ),
-        accountTokens: fn(
-            'Get tokens owned by an account in a collection',
-            [
-                {name: 'accountId', type: 'AccountId32'},
-                {name: 'collectionId', type: 'u32'}
-            ],
-            'Vec<u32>'
-        ),
-        nftChildren: fn(
-            'Get NFT children',
-            [
-                {name: 'collectionId', type: 'u32'},
-                {name: 'nftId', type: 'u32'},
-            ],
-            'Vec<RmrkTypesNftChild>'
-        ),
-        collectionProperties: fn(
-            'Get collection properties',
-            [{name: 'collectionId', type: 'u32'}],
-            'Vec<RmrkTypesPropertyInfo>'
-        ),
-        nftProperties: fn(
-            'Get NFT properties',
-            [
-                {name: 'collectionId', type: 'u32'},
-                {name: 'nftId', type: 'u32'}
-            ],
-            'Vec<RmrkTypesPropertyInfo>'
-        ),
-        nftResources: fn(
-            'Get NFT resources',
-            [
-                {name: 'collectionId', type: 'u32'},
-                {name: 'nftId', type: 'u32'}
-            ],
-            'Vec<RmrkTypesResourceInfo>'
-        ),
-        nftResourcePriorities: fn(
-            'Get NFT resource priorities',
-            [
-                {name: 'collectionId', type: 'u32'},
-                {name: 'nftId', type: 'u32'}
-            ],
-            'Vec<Bytes>'
-        ),
-        base: fn(
-            'Get base info',
-            [{name: 'baseId', type: 'u32'}],
-            'Option<RmrkTypesBaseInfo>'
-        ),
-        baseParts: fn(
-            'Get all Base\'s parts',
-            [{name: 'baseId', type: 'u32'}],
-            'Vec<RmrkTypesPartType>'
-        ),
-        themeNames: fn(
-            'Get Base\'s theme names',
-            [{name: 'baseId', type: 'u32'}],
-            'Vec<Bytes>'
-        ),
-        themes: fn(
-            'Get Theme\'s keys values',
-            [
-                {name: 'baseId', type: 'u32'},
-                {name: 'themeName', type: 'String'},
-                {name: 'keys', type: 'Option<Vec<String>>'}
-            ],
-            'Option<RmrkTypesTheme>'
-        )
-    }
+  types,
+  rpc: {
+    lastCollectionIdx: fn('Get the latest created collection id', [], 'u32'),
+    collectionById: fn('Get collection by id', [{name: 'id', type: 'u32'}], 'Option<RmrkTypesCollectionInfo>'),
+    nftById: fn(
+      'Get NFT by collection id and NFT id',
+      [
+        {name: 'collectionId', type: 'u32'},
+        {name: 'nftId', type: 'u32'},
+      ],
+      'Option<RmrkTypesNftInfo>',
+    ),
+    accountTokens: fn(
+      'Get tokens owned by an account in a collection',
+      [
+        {name: 'accountId', type: 'AccountId32'},
+        {name: 'collectionId', type: 'u32'},
+      ],
+      'Vec<u32>',
+    ),
+    nftChildren: fn(
+      'Get NFT children',
+      [
+        {name: 'collectionId', type: 'u32'},
+        {name: 'nftId', type: 'u32'},
+      ],
+      'Vec<RmrkTypesNftChild>',
+    ),
+    collectionProperties: fn(
+      'Get collection properties',
+      [{name: 'collectionId', type: 'u32'}],
+      'Vec<RmrkTypesPropertyInfo>',
+    ),
+    nftProperties: fn(
+      'Get NFT properties',
+      [
+        {name: 'collectionId', type: 'u32'},
+        {name: 'nftId', type: 'u32'},
+      ],
+      'Vec<RmrkTypesPropertyInfo>',
+    ),
+    nftResources: fn(
+      'Get NFT resources',
+      [
+        {name: 'collectionId', type: 'u32'},
+        {name: 'nftId', type: 'u32'},
+      ],
+      'Vec<RmrkTypesResourceInfo>',
+    ),
+    nftResourcePriorities: fn(
+      'Get NFT resource priorities',
+      [
+        {name: 'collectionId', type: 'u32'},
+        {name: 'nftId', type: 'u32'},
+      ],
+      'Vec<Bytes>',
+    ),
+    base: fn(
+      'Get base info',
+      [{name: 'baseId', type: 'u32'}],
+      'Option<RmrkTypesBaseInfo>',
+    ),
+    baseParts: fn(
+      'Get all Base\'s parts',
+      [{name: 'baseId', type: 'u32'}],
+      'Vec<RmrkTypesPartType>',
+    ),
+    themeNames: fn(
+      'Get Base\'s theme names',
+      [{name: 'baseId', type: 'u32'}],
+      'Vec<Bytes>',
+    ),
+    themes: fn(
+      'Get Theme\'s keys values',
+      [
+        {name: 'baseId', type: 'u32'},
+        {name: 'themeName', type: 'String'},
+        {name: 'keys', type: 'Option<Vec<String>>'},
+      ],
+      'Option<RmrkTypesTheme>',
+    ),
+  },
 };
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -1135,7 +1135,32 @@
     const events = await submitTransactionAsync(sender, tx);
     const result = getCreateItemsResult(events);
 
-    for (let res of result) {
+    for (const res of result) {
+      expect(await api.rpc.unique.tokenProperties(collectionId, res.itemId)).not.to.be.empty;
+    }
+  });
+}
+
+export async function createMultipleItemsWithPropsExpectFailure(sender: IKeyringPair, collectionId: number, itemsData: any, owner: CrossAccountId | string = sender.address) {
+  await usingApi(async (api) => {
+    const to = normalizeAccountId(owner);
+    const tx = api.tx.unique.createMultipleItems(collectionId, to, itemsData);
+
+    const events = await expect(await submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
+    const result = getCreateItemsResult(events);
+
+    expect(result).to.be.equal(false);
+  });
+}
+
+export async function createMultipleItemsExWithPropsExpectSuccess(sender: IKeyringPair, collectionId: number, itemsData: any) {
+  await usingApi(async (api) => {
+    const tx = api.tx.unique.createMultipleItemsEx(collectionId, itemsData);
+
+    const events = await submitTransactionAsync(sender, tx);
+    const result = getCreateItemsResult(events);
+
+    for (const res of result) {
       expect(await api.rpc.unique.tokenProperties(collectionId, res.itemId)).not.to.be.empty;
     }
   });
@@ -1156,7 +1181,7 @@
       const createData = {refungible: {const_data: [], pieces: 100}};
       tx = api.tx.unique.createItem(collectionId, to, createData as any);
     } else {
-      const data = api.createType('UpDataStructsCreateItemData', { NFT: { constData: 'test', properties: props}});
+      const data = api.createType('UpDataStructsCreateItemData', {NFT: {constData: 'test', properties: props}});
       tx = api.tx.unique.createItem(collectionId, to, data as UpDataStructsCreateItemData);
     }
 
@@ -1186,6 +1211,25 @@
   return newItemId;
 }
 
+export async function createItemWithPropsExpectFailure(sender: IKeyringPair, collectionId: number, createMode: string, props: Array<Property>, owner: CrossAccountId | string = sender.address) {
+  await usingApi(async (api) => {
+
+    let tx;
+    if (createMode === 'NFT') {
+      const data = api.createType('UpDataStructsCreateItemData', {NFT: {constData: 'test', properties: props}});
+      tx = api.tx.unique.createItem(collectionId, normalizeAccountId(owner), data);
+    } else {
+      tx = api.tx.unique.createItem(collectionId, normalizeAccountId(owner), createMode);
+    }
+
+
+    const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
+    const result = getCreateItemResult(events);
+
+    expect(result.success).to.be.false;
+  });
+}
+
 export async function createItemExpectSuccess(sender: IKeyringPair, collectionId: number, createMode: string, owner: CrossAccountId | string = sender.address) {
   let newItemId = 0;
   await usingApi(async (api) => {