git.delta.rocks / unique-network / refs/commits / 71f425f89b51

difftreelog

fix(tests) repair createMultipleItem + ..Ex, remove features made obsolete by properties

Fahrrader2022-05-30parent: #2dd1788.patch.diff
in: master

9 files changed

modifiedtests/src/contracts.test.tsdiffbeforeafterboth
--- a/tests/src/contracts.test.ts
+++ b/tests/src/contracts.test.ts
@@ -139,9 +139,9 @@
       await addToAllowListExpectSuccess(alice, collectionId, bob.address);
 
       const transferTx = contract.tx.createMultipleItems(value, gasLimit, bob.address, collectionId, [
-        {Nft: {const_data: '0x010203'}},
-        {Nft: {const_data: '0x010204'}},
-        {Nft: {const_data: '0x010205'}},
+        {NFT: {/*const_data: '0x010203'*/}},
+        {NFT: {/*const_data: '0x010204'*/}},
+        {NFT: {/*const_data: '0x010205'*/}},
       ]);
       const events = await submitTransactionAsync(alice, transferTx);
       const result = getGenericResult(events);
@@ -153,15 +153,15 @@
       expect(tokensAfter).to.be.deep.equal([
         {
           Owner: bob.address,
-          ConstData: '0x010203',
+          //ConstData: '0x010203',
         },
         {
           Owner: bob.address,
-          ConstData: '0x010204',
+          //ConstData: '0x010204',
         },
         {
           Owner: bob.address,
-          ConstData: '0x010205',
+          //ConstData: '0x010205',
         },
       ]);
     });
modifiedtests/src/createCollection.test.tsdiffbeforeafterboth
--- a/tests/src/createCollection.test.ts
+++ b/tests/src/createCollection.test.ts
@@ -63,17 +63,17 @@
       const bob = privateKey('//Bob');
       const tx = api.tx.unique.createCollectionEx({
         mode: {Fungible: 8},
-        access: 'AllowList',
+        //access: 'AllowList',
         name: [1],
         description: [2],
         tokenPrefix: '0x000000',
-        offchainSchema: '0x111111',
-        schemaVersion: 'Unique',
+        //offchainSchema: '0x111111',
+        //schemaVersion: 'Unique',
         pendingSponsor: bob.address,
         limits: {
           accountTokenOwnershipLimit: 3,
         },
-        constOnChainSchema: '0x333333',
+        //constOnChainSchema: '0x333333',
       });
       const events = await submitTransactionAsync(alice, tx);
       const result = getCreateCollectionResult(events);
@@ -81,15 +81,15 @@
       const collection = (await getDetailedCollectionInfo(api, result.collectionId))!;
       expect(collection.owner.toString()).to.equal(alice.address);
       expect(collection.mode.asFungible.toNumber()).to.equal(8);
-      expect(collection.access.isAllowList).to.be.true;
+      //expect(collection.access.isAllowList).to.be.true;
       expect(collection.name.map(v => v.toNumber())).to.deep.equal([1]);
       expect(collection.description.map(v => v.toNumber())).to.deep.equal([2]);
       expect(collection.tokenPrefix.toString()).to.equal('0x000000');
-      expect(collection.offchainSchema.toString()).to.equal('0x111111');
-      expect(collection.schemaVersion.isUnique).to.be.true;
+      //expect(collection.offchainSchema.toString()).to.equal('0x111111');
+      //expect(collection.schemaVersion.isUnique).to.be.true;
       expect(collection.sponsorship.asUnconfirmed.toString()).to.equal(bob.address);
       expect(collection.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.equal(3);
-      expect(collection.constOnChainSchema.toString()).to.equal('0x333333');
+      //expect(collection.constOnChainSchema.toString()).to.equal('0x333333');
     });
   });
 });
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -30,29 +30,34 @@
   getBalance,
   getTokenOwner,
   getLastTokenId,
-  getConstMetadata,
   getCreatedCollectionCount,
   createCollectionWithPropsExpectSuccess,
-  getCreateItemsResult,
   createMultipleItemsWithPropsExpectSuccess,
-  createMultipleItemsWithPropsExpectFailure,
+  getTokenProperties,
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
 
 describe('Integration Test createMultipleItems(collection_id, owner, items_data):', () => {
-  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {
+  it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess();
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
+
       const alice = privateKey('//Alice');
-      const args = [{Nft: {const_data: '0x31'}},
-        {Nft: {const_data: '0x32'}},
-        {Nft: {const_data: '0x33'}}];
-      const createMultipleItemsTx = api.tx.unique
-        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+      await submitTransactionAsync(
+        alice, 
+        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'data', permission: {tokenOwner: true}}])
+      );
+      
+      const args = [
+        {NFT: {properties: [{key: 'data', value: '1'}]}},
+        {NFT: {properties: [{key: 'data', value: '2'}]}},
+        {NFT: {properties: [{key: 'data', value: '3'}]}}
+      ];
+      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await submitTransactionAsync(alice, createMultipleItemsTx);
       const itemsListIndexAfter = await getLastTokenId(api, collectionId);
       expect(itemsListIndexAfter).to.be.equal(3);
@@ -61,13 +66,13 @@
       expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
       expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
 
-      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+      expect((await getTokenProperties(api, collectionId, 1, ['data']))[0].value).to.be.equal('1');
+      expect((await getTokenProperties(api, collectionId, 2, ['data']))[0].value).to.be.equal('2');
+      expect((await getTokenProperties(api, collectionId, 3, ['data']))[0].value).to.be.equal('3');
     });
   });
 
-  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {
+  it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
@@ -87,16 +92,16 @@
     });
   });
 
-  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
+  it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       const alice = privateKey('//Alice');
       const args = [
-        {ReFungible: {const_data: [0x31], pieces: 1}},
-        {ReFungible: {const_data: [0x32], pieces: 1}},
-        {ReFungible: {const_data: [0x33], pieces: 1}},
+        {ReFungible: {pieces: 1}},
+        {ReFungible: {pieces: 2}},
+        {ReFungible: {pieces: 3}},
       ];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
@@ -105,12 +110,8 @@
       expect(itemsListIndexAfter).to.be.equal(3);
 
       expect(await getBalance(api, collectionId, alice.address, 1)).to.be.equal(1n);
-      expect(await getBalance(api, collectionId, alice.address, 2)).to.be.equal(1n);
-      expect(await getBalance(api, collectionId, alice.address, 3)).to.be.equal(1n);
-
-      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+      expect(await getBalance(api, collectionId, alice.address, 2)).to.be.equal(2n);
+      expect(await getBalance(api, collectionId, alice.address, 3)).to.be.equal(3n);
     });
   });
 
@@ -123,8 +124,8 @@
         tokenLimit: 2,
       });
       const args = [
-        {NFT: {const_data: 'A'}},
-        {NFT: {const_data: 'B'}},
+        {NFT: {}},
+        {NFT: {}},
       ];
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       const events = await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -133,16 +134,17 @@
     });
   });
 
-  it('Create  0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {
+  it('Create 0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v1'}]}},
-        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'v2'}]}},
-        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'v3'}]}}];
+      const args = [
+        {NFT: {properties: [{key: 'k', value: 'v1'}]}},
+        {NFT: {properties: [{key: 'k', value: 'v2'}]}},
+        {NFT: {properties: [{key: 'k', value: 'v3'}]}}
+      ];
 
       await createMultipleItemsWithPropsExpectSuccess(alice, collectionId, args);
       const itemsListIndexAfter = await getLastTokenId(api, collectionId);
@@ -152,13 +154,13 @@
       expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
       expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
 
-      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+      expect((await getTokenProperties(api, collectionId, 1, ['k']))[0].value).to.be.equal('v1');
+      expect((await getTokenProperties(api, collectionId, 2, ['k']))[0].value).to.be.equal('v2');
+      expect((await getTokenProperties(api, collectionId, 3, ['k']))[0].value).to.be.equal('v3');
     });
   });
 
-  it('Create  0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {
+  it('Create 0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
@@ -166,9 +168,11 @@
       const alice = privateKey('//Alice');
       const bob = privateKey('//Bob');
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v1'}]}},
-        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'v2'}]}},
-        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'v3'}]}}];
+      const args = [
+        {NFT: {properties: [{key: 'k', value: 'v1'}]}},
+        {NFT: {properties: [{key: 'k', value: 'v2'}]}},
+        {NFT: {properties: [{key: 'k', value: 'v3'}]}}
+      ];
 
       await createMultipleItemsWithPropsExpectSuccess(alice, collectionId, args);
       const itemsListIndexAfter = await getLastTokenId(api, collectionId);
@@ -178,22 +182,25 @@
       expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
       expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
 
-      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+      expect((await getTokenProperties(api, collectionId, 1, ['k']))[0].value).to.be.equal('v1');
+      expect((await getTokenProperties(api, collectionId, 2, ['k']))[0].value).to.be.equal('v2');
+      expect((await getTokenProperties(api, collectionId, 3, ['k']))[0].value).to.be.equal('v3');
     });
   });
 
-  it('Create  0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {
+  it('Create 0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {
     await usingApi(async (api: ApiPromise) => {
-      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});
+      const collectionId = await createCollectionWithPropsExpectSuccess(
+        {propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]}
+      );
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v1'}]}},
-        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'v2'}]}},
-        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'v3'}]}}];
+      const args = [
+        {NFT: {properties: [{key: 'k', value: 'v1'}]}},
+        {NFT: {properties: [{key: 'k', value: 'v2'}]}},
+        {NFT: {properties: [{key: 'k', value: 'v3'}]}}
+      ];
 
       await createMultipleItemsWithPropsExpectSuccess(alice, collectionId, args);
       const itemsListIndexAfter = await getLastTokenId(api, collectionId);
@@ -203,15 +210,14 @@
       expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
       expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
 
-      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+      expect((await getTokenProperties(api, collectionId, 1, ['k']))[0].value).to.be.equal('v1');
+      expect((await getTokenProperties(api, collectionId, 2, ['k']))[0].value).to.be.equal('v2');
+      expect((await getTokenProperties(api, collectionId, 3, ['k']))[0].value).to.be.equal('v3');
     });
   });
 });
 
 describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {
-
   let alice: IKeyringPair;
   let bob: IKeyringPair;
 
@@ -222,15 +228,19 @@
     });
   });
 
-  it('Create  0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {
+  it('Create 0x31, 0x32, 0x33 items in active NFT collection and verify tokens data in chain', async () => {
     await usingApi(async (api: ApiPromise) => {
-      const collectionId = await createCollectionExpectSuccess();
+      const collectionId = await createCollectionWithPropsExpectSuccess(
+        {propPerm: [{key: 'data', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]}
+      );
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const args = [{Nft: {const_data: '0x31'}},
-        {Nft: {const_data: '0x32'}},
-        {Nft: {const_data: '0x33'}}];
+      const args = [
+        {NFT: {properties: [{key: 'data', value: 'v1'}]}},
+        {NFT: {properties: [{key: 'data', value: 'v2'}]}},
+        {NFT: {properties: [{key: 'data', value: 'v3'}]}}
+      ];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
       await submitTransactionAsync(bob, createMultipleItemsTx);
@@ -241,13 +251,13 @@
       expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(bob.address));
       expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(bob.address));
 
-      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+      expect((await getTokenProperties(api, collectionId, 1, ['data']))[0].value).to.be.equal('v1');
+      expect((await getTokenProperties(api, collectionId, 2, ['data']))[0].value).to.be.equal('v2');
+      expect((await getTokenProperties(api, collectionId, 3, ['data']))[0].value).to.be.equal('v3');
     });
   });
 
-  it('Create  0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {
+  it('Create 0x01, 0x02, 0x03 items in active Fungible collection and verify tokens data in chain', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
@@ -267,16 +277,16 @@
     });
   });
 
-  it('Create  0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
+  it('Create 0x31, 0x32, 0x33 items in active ReFungible collection and verify tokens data in chain', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
       const args = [
-        {ReFungible: {const_data: [0x31], pieces: 1}},
-        {ReFungible: {const_data: [0x32], pieces: 1}},
-        {ReFungible: {const_data: [0x33], pieces: 1}},
+        {ReFungible: {pieces: 1}},
+        {ReFungible: {pieces: 2}},
+        {ReFungible: {pieces: 3}},
       ];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
@@ -285,18 +295,13 @@
       expect(itemsListIndexAfter).to.be.equal(3);
 
       expect(await getBalance(api, collectionId, bob.address, 1)).to.be.equal(1n);
-      expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(1n);
-      expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(1n);
-
-      expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+      expect(await getBalance(api, collectionId, bob.address, 2)).to.be.equal(2n);
+      expect(await getBalance(api, collectionId, bob.address, 3)).to.be.equal(3n);
     });
   });
 });
 
 describe('Negative Integration Test createMultipleItems(collection_id, owner, items_data):', () => {
-
   let alice: IKeyringPair;
   let bob: IKeyringPair;
 
@@ -312,12 +317,11 @@
       const collectionId = await createCollectionExpectSuccess();
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
-      const args = [{Nft: {const_data: '0x31'}},
-        {Nft: {const_data: '0x32'}},
-        {Nft: {const_data: '0x33'}}];
-      const createMultipleItemsTx = api.tx.unique
-        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
-      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
+      const args = [{NFT: {}},
+        {NFT: {}},
+        {NFT: {}}];
+      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+      await expect(executeTransaction(api, bob, createMultipleItemsTx)).to.be.rejectedWith(/common\.PublicMintingNotAllowed/);
     });
   });
 
@@ -331,9 +335,8 @@
         {Fungible: {value: 2}},
         {Fungible: {value: 3}},
       ];
-      const createMultipleItemsTx = api.tx.unique
-        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
-      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
+      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+      await expect(executeTransaction(api, bob, createMultipleItemsTx)).to.be.rejectedWith(/common\.PublicMintingNotAllowed/);
     });
   });
 
@@ -343,37 +346,38 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       const args = [
-        {ReFungible: {const_data: [0x31], pieces: 1}},
-        {ReFungible: {const_data: [0x32], pieces: 1}},
-        {ReFungible: {const_data: [0x33], pieces: 1}},
+        {ReFungible: {pieces: 1}},
+        {ReFungible: {pieces: 1}},
+        {ReFungible: {pieces: 1}},
       ];
-      const createMultipleItemsTx = api.tx.unique
-        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
-      await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
+      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+      await expect(executeTransaction(api, bob, createMultipleItemsTx)).to.be.rejectedWith(/common\.PublicMintingNotAllowed/);
     });
   });
 
   it('Create token in not existing collection', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await getCreatedCollectionCount(api) + 1;
-      const createMultipleItemsTx = api.tx.unique
-        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'NFT', 'NFT']);
-      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
+      const createMultipleItemsTx = api.tx.unique.createMultipleItems(
+        collectionId, normalizeAccountId(alice.address), ['NFT', 'NFT', 'NFT']
+      );
+      await expect(executeTransaction(api, alice, createMultipleItemsTx)).to.be.rejectedWith(/common\.CollectionNotFound/);
     });
   });
 
   it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {
     await usingApi(async (api: ApiPromise) => {
       // NFT
-      const collectionId = await createCollectionExpectSuccess();
+      const collectionId = await createCollectionWithPropsExpectSuccess({
+        propPerm: [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]
+      });
       const alice = privateKey('//Alice');
       const args = [
-        {NFT: {const_data: 'A'.repeat(2049)}},
-        {NFT: {const_data: 'B'.repeat(2049)}},
-        {NFT: {const_data: 'C'.repeat(2049)}},
+        {NFT: {properties: [{key: 'key', value: 'A'.repeat(32769)}]}},
+        {NFT: {properties: [{key: 'key', value: 'B'.repeat(32769)}]}},
+        {NFT: {properties: [{key: 'key', value: 'C'.repeat(32769)}]}},
       ];
-      const createMultipleItemsTx = api.tx.unique
-        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
 
       // ReFungible
@@ -395,68 +399,61 @@
       const collectionId = await createCollectionExpectSuccess();
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);
-      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
-      // garbage collection :-D
+      await expect(
+        executeTransaction(api, alice, createMultipleItemsTx)
+      ).to.be.rejectedWith(
+        /nonfungible\.NotNonfungibleDataUsedToMintFungibleCollectionToken/
+      );
+      // garbage collection :-D // lol
       await destroyCollectionExpectSuccess(collectionId);
     });
   });
 
   it('Create tokens with different data limits <> maximum data limit', async () => {
     await usingApi(async (api: ApiPromise) => {
-      const collectionId = await createCollectionExpectSuccess();
+      const collectionId = await createCollectionWithPropsExpectSuccess({
+        propPerm: [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]
+      });
       const args = [
-        {NFT: {const_data: 'A'}},
-        {NFT: {const_data: 'B'.repeat(2049)}},
+        {NFT: {properties: [{key: 'key', value: 'A'}]}},
+        {NFT: {properties: [{key: 'key', value: 'B'.repeat(32769)}]}},
       ];
-      const createMultipleItemsTx = await api.tx.unique
-        .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+      const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
     });
   });
 
   it('Fails when minting tokens exceeds collectionLimits amount', async () => {
     await usingApi(async (api) => {
-
       const collectionId = await createCollectionExpectSuccess();
       await setCollectionLimitsExpectSuccess(alice, collectionId, {
         tokenLimit: 1,
       });
       const args = [
-        {NFT: {const_data: 'A'}},
-        {NFT: {const_data: 'B'}},
+        {NFT: {}},
+        {NFT: {}},
       ];
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
-      await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
-    });
-  });
-
-  it('No editing rights', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
-        propPerm:   [{key: 'key1', permission: {mutable: false, collectionAdmin: false, tokenOwner: true}}]});
-      const itemsListIndexBefore = await getLastTokenId(api, collectionId);
-      expect(itemsListIndexBefore).to.be.equal(0);
-      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const args = [{Nft: {const_data: '0x31', properties: [{key: 'key1', value: 'v2'}]}},
-        {Nft: {const_data: '0x32'}},
-        {Nft: {const_data: '0x33'}}];
-
-      await createMultipleItemsWithPropsExpectFailure(bob, collectionId, args);
+      await expect(executeTransaction(api, alice, createMultipleItemsTx)).to.be.rejectedWith(/common\.CollectionTokenLimitExceeded/);
     });
   });
 
   it('User doesnt have editing rights', async () => {
     await usingApi(async (api: ApiPromise) => {
-      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
-        propPerm:   [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}]});
+      const collectionId = await createCollectionWithPropsExpectSuccess({
+        propPerm: [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}]
+      });
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const args = [{Nft: {const_data: '0x31', properties: [{key: 'key1', value: 'v2'}]}},
-        {Nft: {const_data: '0x32'}},
-        {Nft: {const_data: '0x33'}}];
+      const args = [
+        {NFT: {properties: [{key: 'key1', value: 'v2'}]}},
+        {NFT: {}},
+        {NFT: {}}
+      ];
 
-      await createMultipleItemsWithPropsExpectFailure(bob, collectionId, args);
+      const tx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
+      await expect(executeTransaction(api, bob, tx)).to.be.rejectedWith(/common\.NoPermission/);
     });
   });
 
@@ -466,18 +463,27 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
       expect(itemsListIndexBefore).to.be.equal(0);
-      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'v'}]}},
-        {Nft: {const_data: '0x32'}},
-        {Nft: {const_data: '0x33'}}];
+      const args = [{NFT: {properties: [{key: 'k', value: 'v'}]}},
+        {NFT: {}},
+        {NFT: {}}];
 
-      await createMultipleItemsWithPropsExpectFailure(bob, collectionId, args);
+      const tx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
+      await expect(executeTransaction(api, bob, tx)).to.be.rejectedWith(/common\.NoPermission/);
     });
   });
 
   it('Adding more than 64 prps', async () => {
     await usingApi(async (api: ApiPromise) => {
-      const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
-        propPerm:   [{key: 'key1', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});
+      const propPerms = [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}];
+      for (let i = 0; i < 65; i++) {
+        propPerms.push({key: `key${i}`, permission: {mutable: true, collectionAdmin: true, tokenOwner: true}});
+      }
+
+      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+
+      const tx1 = api.tx.unique.setPropertyPermissions(collectionId, propPerms);
+      await expect(executeTransaction(api, alice, tx1)).to.be.rejectedWith(/common\.PropertyLimitReached/);
+
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
@@ -488,24 +494,31 @@
         prps.push({key: `key${i}`, value: `value${i}`});
       }
 
-      const args = [{Nft: {const_data: '0x31', properties: prps}},
-        {Nft: {const_data: '0x32', properties: prps}},
-        {Nft: {const_data: '0x33', properties: prps}}];
+      const args = [
+        {NFT: {properties: prps}},
+        {NFT: {properties: prps}},
+        {NFT: {properties: prps}}
+      ];
 
-      createMultipleItemsWithPropsExpectFailure(alice, collectionId, args);
+      // there are no permissions, but will fail anyway because of too much weight for a block
+      const tx2 = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);;
+      await expect(submitTransactionExpectFailAsync(alice, tx2)).to.be.rejected;
     });
   });
 
   it('Trying to add bigger property than allowed', async () => {
     await usingApi(async (api: ApiPromise) => {
-      const collectionId = await createCollectionWithPropsExpectSuccess({propPerm:   [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});
+      const collectionId = await createCollectionWithPropsExpectSuccess({
+        propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]
+      });
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
-      const args = [{Nft: {const_data: '0x31', properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}},
-        {Nft: {const_data: '0x32', properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}},
-        {Nft: {const_data: '0x33', properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}}];
+      const args = [{NFT: {properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}},
+        {NFT: {properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}},
+        {NFT: {properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]}}];
 
-      createMultipleItemsWithPropsExpectFailure(alice, collectionId, args);
+      const tx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+      await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);
     });
   });
 });
modifiedtests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItemsEx.test.ts
+++ b/tests/src/createMultipleItemsEx.test.ts
@@ -29,13 +29,13 @@
       const data = [
         {
           owner: {substrate: alice.address},
-          constData: '0x0000',
+          // constData: '0x0000',
         }, {
           owner: {substrate: bob.address},
-          constData: '0x2222',
+          // constData: '0x2222',
         }, {
           owner: {substrate: charlie.address},
-          constData: '0x4444',
+          // constData: '0x4444',
         },
       ];
 
@@ -57,15 +57,15 @@
       const data = [
         {
           owner: {substrate: alice.address},
-          constData: '0x1111',
+          // constData: '0x1111',
           properties: [{key: 'k', value: 'v1'}],
         }, {
           owner: {substrate: bob.address},
-          constData: '0x2222',
+          // constData: '0x2222',
           properties: [{key: 'k', value: 'v2'}],
         }, {
           owner: {substrate: charlie.address},
-          constData: '0x4444',
+          // constData: '0x4444',
           properties: [{key: 'k', value: 'v3'}],
         },
       ];
@@ -88,15 +88,15 @@
       const data = [
         {
           owner: {substrate: alice.address},
-          constData: '0x0000',
+          // constData: '0x0000',
           properties: [{key: 'k', value: 'v1'}],
         }, {
           owner: {substrate: bob.address},
-          constData: '0x2222',
+          // constData: '0x2222',
           properties: [{key: 'k', value: 'v2'}],
         }, {
           owner: {substrate: charlie.address},
-          constData: '0x4444',
+          // constData: '0x4444',
           properties: [{key: 'k', value: 'v3'}],
         },
       ];
@@ -119,15 +119,15 @@
       const data = [
         {
           owner: {substrate: alice.address},
-          constData: '0x0000',
+          // constData: '0x0000',
           properties: [{key: 'k', value: 'v1'}],
         }, {
           owner: {substrate: bob.address},
-          constData: '0x2222',
+          // constData: '0x2222',
           properties: [{key: 'k', value: 'v2'}],
         }, {
           owner: {substrate: charlie.address},
-          constData: '0x4444',
+          // constData: '0x4444',
           properties: [{key: 'k', value: 'v3'}],
         },
       ];
@@ -154,10 +154,10 @@
           owner: {substrate: alice.address},
           properties: [{key: 'key1', value: 'v2'}],
         }, {
-          owner: {substrate: alice.address},
+          owner: {substrate: bob.address},
           properties: [{key: 'key1', value: 'v2'}],
         }, {
-          owner: {substrate: alice.address},
+          owner: {substrate: charlie.address},
           properties: [{key: 'key1', value: 'v2'}],
         },
       ];
@@ -165,7 +165,8 @@
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
       // await executeTransaction(api, alice, tx);
 
-      await submitTransactionExpectFailAsync(alice, tx);
+      //await submitTransactionExpectFailAsync(alice, tx);
+      await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);
     });
   });
 
@@ -193,7 +194,8 @@
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
       // await executeTransaction(api, alice, tx);
 
-      await submitTransactionExpectFailAsync(alice, tx);
+      //await submitTransactionExpectFailAsync(alice, tx);
+      await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);
     });
   });
 
@@ -219,41 +221,24 @@
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
 
-      await submitTransactionExpectFailAsync(alice, tx);
+      await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);
+      //await submitTransactionExpectFailAsync(alice, tx);
     });
   });
 
-  it('Adding more than 64 prps', async () => {
-    const prps = [{key: 'key', value: 'v'}];
-    const propPerm = [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}];
+  it('Adding more than 64 properties', async () => {
+    const propPerms = [{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}});
+      propPerms.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');
-    await addCollectionAdminExpectSuccess(alice, collection, bob.address);
+    const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
     await usingApi(async (api) => {
-      const data = [
-        {
-          owner: {substrate: alice.address},
-          properties: prps,
-        }, {
-          owner: {substrate: alice.address},
-          properties: prps,
-        }, {
-          owner: {substrate: alice.address},
-          properties: prps,
-        },
-      ];
-
-      const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
-
-      await submitTransactionExpectFailAsync(alice, tx);
+      await expect(
+        executeTransaction(api, alice, api.tx.unique.setPropertyPermissions(collection, propPerms))
+      ).to.be.rejectedWith(/common\.PropertyLimitReached/);
     });
   });
 
@@ -276,7 +261,8 @@
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
 
-      await submitTransactionExpectFailAsync(alice, tx);
+      //await submitTransactionExpectFailAsync(alice, tx);
+      await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);
     });
   });
 
@@ -289,13 +275,13 @@
       const data = [
         {
           owner: {substrate: alice.address},
-          constData: '0x0000',
+          // constData: '0x0000',
         }, {
           owner: {substrate: bob.address},
-          constData: '0x2222',
+          // constData: '0x2222',
         }, {
           owner: {substrate: charlie.address},
-          constData: '0x4444',
+          // constData: '0x4444',
         },
       ];
 
@@ -317,13 +303,13 @@
       const data = [
         {
           owner: {substrate: alice.address},
-          constData: '0x0000',
+          // constData: '0x0000',
         }, {
           owner: {substrate: bob.address},
-          constData: '0x2222',
+          // constData: '0x2222',
         }, {
           owner: {substrate: charlie.address},
-          constData: '0x4444',
+          // constData: '0x4444',
         },
       ];
 
modifiedtests/src/nesting/properties.test.tsdiffbeforeafterboth
before · tests/src/nesting/properties.test.ts
1import {expect} from 'chai';2import privateKey from '../substrate/privateKey';3import usingApi, {executeTransaction} from '../substrate/substrate-api';4import {5  addCollectionAdminExpectSuccess,6  createCollectionExpectSuccess,7  createItemExpectSuccess,8  getCreateCollectionResult,9  transferExpectSuccess,10} from '../util/helpers';11import {IKeyringPair} from '@polkadot/types/types';1213let alice: IKeyringPair;14let bob: IKeyringPair;15let charlie: IKeyringPair;1617describe('Composite Properties Test', () => {18  before(async () => {19    await usingApi(async () => {20      alice = privateKey('//Alice');21      bob = privateKey('//Bob');22    });23  });2425  it('Makes sure collectionById supplies required fields', async () => {26    await usingApi(async api => {27      const collectionId = await createCollectionExpectSuccess();2829      const collectionOption = await api.rpc.unique.collectionById(collectionId);30      expect(collectionOption.isSome).to.be.true;31      let collection = collectionOption.unwrap();32      expect(collection.tokenPropertyPermissions.toHuman()).to.be.empty;33      expect(collection.properties.toHuman()).to.be.empty;3435      const propertyPermissions = [36        {key: 'mindgame', permission: {collectionAdmin: true, mutable: false, tokenOwner: true}},37        {key: 'skullduggery', permission: {collectionAdmin: false, mutable: true, tokenOwner: false}},38      ];39      await expect(executeTransaction(40        api, 41        alice, 42        api.tx.unique.setPropertyPermissions(collectionId, propertyPermissions), 43      )).to.not.be.rejected;4445      const collectionProperties = [46        {key: 'black_hole', value: 'LIGO'},47        {key: 'electron', value: 'come bond'}, 48      ];49      await expect(executeTransaction(50        api, 51        alice, 52        api.tx.unique.setCollectionProperties(collectionId, collectionProperties), 53      )).to.not.be.rejected;5455      collection = (await api.rpc.unique.collectionById(collectionId)).unwrap();56      expect(collection.tokenPropertyPermissions.toHuman()).to.be.deep.equal(propertyPermissions);57      expect(collection.properties.toHuman()).to.be.deep.equal(collectionProperties);58    });59  });60});6162// ---------- COLLECTION PROPERTIES6364describe('Integration Test: Collection Properties', () => {65  before(async () => {66    await usingApi(async () => {67      alice = privateKey('//Alice');68      bob = privateKey('//Bob');69    });70  });7172  it('Reads properties from a collection', async () => {73    await usingApi(async api => {74      const collection = await createCollectionExpectSuccess();75      const properties = (await api.query.common.collectionProperties(collection)).toJSON();76      expect(properties.map).to.be.empty;77      expect(properties.consumedSpace).to.equal(0);78    });79  });8081  it('Sets properties for a collection', async () => {82    await usingApi(async api => {83      const events = await executeTransaction(api, bob, api.tx.unique.createCollectionEx({mode: 'NFT'}));84      const {collectionId} = getCreateCollectionResult(events);8586      // As owner87      await expect(executeTransaction(88        api, 89        bob, 90        api.tx.unique.setCollectionProperties(collectionId, [{key: 'electron', value: 'come bond'}]), 91      )).to.not.be.rejected;9293      await addCollectionAdminExpectSuccess(bob, collectionId, alice.address);9495      // As administrator96      await expect(executeTransaction(97        api, 98        alice, 99        api.tx.unique.setCollectionProperties(collectionId, [{key: 'black_hole'}]), 100      )).to.not.be.rejected;101102      const properties = (await api.rpc.unique.collectionProperties(collectionId, ['electron', 'black_hole'])).toHuman();103      expect(properties).to.be.deep.equal([104        {key: 'electron', value: 'come bond'},105        {key: 'black_hole', value: ''},106      ]);107    });108  });109110  it('Changes properties of a collection', async () => {111    await usingApi(async api => {112      const collection = await createCollectionExpectSuccess();113114      await expect(executeTransaction(115        api, 116        alice, 117        api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'come bond'}, {key: 'black_hole'}]), 118      )).to.not.be.rejected;119120      // Mutate the properties121      await expect(executeTransaction(122        api, 123        alice, 124        api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'bonded'}, {key: 'black_hole', value: 'LIGO'}]), 125      )).to.not.be.rejected;126127      const properties = (await api.rpc.unique.collectionProperties(collection, ['electron', 'black_hole'])).toHuman();128      expect(properties).to.be.deep.equal([129        {key: 'electron', value: 'bonded'},130        {key: 'black_hole', value: 'LIGO'},131      ]);132    });133  });134135  it('Deletes properties of a collection', async () => {136    await usingApi(async api => {137      const collection = await createCollectionExpectSuccess();138139      await expect(executeTransaction(140        api, 141        alice, 142        api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}]), 143      )).to.not.be.rejected;144145      await expect(executeTransaction(146        api, 147        alice, 148        api.tx.unique.deleteCollectionProperties(collection, ['electron']), 149      )).to.not.be.rejected;150151      const properties = (await api.rpc.unique.collectionProperties(collection, ['electron', 'black_hole'])).toHuman();152      expect(properties).to.be.deep.equal([153        {key: 'black_hole', value: 'LIGO'},154      ]);155    });156  });157});158159describe('Negative Integration Test: Collection Properties', () => {160  before(async () => {161    await usingApi(async () => {162      alice = privateKey('//Alice');163      bob = privateKey('//Bob');164    });165  });166  167  it('Fails to set properties in a collection if not its onwer/administrator', async () => {168    await usingApi(async api => {169      const collection = await createCollectionExpectSuccess();170171      await expect(executeTransaction(172        api, 173        bob, 174        api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}]), 175      )).to.be.rejectedWith(/common\.NoPermission/);176  177      const properties = (await api.query.common.collectionProperties(collection)).toJSON();178      expect(properties.map).to.be.empty;179      expect(properties.consumedSpace).to.equal(0);180    });181  });182  183  it('Fails to set properties that exceed the limits', async () => {184    await usingApi(async api => {185      const collection = await createCollectionExpectSuccess();186      const spaceLimit = (await api.query.common.collectionProperties(collection)).toJSON().spaceLimit as number; 187188      // Mute the general tx parsing error, too many bytes to process189      {190        console.error = () => {};191        await expect(executeTransaction(192          api, 193          alice, 194          api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'low high '.repeat(Math.ceil(spaceLimit! / 9))}]), 195        )).to.be.rejected;196      }197198      let properties = (await api.rpc.unique.collectionProperties(collection, ['electron'])).toJSON();199      expect(properties).to.be.empty;200201      await expect(executeTransaction(202        api, 203        alice, 204        api.tx.unique.setCollectionProperties(collection, [205          {key: 'electron', value: 'low high '.repeat(Math.ceil(spaceLimit! / 18))}, 206          {key: 'black_hole', value: '0'.repeat(Math.ceil(spaceLimit! / 2))}, 207        ]), 208      )).to.be.rejectedWith(/common\.NoSpaceForProperty/);209210      properties = (await api.rpc.unique.collectionProperties(collection, ['electron', 'black hole'])).toJSON();211      expect(properties).to.be.empty;212    });213  });214  215  it('Fails to set more properties than it is allowed', async () => {216    await usingApi(async api => {217      const collection = await createCollectionExpectSuccess();218219      const propertiesToBeSet = [];220      for (let i = 0; i < 65; i++) {221        propertiesToBeSet.push({222          key: 'electron_' + i,223          value: Math.random() > 0.5 ? 'high' : 'low',224        });225      }226227      await expect(executeTransaction(228        api, 229        alice, 230        api.tx.unique.setCollectionProperties(collection, propertiesToBeSet), 231      )).to.be.rejectedWith(/common\.PropertyLimitReached/);232233      const properties = (await api.query.common.collectionProperties(collection)).toJSON();234      expect(properties.map).to.be.empty;235      expect(properties.consumedSpace).to.equal(0);236    });237  });238239  it('Fails to set properties with invalid names', async () => {240    await usingApi(async api => {241      const collection = await createCollectionExpectSuccess();242243      const invalidProperties = [244        [{key: 'electron', value: 'negative'}, {key: 'string theory', value: 'understandable'}],245        [{key: 'Mr.Sandman', value: 'Bring me a gene'}],246        [{key: 'déjà vu', value: 'hmm...'}],247      ];248249      for (let i = 0; i < invalidProperties.length; i++) {250        await expect(executeTransaction(251          api, 252          alice, 253          api.tx.unique.setCollectionProperties(collection, invalidProperties[i]), 254        ), `on rejecting the new badly-named property #${i}`).to.be.rejectedWith(/common\.InvalidCharacterInPropertyKey/);255      }256257      await expect(executeTransaction(258        api, 259        alice, 260        api.tx.unique.setCollectionProperties(collection, [{key: '', value: 'nothing must not exist'}]), 261      ), 'on rejecting an unnamed property').to.be.rejectedWith(/common\.EmptyPropertyKey/);262263      await expect(executeTransaction(264        api, 265        alice, 266        api.tx.unique.setCollectionProperties(collection, [267          {key: 'CRISPR-Cas9', value: 'rewriting nature!'},268        ]), 269      ), 'on setting the correctly-but-still-badly-named property').to.not.be.rejected;270271      const keys = invalidProperties.flatMap(propertySet => propertySet.map(property => property.key)).concat('CRISPR-Cas9').concat('');272273      const properties = (await api.rpc.unique.collectionProperties(collection, keys)).toHuman();274      expect(properties).to.be.deep.equal([275        {key: 'CRISPR-Cas9', value: 'rewriting nature!'},276      ]);277278      for (let i = 0; i < invalidProperties.length; i++) {279        await expect(executeTransaction(280          api, 281          alice, 282          api.tx.unique.deleteCollectionProperties(collection, invalidProperties[i].map(propertySet => propertySet.key)), 283        ), `on trying to delete the non-existent badly-named property #${i}`).to.be.rejectedWith(/common\.InvalidCharacterInPropertyKey/);284      }285    });286  });287});288289// ---------- ACCESS RIGHTS290291describe('Integration Test: Access Rights to Token Properties', () => {292  before(async () => {293    await usingApi(async () => {294      alice = privateKey('//Alice');295      bob = privateKey('//Bob');296    });297  });298  299  it('Reads access rights to properties of a collection', async () => {300    await usingApi(async api => {301      const collection = await createCollectionExpectSuccess();302      const propertyRights = (await api.query.common.collectionPropertyPermissions(collection)).toJSON();303      expect(propertyRights).to.be.empty;304    });305  });306  307  it('Sets access rights to properties of a collection', async () => {308    await usingApi(async api => {309      const collection = await createCollectionExpectSuccess();310311      await expect(executeTransaction(312        api, 313        alice, 314        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: true}}]), 315      )).to.not.be.rejected;316317      await addCollectionAdminExpectSuccess(alice, collection, bob.address);318319      await expect(executeTransaction(320        api, 321        alice, 322        api.tx.unique.setPropertyPermissions(collection, [{key: 'mindgame', permission: {collectionAdmin: true, tokenOwner: false}}]), 323      )).to.not.be.rejected;324325      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery', 'mindgame'])).toHuman();326      expect(propertyRights).to.be.deep.equal([327        {key: 'skullduggery', permission: {'mutable': true, 'collectionAdmin': false, 'tokenOwner': false}},328        {key: 'mindgame', permission: {'mutable': false, 'collectionAdmin': true, 'tokenOwner': false}},329      ]);330    });331  });332  333  it('Changes access rights to properties of a collection', async () => {334    await usingApi(async api => {335      const collection = await createCollectionExpectSuccess();336337      await expect(executeTransaction(338        api, 339        alice, 340        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: true, collectionAdmin: true}}]), 341      )).to.not.be.rejected;342343      await expect(executeTransaction(344        api, 345        alice, 346        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]), 347      )).to.not.be.rejected;348349      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery'])).toHuman();350      expect(propertyRights).to.be.deep.equal([351        {key: 'skullduggery', permission: {'mutable': false, 'collectionAdmin': false, 'tokenOwner': true}},352      ]);353    });354  });355});356357describe('Negative Integration Test: Access Rights to Token Properties', () => {358  before(async () => {359    await usingApi(async () => {360      alice = privateKey('//Alice');361      bob = privateKey('//Bob');362    });363  });364365  it('Prevents from setting access rights to properties of a collection if not an onwer/admin', async () => {366    await usingApi(async api => {367      const collection = await createCollectionExpectSuccess();368369      await expect(executeTransaction(370        api, 371        bob, 372        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: true, tokenOwner: true}}]), 373      )).to.be.rejectedWith(/common\.NoPermission/);374375      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery'])).toJSON();376      expect(propertyRights).to.be.empty;377    });378  });379380  it('Prevents from adding too many possible properties', async () => {381    await usingApi(async api => {382      const collection = await createCollectionExpectSuccess();383384      const constitution = [];385      for (let i = 0; i < 65; i++) {386        constitution.push({387          key: 'property_' + i,388          permission: Math.random() > 0.5 ? {mutable: true, collectionAdmin: true, tokenOwner: true} : {},389        });390      }391392      await expect(executeTransaction(393        api, 394        alice, 395        api.tx.unique.setPropertyPermissions(collection, constitution), 396      )).to.be.rejectedWith(/common\.PropertyLimitReached/);397398      const propertyRights = (await api.query.common.collectionPropertyPermissions(collection)).toJSON();399      expect(propertyRights).to.be.empty;400    });401  });402403  it('Prevents access rights to be modified if constant', async () => {404    await usingApi(async api => {405      const collection = await createCollectionExpectSuccess();406407      await expect(executeTransaction(408        api, 409        alice, 410        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]), 411      )).to.not.be.rejected;412413      await expect(executeTransaction(414        api, 415        alice, 416        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {}}]), 417      )).to.be.rejectedWith(/common\.NoPermission/);418419      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery'])).toHuman();420      expect(propertyRights).to.deep.equal([421        {key: 'skullduggery', permission: {'mutable': false, 'collectionAdmin': false, 'tokenOwner': true}},422      ]);423    });424  });425426  it('Prevents adding properties with invalid names', async () => {427    await usingApi(async api => {428      const collection = await createCollectionExpectSuccess();429430      const invalidProperties = [431        [{key: 'skullduggery', permission: {tokenOwner: true}}, {key: 'im possible', permission: {collectionAdmin: true}}],432        [{key: 'G#4', permission: {tokenOwner: true}}],433        [{key: 'HÆMILTON', permission: {mutable: false, collectionAdmin: true, tokenOwner: true}}],434      ];435436      for (let i = 0; i < invalidProperties.length; i++) {437        await expect(executeTransaction(438          api, 439          alice, 440          api.tx.unique.setPropertyPermissions(collection, invalidProperties[i]), 441        ), `on setting the new badly-named property #${i}`).to.be.rejectedWith(/common\.InvalidCharacterInPropertyKey/);442      }443444      await expect(executeTransaction(445        api, 446        alice, 447        api.tx.unique.setPropertyPermissions(collection, [{key: '', permission: {}}]), 448      ), 'on rejecting an unnamed property').to.be.rejectedWith(/common\.EmptyPropertyKey/);449450      const correctKey = '--0x03116e387820CA05'; // PolkadotJS would parse this as an already encoded hex-string451      await expect(executeTransaction(452        api, 453        alice, 454        api.tx.unique.setPropertyPermissions(collection, [455          {key: correctKey, permission: {collectionAdmin: true}},456        ]), 457      ), 'on setting the correctly-but-still-badly-named property').to.not.be.rejected;458459      const keys = invalidProperties.flatMap(propertySet => propertySet.map(property => property.key)).concat(correctKey).concat('');460461      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, keys)).toHuman();462      expect(propertyRights).to.be.deep.equal([463        {key: correctKey, permission: {mutable: false, collectionAdmin: true, tokenOwner: false}},464      ]);465    });466  });467});468469// ---------- TOKEN PROPERTIES470471describe('Integration Test: Token Properties', () => {472  let collection: number;473  let token: number;474  let permissions: {permission: any, signers: IKeyringPair[]}[];475476  before(async () => {477    await usingApi(async () => {478      alice = privateKey('//Alice');479      bob = privateKey('//Bob');480      charlie = privateKey('//Charlie');481482      permissions = [483        {permission: {mutable: true, collectionAdmin: true}, signers: [alice, bob]},484        {permission: {mutable: false, collectionAdmin: true}, signers: [alice, bob]},485        {permission: {mutable: true, tokenOwner: true}, signers: [charlie]},486        {permission: {mutable: false, tokenOwner: true}, signers: [charlie]},487        {permission: {mutable: true, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie]},488        {permission: {mutable: false, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie]},489      ];490    });491  });492493  beforeEach(async () => {494    await usingApi(async () => {495      collection = await createCollectionExpectSuccess();496      token = await createItemExpectSuccess(alice, collection, 'NFT');497      await addCollectionAdminExpectSuccess(alice, collection, bob.address);498      await transferExpectSuccess(collection, token, alice, charlie);499    });500  });501  502  it('Reads yet empty properties of a token', async () => {503    await usingApi(async api => {504      const collection = await createCollectionExpectSuccess();505      const token = await createItemExpectSuccess(alice, collection, 'NFT');506  507      const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();508      expect(properties.map).to.be.empty;509      expect(properties.consumedSpace).to.be.equal(0);510511      const tokenData = (await api.rpc.unique.tokenData(collection, token, ['anything'])).toJSON().properties;512      expect(tokenData).to.be.empty;513    });514  });515516  it('Assigns properties to a token according to permissions', async () => {517    await usingApi(async api => {518      const propertyKeys: string[] = [];519      let i = 0;520      for (const permission of permissions) {521        for (const signer of permission.signers) {522          const key = i + '_' + signer.address;523          propertyKeys.push(key);524525          await expect(executeTransaction(526            api, 527            alice, 528            api.tx.unique.setPropertyPermissions(collection, [{key: key, permission: permission.permission}]), 529          ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;530531          await expect(executeTransaction(532            api, 533            signer, 534            api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin increase'}]), 535          ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;536        }537538        i++;539      }540541      const properties = (await api.rpc.unique.tokenProperties(collection, token, propertyKeys)).toHuman() as any[];542      const tokensData = (await api.rpc.unique.tokenData(collection, token, propertyKeys)).toHuman().properties as any[];543      for (let i = 0; i < properties.length; i++) {544        expect(properties[i].value).to.be.equal('Serotonin increase');545        expect(tokensData[i].value).to.be.equal('Serotonin increase');546      }547    });548  });549550  it('Changes properties of a token according to permissions', async () => {551    await usingApi(async api => {552      const propertyKeys: string[] = [];553      let i = 0;554      for (const permission of permissions) {555        if (!permission.permission.mutable) continue;556        557        for (const signer of permission.signers) {558          const key = i + '_' + signer.address;559          propertyKeys.push(key);560561          await expect(executeTransaction(562            api, 563            alice, 564            api.tx.unique.setPropertyPermissions(collection, [{key: key, permission: permission.permission}]), 565          ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;566567          await expect(executeTransaction(568            api, 569            signer, 570            api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin increase'}]), 571          ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;572573          await expect(executeTransaction(574            api, 575            signer, 576            api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin stable'}]), 577          ), `on changing property ${i} by ${signer.address}`).to.not.be.rejected;578        }579580        i++;581      }582583      const properties = (await api.rpc.unique.tokenProperties(collection, token, propertyKeys)).toHuman() as any[];584      const tokensData = (await api.rpc.unique.tokenData(collection, token, propertyKeys)).toHuman().properties as any[];585      for (let i = 0; i < properties.length; i++) {586        expect(properties[i].value).to.be.equal('Serotonin stable');587        expect(tokensData[i].value).to.be.equal('Serotonin stable');588      }589    });590  });591592  it('Deletes properties of a token according to permissions', async () => {593    await usingApi(async api => {594      const propertyKeys: string[] = [];595      let i = 0;596597      for (const permission of permissions) {598        if (!permission.permission.mutable) continue;599        600        for (const signer of permission.signers) {601          const key = i + '_' + signer.address;602          propertyKeys.push(key);603604          await expect(executeTransaction(605            api, 606            alice, 607            api.tx.unique.setPropertyPermissions(collection, [{key: key, permission: permission.permission}]), 608          ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;609610          await expect(executeTransaction(611            api, 612            signer, 613            api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin increase'}]), 614          ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;615616          await expect(executeTransaction(617            api, 618            signer, 619            api.tx.unique.deleteTokenProperties(collection, token, [key]), 620          ), `on deleting property ${i} by ${signer.address}`).to.not.be.rejected;621        }622        623        i++;624      }625626      const properties = (await api.rpc.unique.tokenProperties(collection, token, propertyKeys)).toJSON() as any[];627      expect(properties).to.be.empty;628      const tokensData = (await api.rpc.unique.tokenData(collection, token, propertyKeys)).toJSON().properties as any[];629      expect(tokensData).to.be.empty;630      expect((await api.query.nonfungible.tokenProperties(collection, token)).toJSON().consumedSpace).to.be.equal(0);631    });632  });633});634635describe('Negative Integration Test: Token Properties', () => {636  let collection: number;637  let token: number;638  let originalSpace: number;639  let constitution: {permission: any, signers: IKeyringPair[], sinner: IKeyringPair}[];640641  before(async () => {642    await usingApi(async () => {643      alice = privateKey('//Alice');644      bob = privateKey('//Bob');645      charlie = privateKey('//Charlie');646      const dave = privateKey('//Dave');647648      constitution = [649        {permission: {mutable: true, collectionAdmin: true}, signers: [alice, bob], sinner: charlie},650        {permission: {mutable: false, collectionAdmin: true}, signers: [alice, bob], sinner: charlie},651        {permission: {mutable: true, tokenOwner: true}, signers: [charlie], sinner: alice},652        {permission: {mutable: false, tokenOwner: true}, signers: [charlie], sinner: alice},653        {permission: {mutable: true, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie], sinner: dave},654        {permission: {mutable: false, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie], sinner: dave},655      ];656    });657  });658659  beforeEach(async () => {660    collection = await createCollectionExpectSuccess();661    token = await createItemExpectSuccess(alice, collection, 'NFT');662    await addCollectionAdminExpectSuccess(alice, collection, bob.address);663    await transferExpectSuccess(collection, token, alice, charlie);664        665    await usingApi(async api => {666      let i = 0;667      for (const passage of constitution) {668        const signer = passage.signers[0];669        670        await expect(executeTransaction(671          api, 672          alice, 673          api.tx.unique.setPropertyPermissions(collection, [{key: `${i}`, permission: passage.permission}]), 674        ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;675676        await expect(executeTransaction(677          api, 678          signer, 679          api.tx.unique.setTokenProperties(collection, token, [{key: `${i}`, value: 'Serotonin increase'}]), 680        ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;681682        i++;683      }684685      originalSpace = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON().consumedSpace as number;686    });687  });688689  it('Forbids changing/deleting properties of a token if the user is outside of permissions', async () => {690    await usingApi(async api => {691      let i = -1;692      for (const forbiddance of constitution) {693        i++;694        if (!forbiddance.permission.mutable) continue;695696        await expect(executeTransaction(697          api, 698          forbiddance.sinner, 699          api.tx.unique.setTokenProperties(collection, token, [{key: `${i}`, value: 'Serotonin down'}]), 700        ), `on failing to change property ${i} by ${forbiddance.sinner.address}`).to.be.rejectedWith(/common\.NoPermission/);701702        await expect(executeTransaction(703          api, 704          forbiddance.sinner, 705          api.tx.unique.deleteTokenProperties(collection, token, [`${i}`]), 706        ), `on failing to delete property ${i} by ${forbiddance.sinner.address}`).to.be.rejectedWith(/common\.NoPermission/);707      }708709      const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();710      expect(properties.consumedSpace).to.be.equal(originalSpace);711    });712  });713714  it('Forbids changing/deleting properties of a token if the property is permanent (immutable)', async () => {715    await usingApi(async api => {716      let i = -1;717      for (const permission of constitution) {718        i++;719        if (permission.permission.mutable) continue;720721        await expect(executeTransaction(722          api, 723          permission.signers[0], 724          api.tx.unique.setTokenProperties(collection, token, [{key: `${i}`, value: 'Serotonin down'}]), 725        ), `on failing to change property ${i} by ${permission.signers[0].address}`).to.be.rejectedWith(/common\.NoPermission/);726727        await expect(executeTransaction(728          api, 729          permission.signers[0], 730          api.tx.unique.deleteTokenProperties(collection, token, [i.toString()]), 731        ), `on failing to delete property ${i} by ${permission.signers[0].address}`).to.be.rejectedWith(/common\.NoPermission/);732      }733734      const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();735      expect(properties.consumedSpace).to.be.equal(originalSpace);736    });737  });738739  it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission', async () => {740    await usingApi(async api => {741      await expect(executeTransaction(742        api, 743        alice, 744        api.tx.unique.setTokenProperties(collection, token, [{key: 'non-existent', value: 'I exist!'}]), 745      ), 'on failing to add a previously non-existent property').to.be.rejectedWith(/common\.NoPermission/);746        747      await expect(executeTransaction(748        api, 749        alice, 750        api.tx.unique.setPropertyPermissions(collection, [{key: 'now-existent', permission: {}}]), 751      ), 'on setting a new non-permitted property').to.not.be.rejected;752753      await expect(executeTransaction(754        api, 755        alice, 756        api.tx.unique.setTokenProperties(collection, token, [{key: 'now-existent', value: 'I exist!'}]), 757      ), 'on failing to add a property forbidden by the \'None\' permission').to.be.rejectedWith(/common\.NoPermission/);758759      expect((await api.rpc.unique.tokenProperties(collection, token, ['non-existent', 'now-existent'])).toJSON()).to.be.empty;760      const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();761      expect(properties.consumedSpace).to.be.equal(originalSpace);762    });763  });764765  it('Forbids adding too many properties to a token', async () => {766    await usingApi(async api => {767      await expect(executeTransaction(768        api, 769        alice, 770        api.tx.unique.setPropertyPermissions(collection, [771          {key: 'a_holy_book', permission: {collectionAdmin: true, tokenOwner: true}}, 772          {key: 'young_years', permission: {collectionAdmin: true, tokenOwner: true}},773        ]), 774      ), 'on setting a new non-permitted property').to.not.be.rejected;775776      // Mute the general tx parsing error777      {778        console.error = () => {};779        await expect(executeTransaction(780          api, 781          alice, 782          api.tx.unique.setCollectionProperties(collection, [{key: 'a_holy_book', value: 'word '.repeat(6554)}]), 783        )).to.be.rejected;784      }785786      await expect(executeTransaction(787        api, 788        alice, 789        api.tx.unique.setTokenProperties(collection, token, [790          {key: 'a_holy_book', value: 'word '.repeat(3277)}, 791          {key: 'young_years', value: 'neverending'.repeat(1490)},792        ]), 793      )).to.be.rejectedWith(/common\.NoSpaceForProperty/);794795      expect((await api.rpc.unique.tokenProperties(collection, token, ['a_holy_book', 'young years'])).toJSON()).to.be.empty;796      const propertiesMap = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();797      expect(propertiesMap.consumedSpace).to.be.equal(originalSpace);798    });799  });800});
after · tests/src/nesting/properties.test.ts
1import {expect} from 'chai';2import privateKey from '../substrate/privateKey';3import usingApi, {executeTransaction} from '../substrate/substrate-api';4import {5  addCollectionAdminExpectSuccess,6  createCollectionExpectSuccess,7  createItemExpectSuccess,8  getCreateCollectionResult,9  transferExpectSuccess,10} from '../util/helpers';11import {IKeyringPair} from '@polkadot/types/types';1213let alice: IKeyringPair;14let bob: IKeyringPair;15let charlie: IKeyringPair;1617describe('Composite Properties Test', () => {18  before(async () => {19    await usingApi(async () => {20      alice = privateKey('//Alice');21      bob = privateKey('//Bob');22    });23  });2425  it('Makes sure collectionById supplies required fields', async () => {26    await usingApi(async api => {27      const collectionId = await createCollectionExpectSuccess();2829      const collectionOption = await api.rpc.unique.collectionById(collectionId);30      expect(collectionOption.isSome).to.be.true;31      let collection = collectionOption.unwrap();32      expect(collection.tokenPropertyPermissions.toHuman()).to.be.empty;33      expect(collection.properties.toHuman()).to.be.empty;3435      const propertyPermissions = [36        {key: 'mindgame', permission: {collectionAdmin: true, mutable: false, tokenOwner: true}},37        {key: 'skullduggery', permission: {collectionAdmin: false, mutable: true, tokenOwner: false}},38      ];39      await expect(executeTransaction(40        api, 41        alice, 42        api.tx.unique.setPropertyPermissions(collectionId, propertyPermissions), 43      )).to.not.be.rejected;4445      const collectionProperties = [46        {key: 'black_hole', value: 'LIGO'},47        {key: 'electron', value: 'come bond'}, 48      ];49      await expect(executeTransaction(50        api, 51        alice, 52        api.tx.unique.setCollectionProperties(collectionId, collectionProperties), 53      )).to.not.be.rejected;5455      collection = (await api.rpc.unique.collectionById(collectionId)).unwrap();56      expect(collection.tokenPropertyPermissions.toHuman()).to.be.deep.equal(propertyPermissions);57      expect(collection.properties.toHuman()).to.be.deep.equal(collectionProperties);58    });59  });60});6162// ---------- COLLECTION PROPERTIES6364describe('Integration Test: Collection Properties', () => {65  before(async () => {66    await usingApi(async () => {67      alice = privateKey('//Alice');68      bob = privateKey('//Bob');69    });70  });7172  it('Reads properties from a collection', async () => {73    await usingApi(async api => {74      const collection = await createCollectionExpectSuccess();75      const properties = (await api.query.common.collectionProperties(collection)).toJSON();76      expect(properties.map).to.be.empty;77      expect(properties.consumedSpace).to.equal(0);78    });79  });8081  it('Sets properties for a collection', async () => {82    await usingApi(async api => {83      const events = await executeTransaction(api, bob, api.tx.unique.createCollectionEx({mode: 'NFT'}));84      const {collectionId} = getCreateCollectionResult(events);8586      // As owner87      await expect(executeTransaction(88        api, 89        bob, 90        api.tx.unique.setCollectionProperties(collectionId, [{key: 'electron', value: 'come bond'}]), 91      )).to.not.be.rejected;9293      await addCollectionAdminExpectSuccess(bob, collectionId, alice.address);9495      // As administrator96      await expect(executeTransaction(97        api, 98        alice, 99        api.tx.unique.setCollectionProperties(collectionId, [{key: 'black_hole'}]), 100      )).to.not.be.rejected;101102      const properties = (await api.rpc.unique.collectionProperties(collectionId, ['electron', 'black_hole'])).toHuman();103      expect(properties).to.be.deep.equal([104        {key: 'electron', value: 'come bond'},105        {key: 'black_hole', value: ''},106      ]);107    });108  });109110  it('Changes properties of a collection', async () => {111    await usingApi(async api => {112      const collection = await createCollectionExpectSuccess();113114      await expect(executeTransaction(115        api, 116        alice, 117        api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'come bond'}, {key: 'black_hole'}]), 118      )).to.not.be.rejected;119120      // Mutate the properties121      await expect(executeTransaction(122        api, 123        alice, 124        api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'bonded'}, {key: 'black_hole', value: 'LIGO'}]), 125      )).to.not.be.rejected;126127      const properties = (await api.rpc.unique.collectionProperties(collection, ['electron', 'black_hole'])).toHuman();128      expect(properties).to.be.deep.equal([129        {key: 'electron', value: 'bonded'},130        {key: 'black_hole', value: 'LIGO'},131      ]);132    });133  });134135  it('Deletes properties of a collection', async () => {136    await usingApi(async api => {137      const collection = await createCollectionExpectSuccess();138139      await expect(executeTransaction(140        api, 141        alice, 142        api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}]), 143      )).to.not.be.rejected;144145      await expect(executeTransaction(146        api, 147        alice, 148        api.tx.unique.deleteCollectionProperties(collection, ['electron']), 149      )).to.not.be.rejected;150151      const properties = (await api.rpc.unique.collectionProperties(collection, ['electron', 'black_hole'])).toHuman();152      expect(properties).to.be.deep.equal([153        {key: 'black_hole', value: 'LIGO'},154      ]);155    });156  });157});158159describe('Negative Integration Test: Collection Properties', () => {160  before(async () => {161    await usingApi(async () => {162      alice = privateKey('//Alice');163      bob = privateKey('//Bob');164    });165  });166  167  it('Fails to set properties in a collection if not its onwer/administrator', async () => {168    await usingApi(async api => {169      const collection = await createCollectionExpectSuccess();170171      await expect(executeTransaction(172        api, 173        bob, 174        api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'come bond'}, {key: 'black_hole', value: 'LIGO'}]), 175      )).to.be.rejectedWith(/common\.NoPermission/);176  177      const properties = (await api.query.common.collectionProperties(collection)).toJSON();178      expect(properties.map).to.be.empty;179      expect(properties.consumedSpace).to.equal(0);180    });181  });182  183  it('Fails to set properties that exceed the limits', async () => {184    await usingApi(async api => {185      const collection = await createCollectionExpectSuccess();186      const spaceLimit = (await api.query.common.collectionProperties(collection)).toJSON().spaceLimit as number; 187188      // Mute the general tx parsing error, too many bytes to process189      {190        console.error = () => {};191        await expect(executeTransaction(192          api, 193          alice, 194          api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'low high '.repeat(Math.ceil(spaceLimit! / 9))}]), 195        )).to.be.rejected;196      }197198      let properties = (await api.rpc.unique.collectionProperties(collection, ['electron'])).toJSON();199      expect(properties).to.be.empty;200201      await expect(executeTransaction(202        api, 203        alice, 204        api.tx.unique.setCollectionProperties(collection, [205          {key: 'electron', value: 'low high '.repeat(Math.ceil(spaceLimit! / 18))}, 206          {key: 'black_hole', value: '0'.repeat(Math.ceil(spaceLimit! / 2))}, 207        ]), 208      )).to.be.rejectedWith(/common\.NoSpaceForProperty/);209210      properties = (await api.rpc.unique.collectionProperties(collection, ['electron', 'black hole'])).toJSON();211      expect(properties).to.be.empty;212    });213  });214  215  it('Fails to set more properties than it is allowed', async () => {216    await usingApi(async api => {217      const collection = await createCollectionExpectSuccess();218219      const propertiesToBeSet = [];220      for (let i = 0; i < 65; i++) {221        propertiesToBeSet.push({222          key: 'electron_' + i,223          value: Math.random() > 0.5 ? 'high' : 'low',224        });225      }226227      await expect(executeTransaction(228        api, 229        alice, 230        api.tx.unique.setCollectionProperties(collection, propertiesToBeSet), 231      )).to.be.rejectedWith(/common\.PropertyLimitReached/);232233      const properties = (await api.query.common.collectionProperties(collection)).toJSON();234      expect(properties.map).to.be.empty;235      expect(properties.consumedSpace).to.equal(0);236    });237  });238239  it('Fails to set properties with invalid names', async () => {240    await usingApi(async api => {241      const collection = await createCollectionExpectSuccess();242243      const invalidProperties = [244        [{key: 'electron', value: 'negative'}, {key: 'string theory', value: 'understandable'}],245        [{key: 'Mr.Sandman', value: 'Bring me a gene'}],246        [{key: 'déjà vu', value: 'hmm...'}],247      ];248249      for (let i = 0; i < invalidProperties.length; i++) {250        await expect(executeTransaction(251          api, 252          alice, 253          api.tx.unique.setCollectionProperties(collection, invalidProperties[i]), 254        ), `on rejecting the new badly-named property #${i}`).to.be.rejectedWith(/common\.InvalidCharacterInPropertyKey/);255      }256257      await expect(executeTransaction(258        api, 259        alice, 260        api.tx.unique.setCollectionProperties(collection, [{key: '', value: 'nothing must not exist'}]), 261      ), 'on rejecting an unnamed property').to.be.rejectedWith(/common\.EmptyPropertyKey/);262263      await expect(executeTransaction(264        api, 265        alice, 266        api.tx.unique.setCollectionProperties(collection, [267          {key: 'CRISPR-Cas9', value: 'rewriting nature!'},268        ]), 269      ), 'on setting the correctly-but-still-badly-named property').to.not.be.rejected;270271      const keys = invalidProperties.flatMap(propertySet => propertySet.map(property => property.key)).concat('CRISPR-Cas9').concat('');272273      const properties = (await api.rpc.unique.collectionProperties(collection, keys)).toHuman();274      expect(properties).to.be.deep.equal([275        {key: 'CRISPR-Cas9', value: 'rewriting nature!'},276      ]);277278      for (let i = 0; i < invalidProperties.length; i++) {279        await expect(executeTransaction(280          api, 281          alice, 282          api.tx.unique.deleteCollectionProperties(collection, invalidProperties[i].map(propertySet => propertySet.key)), 283        ), `on trying to delete the non-existent badly-named property #${i}`).to.be.rejectedWith(/common\.InvalidCharacterInPropertyKey/);284      }285    });286  });287});288289// ---------- ACCESS RIGHTS290291describe('Integration Test: Access Rights to Token Properties', () => {292  before(async () => {293    await usingApi(async () => {294      alice = privateKey('//Alice');295      bob = privateKey('//Bob');296    });297  });298  299  it('Reads access rights to properties of a collection', async () => {300    await usingApi(async api => {301      const collection = await createCollectionExpectSuccess();302      const propertyRights = (await api.query.common.collectionPropertyPermissions(collection)).toJSON();303      expect(propertyRights).to.be.empty;304    });305  });306  307  it('Sets access rights to properties of a collection', async () => {308    await usingApi(async api => {309      const collection = await createCollectionExpectSuccess();310311      await expect(executeTransaction(312        api, 313        alice, 314        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: true}}]), 315      )).to.not.be.rejected;316317      await addCollectionAdminExpectSuccess(alice, collection, bob.address);318319      await expect(executeTransaction(320        api, 321        alice, 322        api.tx.unique.setPropertyPermissions(collection, [{key: 'mindgame', permission: {collectionAdmin: true, tokenOwner: false}}]), 323      )).to.not.be.rejected;324325      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery', 'mindgame'])).toHuman();326      expect(propertyRights).to.be.deep.equal([327        {key: 'skullduggery', permission: {'mutable': true, 'collectionAdmin': false, 'tokenOwner': false}},328        {key: 'mindgame', permission: {'mutable': false, 'collectionAdmin': true, 'tokenOwner': false}},329      ]);330    });331  });332  333  it('Changes access rights to properties of a collection', async () => {334    await usingApi(async api => {335      const collection = await createCollectionExpectSuccess();336337      await expect(executeTransaction(338        api, 339        alice, 340        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: true, collectionAdmin: true}}]), 341      )).to.not.be.rejected;342343      await expect(executeTransaction(344        api, 345        alice, 346        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]), 347      )).to.not.be.rejected;348349      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery'])).toHuman();350      expect(propertyRights).to.be.deep.equal([351        {key: 'skullduggery', permission: {'mutable': false, 'collectionAdmin': false, 'tokenOwner': true}},352      ]);353    });354  });355});356357describe('Negative Integration Test: Access Rights to Token Properties', () => {358  before(async () => {359    await usingApi(async () => {360      alice = privateKey('//Alice');361      bob = privateKey('//Bob');362    });363  });364365  it('Prevents from setting access rights to properties of a collection if not an onwer/admin', async () => {366    await usingApi(async api => {367      const collection = await createCollectionExpectSuccess();368369      await expect(executeTransaction(370        api, 371        bob, 372        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: true, tokenOwner: true}}]), 373      )).to.be.rejectedWith(/common\.NoPermission/);374375      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery'])).toJSON();376      expect(propertyRights).to.be.empty;377    });378  });379380  it('Prevents from adding too many possible properties', async () => {381    await usingApi(async api => {382      const collection = await createCollectionExpectSuccess();383384      const constitution = [];385      for (let i = 0; i < 65; i++) {386        constitution.push({387          key: 'property_' + i,388          permission: Math.random() > 0.5 ? {mutable: true, collectionAdmin: true, tokenOwner: true} : {},389        });390      }391392      await expect(executeTransaction(393        api, 394        alice, 395        api.tx.unique.setPropertyPermissions(collection, constitution), 396      )).to.be.rejectedWith(/common\.PropertyLimitReached/);397398      const propertyRights = (await api.query.common.collectionPropertyPermissions(collection)).toJSON();399      expect(propertyRights).to.be.empty;400    });401  });402403  it('Prevents access rights to be modified if constant', async () => {404    await usingApi(async api => {405      const collection = await createCollectionExpectSuccess();406407      await expect(executeTransaction(408        api, 409        alice, 410        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]), 411      )).to.not.be.rejected;412413      await expect(executeTransaction(414        api, 415        alice, 416        api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {}}]), 417      )).to.be.rejectedWith(/common\.NoPermission/);418419      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery'])).toHuman();420      expect(propertyRights).to.deep.equal([421        {key: 'skullduggery', permission: {'mutable': false, 'collectionAdmin': false, 'tokenOwner': true}},422      ]);423    });424  });425426  it('Prevents adding properties with invalid names', async () => {427    await usingApi(async api => {428      const collection = await createCollectionExpectSuccess();429430      const invalidProperties = [431        [{key: 'skullduggery', permission: {tokenOwner: true}}, {key: 'im possible', permission: {collectionAdmin: true}}],432        [{key: 'G#4', permission: {tokenOwner: true}}],433        [{key: 'HÆMILTON', permission: {mutable: false, collectionAdmin: true, tokenOwner: true}}],434      ];435436      for (let i = 0; i < invalidProperties.length; i++) {437        await expect(executeTransaction(438          api, 439          alice, 440          api.tx.unique.setPropertyPermissions(collection, invalidProperties[i]), 441        ), `on setting the new badly-named property #${i}`).to.be.rejectedWith(/common\.InvalidCharacterInPropertyKey/);442      }443444      await expect(executeTransaction(445        api, 446        alice, 447        api.tx.unique.setPropertyPermissions(collection, [{key: '', permission: {}}]), 448      ), 'on rejecting an unnamed property').to.be.rejectedWith(/common\.EmptyPropertyKey/);449450      const correctKey = '--0x03116e387820CA05'; // PolkadotJS would parse this as an already encoded hex-string451      await expect(executeTransaction(452        api, 453        alice, 454        api.tx.unique.setPropertyPermissions(collection, [455          {key: correctKey, permission: {collectionAdmin: true}},456        ]), 457      ), 'on setting the correctly-but-still-badly-named property').to.not.be.rejected;458459      const keys = invalidProperties.flatMap(propertySet => propertySet.map(property => property.key)).concat(correctKey).concat('');460461      const propertyRights = (await api.rpc.unique.propertyPermissions(collection, keys)).toHuman();462      expect(propertyRights).to.be.deep.equal([463        {key: correctKey, permission: {mutable: false, collectionAdmin: true, tokenOwner: false}},464      ]);465    });466  });467});468469// ---------- TOKEN PROPERTIES470471describe('Integration Test: Token Properties', () => {472  let collection: number;473  let token: number;474  let permissions: {permission: any, signers: IKeyringPair[]}[];475476  before(async () => {477    await usingApi(async () => {478      alice = privateKey('//Alice');479      bob = privateKey('//Bob');480      charlie = privateKey('//Charlie');481482      permissions = [483        {permission: {mutable: true, collectionAdmin: true}, signers: [alice, bob]},484        {permission: {mutable: false, collectionAdmin: true}, signers: [alice, bob]},485        {permission: {mutable: true, tokenOwner: true}, signers: [charlie]},486        {permission: {mutable: false, tokenOwner: true}, signers: [charlie]},487        {permission: {mutable: true, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie]},488        {permission: {mutable: false, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie]},489      ];490    });491  });492493  beforeEach(async () => {494    await usingApi(async () => {495      collection = await createCollectionExpectSuccess();496      token = await createItemExpectSuccess(alice, collection, 'NFT');497      await addCollectionAdminExpectSuccess(alice, collection, bob.address);498      await transferExpectSuccess(collection, token, alice, charlie);499    });500  });501  502  it('Reads yet empty properties of a token', async () => {503    await usingApi(async api => {504      const collection = await createCollectionExpectSuccess();505      const token = await createItemExpectSuccess(alice, collection, 'NFT');506  507      const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();508      expect(properties.map).to.be.empty;509      expect(properties.consumedSpace).to.be.equal(0);510511      const tokenData = (await api.rpc.unique.tokenData(collection, token, ['anything'])).toJSON().properties;512      expect(tokenData).to.be.empty;513    });514  });515516  it('Assigns properties to a token according to permissions', async () => {517    await usingApi(async api => {518      const propertyKeys: string[] = [];519      let i = 0;520      for (const permission of permissions) {521        for (const signer of permission.signers) {522          const key = i + '_' + signer.address;523          propertyKeys.push(key);524525          await expect(executeTransaction(526            api, 527            alice, 528            api.tx.unique.setPropertyPermissions(collection, [{key: key, permission: permission.permission}]), 529          ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;530531          await expect(executeTransaction(532            api, 533            signer, 534            api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin increase'}]), 535          ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;536        }537538        i++;539      }540541      const properties = (await api.rpc.unique.tokenProperties(collection, token, propertyKeys)).toHuman() as any[];542      const tokensData = (await api.rpc.unique.tokenData(collection, token, propertyKeys)).toHuman().properties as any[];543      for (let i = 0; i < properties.length; i++) {544        expect(properties[i].value).to.be.equal('Serotonin increase');545        expect(tokensData[i].value).to.be.equal('Serotonin increase');546      }547    });548  });549550  it('Changes properties of a token according to permissions', async () => {551    await usingApi(async api => {552      const propertyKeys: string[] = [];553      let i = 0;554      for (const permission of permissions) {555        if (!permission.permission.mutable) continue;556        557        for (const signer of permission.signers) {558          const key = i + '_' + signer.address;559          propertyKeys.push(key);560561          await expect(executeTransaction(562            api, 563            alice, 564            api.tx.unique.setPropertyPermissions(collection, [{key: key, permission: permission.permission}]), 565          ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;566567          await expect(executeTransaction(568            api, 569            signer, 570            api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin increase'}]), 571          ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;572573          await expect(executeTransaction(574            api, 575            signer, 576            api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin stable'}]), 577          ), `on changing property ${i} by ${signer.address}`).to.not.be.rejected;578        }579580        i++;581      }582583      const properties = (await api.rpc.unique.tokenProperties(collection, token, propertyKeys)).toHuman() as any[];584      const tokensData = (await api.rpc.unique.tokenData(collection, token, propertyKeys)).toHuman().properties as any[];585      for (let i = 0; i < properties.length; i++) {586        expect(properties[i].value).to.be.equal('Serotonin stable');587        expect(tokensData[i].value).to.be.equal('Serotonin stable');588      }589    });590  });591592  it('Deletes properties of a token according to permissions', async () => {593    await usingApi(async api => {594      const propertyKeys: string[] = [];595      let i = 0;596597      for (const permission of permissions) {598        if (!permission.permission.mutable) continue;599        600        for (const signer of permission.signers) {601          const key = i + '_' + signer.address;602          propertyKeys.push(key);603604          await expect(executeTransaction(605            api, 606            alice, 607            api.tx.unique.setPropertyPermissions(collection, [{key: key, permission: permission.permission}]), 608          ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;609610          await expect(executeTransaction(611            api, 612            signer, 613            api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin increase'}]), 614          ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;615616          await expect(executeTransaction(617            api, 618            signer, 619            api.tx.unique.deleteTokenProperties(collection, token, [key]), 620          ), `on deleting property ${i} by ${signer.address}`).to.not.be.rejected;621        }622        623        i++;624      }625626      const properties = (await api.rpc.unique.tokenProperties(collection, token, propertyKeys)).toJSON() as any[];627      expect(properties).to.be.empty;628      const tokensData = (await api.rpc.unique.tokenData(collection, token, propertyKeys)).toJSON().properties as any[];629      expect(tokensData).to.be.empty;630      expect((await api.query.nonfungible.tokenProperties(collection, token)).toJSON().consumedSpace).to.be.equal(0);631    });632  });633});634635describe('Negative Integration Test: Token Properties', () => {636  let collection: number;637  let token: number;638  let originalSpace: number;639  let constitution: {permission: any, signers: IKeyringPair[], sinner: IKeyringPair}[];640641  before(async () => {642    await usingApi(async () => {643      alice = privateKey('//Alice');644      bob = privateKey('//Bob');645      charlie = privateKey('//Charlie');646      const dave = privateKey('//Dave');647648      constitution = [649        {permission: {mutable: true, collectionAdmin: true}, signers: [alice, bob], sinner: charlie},650        {permission: {mutable: false, collectionAdmin: true}, signers: [alice, bob], sinner: charlie},651        {permission: {mutable: true, tokenOwner: true}, signers: [charlie], sinner: alice},652        {permission: {mutable: false, tokenOwner: true}, signers: [charlie], sinner: alice},653        {permission: {mutable: true, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie], sinner: dave},654        {permission: {mutable: false, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie], sinner: dave},655      ];656    });657  });658659  beforeEach(async () => {660    collection = await createCollectionExpectSuccess();661    token = await createItemExpectSuccess(alice, collection, 'NFT');662    await addCollectionAdminExpectSuccess(alice, collection, bob.address);663    await transferExpectSuccess(collection, token, alice, charlie);664        665    await usingApi(async api => {666      let i = 0;667      for (const passage of constitution) {668        const signer = passage.signers[0];669        670        await expect(executeTransaction(671          api, 672          alice, 673          api.tx.unique.setPropertyPermissions(collection, [{key: `${i}`, permission: passage.permission}]), 674        ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;675676        await expect(executeTransaction(677          api, 678          signer, 679          api.tx.unique.setTokenProperties(collection, token, [{key: `${i}`, value: 'Serotonin increase'}]), 680        ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;681682        i++;683      }684685      originalSpace = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON().consumedSpace as number;686    });687  });688689  it('Forbids changing/deleting properties of a token if the user is outside of permissions', async () => {690    await usingApi(async api => {691      let i = -1;692      for (const forbiddance of constitution) {693        i++;694        if (!forbiddance.permission.mutable) continue;695696        await expect(executeTransaction(697          api, 698          forbiddance.sinner, 699          api.tx.unique.setTokenProperties(collection, token, [{key: `${i}`, value: 'Serotonin down'}]), 700        ), `on failing to change property ${i} by ${forbiddance.sinner.address}`).to.be.rejectedWith(/common\.NoPermission/);701702        await expect(executeTransaction(703          api, 704          forbiddance.sinner, 705          api.tx.unique.deleteTokenProperties(collection, token, [`${i}`]), 706        ), `on failing to delete property ${i} by ${forbiddance.sinner.address}`).to.be.rejectedWith(/common\.NoPermission/);707      }708709      const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();710      expect(properties.consumedSpace).to.be.equal(originalSpace);711    });712  });713714  it('Forbids changing/deleting properties of a token if the property is permanent (immutable)', async () => {715    await usingApi(async api => {716      let i = -1;717      for (const permission of constitution) {718        i++;719        if (permission.permission.mutable) continue;720721        await expect(executeTransaction(722          api, 723          permission.signers[0], 724          api.tx.unique.setTokenProperties(collection, token, [{key: `${i}`, value: 'Serotonin down'}]), 725        ), `on failing to change property ${i} by ${permission.signers[0].address}`).to.be.rejectedWith(/common\.NoPermission/);726727        await expect(executeTransaction(728          api, 729          permission.signers[0], 730          api.tx.unique.deleteTokenProperties(collection, token, [i.toString()]), 731        ), `on failing to delete property ${i} by ${permission.signers[0].address}`).to.be.rejectedWith(/common\.NoPermission/);732      }733734      const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();735      expect(properties.consumedSpace).to.be.equal(originalSpace);736    });737  });738739  it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission', async () => {740    await usingApi(async api => {741      await expect(executeTransaction(742        api, 743        alice, 744        api.tx.unique.setTokenProperties(collection, token, [{key: 'non-existent', value: 'I exist!'}]), 745      ), 'on failing to add a previously non-existent property').to.be.rejectedWith(/common\.NoPermission/);746        747      await expect(executeTransaction(748        api, 749        alice, 750        api.tx.unique.setPropertyPermissions(collection, [{key: 'now-existent', permission: {}}]), 751      ), 'on setting a new non-permitted property').to.not.be.rejected;752753      await expect(executeTransaction(754        api, 755        alice, 756        api.tx.unique.setTokenProperties(collection, token, [{key: 'now-existent', value: 'I exist!'}]), 757      ), 'on failing to add a property forbidden by the \'None\' permission').to.be.rejectedWith(/common\.NoPermission/);758759      expect((await api.rpc.unique.tokenProperties(collection, token, ['non-existent', 'now-existent'])).toJSON()).to.be.empty;760      const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();761      expect(properties.consumedSpace).to.be.equal(originalSpace);762    });763  });764765  it('Forbids adding too many properties to a token', async () => {766    await usingApi(async api => {767      await expect(executeTransaction(768        api, 769        alice, 770        api.tx.unique.setPropertyPermissions(collection, [771          {key: 'a_holy_book', permission: {collectionAdmin: true, tokenOwner: true}}, 772          {key: 'young_years', permission: {collectionAdmin: true, tokenOwner: true}},773        ]), 774      ), 'on setting a new non-permitted property').to.not.be.rejected;775776      // Mute the general tx parsing error777      {778        console.error = () => {};779        await expect(executeTransaction(780          api, 781          alice, 782          api.tx.unique.setCollectionProperties(collection, [{key: 'a_holy_book', value: 'word '.repeat(6554)}]), 783        )).to.be.rejected;784      }785786      await expect(executeTransaction(787        api, 788        alice, 789        api.tx.unique.setTokenProperties(collection, token, [790          {key: 'a_holy_book', value: 'word '.repeat(3277)}, 791          {key: 'young_years', value: 'neverending'.repeat(1490)},792        ]), 793      )).to.be.rejectedWith(/common\.NoSpaceForProperty/);794795      expect((await api.rpc.unique.tokenProperties(collection, token, ['a_holy_book', 'young_years'])).toJSON()).to.be.empty;796      const propertiesMap = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();797      expect(propertiesMap.consumedSpace).to.be.equal(originalSpace);798    });799  });800});
deletedtests/src/setConstOnChainSchema.test.tsdiffbeforeafterboth
--- a/tests/src/setConstOnChainSchema.test.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-import {Keyring} from '@polkadot/api';
-import {IKeyringPair} from '@polkadot/types/types';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess,
-  destroyCollectionExpectSuccess,
-  addCollectionAdminExpectSuccess,
-  queryCollectionExpectSuccess,
-  getCreatedCollectionCount,
-} from './util/helpers';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-let schema: any;
-let largeSchema: any;
-
-before(async () => {
-  await usingApi(async () => {
-    const keyring = new Keyring({type: 'sr25519'});
-    alice = keyring.addFromUri('//Alice');
-    bob = keyring.addFromUri('//Bob');
-    schema = '0x31';
-    largeSchema = new Array(1024 * 1024 + 10).fill(0xff);
-  });
-});
-describe('Integration Test ext. setConstOnChainSchema()', () => {
-
-  it('Run extrinsic with parameters of the collection id, set the scheme', async () => {
-    await usingApi(async (api) => {
-      const collectionId = await createCollectionExpectSuccess();
-      const collection = await queryCollectionExpectSuccess(api, collectionId);
-      expect(collection.owner.toString()).to.be.eq(alice.address);
-      const setSchema = api.tx.unique.setConstOnChainSchema(collectionId, schema);
-      await submitTransactionAsync(alice, setSchema);
-    });
-  });
-
-  it('Collection admin can set the scheme', async () => {
-    await usingApi(async (api) => {
-      const collectionId = await createCollectionExpectSuccess();
-      const collection = await queryCollectionExpectSuccess(api, collectionId);
-      expect(collection.owner.toString()).to.be.eq(alice.address);
-      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const setSchema = api.tx.unique.setConstOnChainSchema(collectionId, schema);
-      await submitTransactionAsync(bob, setSchema);
-    });
-  });
-
-  it('Checking collection data using the ConstOnChainSchema parameter', async () => {
-    await usingApi(async (api) => {
-      const collectionId = await createCollectionExpectSuccess();
-      const setSchema = api.tx.unique.setConstOnChainSchema(collectionId, schema);
-      await submitTransactionAsync(alice, setSchema);
-      const collection = await queryCollectionExpectSuccess(api, collectionId);
-      expect(collection.constOnChainSchema.toString()).to.be.eq(schema);
-    });
-  });
-});
-
-describe('Negative Integration Test ext. setConstOnChainSchema()', () => {
-
-  it('Set a non-existent collection', async () => {
-    await usingApi(async (api) => {
-      // tslint:disable-next-line: radix
-      const collectionId = await getCreatedCollectionCount(api) + 1;
-      const setSchema = api.tx.unique.setConstOnChainSchema(collectionId, schema);
-      await expect(submitTransactionExpectFailAsync(alice, setSchema)).to.be.rejected;
-    });
-  });
-
-  it('Set a previously deleted collection', async () => {
-    await usingApi(async (api) => {
-      const collectionId = await createCollectionExpectSuccess();
-      await destroyCollectionExpectSuccess(collectionId);
-      const setSchema = api.tx.unique.setConstOnChainSchema(collectionId, schema);
-      await expect(submitTransactionExpectFailAsync(alice, setSchema)).to.be.rejected;
-    });
-  });
-
-  it('Set invalid data in schema (size too large:> 1MB)', async () => {
-    await usingApi(async (api) => {
-      const collectionId = await createCollectionExpectSuccess();
-      const setSchema = api.tx.unique.setConstOnChainSchema(collectionId, largeSchema);
-      await expect(submitTransactionExpectFailAsync(alice, setSchema)).to.be.rejected;
-    });
-  });
-
-  it('Execute method not on behalf of the collection owner', async () => {
-    await usingApi(async (api) => {
-      const collectionId = await createCollectionExpectSuccess();
-      const collection = await queryCollectionExpectSuccess(api, collectionId);
-      expect(collection.owner.toString()).to.be.eq(alice.address);
-      const setSchema = api.tx.unique.setConstOnChainSchema(collectionId, schema);
-      await expect(submitTransactionExpectFailAsync(bob, setSchema)).to.be.rejected;
-    });
-  });
-
-});
deletedtests/src/setOffchainSchema.test.tsdiffbeforeafterboth
--- a/tests/src/setOffchainSchema.test.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-import {IKeyringPair} from '@polkadot/types/types';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import privateKey from './substrate/privateKey';
-import usingApi from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess,
-  destroyCollectionExpectSuccess,
-  findNotExistingCollection,
-  queryCollectionExpectSuccess,
-  setOffchainSchemaExpectFailure,
-  setOffchainSchemaExpectSuccess,
-  addCollectionAdminExpectSuccess,
-} from './util/helpers';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
-const DATA = [1, 2, 3, 4];
-
-describe('Integration Test setOffchainSchema', () => {
-  let alice: IKeyringPair;
-  let bob: IKeyringPair;
-
-  before(async () => {
-    await usingApi(async () => {
-      alice = privateKey('//Alice');
-      bob = privateKey('//Bob');
-    });
-  });
-
-  it('execute setOffchainSchema, verify data was set', async () => {
-    await usingApi(async api => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await setOffchainSchemaExpectSuccess(alice, collectionId, DATA);
-      const collection = await queryCollectionExpectSuccess(api, collectionId);
-
-      expect('0x' + Buffer.from(collection.offchainSchema).toString('hex')).to.be.equal('0x' + Buffer.from(DATA).toString('hex'));
-    });
-  });
-
-  it('execute setOffchainSchema (collection admin), verify data was set', async () => {
-    await usingApi(async api => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      await setOffchainSchemaExpectSuccess(bob, collectionId, DATA);
-      const collection = await queryCollectionExpectSuccess(api, collectionId);
-
-      expect('0x' + Buffer.from(collection.offchainSchema).toString('hex')).to.be.equal('0x' + Buffer.from(DATA).toString('hex'));
-    });
-  });
-});
-
-describe('Negative Integration Test setOffchainSchema', () => {
-  let alice: IKeyringPair;
-  let bob: IKeyringPair;
-
-  let validCollectionId: number;
-
-  before(async () => {
-    await usingApi(async () => {
-      alice = privateKey('//Alice');
-      bob = privateKey('//Bob');
-
-      validCollectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    });
-  });
-
-  it('fails on not existing collection id', async () => {
-    const nonExistingCollectionId = await usingApi(findNotExistingCollection);
-
-    await setOffchainSchemaExpectFailure(alice, nonExistingCollectionId, DATA);
-  });
-
-  it('fails on destroyed collection id', async () => {
-    const destroyedCollectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    await destroyCollectionExpectSuccess(destroyedCollectionId);
-
-    await setOffchainSchemaExpectFailure(alice, destroyedCollectionId, DATA);
-  });
-
-  it('fails on too long data', async () => {
-    const tooLongData = new Array(8 * 1024 + 10).fill(0xff);
-
-    await setOffchainSchemaExpectFailure(alice, validCollectionId, tooLongData);
-  });
-
-  it('fails on execution by non-owner', async () => {
-    await setOffchainSchemaExpectFailure(bob, validCollectionId, DATA);
-  });
-});
deletedtests/src/setSchemaVersion.test.tsdiffbeforeafterboth
--- a/tests/src/setSchemaVersion.test.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-// https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion
-import {ApiPromise, Keyring} from '@polkadot/api';
-import {IKeyringPair} from '@polkadot/types/types';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import usingApi, {submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess,
-  destroyCollectionExpectSuccess,
-  getCreatedCollectionCount,
-  getCreateItemResult,
-  getDetailedCollectionInfo,
-  addCollectionAdminExpectSuccess,
-} from './util/helpers';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-let charlie: IKeyringPair;
-
-/*
-1. We create collection.
-2. Save just created collection id.
-3. Use this id for setSchemaVersion.
-*/
-describe('setSchemaVersion positive', () => {
-  let tx;
-  before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-    });
-  });
-  it('execute setSchemaVersion with image url and unique ', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
-      tx = api.tx.unique.setSchemaVersion(collectionIdForTesting, 'Unique');
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateItemResult(events);
-      const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting);
-      // tslint:disable-next-line:no-unused-expression
-      expect(result.success).to.be.true;
-      // tslint:disable-next-line:no-unused-expression
-      expect(collectionInfo).to.be.exist;
-      // tslint:disable-next-line:no-unused-expression
-      expect(collectionInfo ? collectionInfo.schemaVersion.toString() : '').to.be.equal('Unique');
-    });
-  });
-});
-
-describe('Collection admin setSchemaVersion positive', () => {
-  let tx;
-  let collectionIdForTesting: any;
-
-  before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      bob = keyring.addFromUri('//Bob');
-      collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
-      await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob.address);
-    });
-  });
-  it('execute setSchemaVersion with image url and unique ', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      tx = api.tx.unique.setSchemaVersion(collectionIdForTesting, 'Unique');
-      const events = await submitTransactionAsync(bob, tx);
-      const result = getCreateItemResult(events);
-      const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting);
-      // tslint:disable-next-line:no-unused-expression
-      expect(result.success).to.be.true;
-      // tslint:disable-next-line:no-unused-expression
-      expect(collectionInfo).to.be.exist;
-      // tslint:disable-next-line:no-unused-expression
-      expect(collectionInfo ? collectionInfo.schemaVersion.toString() : '').to.be.equal('Unique');
-    });
-  });
-
-  it('validate schema version with just entered data', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      tx = api.tx.unique.setSchemaVersion(collectionIdForTesting, 'ImageURL');
-      const events = await submitTransactionAsync(bob, tx);
-      const result = getCreateItemResult(events);
-      const collectionInfo = await getDetailedCollectionInfo(api, collectionIdForTesting);
-      // tslint:disable-next-line:no-unused-expression
-      expect(result.success).to.be.true;
-      // tslint:disable-next-line:no-unused-expression
-      expect(collectionInfo).to.be.exist;
-      // tslint:disable-next-line:no-unused-expression
-      expect(collectionInfo ? collectionInfo.schemaVersion.toString() : '').to.be.equal('ImageURL');
-    });
-  });
-});
-
-describe('setSchemaVersion negative', () => {
-  let tx;
-  let collectionIdForTesting: any;
-  before(async () => {
-    await usingApi(async () => {
-      const keyring = new Keyring({type: 'sr25519'});
-      alice = keyring.addFromUri('//Alice');
-      charlie = keyring.addFromUri('//Charlie');
-      collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
-    });
-  });
-  it('execute setSchemaVersion for not exists collection', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const collectionCount = await getCreatedCollectionCount(api);
-      const nonExistedCollectionId = collectionCount + 1;
-      tx = api.tx.unique.setSchemaVersion(nonExistedCollectionId, 'ImageURL');
-      await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
-    });
-  });
-  it('execute setSchemaVersion for deleted collection', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      await destroyCollectionExpectSuccess(collectionIdForTesting);
-      tx = api.tx.unique.setSchemaVersion(collectionIdForTesting, 'ImageURL');
-      await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
-    });
-  });
-  it('Regular user can`t execute setSchemaVersion with image url and unique ', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      tx = api.tx.unique.setSchemaVersion(collectionIdForTesting, 'Unique');
-      await expect(submitTransactionAsync(charlie, tx)).to.be.rejected;
-    });
-  });
-});
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -27,7 +27,7 @@
 import privateKey from '../substrate/privateKey';
 import {default as usingApi, executeTransaction, submitTransactionAsync, submitTransactionExpectFailAsync} from '../substrate/substrate-api';
 import {hexToStr, strToUTF16, utf16ToStr} from './util';
-import {UpDataStructsRpcCollection, UpDataStructsCreateItemData} from '@polkadot/types/lookup';
+import {UpDataStructsRpcCollection, UpDataStructsCreateItemData, UpDataStructsProperty} from '@polkadot/types/lookup';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
@@ -141,7 +141,6 @@
 
 export interface IReFungibleTokenDataType {
   owner: IReFungibleOwner[];
-  constData: number[];
 }
 
 export function uniqueEventMessage(events: EventRecord[]): IGetMessage {
@@ -784,7 +783,7 @@
   });
 }
 
-export async function setOffchainSchemaExpectSuccess(sender: IKeyringPair, collectionId: number, data: number[]) {
+/*export async function setOffchainSchemaExpectSuccess(sender: IKeyringPair, collectionId: number, data: number[]) {
   await usingApi(async (api) => {
     const tx = api.tx.unique.setOffchainSchema(collectionId, '0x' + Buffer.from(data).toString('hex'));
     const events = await submitTransactionAsync(sender, tx);
@@ -799,7 +798,7 @@
     const tx = api.tx.unique.setOffchainSchema(collectionId, '0x' + Buffer.from(data).toString('hex'));
     await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
   });
-}
+}*/
 
 export interface CreateFungibleData {
   readonly Value: bigint;
@@ -1111,12 +1110,20 @@
 ): Promise<string[]> {
   return (await api.rpc.unique.adminlist(collectionId)).toHuman() as any;
 }
-export async function getConstMetadata(
+/*export async function getConstMetadata(
   api: ApiPromise,
   collectionId: number,
   tokenId: number,
 ): Promise<number[]> {
   return [...(await api.rpc.unique.constMetadata(collectionId, tokenId))];
+}*/
+export async function getTokenProperties(
+  api: ApiPromise,
+  collectionId: number,
+  tokenId: number,
+  propertyKeys: string[],
+): Promise<UpDataStructsProperty[]> {
+  return (await api.rpc.unique.tokenProperties(collectionId, tokenId, propertyKeys)).toHuman() as any;
 }
 
 export async function createFungibleItemExpectSuccess(
@@ -1150,18 +1157,6 @@
   });
 }
 
-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);
@@ -1187,10 +1182,10 @@
       const createData = {fungible: {value: 10}};
       tx = api.tx.unique.createItem(collectionId, to, createData as any);
     } else if (createMode === 'ReFungible') {
-      const createData = {refungible: {const_data: [], pieces: 100}};
+      const createData = {refungible: {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: {properties: props}});
       tx = api.tx.unique.createItem(collectionId, to, data as UpDataStructsCreateItemData);
     }
 
@@ -1225,7 +1220,7 @@
 
     let tx;
     if (createMode === 'NFT') {
-      const data = api.createType('UpDataStructsCreateItemData', {NFT: {constData: 'test', properties: props}});
+      const data = api.createType('UpDataStructsCreateItemData', {NFT: {properties: props}});
       tx = api.tx.unique.createItem(collectionId, normalizeAccountId(owner), data);
     } else {
       tx = api.tx.unique.createItem(collectionId, normalizeAccountId(owner), createMode);
@@ -1251,10 +1246,10 @@
       const createData = {fungible: {value: 10}};
       tx = api.tx.unique.createItem(collectionId, to, createData as any);
     } else if (createMode === 'ReFungible') {
-      const createData = {refungible: {const_data: [], pieces: 100}};
+      const createData = {refungible: {pieces: 100}};
       tx = api.tx.unique.createItem(collectionId, to, createData as any);
     } else {
-      const createData = {nft: {const_data: []}};
+      const createData = {nft: {}};
       tx = api.tx.unique.createItem(collectionId, to, createData as any);
     }