git.delta.rocks / unique-network / refs/commits / 3d7ffe75f2a8

difftreelog

fix skip refungible and scheduler tests on qtz/unq

Daniel Shiposha2022-08-09parent: #5eadf5f.patch.diff
in: master

43 files changed

modifiedtests/src/approve.test.tsdiffbeforeafterboth
--- a/tests/src/approve.test.ts
+++ b/tests/src/approve.test.ts
@@ -32,6 +32,8 @@
   getCreatedCollectionCount,
   transferFromExpectSuccess,
   transferFromExpectFail,
+  requirePallets,
+  Pallets
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -49,34 +51,44 @@
     });
   });
 
-  it('Execute the extrinsic and check approvedList', async () => {
+  it('[nft] Execute the extrinsic and check approvedList', async () => {
     const nftCollectionId = await createCollectionExpectSuccess();
-    // nft
     const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
     await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
-    // fungible
+  });
+
+  it('[fungible] Execute the extrinsic and check approvedList', async () => {
     const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
     await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
-    // reFungible
+  });
+
+  it('[refungible] Execute the extrinsic and check approvedList', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const reFungibleCollectionId =
       await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
     await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
   });
 
-  it('Remove approval by using 0 amount', async () => {
+  it('[nft] Remove approval by using 0 amount', async () => {
     const nftCollectionId = await createCollectionExpectSuccess();
-    // nft
     const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
     await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 1);
     await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address, 0);
-    // fungible
+  });
+
+  it('[fungible] Remove approval by using 0 amount', async () => {
     const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
     await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 1);
     await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 0);
-    // reFungible
+  });
+
+  it('[refungible] Remove approval by using 0 amount', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const reFungibleCollectionId =
       await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -117,7 +129,9 @@
     await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
   });
 
-  it('ReFungible up to an approved amount', async () => {
+  it('ReFungible up to an approved amount', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
     const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
     await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
@@ -151,7 +165,9 @@
     await transferFromExpectSuccess(collectionId, itemId, charlie, bob, alice, 1, 'Fungible');
   });
 
-  it('ReFungible up to an approved amount', async () => {
+  it('ReFungible up to an approved amount', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
     const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
     await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
@@ -188,7 +204,9 @@
     await transferFromExpectFail(collectionId, itemId, charlie, bob, alice, 1);
   });
 
-  it('ReFungible up to an approved amount', async () => {
+  it('ReFungible up to an approved amount', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
     const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', bob.address);
     await approveExpectSuccess(collectionId, itemId, bob, charlie.address);
@@ -250,7 +268,9 @@
     await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, bob, charlie, 1);
   });
 
-  it('ReFungible', async () => {
+  it('ReFungible', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const reFungibleCollectionId =
       await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -285,7 +305,9 @@
     await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, charlie, 11);
   });
 
-  it('ReFungible', async () => {
+  it('ReFungible', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
     await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, charlie, 101);
@@ -325,7 +347,9 @@
     await transferFromExpectSuccess(collectionId, itemId, bob, dave, alice, 1, 'Fungible');
   });
 
-  it('ReFungible up to an approved amount', async () => {
+  it('ReFungible up to an approved amount', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const collectionId = await createCollectionExpectSuccess({mode:{type: 'ReFungible'}});
     await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
     const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', charlie.address);
@@ -422,63 +446,87 @@
     });
   });
 
-  it('Approve for a collection that does not exist', async () => {
+  it('[nft] Approve for a collection that does not exist', async () => {
     await usingApi(async (api: ApiPromise) => {
-      // nft
       const nftCollectionCount = await getCreatedCollectionCount(api);
       await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
-      // fungible
+    });
+  });
+
+  it('[fungible] Approve for a collection that does not exist', async () => {
+    await usingApi(async (api: ApiPromise) => {
       const fungibleCollectionCount = await getCreatedCollectionCount(api);
       await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
-      // reFungible
+    });
+  });
+
+  it('[refungible] Approve for a collection that does not exist', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    await usingApi(async (api: ApiPromise) => {
       const reFungibleCollectionCount = await getCreatedCollectionCount(api);
       await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
     });
   });
 
-  it('Approve for a collection that was destroyed', async () => {
-    // nft
+  it('[nft] Approve for a collection that was destroyed', async () => {
     const nftCollectionId = await createCollectionExpectSuccess();
     await destroyCollectionExpectSuccess(nftCollectionId);
     await approveExpectFail(nftCollectionId, 1, alice, bob);
-    // fungible
+  });
+
+  it('Approve for a collection that was destroyed', async () => {
     const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     await destroyCollectionExpectSuccess(fungibleCollectionId);
     await approveExpectFail(fungibleCollectionId, 0, alice, bob);
-    // reFungible
+  });
+
+  it('[refungible] Approve for a collection that was destroyed', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const reFungibleCollectionId =
       await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     await destroyCollectionExpectSuccess(reFungibleCollectionId);
     await approveExpectFail(reFungibleCollectionId, 1, alice, bob);
   });
 
-  it('Approve transfer of a token that does not exist', async () => {
-    // nft
+  it('[nft] Approve transfer of a token that does not exist', async () => {
     const nftCollectionId = await createCollectionExpectSuccess();
     await approveExpectFail(nftCollectionId, 2, alice, bob);
-    // reFungible
+  });
+
+  it('[refungible] Approve transfer of a token that does not exist', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const reFungibleCollectionId =
       await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     await approveExpectFail(reFungibleCollectionId, 2, alice, bob);
   });
 
-  it('Approve using the address that does not own the approved token', async () => {
+  it('[nft] Approve using the address that does not own the approved token', async () => {
     const nftCollectionId = await createCollectionExpectSuccess();
-    // nft
     const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
     await approveExpectFail(nftCollectionId, newNftTokenId, bob, alice);
-    // fungible
+  });
+
+  it('[fungible] Approve using the address that does not own the approved token', async () => {
     const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
     await approveExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice);
-    // reFungible
+  });
+
+  it('[refungible] Approve using the address that does not own the approved token', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const reFungibleCollectionId =
       await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
     await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice);
   });
 
-  it('should fail if approved more ReFungibles than owned', async () => {
+  it('should fail if approved more ReFungibles than owned', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const nftCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'ReFungible');
     await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 100, 'ReFungible');
modifiedtests/src/burnItem.test.tsdiffbeforeafterboth
--- a/tests/src/burnItem.test.ts
+++ b/tests/src/burnItem.test.ts
@@ -25,6 +25,8 @@
   getBalance,
   setCollectionLimitsExpectSuccess,
   isTokenExists,
+  requirePallets,
+  Pallets
 } from './util/helpers';
 
 import chai from 'chai';
@@ -80,7 +82,9 @@
     });
   });
 
-  it('Burn item in ReFungible collection', async () => {
+  it('Burn item in ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const createMode = 'ReFungible';
     const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
     const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
@@ -99,7 +103,9 @@
     });
   });
 
-  it('Burn owned portion of item in ReFungible collection', async () => {
+  it('Burn owned portion of item in ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const createMode = 'ReFungible';
     const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
     const tokenId = await createItemExpectSuccess(alice, collectionId, createMode);
@@ -189,7 +195,9 @@
   });
 
   // TODO: burnFrom
-  it('Burn item in ReFungible collection', async () => {
+  it('Burn item in ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const createMode = 'ReFungible';
     const collectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
     await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
modifiedtests/src/confirmSponsorship.test.tsdiffbeforeafterboth
--- a/tests/src/confirmSponsorship.test.ts
+++ b/tests/src/confirmSponsorship.test.ts
@@ -33,6 +33,8 @@
   addCollectionAdminExpectSuccess,
   getCreatedCollectionCount,
   UNIQUE,
+  requirePallets,
+  Pallets
 } from './util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
 
@@ -124,7 +126,9 @@
     });
   });
 
-  it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async () => {
+  it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
     await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
@@ -252,7 +256,9 @@
     });
   });
 
-  it('ReFungible: Sponsoring is rate limited', async () => {
+  it('ReFungible: Sponsoring is rate limited', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
     await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
modifiedtests/src/createCollection.test.tsdiffbeforeafterboth
--- a/tests/src/createCollection.test.ts
+++ b/tests/src/createCollection.test.ts
@@ -16,7 +16,7 @@
 
 import {expect} from 'chai';
 import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';
-import {createCollectionWithPropsExpectFailure, createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo, createCollectionWithPropsExpectSuccess} from './util/helpers';
+import {createCollectionWithPropsExpectFailure, createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo, createCollectionWithPropsExpectSuccess, requirePallets, Pallets} from './util/helpers';
 
 describe('integration test: ext. createCollection():', () => {
   it('Create new NFT collection', async () => {
@@ -34,7 +34,9 @@
   it('Create new Fungible collection', async () => {
     await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
   });
-  it('Create new ReFungible collection', async () => {
+  it('Create new ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
   });
 
modifiedtests/src/createItem.test.tsdiffbeforeafterboth
--- a/tests/src/createItem.test.ts
+++ b/tests/src/createItem.test.ts
@@ -29,6 +29,8 @@
   itApi,
   normalizeAccountId,
   getCreateItemResult,
+  requirePallets,
+  Pallets
 } from './util/helpers';
 
 const expect = chai.expect;
@@ -79,7 +81,9 @@
     }
 
   });
-  it('Create new item in ReFungible collection', async () => {
+  it('Create new item in ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const createMode = 'ReFungible';
     const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
     await createItemExpectSuccess(alice, newCollectionID, createMode);
@@ -96,7 +100,9 @@
     await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
     await createItemExpectSuccess(bob, newCollectionID, createMode);
   });
-  it('Create new item in ReFungible collection with collection admin permissions', async () => {
+  it('Create new item in ReFungible collection with collection admin permissions', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const createMode = 'ReFungible';
     const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
     await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
@@ -175,7 +181,9 @@
     });
   });
 
-  it('Check total pieces of ReFungible token', async () => {
+  it('Check total pieces of ReFungible token', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const createMode = 'ReFungible';
       const createCollectionResult = await createCollection(api, alice, {mode: {type: createMode}});
@@ -219,7 +227,9 @@
     const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
     await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
   });
-  it('Regular user cannot create new item in ReFungible collection', async () => {
+  it('Regular user cannot create new item in ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const createMode = 'ReFungible';
     const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
     await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
@@ -296,7 +306,9 @@
     });
   });
 
-  it('Check total pieces for invalid Refungible token', async () => {
+  it('Check total pieces for invalid Refungible token', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const createCollectionResult = await createCollection(api, alice, {mode: {type: 'ReFungible'}});
       const collectionId  = createCollectionResult.collectionId;
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -33,6 +33,9 @@
   createCollectionWithPropsExpectSuccess,
   createMultipleItemsWithPropsExpectSuccess,
   getTokenProperties,
+  requirePallets,
+  Pallets,
+  checkPalletsPresence
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -91,7 +94,9 @@
     });
   });
 
-  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 function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api, privateKeyWrapper) => {
       const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
@@ -272,7 +277,9 @@
     });
   });
 
-  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 function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
@@ -335,7 +342,9 @@
     });
   });
 
-  it('Regular user cannot create items in active ReFungible collection', async () => {
+  it('Regular user cannot create items in active ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
@@ -358,9 +367,8 @@
     });
   });
 
-  it('Create NFT and Re-fungible tokens that has reached the maximum data limit', async () => {
+  it('Create NFTs that has reached the maximum data limit', async function() {
     await usingApi(async (api, privateKeyWrapper) => {
-      // NFT
       const collectionId = await createCollectionWithPropsExpectSuccess({
         propPerm: [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}],
       });
@@ -372,8 +380,13 @@
       ];
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
+    });
+  });
 
-      // ReFungible
+  it('Create Refungible tokens that has reached the maximum data limit', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    await usingApi(async api => {
       const collectionIdReFungible =
         await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       {
@@ -402,8 +415,15 @@
   it('Create tokens with different types', async () => {
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess();
+
+      let types = ['NFT', 'Fungible'];
+
+      if (await checkPalletsPresence([Pallets.ReFungible])) {
+        types.push('ReFungible');
+      }
+
       const createMultipleItemsTx = api.tx.unique
-        .createMultipleItems(collectionId, normalizeAccountId(alice.address), ['NFT', 'Fungible', 'ReFungible']);
+        .createMultipleItems(collectionId, normalizeAccountId(alice.address), types);
       await expect(executeTransaction(api, alice, createMultipleItemsTx)).to.be.rejectedWith(/nonfungible\.NotNonfungibleDataUsedToMintFungibleCollectionToken/);
       // garbage collection :-D // lol
       await destroyCollectionExpectSuccess(collectionId);
modifiedtests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItemsEx.test.ts
+++ b/tests/src/createMultipleItemsEx.test.ts
@@ -16,7 +16,7 @@
 
 import {expect} from 'chai';
 import usingApi, {executeTransaction} from './substrate/substrate-api';
-import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, getBalance, getLastTokenId, getTokenProperties} from './util/helpers';
+import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, getBalance, getLastTokenId, getTokenProperties, requirePallets, Pallets} from './util/helpers';
 
 describe.only('Integration Test: createMultipleItemsEx', () => {
   it('can initialize multiple NFT with different owners', async () => {
@@ -146,7 +146,9 @@
     });
   });
 
-  it('can initialize an RFT with multiple owners', async () => {
+  it('can initialize an RFT with multiple owners', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api, privateKeyWrapper) => {
       const alice = privateKeyWrapper('//Alice');
       const bob = privateKeyWrapper('//Bob');
@@ -178,7 +180,9 @@
     });
   });
 
-  it('can initialize multiple RFTs with the same owner', async () => {
+  it('can initialize multiple RFTs with the same owner', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api, privateKeyWrapper) => {
       const alice = privateKeyWrapper('//Alice');
       const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
@@ -389,7 +393,9 @@
     });
   });
 
-  it('fails when trying to set multiple owners when creating multiple refungibles', async () => {
+  it('fails when trying to set multiple owners when creating multiple refungibles', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
 
     await usingApi(async (api, privateKeyWrapper) => {
modifiedtests/src/destroyCollection.test.tsdiffbeforeafterboth
--- a/tests/src/destroyCollection.test.ts
+++ b/tests/src/destroyCollection.test.ts
@@ -25,6 +25,8 @@
   addCollectionAdminExpectSuccess,
   getCreatedCollectionCount,
   createItemExpectSuccess,
+  requirePallets,
+  Pallets
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -38,7 +40,9 @@
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     await destroyCollectionExpectSuccess(collectionId);
   });
-  it('ReFungible collection can be destroyed', async () => {
+  it('ReFungible collection can be destroyed', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     await destroyCollectionExpectSuccess(collectionId);
   });
modifiedtests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth
--- a/tests/src/eth/createRFTCollection.test.ts
+++ b/tests/src/eth/createRFTCollection.test.ts
@@ -16,7 +16,7 @@
 
 import {evmToAddress} from '@polkadot/util-crypto';
 import {expect} from 'chai';
-import {getCreatedCollectionCount, getDetailedCollectionInfo} from '../util/helpers';
+import {getCreatedCollectionCount, getDetailedCollectionInfo, requirePallets, Pallets} from '../util/helpers';
 import {
   evmCollectionHelpers,
   collectionIdToAddress,
@@ -28,6 +28,10 @@
 } from './util/helpers';
 
 describe('Create RFT collection from EVM', () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+  });
+
   itWeb3('Create collection', async ({api, web3, privateKeyWrapper}) => {
     const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const collectionHelper = evmCollectionHelpers(web3, owner);
@@ -146,6 +150,10 @@
 });
 
 describe('(!negative tests!) Create RFT collection from EVM', () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+  });
+
   itWeb3('(!negative test!) Create collection (bad lengths)', async ({api, web3, privateKeyWrapper}) => {
     const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const helper = evmCollectionHelpers(web3, owner);
@@ -228,4 +236,4 @@
       .setCollectionLimit('badLimit', 'true')
       .call()).to.be.rejectedWith('unknown boolean limit "badLimit"');
   });
-});
\ No newline at end of file
+});
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -14,12 +14,16 @@
 // 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 {createCollectionExpectSuccess, UNIQUE} from '../util/helpers';
+import {createCollectionExpectSuccess, UNIQUE, requirePallets, Pallets} from '../util/helpers';
 import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, tokenIdToAddress} from './util/helpers';
 import reFungibleTokenAbi from './reFungibleTokenAbi.json';
 import {expect} from 'chai';
 
 describe('Refungible: Information getting', () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+  });
+
   itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {
     const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const helper = evmCollectionHelpers(web3, caller);
@@ -120,6 +124,10 @@
 });
 
 describe('Refungible: Plain calls', () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+  });
+
   itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {
     const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const helper = evmCollectionHelpers(web3, owner);
@@ -399,6 +407,10 @@
 });
 
 describe('RFT: Fees', () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+  });
+
   itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {
     const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const helper = evmCollectionHelpers(web3, caller);
@@ -435,6 +447,10 @@
 });
 
 describe('Common metadata', () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+  });
+
   itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {
     const collection = await createCollectionExpectSuccess({
       name: 'token name',
@@ -462,4 +478,4 @@
 
     expect(symbol).to.equal('TOK');
   });
-});
\ No newline at end of file
+});
modifiedtests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth
before · tests/src/eth/reFungibleToken.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE} from '../util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth} from './util/helpers';19import reFungibleTokenAbi from './reFungibleTokenAbi.json';2021import chai from 'chai';22import chaiAsPromised from 'chai-as-promised';23chai.use(chaiAsPromised);24const expect = chai.expect;2526describe('Refungible token: Information getting', () => {27  itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {28    const alice = privateKeyWrapper('//Alice');2930    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;3132    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);3334    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;3536    const address = tokenIdToAddress(collectionId, tokenId);37    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});38    const totalSupply = await contract.methods.totalSupply().call();3940    expect(totalSupply).to.equal('200');41  });4243  itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {44    const alice = privateKeyWrapper('//Alice');4546    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;4748    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);4950    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;5152    const address = tokenIdToAddress(collectionId, tokenId);53    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});54    const balance = await contract.methods.balanceOf(caller).call();5556    expect(balance).to.equal('200');57  });5859  itWeb3('decimals', async ({api, web3, privateKeyWrapper}) => {60    const alice = privateKeyWrapper('//Alice');6162    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;6364    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);6566    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;6768    const address = tokenIdToAddress(collectionId, tokenId);69    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});70    const decimals = await contract.methods.decimals().call();7172    expect(decimals).to.equal('0');73  });74});7576// FIXME: Need erc721 for ReFubgible.77describe('Check ERC721 token URI for ReFungible', () => {78  itWeb3('Empty tokenURI', async ({web3, api, privateKeyWrapper}) => {79    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);80    const helper = evmCollectionHelpers(web3, owner);81    let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', '').send();82    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);83    const receiver = createEthAccount(web3);84    const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});85    86    const nextTokenId = await contract.methods.nextTokenId().call();87    expect(nextTokenId).to.be.equal('1');88    result = await contract.methods.mint(89      receiver,90      nextTokenId,91    ).send();9293    const events = normalizeEvents(result.events);94    const address = collectionIdToAddress(collectionId);9596    expect(events).to.be.deep.equal([97      {98        address,99        event: 'Transfer',100        args: {101          from: '0x0000000000000000000000000000000000000000',102          to: receiver,103          tokenId: nextTokenId,104        },105      },106    ]);107108    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');109  });110111  itWeb3('TokenURI from url', async ({web3, api, privateKeyWrapper}) => {112    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);113    const helper = evmCollectionHelpers(web3, owner);114    let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();115    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);116    const receiver = createEthAccount(web3);117    const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});118    119    const nextTokenId = await contract.methods.nextTokenId().call();120    expect(nextTokenId).to.be.equal('1');121    result = await contract.methods.mint(122      receiver,123      nextTokenId,124    ).send();125    126    // Set URL127    await contract.methods.setProperty(nextTokenId, 'url', Buffer.from('Token URI')).send();128      129    const events = normalizeEvents(result.events);130    const address = collectionIdToAddress(collectionId);131132    expect(events).to.be.deep.equal([133      {134        address,135        event: 'Transfer',136        args: {137          from: '0x0000000000000000000000000000000000000000',138          to: receiver,139          tokenId: nextTokenId,140        },141      },142    ]);143144    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');145  });146147  itWeb3('TokenURI from baseURI + tokenId', async ({web3, api, privateKeyWrapper}) => {148    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);149    const helper = evmCollectionHelpers(web3, owner);150    let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();151    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);152    const receiver = createEthAccount(web3);153    const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});154    155    const nextTokenId = await contract.methods.nextTokenId().call();156    expect(nextTokenId).to.be.equal('1');157    result = await contract.methods.mint(158      receiver,159      nextTokenId,160    ).send();161          162    const events = normalizeEvents(result.events);163    const address = collectionIdToAddress(collectionId);164165    expect(events).to.be.deep.equal([166      {167        address,168        event: 'Transfer',169        args: {170          from: '0x0000000000000000000000000000000000000000',171          to: receiver,172          tokenId: nextTokenId,173        },174      },175    ]);176177    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + nextTokenId);178  });179180  itWeb3('TokenURI from baseURI + suffix', async ({web3, api, privateKeyWrapper}) => {181    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);182    const helper = evmCollectionHelpers(web3, owner);183    let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();184    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);185    const receiver = createEthAccount(web3);186    const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});187    188    const nextTokenId = await contract.methods.nextTokenId().call();189    expect(nextTokenId).to.be.equal('1');190    result = await contract.methods.mint(191      receiver,192      nextTokenId,193    ).send();194          195    // Set suffix196    const suffix = '/some/suffix';197    await contract.methods.setProperty(nextTokenId, 'suffix', Buffer.from(suffix)).send();198199    const events = normalizeEvents(result.events);200    const address = collectionIdToAddress(collectionId);201202    expect(events).to.be.deep.equal([203      {204        address,205        event: 'Transfer',206        args: {207          from: '0x0000000000000000000000000000000000000000',208          to: receiver,209          tokenId: nextTokenId,210        },211      },212    ]);213214    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);215  });216});217218describe('Refungible: Plain calls', () => {219  itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {220    const alice = privateKeyWrapper('//Alice');221222    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;223224    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);225226    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;227228    const address = tokenIdToAddress(collectionId, tokenId);229230    const spender = createEthAccount(web3);231232    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});233234    {235      const result = await contract.methods.approve(spender, 100).send({from: owner});236      const events = normalizeEvents(result.events);237238      expect(events).to.be.deep.equal([239        {240          address,241          event: 'Approval',242          args: {243            owner,244            spender,245            value: '100',246          },247        },248      ]);249    }250251    {252      const allowance = await contract.methods.allowance(owner, spender).call();253      expect(+allowance).to.equal(100);254    }255  });256257  itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {258    const alice = privateKeyWrapper('//Alice');259260    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;261262    const owner = createEthAccount(web3);263    await transferBalanceToEth(api, alice, owner);264265    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;266267    const spender = createEthAccount(web3);268    await transferBalanceToEth(api, alice, spender);269270    const receiver = createEthAccount(web3);271272    const address = tokenIdToAddress(collectionId, tokenId);273    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});274275    await contract.methods.approve(spender, 100).send();276277    {278      const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});279      const events = normalizeEvents(result.events);280      expect(events).to.include.deep.members([281        {282          address,283          event: 'Transfer',284          args: {285            from: owner,286            to: receiver,287            value: '49',288          },289        },290        {291          address,292          event: 'Approval',293          args: {294            owner,295            spender,296            value: '51',297          },298        },299      ]);300    }301302    {303      const balance = await contract.methods.balanceOf(receiver).call();304      expect(+balance).to.equal(49);305    }306307    {308      const balance = await contract.methods.balanceOf(owner).call();309      expect(+balance).to.equal(151);310    }311  });312313  itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {314    const alice = privateKeyWrapper('//Alice');315316    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;317318    const owner = createEthAccount(web3);319    await transferBalanceToEth(api, alice, owner);320321    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;322323    const receiver = createEthAccount(web3);324    await transferBalanceToEth(api, alice, receiver);325326    const address = tokenIdToAddress(collectionId, tokenId);327    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});328329    {330      const result = await contract.methods.transfer(receiver, 50).send({from: owner});331      const events = normalizeEvents(result.events);332      expect(events).to.include.deep.members([333        {334          address,335          event: 'Transfer',336          args: {337            from: owner,338            to: receiver,339            value: '50',340          },341        },342      ]);343    }344345    {346      const balance = await contract.methods.balanceOf(owner).call();347      expect(+balance).to.equal(150);348    }349350    {351      const balance = await contract.methods.balanceOf(receiver).call();352      expect(+balance).to.equal(50);353    }354  });355356  itWeb3('Can perform repartition()', async ({web3, api, privateKeyWrapper}) => {357    const alice = privateKeyWrapper('//Alice');358359    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;360361    const owner = createEthAccount(web3);362    await transferBalanceToEth(api, alice, owner);363364    const receiver = createEthAccount(web3);365    await transferBalanceToEth(api, alice, receiver);366367    const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;368369    const address = tokenIdToAddress(collectionId, tokenId);370    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});371372    await contract.methods.repartition(200).send({from: owner});373    expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);374    await contract.methods.transfer(receiver, 110).send({from: owner});375    expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);376    expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);377    378    await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected;379380    await contract.methods.transfer(receiver, 90).send({from: owner});381    expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(0);382    expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(200);383384    await contract.methods.repartition(150).send({from: receiver});385    await expect(contract.methods.transfer(owner, 160).send({from: receiver})).to.eventually.be.rejected;386    expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(150);387  });388389  itWeb3('Can repartition with increased amount', async ({web3, api, privateKeyWrapper}) => {390    const alice = privateKeyWrapper('//Alice');391392    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;393394    const owner = createEthAccount(web3);395    await transferBalanceToEth(api, alice, owner);396397    const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;398399    const address = tokenIdToAddress(collectionId, tokenId);400    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});401402    const result = await contract.methods.repartition(200).send();403    const events = normalizeEvents(result.events);404405    expect(events).to.deep.equal([406      {407        address,408        event: 'Transfer',409        args: {410          from: '0x0000000000000000000000000000000000000000',411          to: owner,412          value: '100',413        },414      },415    ]);416  });417418  itWeb3('Can repartition with decreased amount', async ({web3, api, privateKeyWrapper}) => {419    const alice = privateKeyWrapper('//Alice');420421    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;422423    const owner = createEthAccount(web3);424    await transferBalanceToEth(api, alice, owner);425426    const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;427428    const address = tokenIdToAddress(collectionId, tokenId);429    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});430431    const result = await contract.methods.repartition(50).send();432    const events = normalizeEvents(result.events);433    expect(events).to.deep.equal([434      {435        address,436        event: 'Transfer',437        args: {438          from: owner,439          to: '0x0000000000000000000000000000000000000000',440          value: '50',441        },442      },443    ]);444  });445446  itWeb3('Receiving Transfer event on burning into full ownership', async ({web3, api, privateKeyWrapper}) => {447    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);448    const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);449    const helper = evmCollectionHelpers(web3, caller);450    const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();451    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);452    const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});453454    const tokenId = await contract.methods.nextTokenId().call();455    await contract.methods.mint(caller, tokenId).send();456457    const address = tokenIdToAddress(collectionId, tokenId);458459    const tokenContract =  new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});460    await tokenContract.methods.repartition(2).send();461    await tokenContract.methods.transfer(receiver, 1).send();462463    const events =  await recordEvents(contract, async () => 464      await tokenContract.methods.burnFrom(caller, 1).send());465    expect(events).to.deep.equal([466      {467        address: collectionIdAddress,468        event: 'Transfer',469        args: {470          from: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',471          to: receiver,472          tokenId,473        },474      },475    ]);476  });477});478479describe('Refungible: Fees', () => {480  itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {481    const alice = privateKeyWrapper('//Alice');482483    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;484485    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);486    const spender = createEthAccount(web3);487488    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;489490    const address = tokenIdToAddress(collectionId, tokenId);491    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});492493    const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));494    expect(cost < BigInt(0.2 * Number(UNIQUE)));495  });496497  itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {498    const alice = privateKeyWrapper('//Alice');499500    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;501502    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);503    const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);504505    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;506507    const address = tokenIdToAddress(collectionId, tokenId);508    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});509510    await contract.methods.approve(spender, 100).send({from: owner});511512    const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));513    expect(cost < BigInt(0.2 * Number(UNIQUE)));514  });515516  itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {517    const alice = privateKeyWrapper('//Alice');518519    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;520521    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);522    const receiver = createEthAccount(web3);523524    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;525526    const address = tokenIdToAddress(collectionId, tokenId);527    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});528529    const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));530    expect(cost < BigInt(0.2 * Number(UNIQUE)));531  });532});533534describe('Refungible: Substrate calls', () => {535  itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {536    const alice = privateKeyWrapper('//Alice');537538    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;539540    const receiver = createEthAccount(web3);541542    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;543544    const address = tokenIdToAddress(collectionId, tokenId);545    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);546547    const events = await recordEvents(contract, async () => {548      expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;549    });550551    expect(events).to.be.deep.equal([552      {553        address,554        event: 'Approval',555        args: {556          owner: subToEth(alice.address),557          spender: receiver,558          value: '100',559        },560      },561    ]);562  });563564  itWeb3('Events emitted for transferFrom()', async ({web3, api, privateKeyWrapper}) => {565    const alice = privateKeyWrapper('//Alice');566567    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;568    const bob = privateKeyWrapper('//Bob');569570    const receiver = createEthAccount(web3);571572    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;573    expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;574575    const address = tokenIdToAddress(collectionId, tokenId);576    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);577578    const events = await recordEvents(contract, async () => {579      expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver},  51n)).to.be.true;580    });581582    expect(events).to.be.deep.equal([583      {584        address,585        event: 'Transfer',586        args: {587          from: subToEth(alice.address),588          to: receiver,589          value: '51',590        },591      },592      {593        address,594        event: 'Approval',595        args: {596          owner: subToEth(alice.address),597          spender: subToEth(bob.address),598          value: '49',599        },600      },601    ]);602  });603604  itWeb3('Events emitted for transfer()', async ({web3, api, privateKeyWrapper}) => {605    const alice = privateKeyWrapper('//Alice');606607    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;608609    const receiver = createEthAccount(web3);610611    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;612613    const address = tokenIdToAddress(collectionId, tokenId);614    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);615616    const events = await recordEvents(contract, async () => {617      expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver},  51n)).to.be.true;618    });619620    expect(events).to.be.deep.equal([621      {622        address,623        event: 'Transfer',624        args: {625          from: subToEth(alice.address),626          to: receiver,627          value: '51',628        },629      },630    ]);631  });632});
after · tests/src/eth/reFungibleToken.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE, requirePallets, Pallets} from '../util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth} from './util/helpers';19import reFungibleTokenAbi from './reFungibleTokenAbi.json';2021import chai from 'chai';22import chaiAsPromised from 'chai-as-promised';23chai.use(chaiAsPromised);24const expect = chai.expect;2526describe('Refungible token: Information getting', () => {27  before(async function() {28    await requirePallets(this, [Pallets.ReFungible]);29  });3031  itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {32    const alice = privateKeyWrapper('//Alice');3334    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;3536    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);3738    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;3940    const address = tokenIdToAddress(collectionId, tokenId);41    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});42    const totalSupply = await contract.methods.totalSupply().call();4344    expect(totalSupply).to.equal('200');45  });4647  itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {48    const alice = privateKeyWrapper('//Alice');4950    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;5152    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);5354    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;5556    const address = tokenIdToAddress(collectionId, tokenId);57    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});58    const balance = await contract.methods.balanceOf(caller).call();5960    expect(balance).to.equal('200');61  });6263  itWeb3('decimals', async ({api, web3, privateKeyWrapper}) => {64    const alice = privateKeyWrapper('//Alice');6566    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;6768    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);6970    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;7172    const address = tokenIdToAddress(collectionId, tokenId);73    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});74    const decimals = await contract.methods.decimals().call();7576    expect(decimals).to.equal('0');77  });78});7980// FIXME: Need erc721 for ReFubgible.81describe('Check ERC721 token URI for ReFungible', () => {82  before(async function() {83    await requirePallets(this, [Pallets.ReFungible]);84  });8586  itWeb3('Empty tokenURI', async ({web3, api, privateKeyWrapper}) => {87    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);88    const helper = evmCollectionHelpers(web3, owner);89    let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', '').send();90    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);91    const receiver = createEthAccount(web3);92    const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});93    94    const nextTokenId = await contract.methods.nextTokenId().call();95    expect(nextTokenId).to.be.equal('1');96    result = await contract.methods.mint(97      receiver,98      nextTokenId,99    ).send();100101    const events = normalizeEvents(result.events);102    const address = collectionIdToAddress(collectionId);103104    expect(events).to.be.deep.equal([105      {106        address,107        event: 'Transfer',108        args: {109          from: '0x0000000000000000000000000000000000000000',110          to: receiver,111          tokenId: nextTokenId,112        },113      },114    ]);115116    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');117  });118119  itWeb3('TokenURI from url', async ({web3, api, privateKeyWrapper}) => {120    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);121    const helper = evmCollectionHelpers(web3, owner);122    let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();123    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);124    const receiver = createEthAccount(web3);125    const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});126    127    const nextTokenId = await contract.methods.nextTokenId().call();128    expect(nextTokenId).to.be.equal('1');129    result = await contract.methods.mint(130      receiver,131      nextTokenId,132    ).send();133    134    // Set URL135    await contract.methods.setProperty(nextTokenId, 'url', Buffer.from('Token URI')).send();136      137    const events = normalizeEvents(result.events);138    const address = collectionIdToAddress(collectionId);139140    expect(events).to.be.deep.equal([141      {142        address,143        event: 'Transfer',144        args: {145          from: '0x0000000000000000000000000000000000000000',146          to: receiver,147          tokenId: nextTokenId,148        },149      },150    ]);151152    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');153  });154155  itWeb3('TokenURI from baseURI + tokenId', async ({web3, api, privateKeyWrapper}) => {156    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);157    const helper = evmCollectionHelpers(web3, owner);158    let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();159    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);160    const receiver = createEthAccount(web3);161    const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});162    163    const nextTokenId = await contract.methods.nextTokenId().call();164    expect(nextTokenId).to.be.equal('1');165    result = await contract.methods.mint(166      receiver,167      nextTokenId,168    ).send();169          170    const events = normalizeEvents(result.events);171    const address = collectionIdToAddress(collectionId);172173    expect(events).to.be.deep.equal([174      {175        address,176        event: 'Transfer',177        args: {178          from: '0x0000000000000000000000000000000000000000',179          to: receiver,180          tokenId: nextTokenId,181        },182      },183    ]);184185    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + nextTokenId);186  });187188  itWeb3('TokenURI from baseURI + suffix', async ({web3, api, privateKeyWrapper}) => {189    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);190    const helper = evmCollectionHelpers(web3, owner);191    let result = await helper.methods.createERC721MetadataCompatibleCollection('Mint collection', '1', '1', 'BaseURI_').send();192    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);193    const receiver = createEthAccount(web3);194    const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});195    196    const nextTokenId = await contract.methods.nextTokenId().call();197    expect(nextTokenId).to.be.equal('1');198    result = await contract.methods.mint(199      receiver,200      nextTokenId,201    ).send();202          203    // Set suffix204    const suffix = '/some/suffix';205    await contract.methods.setProperty(nextTokenId, 'suffix', Buffer.from(suffix)).send();206207    const events = normalizeEvents(result.events);208    const address = collectionIdToAddress(collectionId);209210    expect(events).to.be.deep.equal([211      {212        address,213        event: 'Transfer',214        args: {215          from: '0x0000000000000000000000000000000000000000',216          to: receiver,217          tokenId: nextTokenId,218        },219      },220    ]);221222    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);223  });224});225226describe('Refungible: Plain calls', () => {227  before(async function() {228    await requirePallets(this, [Pallets.ReFungible]);229  });230231  itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {232    const alice = privateKeyWrapper('//Alice');233234    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;235236    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);237238    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;239240    const address = tokenIdToAddress(collectionId, tokenId);241242    const spender = createEthAccount(web3);243244    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});245246    {247      const result = await contract.methods.approve(spender, 100).send({from: owner});248      const events = normalizeEvents(result.events);249250      expect(events).to.be.deep.equal([251        {252          address,253          event: 'Approval',254          args: {255            owner,256            spender,257            value: '100',258          },259        },260      ]);261    }262263    {264      const allowance = await contract.methods.allowance(owner, spender).call();265      expect(+allowance).to.equal(100);266    }267  });268269  itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {270    const alice = privateKeyWrapper('//Alice');271272    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;273274    const owner = createEthAccount(web3);275    await transferBalanceToEth(api, alice, owner);276277    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;278279    const spender = createEthAccount(web3);280    await transferBalanceToEth(api, alice, spender);281282    const receiver = createEthAccount(web3);283284    const address = tokenIdToAddress(collectionId, tokenId);285    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});286287    await contract.methods.approve(spender, 100).send();288289    {290      const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});291      const events = normalizeEvents(result.events);292      expect(events).to.include.deep.members([293        {294          address,295          event: 'Transfer',296          args: {297            from: owner,298            to: receiver,299            value: '49',300          },301        },302        {303          address,304          event: 'Approval',305          args: {306            owner,307            spender,308            value: '51',309          },310        },311      ]);312    }313314    {315      const balance = await contract.methods.balanceOf(receiver).call();316      expect(+balance).to.equal(49);317    }318319    {320      const balance = await contract.methods.balanceOf(owner).call();321      expect(+balance).to.equal(151);322    }323  });324325  itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {326    const alice = privateKeyWrapper('//Alice');327328    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;329330    const owner = createEthAccount(web3);331    await transferBalanceToEth(api, alice, owner);332333    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;334335    const receiver = createEthAccount(web3);336    await transferBalanceToEth(api, alice, receiver);337338    const address = tokenIdToAddress(collectionId, tokenId);339    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});340341    {342      const result = await contract.methods.transfer(receiver, 50).send({from: owner});343      const events = normalizeEvents(result.events);344      expect(events).to.include.deep.members([345        {346          address,347          event: 'Transfer',348          args: {349            from: owner,350            to: receiver,351            value: '50',352          },353        },354      ]);355    }356357    {358      const balance = await contract.methods.balanceOf(owner).call();359      expect(+balance).to.equal(150);360    }361362    {363      const balance = await contract.methods.balanceOf(receiver).call();364      expect(+balance).to.equal(50);365    }366  });367368  itWeb3('Can perform repartition()', async ({web3, api, privateKeyWrapper}) => {369    const alice = privateKeyWrapper('//Alice');370371    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;372373    const owner = createEthAccount(web3);374    await transferBalanceToEth(api, alice, owner);375376    const receiver = createEthAccount(web3);377    await transferBalanceToEth(api, alice, receiver);378379    const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;380381    const address = tokenIdToAddress(collectionId, tokenId);382    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});383384    await contract.methods.repartition(200).send({from: owner});385    expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);386    await contract.methods.transfer(receiver, 110).send({from: owner});387    expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);388    expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);389    390    await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected;391392    await contract.methods.transfer(receiver, 90).send({from: owner});393    expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(0);394    expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(200);395396    await contract.methods.repartition(150).send({from: receiver});397    await expect(contract.methods.transfer(owner, 160).send({from: receiver})).to.eventually.be.rejected;398    expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(150);399  });400401  itWeb3('Can repartition with increased amount', async ({web3, api, privateKeyWrapper}) => {402    const alice = privateKeyWrapper('//Alice');403404    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;405406    const owner = createEthAccount(web3);407    await transferBalanceToEth(api, alice, owner);408409    const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;410411    const address = tokenIdToAddress(collectionId, tokenId);412    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});413414    const result = await contract.methods.repartition(200).send();415    const events = normalizeEvents(result.events);416417    expect(events).to.deep.equal([418      {419        address,420        event: 'Transfer',421        args: {422          from: '0x0000000000000000000000000000000000000000',423          to: owner,424          value: '100',425        },426      },427    ]);428  });429430  itWeb3('Can repartition with decreased amount', async ({web3, api, privateKeyWrapper}) => {431    const alice = privateKeyWrapper('//Alice');432433    const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;434435    const owner = createEthAccount(web3);436    await transferBalanceToEth(api, alice, owner);437438    const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;439440    const address = tokenIdToAddress(collectionId, tokenId);441    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});442443    const result = await contract.methods.repartition(50).send();444    const events = normalizeEvents(result.events);445    expect(events).to.deep.equal([446      {447        address,448        event: 'Transfer',449        args: {450          from: owner,451          to: '0x0000000000000000000000000000000000000000',452          value: '50',453        },454      },455    ]);456  });457458  itWeb3('Receiving Transfer event on burning into full ownership', async ({web3, api, privateKeyWrapper}) => {459    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);460    const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);461    const helper = evmCollectionHelpers(web3, caller);462    const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();463    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);464    const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});465466    const tokenId = await contract.methods.nextTokenId().call();467    await contract.methods.mint(caller, tokenId).send();468469    const address = tokenIdToAddress(collectionId, tokenId);470471    const tokenContract =  new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});472    await tokenContract.methods.repartition(2).send();473    await tokenContract.methods.transfer(receiver, 1).send();474475    const events =  await recordEvents(contract, async () => 476      await tokenContract.methods.burnFrom(caller, 1).send());477    expect(events).to.deep.equal([478      {479        address: collectionIdAddress,480        event: 'Transfer',481        args: {482          from: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',483          to: receiver,484          tokenId,485        },486      },487    ]);488  });489});490491describe('Refungible: Fees', () => {492  before(async function() {493    await requirePallets(this, [Pallets.ReFungible]);494  });495496  itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {497    const alice = privateKeyWrapper('//Alice');498499    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;500501    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);502    const spender = createEthAccount(web3);503504    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;505506    const address = tokenIdToAddress(collectionId, tokenId);507    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});508509    const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));510    expect(cost < BigInt(0.2 * Number(UNIQUE)));511  });512513  itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {514    const alice = privateKeyWrapper('//Alice');515516    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;517518    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);519    const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);520521    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;522523    const address = tokenIdToAddress(collectionId, tokenId);524    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});525526    await contract.methods.approve(spender, 100).send({from: owner});527528    const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));529    expect(cost < BigInt(0.2 * Number(UNIQUE)));530  });531532  itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {533    const alice = privateKeyWrapper('//Alice');534535    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;536537    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);538    const receiver = createEthAccount(web3);539540    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;541542    const address = tokenIdToAddress(collectionId, tokenId);543    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});544545    const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));546    expect(cost < BigInt(0.2 * Number(UNIQUE)));547  });548});549550describe('Refungible: Substrate calls', () => {551  before(async function() {552    await requirePallets(this, [Pallets.ReFungible]);553  });554555  itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {556    const alice = privateKeyWrapper('//Alice');557558    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;559560    const receiver = createEthAccount(web3);561562    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;563564    const address = tokenIdToAddress(collectionId, tokenId);565    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);566567    const events = await recordEvents(contract, async () => {568      expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;569    });570571    expect(events).to.be.deep.equal([572      {573        address,574        event: 'Approval',575        args: {576          owner: subToEth(alice.address),577          spender: receiver,578          value: '100',579        },580      },581    ]);582  });583584  itWeb3('Events emitted for transferFrom()', async ({web3, api, privateKeyWrapper}) => {585    const alice = privateKeyWrapper('//Alice');586587    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;588    const bob = privateKeyWrapper('//Bob');589590    const receiver = createEthAccount(web3);591592    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;593    expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;594595    const address = tokenIdToAddress(collectionId, tokenId);596    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);597598    const events = await recordEvents(contract, async () => {599      expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver},  51n)).to.be.true;600    });601602    expect(events).to.be.deep.equal([603      {604        address,605        event: 'Transfer',606        args: {607          from: subToEth(alice.address),608          to: receiver,609          value: '51',610        },611      },612      {613        address,614        event: 'Approval',615        args: {616          owner: subToEth(alice.address),617          spender: subToEth(bob.address),618          value: '49',619        },620      },621    ]);622  });623624  itWeb3('Events emitted for transfer()', async ({web3, api, privateKeyWrapper}) => {625    const alice = privateKeyWrapper('//Alice');626627    const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;628629    const receiver = createEthAccount(web3);630631    const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;632633    const address = tokenIdToAddress(collectionId, tokenId);634    const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);635636    const events = await recordEvents(contract, async () => {637      expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver},  51n)).to.be.true;638    });639640    expect(events).to.be.deep.equal([641      {642        address,643        event: 'Transfer',644        args: {645          from: subToEth(alice.address),646          to: receiver,647          value: '51',648        },649      },650    ]);651  });652});
modifiedtests/src/eth/scheduling.test.tsdiffbeforeafterboth
--- a/tests/src/eth/scheduling.test.ts
+++ b/tests/src/eth/scheduling.test.ts
@@ -16,9 +16,13 @@
 
 import {expect} from 'chai';
 import {createEthAccountWithBalance, deployFlipper, GAS_ARGS, itWeb3, subToEth, transferBalanceToEth} from './util/helpers';
-import {scheduleExpectSuccess, waitNewBlocks} from '../util/helpers';
+import {scheduleExpectSuccess, waitNewBlocks, requirePallets, Pallets} from '../util/helpers';
 
 describe('Scheduing EVM smart contracts', () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.Scheduler]);
+  });
+
   itWeb3('Successfully schedules and periodically executes an EVM contract', async ({api, web3, privateKeyWrapper}) => {
     const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
     const flipper = await deployFlipper(web3, deployer);
@@ -51,4 +55,4 @@
       expect(await flipper.methods.getValue().call()).to.be.equal(initialValue);
     }
   });
-});
\ No newline at end of file
+});
modifiedtests/src/limits.test.tsdiffbeforeafterboth
--- a/tests/src/limits.test.ts
+++ b/tests/src/limits.test.ts
@@ -27,6 +27,8 @@
   transferExpectSuccess,
   getFreeBalance,
   waitNewBlocks, burnItemExpectSuccess,
+  requirePallets,
+  Pallets
 } from './util/helpers';
 import {expect} from 'chai';
 
@@ -67,7 +69,9 @@
 describe('Number of tokens per address (ReFungible)', () => {
   let alice: IKeyringPair;
 
-  before(async () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api, privateKeyWrapper) => {
       alice = privateKeyWrapper('//Alice');
     });
@@ -367,7 +371,9 @@
   let bob: IKeyringPair;
   let charlie: IKeyringPair;
 
-  before(async () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api, privateKeyWrapper) => {
       alice = privateKeyWrapper('//Alice');
       bob = privateKeyWrapper('//Bob');
modifiedtests/src/nesting/nest.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/nest.test.ts
+++ b/tests/src/nesting/nest.test.ts
@@ -17,6 +17,8 @@
   transferExpectSuccess,
   transferFromExpectSuccess,
   setCollectionLimitsExpectSuccess,
+  requirePallets,
+  Pallets
 } from '../util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
 
@@ -311,7 +313,9 @@
 
   // ---------- Re-Fungible ----------
 
-  it('ReFungible: allows an Owner to nest/unnest their token', async () => {
+  it('ReFungible: allows an Owner to nest/unnest their token', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
       await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {tokenOwner: true}});
@@ -333,7 +337,9 @@
     });
   });
 
-  it('ReFungible: allows an Owner to nest/unnest their token (Restricted nesting)', async () => {
+  it('ReFungible: allows an Owner to nest/unnest their token (Restricted nesting)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
       const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT', {Substrate: alice.address});
@@ -715,7 +721,9 @@
 
   // ---------- Re-Fungible ----------
 
-  it('ReFungible: disallows to nest token if nesting is disabled', async () => {
+  it('ReFungible: disallows to nest token if nesting is disabled', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
       await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {}});
@@ -745,7 +753,9 @@
     });
   });
 
-  it('ReFungible: disallows a non-Owner to nest someone else\'s token', async () => {
+  it('ReFungible: disallows a non-Owner to nest someone else\'s token', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
       await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {tokenOwner: true}});
@@ -773,7 +783,9 @@
     });
   });
 
-  it('ReFungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async () => {
+  it('ReFungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
       await addToAllowListExpectSuccess(alice, collectionNFT, bob.address);
@@ -800,7 +812,9 @@
     });
   });
 
-  it('ReFungible: disallows to nest token to an unlisted collection', async () => {
+  it('ReFungible: disallows to nest token to an unlisted collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
       await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {tokenOwner: true, restricted:[]}});
modifiedtests/src/nesting/properties.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/properties.test.ts
+++ b/tests/src/nesting/properties.test.ts
@@ -8,6 +8,8 @@
   createItemExpectSuccess,
   getCreateCollectionResult,
   transferExpectSuccess,
+  requirePallets,
+  Pallets
 } from '../util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
 import {tokenIdToAddress} from '../eth/util/helpers';
@@ -64,7 +66,9 @@
     await testMakeSureSuppliesRequired({type: 'NFT'});
   });
 
-  it('Makes sure collectionById supplies required fields for ReFungible', async () => {
+  it('Makes sure collectionById supplies required fields for ReFungible', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testMakeSureSuppliesRequired({type: 'ReFungible'});
   });
 });
@@ -120,7 +124,9 @@
   it('Sets properties for a NFT collection', async () => {
     await testSetsPropertiesForCollection('NFT');
   });
-  it('Sets properties for a ReFungible collection', async () => {
+  it('Sets properties for a ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testSetsPropertiesForCollection('ReFungible');
   });
 
@@ -178,7 +184,9 @@
   it('Check valid names for NFT collection properties keys', async () => {
     await testCheckValidNames('NFT');
   });
-  it('Check valid names for ReFungible collection properties keys', async () => {
+  it('Check valid names for ReFungible collection properties keys', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testCheckValidNames('ReFungible');
   });
 
@@ -209,7 +217,9 @@
   it('Changes properties of a NFT collection', async () => {
     await testChangesProperties({type: 'NFT'});
   });
-  it('Changes properties of a ReFungible collection', async () => {
+  it('Changes properties of a ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testChangesProperties({type: 'ReFungible'});
   });
 
@@ -238,7 +248,9 @@
   it('Deletes properties of a NFT collection', async () => {
     await testDeleteProperties({type: 'NFT'});
   });
-  it('Deletes properties of a ReFungible collection', async () => {
+  it('Deletes properties of a ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testDeleteProperties({type: 'ReFungible'});
   });
 });
@@ -269,7 +281,9 @@
   it('Fails to set properties in a NFT collection if not its onwer/administrator', async () => {
     await testFailsSetPropertiesIfNotOwnerOrAdmin({type: 'NFT'});
   });
-  it('Fails to set properties in a ReFungible collection if not its onwer/administrator', async () => {
+  it('Fails to set properties in a ReFungible collection if not its onwer/administrator', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testFailsSetPropertiesIfNotOwnerOrAdmin({type: 'ReFungible'});
   });
   
@@ -307,7 +321,9 @@
   it('Fails to set properties that exceed the limits (NFT)', async () => {
     await testFailsSetPropertiesThatExeedLimits({type: 'NFT'});
   });
-  it('Fails to set properties that exceed the limits (ReFungible)', async () => {
+  it('Fails to set properties that exceed the limits (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testFailsSetPropertiesThatExeedLimits({type: 'ReFungible'});
   });
   
@@ -337,7 +353,9 @@
   it('Fails to set more properties than it is allowed (NFT)', async () => {
     await testFailsSetMorePropertiesThanAllowed({type: 'NFT'});
   });
-  it('Fails to set more properties than it is allowed (ReFungible)', async () => {
+  it('Fails to set more properties than it is allowed (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testFailsSetMorePropertiesThanAllowed({type: 'ReFungible'});
   });
   
@@ -392,7 +410,9 @@
   it('Fails to set properties with invalid names (NFT)', async () => {
     await testFailsSetPropertiesWithInvalidNames({type: 'NFT'});
   });
-  it('Fails to set properties with invalid names (ReFungible)', async () => {
+  it('Fails to set properties with invalid names (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testFailsSetPropertiesWithInvalidNames({type: 'ReFungible'});
   });
 });
@@ -443,7 +463,9 @@
   it('Sets access rights to properties of a collection (NFT)', async () => {
     await testSetsAccessRightsToProperties({type: 'NFT'});
   });
-  it('Sets access rights to properties of a collection (ReFungible)', async () => {
+  it('Sets access rights to properties of a collection (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testSetsAccessRightsToProperties({type: 'ReFungible'});
   });
   
@@ -472,7 +494,9 @@
   it('Changes access rights to properties of a NFT collection', async () => {
     await testChangesAccessRightsToProperty({type: 'NFT'});
   });
-  it('Changes access rights to properties of a ReFungible collection', async () => {
+  it('Changes access rights to properties of a ReFungible collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testChangesAccessRightsToProperty({type: 'ReFungible'});
   });
 });
@@ -502,7 +526,9 @@
   it('Prevents from setting access rights to properties of a NFT collection if not an onwer/admin', async () => {
     await testPreventsFromSettingAccessRightsNotAdminOrOwner({type: 'NFT'});
   });
-  it('Prevents from setting access rights to properties of a ReFungible collection if not an onwer/admin', async () => {
+  it('Prevents from setting access rights to properties of a ReFungible collection if not an onwer/admin', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testPreventsFromSettingAccessRightsNotAdminOrOwner({type: 'ReFungible'});
   });
 
@@ -531,7 +557,9 @@
   it('Prevents from adding too many possible properties (NFT)', async () => {
     await testPreventFromAddingTooManyPossibleProperties({type: 'NFT'});
   });
-  it('Prevents from adding too many possible properties (ReFungible)', async () => {
+  it('Prevents from adding too many possible properties (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testPreventFromAddingTooManyPossibleProperties({type: 'ReFungible'});
   });
 
@@ -560,7 +588,9 @@
   it('Prevents access rights to be modified if constant (NFT)', async () => {
     await testPreventAccessRightsModifiedIfConstant({type: 'NFT'});
   });
-  it('Prevents access rights to be modified if constant (ReFungible)', async () => {
+  it('Prevents access rights to be modified if constant (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testPreventAccessRightsModifiedIfConstant({type: 'ReFungible'});
   });
 
@@ -608,7 +638,9 @@
   it('Prevents adding properties with invalid names (NFT)', async () => {
     await testPreventsAddingPropertiesWithInvalidNames({type: 'NFT'});
   });
-  it('Prevents adding properties with invalid names (ReFungible)', async () => {
+  it('Prevents adding properties with invalid names (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testPreventsAddingPropertiesWithInvalidNames({type: 'ReFungible'});
   });
 });
@@ -651,7 +683,9 @@
   it('Reads yet empty properties of a token (NFT)', async () => {
     await testReadsYetEmptyProperties({type: 'NFT'});
   });
-  it('Reads yet empty properties of a token (ReFungible)', async () => {
+  it('Reads yet empty properties of a token (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testReadsYetEmptyProperties({type: 'ReFungible'});
   });
 
@@ -696,7 +730,9 @@
   it('Assigns properties to a token according to permissions (NFT)', async () => {
     await testAssignPropertiesAccordingToPermissions({type: 'NFT'}, 1);
   });
-  it('Assigns properties to a token according to permissions (ReFungible)', async () => {
+  it('Assigns properties to a token according to permissions (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testAssignPropertiesAccordingToPermissions({type: 'ReFungible'}, 100);
   });
 
@@ -749,7 +785,9 @@
   it('Changes properties of a token according to permissions (NFT)', async () => {
     await testChangesPropertiesAccordingPermission({type: 'NFT'}, 1);
   });
-  it('Changes properties of a token according to permissions (ReFungible)', async () => {
+  it('Changes properties of a token according to permissions (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testChangesPropertiesAccordingPermission({type: 'ReFungible'}, 100);
   });
 
@@ -802,7 +840,9 @@
   it('Deletes properties of a token according to permissions (NFT)', async () => {
     await testDeletePropertiesAccordingPermission({type: 'NFT'}, 1);
   });
-  it('Deletes properties of a token according to permissions (ReFungible)', async () => {
+  it('Deletes properties of a token according to permissions (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testDeletePropertiesAccordingPermission({type: 'ReFungible'}, 100);
   });
 
@@ -1029,7 +1069,9 @@
   it('Forbids changing/deleting properties of a token if the user is outside of permissions (NFT)', async () => {
     await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions({type: 'NFT'}, 1);
   });
-  it('Forbids changing/deleting properties of a token if the user is outside of permissions (ReFungible)', async () => {
+  it('Forbids changing/deleting properties of a token if the user is outside of permissions (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testForbidsChangingDeletingPropertiesUserOutsideOfPermissions({type: 'ReFungible'}, 100);
   });
 
@@ -1062,7 +1104,9 @@
   it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (NFT)', async () => {
     await testForbidsChangingDeletingPropertiesIfPropertyImmutable({type: 'NFT'}, 1);
   });
-  it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (ReFungible)', async () => {
+  it('Forbids changing/deleting properties of a token if the property is permanent (immutable) (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testForbidsChangingDeletingPropertiesIfPropertyImmutable({type: 'ReFungible'}, 100);
   });
 
@@ -1096,7 +1140,9 @@
   it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (NFT)', async () => {
     await testForbidsAddingPropertiesIfPropertyNotDeclared({type: 'NFT'}, 1);
   });
-  it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (ReFungible)', async () => {
+  it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testForbidsAddingPropertiesIfPropertyNotDeclared({type: 'ReFungible'}, 100);
   });
 
@@ -1140,7 +1186,9 @@
   it('Forbids adding too many properties to a token (NFT)', async () => {
     await testForbidsAddingTooManyProperties({type: 'NFT'}, 1);
   });
-  it('Forbids adding too many properties to a token (ReFungible)', async () => {
+  it('Forbids adding too many properties to a token (ReFungible)', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await testForbidsAddingTooManyProperties({type: 'ReFungible'}, 100);
   });
 });
@@ -1149,7 +1197,9 @@
   let collection: number;
   let token: number;
 
-  before(async () => {
+  before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api, privateKeyWrapper) => {
       alice = privateKeyWrapper('//Alice');
       bob = privateKeyWrapper('//Bob');
modifiedtests/src/nesting/rules-smoke.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/rules-smoke.test.ts
+++ b/tests/src/nesting/rules-smoke.test.ts
@@ -1,7 +1,7 @@
 import {expect} from 'chai';
 import {tokenIdToAddress} from '../eth/util/helpers';
 import usingApi, {executeTransaction} from '../substrate/substrate-api';
-import {createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, CrossAccountId, getCreateCollectionResult} from '../util/helpers';
+import {createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, CrossAccountId, getCreateCollectionResult, requirePallets, Pallets} from '../util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
 
 describe('nesting check', () => {
@@ -47,7 +47,9 @@
     });
   });
 
-  it('called for refungible', async () => {
+  it('called for refungible', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       await expect(executeTransaction(api, alice, api.tx.unique.createItem(collection, nestTarget, {ReFungible: {}})))
modifiedtests/src/nesting/unnest.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/unnest.test.ts
+++ b/tests/src/nesting/unnest.test.ts
@@ -10,6 +10,8 @@
   setCollectionPermissionsExpectSuccess,
   transferExpectSuccess,
   transferFromExpectSuccess,
+  requirePallets,
+  Pallets
 } from '../util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
 
@@ -80,7 +82,9 @@
     });
   });
 
-  it('ReFungible: allows the owner to successfully unnest a token', async () => {
+  it('ReFungible: allows the owner to successfully unnest a token', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async api => {
       const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
       await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: {tokenOwner: true}});
modifiedtests/src/nextSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/nextSponsoring.test.ts
+++ b/tests/src/nextSponsoring.test.ts
@@ -27,6 +27,8 @@
   transferExpectSuccess,
   normalizeAccountId,
   getNextSponsored,
+  requirePallets,
+  Pallets
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -89,7 +91,9 @@
     });
   });
 
-  it('ReFungible', async () => {
+  it('ReFungible', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api: ApiPromise) => {
 
       const createMode = 'ReFungible';
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -49,8 +49,6 @@
   'inflation',
   'unique',
   'nonfungible',
-  'refungible',
-  'scheduler',
   'charging',
 ];
 
@@ -66,8 +64,16 @@
     await usingApi(async api => {
       const chain = await api.rpc.system.chain();
 
-      if (!chain.eq('UNIQUE')) {
-        requiredPallets.push(...['rmrkcore', 'rmrkequip']);
+      const refungible = 'refungible';
+      const scheduler = 'scheduler';
+      const rmrkPallets = ['rmrkcore', 'rmrkequip'];
+
+      if (chain.eq('OPAL by UNIQUE')) {
+        requiredPallets.push(refungible, scheduler, ...rmrkPallets);
+      } else if (chain.eq('QUARTZ by UNIQUE')) {
+        // Insert Quartz additional pallets here
+      } else if (chain.eq('UNIQUE')) {
+        // Insert Unique additional pallets here
       }
     });
   });
modifiedtests/src/refungible.test.tsdiffbeforeafterboth
--- a/tests/src/refungible.test.ts
+++ b/tests/src/refungible.test.ts
@@ -38,6 +38,7 @@
   getDestroyItemsResult,
   getModuleNames,
   Pallets,
+  requirePallets
 } from './util/helpers';
 
 import chai from 'chai';
@@ -52,6 +53,8 @@
 
 describe('integration test: Refungible functionality:', async () => {
   before(async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api, privateKeyWrapper) => {
       alice = privateKeyWrapper('//Alice');
       bob = privateKeyWrapper('//Bob');
modifiedtests/src/rmrk/acceptNft.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/acceptNft.test.ts
+++ b/tests/src/rmrk/acceptNft.test.ts
@@ -14,7 +14,7 @@
   let api: any;
   before(async function() {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
   
   
modifiedtests/src/rmrk/addResource.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/addResource.test.ts
+++ b/tests/src/rmrk/addResource.test.ts
@@ -27,7 +27,7 @@
   let api: any;
   before(async function() {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
   it('add resource', async () => {
modifiedtests/src/rmrk/addTheme.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/addTheme.test.ts
+++ b/tests/src/rmrk/addTheme.test.ts
@@ -9,7 +9,7 @@
   let api: any;
   before(async function() {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkEquip]);
+    await requirePallets(this, [Pallets.RmrkEquip]);
   });
 
   const alice = '//Alice';
modifiedtests/src/rmrk/burnNft.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/burnNft.test.ts
+++ b/tests/src/rmrk/burnNft.test.ts
@@ -17,7 +17,7 @@
   let api: any;
   before(async function() {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
 
modifiedtests/src/rmrk/changeCollectionIssuer.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/changeCollectionIssuer.test.ts
+++ b/tests/src/rmrk/changeCollectionIssuer.test.ts
@@ -13,7 +13,7 @@
   let api: any;
   before(async function() {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
 
modifiedtests/src/rmrk/createBase.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/createBase.test.ts
+++ b/tests/src/rmrk/createBase.test.ts
@@ -6,7 +6,7 @@
   let api: any;
   before(async function() {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore, Pallets.RmrkEquip]);
+    await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]);
   });
 
   const alice = '//Alice';
modifiedtests/src/rmrk/createCollection.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/createCollection.test.ts
+++ b/tests/src/rmrk/createCollection.test.ts
@@ -6,7 +6,7 @@
   let api: any;
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
 
modifiedtests/src/rmrk/deleteCollection.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/deleteCollection.test.ts
+++ b/tests/src/rmrk/deleteCollection.test.ts
@@ -7,7 +7,7 @@
   let api: any;
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
   const Alice = '//Alice';
modifiedtests/src/rmrk/equipNft.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/equipNft.test.ts
+++ b/tests/src/rmrk/equipNft.test.ts
@@ -126,7 +126,7 @@
   
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore, Pallets.RmrkEquip]);
+    await requirePallets(this, [Pallets.RmrkCore, Pallets.RmrkEquip]);
   });
 
   it('equip nft', async () => {
modifiedtests/src/rmrk/getOwnedNfts.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/getOwnedNfts.test.ts
+++ b/tests/src/rmrk/getOwnedNfts.test.ts
@@ -9,7 +9,7 @@
   
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
 
modifiedtests/src/rmrk/lockCollection.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/lockCollection.test.ts
+++ b/tests/src/rmrk/lockCollection.test.ts
@@ -11,7 +11,7 @@
   let api: any;
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
   it('lock collection', async () => {
modifiedtests/src/rmrk/mintNft.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/mintNft.test.ts
+++ b/tests/src/rmrk/mintNft.test.ts
@@ -10,7 +10,7 @@
  
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
 
modifiedtests/src/rmrk/rejectNft.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/rejectNft.test.ts
+++ b/tests/src/rmrk/rejectNft.test.ts
@@ -14,7 +14,7 @@
   let api: any;
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
 
modifiedtests/src/rmrk/removeResource.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/removeResource.test.ts
+++ b/tests/src/rmrk/removeResource.test.ts
@@ -20,7 +20,7 @@
   before(async function() {
     api = await getApiConnection();
     ss58Format = api.registry.getChainProperties()!.toJSON().ss58Format;
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
   const Alice = '//Alice';
modifiedtests/src/rmrk/rmrkIsolation.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/rmrkIsolation.test.ts
+++ b/tests/src/rmrk/rmrkIsolation.test.ts
@@ -64,7 +64,7 @@
   before(async function() {
     await usingApi(async (api, privateKeyWrapper) => {
       alice = privateKeyWrapper('//Alice');
-      requirePallets(this, api, [Pallets.RmrkCore]);
+      await requirePallets(this, [Pallets.RmrkCore]);
     });
   });
 
modifiedtests/src/rmrk/sendNft.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/sendNft.test.ts
+++ b/tests/src/rmrk/sendNft.test.ts
@@ -9,7 +9,7 @@
   let api: any;
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
   const maxNftId = 0xFFFFFFFF;
modifiedtests/src/rmrk/setCollectionProperty.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/setCollectionProperty.test.ts
+++ b/tests/src/rmrk/setCollectionProperty.test.ts
@@ -10,7 +10,7 @@
   let api: any;
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
   it('set collection property', async () => {
modifiedtests/src/rmrk/setEquippableList.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/setEquippableList.test.ts
+++ b/tests/src/rmrk/setEquippableList.test.ts
@@ -7,7 +7,7 @@
   let api: any;
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
   const alice = '//Alice';
modifiedtests/src/rmrk/setNftProperty.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/setNftProperty.test.ts
+++ b/tests/src/rmrk/setNftProperty.test.ts
@@ -8,7 +8,7 @@
   let api: any;
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
   const alice = '//Alice';
modifiedtests/src/rmrk/setResourcePriorities.test.tsdiffbeforeafterboth
--- a/tests/src/rmrk/setResourcePriorities.test.ts
+++ b/tests/src/rmrk/setResourcePriorities.test.ts
@@ -7,7 +7,7 @@
   let api: any;
   before(async function () {
     api = await getApiConnection();
-    requirePallets(this, api, [Pallets.RmrkCore]);
+    await requirePallets(this, [Pallets.RmrkCore]);
   });
 
   const alice = '//Alice';
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionSponsor.test.ts
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -23,6 +23,8 @@
   setCollectionSponsorExpectFailure,
   addCollectionAdminExpectSuccess,
   getCreatedCollectionCount,
+  requirePallets,
+  Pallets
 } from './util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
 
@@ -50,7 +52,9 @@
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
   });
-  it('Set ReFungible collection sponsor', async () => {
+  it('Set ReFungible collection sponsor', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     await setCollectionSponsorExpectSuccess(collectionId, bob.address);
   });
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -35,11 +35,14 @@
   getBalance as getTokenBalance,
   transferFromExpectSuccess,
   transferFromExpectFail,
+  requirePallets,
+  Pallets,
 } from './util/helpers';
 import {
   subToEth,
   itWeb3, 
 } from './eth/util/helpers';
+import { request } from 'https';
 
 let alice: IKeyringPair;
 let bob: IKeyringPair;
@@ -89,56 +92,61 @@
     });
   });
 
-  it('User can transfer owned token', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');
-      // fungible
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');
-      // reFungible
-      const reFungibleCollectionId = await
-      createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      await transferExpectSuccess(
-        reFungibleCollectionId,
-        newReFungibleTokenId,
-        alice,
-        bob,
-        100,
-        'ReFungible',
-      );
-    });
+  it('[nft] User can transfer owned token', async () => {
+    const nftCollectionId = await createCollectionExpectSuccess();
+    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+    await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');
+  });
+
+  it('[fungible] User can transfer owned token', async () => {
+    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
+    await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');
+  });
+
+  it('[refungible] User can transfer owned token', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
+    await transferExpectSuccess(
+      reFungibleCollectionId,
+      newReFungibleTokenId,
+      alice,
+      bob,
+      100,
+      'ReFungible',
+    );
+  });
+
+  it('[nft] Collection admin can transfer owned token', async () => {
+    const nftCollectionId = await createCollectionExpectSuccess();
+    await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
+    const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);
+    await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');
+  });
+
+  it('[fungible] Collection admin can transfer owned token', async () => {
+    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+    await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);
+    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);
+    await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');
   });
 
-  it('Collection admin can transfer owned token', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
-      const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);
-      await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');
-      // fungible
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);
-      await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');
-      // reFungible
-      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);
-      const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);
-      await transferExpectSuccess(
-        reFungibleCollectionId,
-        newReFungibleTokenId,
-        bob,
-        alice,
-        100,
-        'ReFungible',
-      );
-    });
+  it('[refungible] Collection admin can transfer owned token', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+    await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);
+    const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);
+    await transferExpectSuccess(
+      reFungibleCollectionId,
+      newReFungibleTokenId,
+      bob,
+      alice,
+      100,
+      'ReFungible',
+    );
   });
 });
 
@@ -150,33 +158,49 @@
       charlie = privateKeyWrapper('//Charlie');
     });
   });
-  it('Transfer with not existed collection_id', async () => {
+
+  it('[nft] Transfer with not existed collection_id', async () => {
     await usingApi(async (api) => {
-      // nft
       const nftCollectionCount = await getCreatedCollectionCount(api);
       await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);
-      // fungible
+    });
+  });
+
+  it('[fungible] Transfer with not existed collection_id', async () => {
+    await usingApi(async (api) => {
       const fungibleCollectionCount = await getCreatedCollectionCount(api);
       await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);
-      // reFungible
+    });
+  });
+
+  it('[refungible] Transfer with not existed collection_id', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    await usingApi(async (api) => {
       const reFungibleCollectionCount = await getCreatedCollectionCount(api);
       await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);
     });
   });
-  it('Transfer with deleted collection_id', async () => {
-    // nft
+
+  it('[nft] Transfer with deleted collection_id', async () => {
     const nftCollectionId = await createCollectionExpectSuccess();
     const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
     await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);
     await destroyCollectionExpectSuccess(nftCollectionId);
     await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
-    // fungible
+  });
+
+  it('[fungible] Transfer with deleted collection_id', async () => {
     const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
     await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
     await destroyCollectionExpectSuccess(fungibleCollectionId);
     await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
-    // reFungible
+  });
+
+  it('[refungible] Transfer with deleted collection_id', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const reFungibleCollectionId = await
     createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -190,16 +214,21 @@
       1,
     );
   });
-  it('Transfer with not existed item_id', async () => {
-    // nft
+
+  it('[nft] Transfer with not existed item_id', async () => {
     const nftCollectionId = await createCollectionExpectSuccess();
     await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);
-    // fungible
+  });
+
+  it('[fungible] Transfer with not existed item_id', async () => {
     const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);
-    // reFungible
-    const reFungibleCollectionId = await
-    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+  });
+
+  it('[refungible] Transfer with not existed item_id', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     await transferExpectFailure(
       reFungibleCollectionId,
       2,
@@ -208,18 +237,24 @@
       1,
     );
   });
-  it('Transfer with deleted item_id', async () => {
-    // nft
+
+  it('[nft] Transfer with deleted item_id', async () => {
     const nftCollectionId = await createCollectionExpectSuccess();
     const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
     await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
     await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
-    // fungible
+  });
+
+  it('[fungible] Transfer with deleted item_id', async () => {
     const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
     await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
     await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
-    // reFungible
+  });
+
+  it('[refungible] Transfer with deleted item_id', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     const reFungibleCollectionId = await
     createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -232,18 +267,23 @@
       1,
     );
   });
-  it('Transfer with recipient that is not owner', async () => {
-    // nft
+
+  it('[nft] Transfer with recipient that is not owner', async () => {
     const nftCollectionId = await createCollectionExpectSuccess();
     const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
     await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);
-    // fungible
+  });
+
+  it('[fungible] Transfer with recipient that is not owner', async () => {
     const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
     await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);
-    // reFungible
-    const reFungibleCollectionId = await
-    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+  });
+
+  it('[refungible] Transfer with recipient that is not owner', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
     await transferExpectFailure(
       reFungibleCollectionId,
@@ -276,7 +316,9 @@
     });
   });
 
-  it('RFT', async () => {
+  it('RFT', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async (api: ApiPromise) => {
       const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
--- a/tests/src/transferFrom.test.ts
+++ b/tests/src/transferFrom.test.ts
@@ -31,6 +31,8 @@
   burnItemExpectSuccess,
   setCollectionLimitsExpectSuccess,
   getCreatedCollectionCount,
+  requirePallets,
+  Pallets
 } from './util/helpers';
 
 chai.use(chaiAsPromised);
@@ -49,36 +51,36 @@
     });
   });
 
-  it('Execute the extrinsic and check nftItemList - owner of token', async () => {
-    await usingApi(async () => {
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
+  it('[nft] Execute the extrinsic and check nftItemList - owner of token', async () => {
+    const nftCollectionId = await createCollectionExpectSuccess();
+    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+    await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
 
-      await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');
+    await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');
+  });
 
-      // fungible
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
-      await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');
+  it('[fungible] Execute the extrinsic and check nftItemList - owner of token', async () => {
+    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
+    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
+    await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');
+  });
 
-      // reFungible
-      const reFungibleCollectionId = await
-      createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);
-      await transferFromExpectSuccess(
-        reFungibleCollectionId,
-        newReFungibleTokenId,
-        bob,
-        alice,
-        charlie,
-        100,
-        'ReFungible',
-      );
-    });
+  it('[refungible] Execute the extrinsic and check nftItemList - owner of token', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
+    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);
+    await transferFromExpectSuccess(
+      reFungibleCollectionId,
+      newReFungibleTokenId,
+      bob,
+      alice,
+      charlie,
+      100,
+      'ReFungible',
+    );
   });
 
   it('Should reduce allowance if value is big', async () => {
@@ -119,20 +121,28 @@
     });
   });
 
-  it('transferFrom for a collection that does not exist', async () => {
+  it('[nft] transferFrom for a collection that does not exist', async () => {
     await usingApi(async (api: ApiPromise) => {
-      // nft
       const nftCollectionCount = await getCreatedCollectionCount(api);
       await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
 
       await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);
+    });
+  });
 
-      // fungible
+  it('[fungible] transferFrom for a collection that does not exist', async () => {
+    await usingApi(async (api: ApiPromise) => {
       const fungibleCollectionCount = await getCreatedCollectionCount(api);
       await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
 
       await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);
-      // reFungible
+    });
+  });
+
+  it('[refungible] transferFrom for a collection that does not exist', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    await usingApi(async (api: ApiPromise) => {
       const reFungibleCollectionCount = await getCreatedCollectionCount(api);
       await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
 
@@ -158,67 +168,70 @@
     });
   }); */
 
-  it('transferFrom for not approved address', async () => {
-    await usingApi(async () => {
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+  it('[nft] transferFrom for not approved address', async () => {
+    const nftCollectionId = await createCollectionExpectSuccess();
+    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
 
-      await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
+    await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
+  });
 
-      // fungible
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
-      // reFungible
-      const reFungibleCollectionId = await
-      createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      await transferFromExpectFail(
-        reFungibleCollectionId,
-        newReFungibleTokenId,
-        bob,
-        alice,
-        charlie,
-        1,
-      );
-    });
+  it('[fungible] transferFrom for not approved address', async () => {
+    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
+    await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
+  });
+
+  it('[refungible] transferFrom for not approved address', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    const reFungibleCollectionId = await
+    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
+    await transferFromExpectFail(
+      reFungibleCollectionId,
+      newReFungibleTokenId,
+      bob,
+      alice,
+      charlie,
+      1,
+    );
+  });
+
+  it('[nft] transferFrom incorrect token count', async () => {
+    const nftCollectionId = await createCollectionExpectSuccess();
+    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+    await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
+
+    await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);
   });
 
-  it('transferFrom incorrect token count', async () => {
-    await usingApi(async () => {
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
+  it('[fungible] transferFrom incorrect token count', async () => {
+    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
+    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
+    await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);
+  });
 
-      await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);
+  it('[refungible] transferFrom incorrect token count', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
 
-      // fungible
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
-      await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);
-      // reFungible
-      const reFungibleCollectionId = await
-      createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
-      await transferFromExpectFail(
-        reFungibleCollectionId,
-        newReFungibleTokenId,
-        bob,
-        alice,
-        charlie,
-        2,
-      );
-    });
+    const reFungibleCollectionId = await
+    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
+    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
+    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
+    await transferFromExpectFail(
+      reFungibleCollectionId,
+      newReFungibleTokenId,
+      bob,
+      alice,
+      charlie,
+      2,
+    );
   });
 
-  it('execute transferFrom from account that is not owner of collection', async () => {
+  it('[nft] execute transferFrom from account that is not owner of collection', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
       const dave = privateKeyWrapper('//Dave');
-      // nft
       const nftCollectionId = await createCollectionExpectSuccess();
       const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
       try {
@@ -230,8 +243,13 @@
       }
 
       // await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);
+    });
+  });
 
-      // fungible
+  it('[fungible] execute transferFrom from account that is not owner of collection', async () => {
+    await usingApi(async (api, privateKeyWrapper) => {
+      const dave = privateKeyWrapper('//Dave');
+
       const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
       const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
       try {
@@ -241,7 +259,14 @@
         // tslint:disable-next-line:no-unused-expression
         expect(e).to.be.exist;
       }
-      // reFungible
+    });
+  });
+
+  it('[refungible] execute transferFrom from account that is not owner of collection', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
+    await usingApi(async (api, privateKeyWrapper) => {
+      const dave = privateKeyWrapper('//Dave');
       const reFungibleCollectionId = await
       createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
@@ -276,7 +301,9 @@
 
     });
   });
-  it('transferFrom burnt token before approve ReFungible', async () => {
+  it('transferFrom burnt token before approve ReFungible', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async () => {
       const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       await setCollectionLimitsExpectSuccess(alice, reFungibleCollectionId, {ownerCanTransfer: true});
@@ -308,7 +335,9 @@
 
     });
   });
-  it('transferFrom burnt token after approve ReFungible', async () => {
+  it('transferFrom burnt token after approve ReFungible', async function() {
+    await requirePallets(this, [Pallets.ReFungible]);
+
     await usingApi(async () => {
       const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');