git.delta.rocks / unique-network / refs/commits / 6804826993dd

difftreelog

createMultipeItems migrated

rkv2022-09-13parent: #3404470.patch.diff
in: master

1 file changed

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 {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync, executeTransaction} from './substrate/substrate-api';22import {23  createCollectionExpectSuccess,24  destroyCollectionExpectSuccess,25  getGenericResult,26  normalizeAccountId,27  setCollectionLimitsExpectSuccess,28  addCollectionAdminExpectSuccess,29  getBalance,30  getTokenOwner,31  getLastTokenId,32  getCreatedCollectionCount,33  createCollectionWithPropsExpectSuccess,34  createMultipleItemsWithPropsExpectSuccess,35  getTokenProperties,36  requirePallets,37  Pallets,38  checkPalletsPresence,39} from './util/helpers';40import {usingPlaygrounds} from './util/playgrounds';4142chai.use(chaiAsPromised);43const expect = chai.expect;4445let donor: IKeyringPair;4647before(async () => {48  await usingPlaygrounds(async (_, privateKey) => {49    donor = privateKey('//Alice');50  });51});5253let alice: IKeyringPair;54let bob: IKeyringPair;5556describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {57  before(async () => {58    await usingPlaygrounds(async (helper) => {59      [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);60    });61  });6263  it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {64    await usingPlaygrounds(async (helper) => {65      const collection = await helper.nft.mintCollection(alice, {66        name: 'name',67        description: 'descr',68        tokenPrefix: 'COL',69        tokenPropertyPermissions: [70          {key: 'data', permission: {tokenOwner: true, mutable: false, collectionAdmin: false}},71        ],72      });73      const args = [74        {properties: [{key: 'data', value: '1'}]},75        {properties: [{key: 'data', value: '2'}]},76        {properties: [{key: 'data', value: '3'}]},77      ];78      const tokens = await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);79      for (const [i, token] of tokens.entries()) {80        const tokenData = await token.getData();81        expect(tokenData?.normalizedOwner).to.be.deep.equal({Substrate: alice.address});82        expect(tokenData?.properties[0].value).to.be.equal(args[i].properties[0].value);83      }84    });85  });8687  it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {88    await usingPlaygrounds(async (helper) => {89      const collection = await helper.ft.mintCollection(alice, {90        name: 'name',91        description: 'descr',92        tokenPrefix: 'COL',93      });94      const args = [95        {value: 1n},96        {value: 2n},97        {value: 3n},98      ];99      await helper.ft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);100      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(6n);101    });102  });103104  it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async function() {105    await usingPlaygrounds(async (helper) => {106      const collection = await helper.rft.mintCollection(alice, {107        name: 'name',108        description: 'descr',109        tokenPrefix: 'COL',110      });111      const args = [112        {pieces: 1n},113        {pieces: 2n},114        {pieces: 3n},115      ];116      const tokens = await helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);117118      for (const [i, token] of tokens.entries()) {119        expect(await token.getBalance({Substrate: alice.address})).to.be.equal(BigInt(i + 1));120      }121    });122  });123124  it('Can mint amount of items equals to collection limits', async () => {125    await usingPlaygrounds(async (helper) => {126      const collection = await helper.nft.mintCollection(alice, {127        name: 'name',128        description: 'descr',129        tokenPrefix: 'COL',130        limits: {131          tokenLimit: 2,132        },133      });134      const args = [{}, {}];135      await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);136    });137  });138139  it('Create 0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {140    await usingPlaygrounds(async (helper) => {141      const collection = await helper.nft.mintCollection(alice, {142        name: 'name',143        description: 'descr',144        tokenPrefix: 'COL',145        tokenPropertyPermissions: [146          {key: 'data', permission: {tokenOwner: false, mutable: true, collectionAdmin: true}},147        ],148      });149      const args = [150        {properties: [{key: 'data', value: '1'}]},151        {properties: [{key: 'data', value: '2'}]},152        {properties: [{key: 'data', value: '3'}]},153      ];154      const tokens = await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);155      for (const [i, token] of tokens.entries()) {156        const tokenData = await token.getData();157        expect(tokenData?.normalizedOwner).to.be.deep.equal({Substrate: alice.address});158        expect(tokenData?.properties[0].value).to.be.equal(args[i].properties[0].value);159      }160    });161  });162163  it('Create 0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {164    await usingPlaygrounds(async (helper) => {165      const collection = await helper.nft.mintCollection(alice, {166        name: 'name',167        description: 'descr',168        tokenPrefix: 'COL',169        tokenPropertyPermissions: [170          {key: 'data', permission: {tokenOwner: false, mutable: false, collectionAdmin: true}},171        ],172      });173      const args = [174        {properties: [{key: 'data', value: '1'}]},175        {properties: [{key: 'data', value: '2'}]},176        {properties: [{key: 'data', value: '3'}]},177      ];178      const tokens = await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);179      for (const [i, token] of tokens.entries()) {180        const tokenData = await token.getData();181        expect(tokenData?.normalizedOwner).to.be.deep.equal({Substrate: alice.address});182        expect(tokenData?.properties[0].value).to.be.equal(args[i].properties[0].value);183      }184    });185  });186187  it('Create 0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {188    await usingPlaygrounds(async (helper) => {189      const collection = await helper.nft.mintCollection(alice, {190        name: 'name',191        description: 'descr',192        tokenPrefix: 'COL',193        tokenPropertyPermissions: [194          {key: 'data', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},195        ],196      });197      const args = [198        {properties: [{key: 'data', value: '1'}]},199        {properties: [{key: 'data', value: '2'}]},200        {properties: [{key: 'data', value: '3'}]},201      ];202      const tokens = await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);203      for (const [i, token] of tokens.entries()) {204        const tokenData = await token.getData();205        expect(tokenData?.normalizedOwner).to.be.deep.equal({Substrate: alice.address});206        expect(tokenData?.properties[0].value).to.be.equal(args[i].properties[0].value);207      }208    });209  });210});211212describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {213  let alice: IKeyringPair;214  let bob: IKeyringPair;215216  before(async () => {217    await usingApi(async (api, privateKeyWrapper) => {218      alice = privateKeyWrapper('//Alice');219      bob = privateKeyWrapper('//Bob');220    });221  });222223  it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {224    await usingApi(async (api: ApiPromise) => {225      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'data', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});226      const itemsListIndexBefore = await getLastTokenId(api, collectionId);227      expect(itemsListIndexBefore).to.be.equal(0);228      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);229      const args = [230        {NFT: {properties: [{key: 'data', value: 'v1'}]}},231        {NFT: {properties: [{key: 'data', value: 'v2'}]}},232        {NFT: {properties: [{key: 'data', value: 'v3'}]}},233      ];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 getTokenProperties(api, collectionId, 1, ['data']))[0].value).to.be.equal('v1');245      expect((await getTokenProperties(api, collectionId, 2, ['data']))[0].value).to.be.equal('v2');246      expect((await getTokenProperties(api, collectionId, 3, ['data']))[0].value).to.be.equal('v3');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 function() {271    await requirePallets(this, [Pallets.ReFungible]);272273    await usingApi(async (api: ApiPromise) => {274      const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});275      const itemsListIndexBefore = await getLastTokenId(api, collectionId);276      expect(itemsListIndexBefore).to.be.equal(0);277      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);278      const args = [279        {ReFungible: {pieces: 1}},280        {ReFungible: {pieces: 2}},281        {ReFungible: {pieces: 3}},282      ];283      const createMultipleItemsTx = api.tx.unique284        .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);285      await submitTransactionAsync(bob, createMultipleItemsTx);286      const itemsListIndexAfter = await getLastTokenId(api, collectionId);287      expect(itemsListIndexAfter).to.be.equal(3);288289      expect(await getBalance(api, collectionId, bob.address, 1)).to.be.equal(1n);290      expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(2n);291      expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(3n);292    });293  });294});295296describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {297  let alice: IKeyringPair;298  let bob: IKeyringPair;299300  before(async () => {301    await usingPlaygrounds(async (helper) => {302      [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);303    });304  });305306  it('Regular user cannot create items in active NFT collection', async () => {307    await usingPlaygrounds(async (helper) => {308      const collection = await helper.nft.mintCollection(alice, {309        name: 'name',310        description: 'descr',311        tokenPrefix: 'COL',312      });313      const args = [314        {},315        {},316      ];317      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(bob, collection.collectionId, {Substrate: alice.address}, args);318      await expect(mintTx()).to.be.rejectedWith(/common\.PublicMintingNotAllowed/);319    });320  });321322  it('Regular user cannot create items in active Fungible collection', async () => {323    await usingPlaygrounds(async (helper) => {324      const collection = await helper.ft.mintCollection(alice, {325        name: 'name',326        description: 'descr',327        tokenPrefix: 'COL',328      });329      const args = [330        {value: 1n},331        {value: 2n},332        {value: 3n},333      ];334      const mintTx = async () => helper.ft.mintMultipleTokensWithOneOwner(bob, collection.collectionId, {Substrate: alice.address}, args);335      await expect(mintTx()).to.be.rejectedWith(/common\.PublicMintingNotAllowed/);336    });337  });338339  it('Regular user cannot create items in active ReFungible collection', async function() {340    await usingPlaygrounds(async (helper) => {341      const collection = await helper.rft.mintCollection(alice, {342        name: 'name',343        description: 'descr',344        tokenPrefix: 'COL',345      });346      const args = [347        {pieces: 1n},348        {pieces: 1n},349        {pieces: 1n},350      ];351      const mintTx = async () => helper.rft.mintMultipleTokensWithOneOwner(bob, collection.collectionId, {Substrate: alice.address}, args);352      await expect(mintTx()).to.be.rejectedWith(/common\.PublicMintingNotAllowed/);353    });354  });355356  it('Create token in not existing collection', async () => {357    await usingPlaygrounds(async (helper) => {358      const collectionId = 1_000_000;359      const args = [360        {},361        {},362      ];363      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(bob, collectionId, {Substrate: alice.address}, args);364      await expect(mintTx()).to.be.rejectedWith(/common\.CollectionNotFound/);365    });366  });367368  it('Create NFTs that has reached the maximum data limit', async function() {369    await usingPlaygrounds(async (helper) => {370      const collection = await helper.nft.mintCollection(alice, {371        name: 'name',372        description: 'descr',373        tokenPrefix: 'COL',374        tokenPropertyPermissions: [375          {key: 'data', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},376        ],377      });378      const args = [379        {properties: [{key: 'data', value: 'A'.repeat(32769)}]},380        {properties: [{key: 'data', value: 'B'.repeat(32769)}]},381        {properties: [{key: 'data', value: 'C'.repeat(32769)}]},382      ];383      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);384      await expect(mintTx()).to.be.rejected;385    });386  });387388  it('Create Refungible tokens that has reached the maximum data limit', async function() {389    await usingPlaygrounds(async (helper) => {390      const collection = await helper.rft.mintCollection(alice, {391        name: 'name',392        description: 'descr',393        tokenPrefix: 'COL',394        tokenPropertyPermissions: [395          {key: 'data', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},396        ],397      });398      const args = [399        {pieces: 10n, properties: [{key: 'data', value: 'A'.repeat(32769)}]},400        {pieces: 10n, properties: [{key: 'data', value: 'B'.repeat(32769)}]},401        {pieces: 10n, properties: [{key: 'data', value: 'C'.repeat(32769)}]},402      ];403      const mintTx = async () => helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);404      await expect(mintTx()).to.be.rejected;405    });406  });407408  it('Create tokens with different types', async () => {409    await usingPlaygrounds(async (helper) => {410      const {collectionId} = await helper.nft.mintCollection(alice, {411        name: 'name',412        description: 'descr',413        tokenPrefix: 'COL',414      });415416      //FIXME:417      const types = ['NFT', 'Fungible', 'ReFungible'];418      const mintTx = helper.api?.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), types);419      await expect(helper.signTransaction(alice, mintTx)).to.be.rejected;420    });421  });422423  it('Create tokens with different data limits <> maximum data limit', async () => {424    await usingApi(async (api: ApiPromise) => {425      const collectionId = await createCollectionWithPropsExpectSuccess({426        propPerm: [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}],427      });428      const args = [429        {NFT: {properties: [{key: 'key', value: 'A'}]}},430        {NFT: {properties: [{key: 'key', value: 'B'.repeat(32769)}]}},431      ];432      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);433      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;434    });435  });436437  it('Fails when minting tokens exceeds collectionLimits amount', async () => {438    await usingApi(async (api) => {439      const collectionId = await createCollectionExpectSuccess();440      await setCollectionLimitsExpectSuccess(alice, collectionId, {441        tokenLimit: 1,442      });443      const args = [444        {NFT: {}},445        {NFT: {}},446      ];447      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);448      await expect(executeTransaction(api, alice, createMultipleItemsTx)).to.be.rejectedWith(/common\.CollectionTokenLimitExceeded/);449    });450  });451452  it('User doesnt have editing rights', async () => {453    await usingApi(async (api: ApiPromise) => {454      const collectionId = await createCollectionWithPropsExpectSuccess({455        propPerm: [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}],456      });457      const itemsListIndexBefore = await getLastTokenId(api, collectionId);458      expect(itemsListIndexBefore).to.be.equal(0);459      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);460      const args = [461        {NFT: {properties: [{key: 'key1', value: 'v2'}]}},462        {NFT: {}},463        {NFT: {}},464      ];465466      const tx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(bob.address), args);467      await expect(executeTransaction(api, bob, tx)).to.be.rejectedWith(/common\.NoPermission/);468    });469  });470471  it('Adding property without access rights', async () => {472    await usingApi(async (api: ApiPromise) => {473      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'k', value: 'v1'}]});474      const itemsListIndexBefore = await getLastTokenId(api, collectionId);475      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);476      expect(itemsListIndexBefore).to.be.equal(0);477      const args = [{NFT: {properties: [{key: 'k', value: 'v'}]}},478        {NFT: {}},479        {NFT: {}}];480481      const tx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(bob.address), args);482      await expect(executeTransaction(api, bob, tx)).to.be.rejectedWith(/common\.NoPermission/);483    });484  });485486  it('Adding more than 64 prps', async () => {487    await usingApi(async (api: ApiPromise) => {488      const propPerms = [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}];489      for (let i = 0; i < 65; i++) {490        propPerms.push({key: `key${i}`, permission: {mutable: true, collectionAdmin: true, tokenOwner: true}});491      }492493      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});494495      const tx1 = api.tx.unique.setTokenPropertyPermissions(collectionId, propPerms);496      await expect(executeTransaction(api, alice, tx1)).to.be.rejectedWith(/common\.PropertyLimitReached/);497498      const itemsListIndexBefore = await getLastTokenId(api, collectionId);499      expect(itemsListIndexBefore).to.be.equal(0);500      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);501502      const prps = [];503504      for (let i = 0; i < 65; i++) {505        prps.push({key: `key${i}`, value: `value${i}`});506      }507508      const args = [509        {NFT: {properties: prps}},510        {NFT: {properties: prps}},511        {NFT: {properties: prps}},512      ];513514      // there are no permissions, but will fail anyway because of too much weight for a block515      const tx2 = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);516      await expect(submitTransactionExpectFailAsync(alice, tx2)).to.be.rejected;517    });518  });519520  it('Trying to add bigger property than allowed', async () => {521    await usingApi(async (api: ApiPromise) => {522      const collectionId = await createCollectionWithPropsExpectSuccess({523        propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}],524      });525      const itemsListIndexBefore = await getLastTokenId(api, collectionId);526      expect(itemsListIndexBefore).to.be.equal(0);527      const args = [{NFT: {properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}},528        {NFT: {properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}},529        {NFT: {properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}}];530531      const tx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);532      await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);533    });534  });535});
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 {IKeyringPair} from '@polkadot/types/types';18import chai from 'chai';19import chaiAsPromised from 'chai-as-promised';20import {21  normalizeAccountId,22} from './util/helpers';23import {usingPlaygrounds} from './util/playgrounds';2425chai.use(chaiAsPromised);26const expect = chai.expect;2728let donor: IKeyringPair;2930before(async () => {31  await usingPlaygrounds(async (_, privateKey) => {32    donor = privateKey('//Alice');33  });34});3536describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {37  let alice: IKeyringPair;3839  before(async () => {40    await usingPlaygrounds(async (helper) => {41      [alice] = await helper.arrange.createAccounts([100n], donor);42    });43  });4445  it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {46    await usingPlaygrounds(async (helper) => {47      const collection = await helper.nft.mintCollection(alice, {48        name: 'name',49        description: 'descr',50        tokenPrefix: 'COL',51        tokenPropertyPermissions: [52          {key: 'data', permission: {tokenOwner: true, mutable: false, collectionAdmin: false}},53        ],54      });55      const args = [56        {properties: [{key: 'data', value: '1'}]},57        {properties: [{key: 'data', value: '2'}]},58        {properties: [{key: 'data', value: '3'}]},59      ];60      const tokens = await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);61      for (const [i, token] of tokens.entries()) {62        const tokenData = await token.getData();63        expect(tokenData?.normalizedOwner).to.be.deep.equal({Substrate: alice.address});64        expect(tokenData?.properties[0].value).to.be.equal(args[i].properties[0].value);65      }66    });67  });6869  it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {70    await usingPlaygrounds(async (helper) => {71      const collection = await helper.ft.mintCollection(alice, {72        name: 'name',73        description: 'descr',74        tokenPrefix: 'COL',75      });76      const args = [77        {value: 1n},78        {value: 2n},79        {value: 3n},80      ];81      await helper.ft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);82      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(6n);83    });84  });8586  it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async function() {87    await usingPlaygrounds(async (helper) => {88      const collection = await helper.rft.mintCollection(alice, {89        name: 'name',90        description: 'descr',91        tokenPrefix: 'COL',92      });93      const args = [94        {pieces: 1n},95        {pieces: 2n},96        {pieces: 3n},97      ];98      const tokens = await helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);99100      for (const [i, token] of tokens.entries()) {101        expect(await token.getBalance({Substrate: alice.address})).to.be.equal(BigInt(i + 1));102      }103    });104  });105106  it('Can mint amount of items equals to collection limits', async () => {107    await usingPlaygrounds(async (helper) => {108      const collection = await helper.nft.mintCollection(alice, {109        name: 'name',110        description: 'descr',111        tokenPrefix: 'COL',112        limits: {113          tokenLimit: 2,114        },115      });116      const args = [{}, {}];117      await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);118    });119  });120121  it('Create 0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {122    await usingPlaygrounds(async (helper) => {123      const collection = await helper.nft.mintCollection(alice, {124        name: 'name',125        description: 'descr',126        tokenPrefix: 'COL',127        tokenPropertyPermissions: [128          {key: 'data', permission: {tokenOwner: false, mutable: true, collectionAdmin: true}},129        ],130      });131      const args = [132        {properties: [{key: 'data', value: '1'}]},133        {properties: [{key: 'data', value: '2'}]},134        {properties: [{key: 'data', value: '3'}]},135      ];136      const tokens = await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);137      for (const [i, token] of tokens.entries()) {138        const tokenData = await token.getData();139        expect(tokenData?.normalizedOwner).to.be.deep.equal({Substrate: alice.address});140        expect(tokenData?.properties[0].value).to.be.equal(args[i].properties[0].value);141      }142    });143  });144145  it('Create 0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {146    await usingPlaygrounds(async (helper) => {147      const collection = await helper.nft.mintCollection(alice, {148        name: 'name',149        description: 'descr',150        tokenPrefix: 'COL',151        tokenPropertyPermissions: [152          {key: 'data', permission: {tokenOwner: false, mutable: false, collectionAdmin: true}},153        ],154      });155      const args = [156        {properties: [{key: 'data', value: '1'}]},157        {properties: [{key: 'data', value: '2'}]},158        {properties: [{key: 'data', value: '3'}]},159      ];160      const tokens = await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);161      for (const [i, token] of tokens.entries()) {162        const tokenData = await token.getData();163        expect(tokenData?.normalizedOwner).to.be.deep.equal({Substrate: alice.address});164        expect(tokenData?.properties[0].value).to.be.equal(args[i].properties[0].value);165      }166    });167  });168169  it('Create 0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {170    await usingPlaygrounds(async (helper) => {171      const collection = await helper.nft.mintCollection(alice, {172        name: 'name',173        description: 'descr',174        tokenPrefix: 'COL',175        tokenPropertyPermissions: [176          {key: 'data', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},177        ],178      });179      const args = [180        {properties: [{key: 'data', value: '1'}]},181        {properties: [{key: 'data', value: '2'}]},182        {properties: [{key: 'data', value: '3'}]},183      ];184      const tokens = await helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);185      for (const [i, token] of tokens.entries()) {186        const tokenData = await token.getData();187        expect(tokenData?.normalizedOwner).to.be.deep.equal({Substrate: alice.address});188        expect(tokenData?.properties[0].value).to.be.equal(args[i].properties[0].value);189      }190    });191  });192});193194describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {195  let alice: IKeyringPair;196  let bob: IKeyringPair;197198  before(async () => {199    await usingPlaygrounds(async (helper) => {200      [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);201    });202  });203204  it('Regular user cannot create items in active NFT collection', async () => {205    await usingPlaygrounds(async (helper) => {206      const collection = await helper.nft.mintCollection(alice, {207        name: 'name',208        description: 'descr',209        tokenPrefix: 'COL',210      });211      const args = [212        {},213        {},214      ];215      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(bob, collection.collectionId, {Substrate: alice.address}, args);216      await expect(mintTx()).to.be.rejectedWith(/common\.PublicMintingNotAllowed/);217    });218  });219220  it('Regular user cannot create items in active Fungible collection', async () => {221    await usingPlaygrounds(async (helper) => {222      const collection = await helper.ft.mintCollection(alice, {223        name: 'name',224        description: 'descr',225        tokenPrefix: 'COL',226      });227      const args = [228        {value: 1n},229        {value: 2n},230        {value: 3n},231      ];232      const mintTx = async () => helper.ft.mintMultipleTokensWithOneOwner(bob, collection.collectionId, {Substrate: alice.address}, args);233      await expect(mintTx()).to.be.rejectedWith(/common\.PublicMintingNotAllowed/);234    });235  });236237  it('Regular user cannot create items in active ReFungible collection', async function() {238    await usingPlaygrounds(async (helper) => {239      const collection = await helper.rft.mintCollection(alice, {240        name: 'name',241        description: 'descr',242        tokenPrefix: 'COL',243      });244      const args = [245        {pieces: 1n},246        {pieces: 1n},247        {pieces: 1n},248      ];249      const mintTx = async () => helper.rft.mintMultipleTokensWithOneOwner(bob, collection.collectionId, {Substrate: alice.address}, args);250      await expect(mintTx()).to.be.rejectedWith(/common\.PublicMintingNotAllowed/);251    });252  });253254  it('Create token in not existing collection', async () => {255    await usingPlaygrounds(async (helper) => {256      const collectionId = 1_000_000;257      const args = [258        {},259        {},260      ];261      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(bob, collectionId, {Substrate: alice.address}, args);262      await expect(mintTx()).to.be.rejectedWith(/common\.CollectionNotFound/);263    });264  });265266  it('Create NFTs that has reached the maximum data limit', async function() {267    await usingPlaygrounds(async (helper) => {268      const collection = await helper.nft.mintCollection(alice, {269        name: 'name',270        description: 'descr',271        tokenPrefix: 'COL',272        tokenPropertyPermissions: [273          {key: 'data', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},274        ],275      });276      const args = [277        {properties: [{key: 'data', value: 'A'.repeat(32769)}]},278        {properties: [{key: 'data', value: 'B'.repeat(32769)}]},279        {properties: [{key: 'data', value: 'C'.repeat(32769)}]},280      ];281      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);282      await expect(mintTx()).to.be.rejected;283    });284  });285286  it('Create Refungible tokens that has reached the maximum data limit', async function() {287    await usingPlaygrounds(async (helper) => {288      const collection = await helper.rft.mintCollection(alice, {289        name: 'name',290        description: 'descr',291        tokenPrefix: 'COL',292        tokenPropertyPermissions: [293          {key: 'data', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},294        ],295      });296      const args = [297        {pieces: 10n, properties: [{key: 'data', value: 'A'.repeat(32769)}]},298        {pieces: 10n, properties: [{key: 'data', value: 'B'.repeat(32769)}]},299        {pieces: 10n, properties: [{key: 'data', value: 'C'.repeat(32769)}]},300      ];301      const mintTx = async () => helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);302      await expect(mintTx()).to.be.rejected;303    });304  });305306  it('Create tokens with different types', async () => {307    await usingPlaygrounds(async (helper) => {308      const {collectionId} = await helper.nft.mintCollection(alice, {309        name: 'name',310        description: 'descr',311        tokenPrefix: 'COL',312      });313314      //FIXME:315      const types = ['NFT', 'Fungible', 'ReFungible'];316      const mintTx = helper.api?.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), types);317      await expect(helper.signTransaction(alice, mintTx)).to.be.rejected;318    });319  });320321  it('Create tokens with different data limits <> maximum data limit', async () => {322    await usingPlaygrounds(async (helper) => {323      const collection = await helper.nft.mintCollection(alice, {324        name: 'name',325        description: 'descr',326        tokenPrefix: 'COL',327        tokenPropertyPermissions: [328          {key: 'data', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},329        ],330      });331      const args = [332        {properties: [{key: 'data', value: 'A'}]},333        {properties: [{key: 'data', value: 'B'.repeat(32769)}]},334      ];335      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);336      await expect(mintTx()).to.be.rejected;337    });338  });339340  it('Fails when minting tokens exceeds collectionLimits amount', async () => {341    await usingPlaygrounds(async (helper) => {342      const collection = await helper.nft.mintCollection(alice, {343        name: 'name',344        description: 'descr',345        tokenPrefix: 'COL',346        tokenPropertyPermissions: [347          {key: 'data', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},348        ],349        limits: {350          tokenLimit: 1,351        },352      });353      const args = [354        {},355        {},356      ];357      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);358      await expect(mintTx()).to.be.rejected;359    });360  });361362  it('User doesnt have editing rights', async () => {363    await usingPlaygrounds(async (helper) => {364      const collection = await helper.nft.mintCollection(alice, {365        name: 'name',366        description: 'descr',367        tokenPrefix: 'COL',368        tokenPropertyPermissions: [369          {key: 'data', permission: {tokenOwner: false, mutable: true, collectionAdmin: false}},370        ],371      });372      const args = [373        {properties: [{key: 'data', value: 'A'}]},374      ];375      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);376      await expect(mintTx()).to.be.rejected;377    });378  });379380  it('Adding property without access rights', async () => {381    await usingPlaygrounds(async (helper) => {382      const collection = await helper.nft.mintCollection(alice, {383        name: 'name',384        description: 'descr',385        tokenPrefix: 'COL',386        properties: [387          {388            key: 'data',389            value: 'v',390          },391        ],392      });393      const args = [394        {properties: [{key: 'data', value: 'A'}]},395      ];396      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);397      await expect(mintTx()).to.be.rejected;398    });399  });400401  it('Adding more than 64 prps', async () => {402    await usingPlaygrounds(async (helper) => {403      const collection = await helper.nft.mintCollection(alice, {404        name: 'name',405        description: 'descr',406        tokenPrefix: 'COL',407      });408      const prps = [];409410      for (let i = 0; i < 65; i++) {411        prps.push({key: `key${i}`, value: `value${i}`});412      }413414      const args = [415        {properties: prps},416        {properties: prps},417        {properties: prps},418      ];419420      const mintTx = async () => helper.nft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, args);421      await expect(mintTx()).to.be.rejected;422    });423  });424});