git.delta.rocks / unique-network / refs/commits / 6069e8a874a9

difftreelog

tests: upgrade part of them in ascending naming order to use playgrounds

Fahrrader2022-09-09parent: #4f3f998.patch.diff
in: master

24 files changed

modifiedtests/src/addCollectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/addCollectionAdmin.test.ts
+++ b/tests/src/addCollectionAdmin.test.ts
@@ -17,119 +17,114 @@
 import {IKeyringPair} from '@polkadot/types/types';
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import {usingPlaygrounds} from './util/playgrounds';
+import {itSub, usingPlaygrounds} from './util/playgrounds';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
 
-let donor: IKeyringPair;
+describe('Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
+  let donor: IKeyringPair;
 
-before(async () => {
-  await usingPlaygrounds(async (_, privateKeyWrapper) => {
-    donor = privateKeyWrapper('//Alice');
+  before(async () => {
+    await usingPlaygrounds(async (_, privateKeyWrapper) => {
+      donor = privateKeyWrapper('//Alice');
+    });
   });
-});
 
-describe('Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
-  it('Add collection admin.', async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
-      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  itSub('Add collection admin.', async ({helper}) => {
+    const [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
+    const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      const collection = await helper.collection.getData(collectionId);
-      expect(collection!.normalizedOwner!).to.be.equal(alice.address);
+    const collection = await helper.collection.getData(collectionId);
+    expect(collection!.normalizedOwner!).to.be.equal(helper.address.normalizeSubstrate(alice.address));
 
-      await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});
+    await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});
 
-      const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
-    });
+    const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
   });
 });
 
 describe('Negative Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
-  it("Not owner can't add collection admin.", async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
-      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  let donor: IKeyringPair;
+
+  before(async () => {
+    await usingPlaygrounds(async (_, privateKeyWrapper) => {
+      donor = privateKeyWrapper('//Alice');
+    });
+  });
 
-      const collection = await helper.collection.getData(collectionId);
-      expect(collection?.normalizedOwner).to.be.equal(alice.address);
+  itSub("Not owner can't add collection admin.", async ({helper}) => {
+    const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
+    const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      const changeAdminTxBob = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: bob.address});
-      const changeAdminTxCharlie = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: charlie.address});
-      await expect(changeAdminTxCharlie()).to.be.rejected;
-      await expect(changeAdminTxBob()).to.be.rejected;
+    const collection = await helper.collection.getData(collectionId);
+    expect(collection?.normalizedOwner).to.be.equal(helper.address.normalizeSubstrate(alice.address));
+
+    const changeAdminTxBob = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: bob.address});
+    const changeAdminTxCharlie = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: charlie.address});
+    await expect(changeAdminTxCharlie()).to.be.rejectedWith(/common\.NoPermission/);
+    await expect(changeAdminTxBob()).to.be.rejectedWith(/common\.NoPermission/);
 
-      const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
-      expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: charlie.address});
-      expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: bob.address});
-    });
+    const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
+    expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: charlie.address});
+    expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: bob.address});
   });
 
-  it("Admin can't add collection admin.", async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
-      const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  itSub("Admin can't add collection admin.", async ({helper}) => {
+    const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
+    const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      await collection.addAdmin(alice, {Substrate: bob.address});
+    await collection.addAdmin(alice, {Substrate: bob.address});
 
-      const adminListAfterAddAdmin = await collection.getAdmins();
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
+    const adminListAfterAddAdmin = await collection.getAdmins();
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
 
-      const changeAdminTxCharlie = async () => collection.addAdmin(bob, {Substrate: charlie.address});
-      await expect(changeAdminTxCharlie()).to.be.rejected;
+    const changeAdminTxCharlie = async () => collection.addAdmin(bob, {Substrate: charlie.address});
+    await expect(changeAdminTxCharlie()).to.be.rejectedWith(/common\.NoPermission/);
 
-      const adminListAfterAddNewAdmin = await collection.getAdmins();
-      expect(adminListAfterAddNewAdmin).to.be.deep.contains({Substrate: bob.address});
-      expect(adminListAfterAddNewAdmin).to.be.not.deep.contains({Substrate: charlie.address});
-    });
+    const adminListAfterAddNewAdmin = await collection.getAdmins();
+    expect(adminListAfterAddNewAdmin).to.be.deep.contains({Substrate: bob.address});
+    expect(adminListAfterAddNewAdmin).to.be.not.deep.contains({Substrate: charlie.address});
   });
 
-  it("Can't add collection admin of not existing collection.", async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = (1 << 32) - 1;
+  itSub("Can't add collection admin of not existing collection.", async ({helper}) => {
+    const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
+    const collectionId = (1 << 32) - 1;
 
-      const addAdminTx = async () => helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
-      await expect(addAdminTx()).to.be.rejected;
+    const addAdminTx = async () => helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
+    await expect(addAdminTx()).to.be.rejectedWith(/common\.CollectionNotFound/);
 
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
-    });
+    // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
+    await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
   });
 
-  it("Can't add an admin to a destroyed collection.", async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
-      const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  itSub("Can't add an admin to a destroyed collection.", async ({helper}) => {
+    const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
+    const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      await collection.burn(alice);
-      const addAdminTx = async () => collection.addAdmin(alice, {Substrate: bob.address});
-      await expect(addAdminTx()).to.be.rejected;
+    await collection.burn(alice);
+    const addAdminTx = async () => collection.addAdmin(alice, {Substrate: bob.address});
+    await expect(addAdminTx()).to.be.rejectedWith(/common\.CollectionNotFound/);
 
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
-    });
+    // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
+    await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
   });
 
-  it('Add an admin to a collection that has reached the maximum number of admins limit', async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, ...accounts] = await helper.arrange.createAccounts([10n, 0n, 0n, 0n, 0n, 0n, 0n, 0n], donor);
-      const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  itSub('Add an admin to a collection that has reached the maximum number of admins limit', async ({helper}) => {
+    const [alice, ...accounts] = await helper.arrange.createAccounts([10n, 0n, 0n, 0n, 0n, 0n, 0n, 0n], donor);
+    const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      const chainAdminLimit = (helper.api!.consts.common.collectionAdminsLimit as any).toNumber();
-      expect(chainAdminLimit).to.be.equal(5);
+    const chainAdminLimit = (helper.api!.consts.common.collectionAdminsLimit as any).toNumber();
+    expect(chainAdminLimit).to.be.equal(5);
 
-      for (let i = 0; i < chainAdminLimit; i++) {
-        await collection.addAdmin(alice, {Substrate: accounts[i].address});
-        const adminListAfterAddAdmin = await collection.getAdmins();
-        expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: accounts[i].address});
-      }
+    for (let i = 0; i < chainAdminLimit; i++) {
+      await collection.addAdmin(alice, {Substrate: accounts[i].address});
+      const adminListAfterAddAdmin = await collection.getAdmins();
+      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: accounts[i].address});
+    }
 
-      const addExtraAdminTx = async () => collection.addAdmin(alice, {Substrate: accounts[chainAdminLimit].address});
-      await expect(addExtraAdminTx()).to.be.rejected;
-    });
+    const addExtraAdminTx = async () => collection.addAdmin(alice, {Substrate: accounts[chainAdminLimit].address});
+    await expect(addExtraAdminTx()).to.be.rejectedWith(/common\.CollectionAdminCountExceeded/);
   });
 });
modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nesting/nest.test.ts
+++ b/tests/src/eth/nesting/nest.test.ts
@@ -20,7 +20,7 @@
   let donor: IKeyringPair;
 
   before(async function() {
-    await usingEthPlaygrounds(async (helper, privateKey) => {
+    await usingEthPlaygrounds(async (_, privateKey) => {
       donor = privateKey('//Alice');
     });
   });
modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
--- a/tests/src/eth/payable.test.ts
+++ b/tests/src/eth/payable.test.ts
@@ -22,7 +22,7 @@
   let donor: IKeyringPair;
 
   before(async function() {
-    await usingEthPlaygrounds(async (helper, privateKey) => {
+    await usingEthPlaygrounds(async (_, privateKey) => {
       donor = privateKey('//Alice');
     });
   });
modifiedtests/src/fungible.test.tsdiffbeforeafterboth
--- a/tests/src/fungible.test.ts
+++ b/tests/src/fungible.test.ts
@@ -16,11 +16,10 @@
 
 import {IKeyringPair} from '@polkadot/types/types';
 import {U128_MAX} from './util/helpers';
-
-import {usingPlaygrounds} from './util/playgrounds';
-
+import {itSub, usingPlaygrounds} from './util/playgrounds';
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
+
 chai.use(chaiAsPromised);
 const expect = chai.expect;
 
@@ -35,131 +34,117 @@
     });
   });
 
-  it('Create fungible collection and token', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});
-      const defaultTokenId = await collection.getLastTokenId();
-      expect(defaultTokenId).to.be.equal(0);
+  itSub('Create fungible collection and token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});
+    const defaultTokenId = await collection.getLastTokenId();
+    expect(defaultTokenId).to.be.equal(0);
 
-      await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
-      const aliceBalance = await collection.getBalance({Substrate: alice.address});
-      const itemCountAfter = await collection.getLastTokenId();
+    await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
+    const aliceBalance = await collection.getBalance({Substrate: alice.address});
+    const itemCountAfter = await collection.getLastTokenId();
 
-      expect(itemCountAfter).to.be.equal(defaultTokenId);
-      expect(aliceBalance).to.be.equal(U128_MAX);
-    });
+    expect(itemCountAfter).to.be.equal(defaultTokenId);
+    expect(aliceBalance).to.be.equal(U128_MAX);
   });
   
-  it('RPC method tokenOnewrs for fungible collection and token', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
+  itSub('RPC method tokenOnewrs for fungible collection and token', async ({helper, privateKey}) => {
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
 
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
 
-      await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
+    await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
 
-      await collection.transfer(alice, {Substrate: bob.address}, 1000n);
-      await collection.transfer(alice, ethAcc, 900n);
-      
-      for (let i = 0; i < 7; i++) {
-        await collection.transfer(alice, facelessCrowd[i], 1n);
-      } 
+    await collection.transfer(alice, {Substrate: bob.address}, 1000n);
+    await collection.transfer(alice, ethAcc, 900n);
+    
+    for (let i = 0; i < 7; i++) {
+      await collection.transfer(alice, facelessCrowd[i], 1n);
+    } 
 
-      const owners = await collection.getTop10Owners();
+    const owners = await collection.getTop10Owners();
 
-      // What to expect
-      expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
-      expect(owners.length).to.be.equal(10);
-      
-      const eleven = privateKey('//ALice+11');
-      expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
-      expect((await collection.getTop10Owners()).length).to.be.equal(10);
-    });
+    // What to expect
+    expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
+    expect(owners.length).to.be.equal(10);
+    
+    const eleven = privateKey('//ALice+11');
+    expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
+    expect((await collection.getTop10Owners()).length).to.be.equal(10);
   });
   
-  it('Transfer token', async () => {
-    await usingPlaygrounds(async helper => {
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      await collection.mint(alice, {Substrate: alice.address}, 500n);
+  itSub('Transfer token', async ({helper}) => {
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    await collection.mint(alice, {Substrate: alice.address}, 500n);
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
-      expect(await collection.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
-      expect(await collection.transfer(alice, ethAcc, 140n)).to.be.true;
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
+    expect(await collection.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    expect(await collection.transfer(alice, ethAcc, 140n)).to.be.true;
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(300n);
-      expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(60n);
-      expect(await collection.getBalance(ethAcc)).to.be.equal(140n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(300n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(60n);
+    expect(await collection.getBalance(ethAcc)).to.be.equal(140n);
 
-      await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;
-    });
+    await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;
   });
 
-  it('Tokens multiple creation', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  itSub('Tokens multiple creation', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
 
-      await collection.mintWithOneOwner(alice, {Substrate: alice.address}, [
-        {value: 500n},
-        {value: 400n},
-        {value: 300n},
-      ]);
+    await collection.mintWithOneOwner(alice, {Substrate: alice.address}, [
+      {value: 500n},
+      {value: 400n},
+      {value: 300n},
+    ]);
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);
-    });
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);
   });
 
-  it('Burn some tokens ', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      await collection.mint(alice, {Substrate: alice.address}, 500n);
+  itSub('Burn some tokens ', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    await collection.mint(alice, {Substrate: alice.address}, 500n);
 
-      expect(await collection.isTokenExists(0)).to.be.true;
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
-      expect(await collection.burnTokens(alice, 499n)).to.be.true;
-      expect(await collection.isTokenExists(0)).to.be.true;
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
-    });
+    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
+    expect(await collection.burnTokens(alice, 499n)).to.be.true;
+    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
   
-  it('Burn all tokens ', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      await collection.mint(alice, {Substrate: alice.address}, 500n);
+  itSub('Burn all tokens ', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    await collection.mint(alice, {Substrate: alice.address}, 500n);
 
-      expect(await collection.isTokenExists(0)).to.be.true;
-      expect(await collection.burnTokens(alice, 500n)).to.be.true;
-      expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.burnTokens(alice, 500n)).to.be.true;
+    expect(await collection.isTokenExists(0)).to.be.true;
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);
-      expect(await collection.getTotalPieces()).to.be.equal(0n);
-    });
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);
+    expect(await collection.getTotalPieces()).to.be.equal(0n);
   });
 
-  it('Set allowance for token', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      await collection.mint(alice, {Substrate: alice.address}, 100n);
+  itSub('Set allowance for token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    await collection.mint(alice, {Substrate: alice.address}, 100n);
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(100n);
-      
-      expect(await collection.approveTokens(alice, {Substrate: bob.address}, 60n)).to.be.true;
-      expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
-      expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(100n);
+    
+    expect(await collection.approveTokens(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
 
-      expect(await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(80n);
-      expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(20n);
-      expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
+    expect(await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(80n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(20n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
 
-      await collection.burnTokensFrom(bob, {Substrate: alice.address}, 10n);
+    await collection.burnTokensFrom(bob, {Substrate: alice.address}, 10n);
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(70n);
-      expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);
-      expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;
-      expect(await collection.getBalance(ethAcc)).to.be.equal(10n);
-    });
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(70n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);
+    expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;
+    expect(await collection.getBalance(ethAcc)).to.be.equal(10n);
   });
 });
modifiedtests/src/overflow.test.tsdiffbeforeafterboth
--- a/tests/src/overflow.test.ts
+++ b/tests/src/overflow.test.ts
@@ -23,6 +23,7 @@
 chai.use(chaiAsPromised);
 const expect = chai.expect;
 
+// todo:playgrounds skipped ~ postponed
 describe.skip('Integration Test fungible overflows', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -14,13 +14,8 @@
 // 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 {ApiPromise} from '@polkadot/api';
 import {expect} from 'chai';
-import usingApi from './substrate/substrate-api';
-
-function getModuleNames(api: ApiPromise): string[] {
-  return api.runtimeMetadata.asLatest.pallets.map(m => m.name.toString().toLowerCase());
-}
+import {itSub, usingPlaygrounds} from './util/playgrounds';
 
 // Pallets that must always be present
 const requiredPallets = [
@@ -62,8 +57,8 @@
 
 describe('Pallet presence', () => {
   before(async () => {
-    await usingApi(async api => {
-      const chain = await api.rpc.system.chain();
+    await usingPlaygrounds(async helper => {
+      const chain = await helper.api!.rpc.system.chain();
 
       const refungible = 'refungible';
       const scheduler = 'scheduler';
@@ -80,23 +75,15 @@
     });
   });
 
-  it('Required pallets are present', async () => {
-    await usingApi(async api => {
-      for (let i=0; i<requiredPallets.length; i++) {
-        expect(getModuleNames(api)).to.include(requiredPallets[i]);
-      }
-    });
+  itSub('Required pallets are present', async ({helper}) => {
+    expect(helper.fetchAllPalletNames()).to.contain.members([...requiredPallets]);
   });
-  it('Governance and consensus pallets are present', async () => {
-    await usingApi(async api => {
-      for (let i=0; i<consensusPallets.length; i++) {
-        expect(getModuleNames(api)).to.include(consensusPallets[i]);
-      }
-    });
+
+  itSub('Governance and consensus pallets are present', async ({helper}) => {
+    expect(helper.fetchAllPalletNames()).to.contain.members([...consensusPallets]);
   });
-  it('No extra pallets are included', async () => {
-    await usingApi(async api => {
-      expect(getModuleNames(api).sort()).to.be.deep.equal([...requiredPallets, ...consensusPallets].sort());
-    });
+
+  itSub('No extra pallets are included', async ({helper}) => {
+    expect(helper.fetchAllPalletNames().sort()).to.be.deep.equal([...requiredPallets, ...consensusPallets].sort());
   });
 });
modifiedtests/src/refungible.test.tsdiffbeforeafterboth
--- a/tests/src/refungible.test.ts
+++ b/tests/src/refungible.test.ts
@@ -15,13 +15,7 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {IKeyringPair} from '@polkadot/types/types';
-
-import {usingPlaygrounds} from './util/playgrounds';
-import {
-  getModuleNames,
-  Pallets,
-  requirePallets,
-} from './util/helpers';
+import {itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from './util/playgrounds';
 
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
@@ -34,255 +28,231 @@
 
 describe('integration test: Refungible functionality:', async () => {
   before(async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+    await usingPlaygrounds(async (helper, privateKey) => {
+      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
 
-    await usingPlaygrounds(async (helper, privateKey) => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
-      if (!getModuleNames(helper.api!).includes(Pallets.ReFungible)) this.skip();
     });
   });
   
-  it('Create refungible collection and token', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  itSub('Create refungible collection and token', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
 
-      const itemCountBefore = await collection.getLastTokenId();
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      
-      const itemCountAfter = await collection.getLastTokenId();
-      
-      // What to expect
-      expect(token?.tokenId).to.be.gte(itemCountBefore);
-      expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
-      expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());
-    });
+    const itemCountBefore = await collection.getLastTokenId();
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+    
+    const itemCountAfter = await collection.getLastTokenId();
+    
+    // What to expect
+    expect(token?.tokenId).to.be.gte(itemCountBefore);
+    expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
+    expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());
   });
   
-  it('Checking RPC methods when interacting with maximum allowed values (MAX_REFUNGIBLE_PIECES)', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES);
-      
-      expect(await collection.getTokenBalance(token.tokenId, {Substrate: alice.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
-      
-      await collection.transferToken(alice, token.tokenId, {Substrate: bob.address}, MAX_REFUNGIBLE_PIECES);
-      expect(await collection.getTokenBalance(token.tokenId, {Substrate: bob.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
-      expect(await token.getTotalPieces()).to.be.equal(MAX_REFUNGIBLE_PIECES);
-      
-      await expect(collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES + 1n)).to.eventually.be.rejected;
-    });
+  itSub('Checking RPC methods when interacting with maximum allowed values (MAX_REFUNGIBLE_PIECES)', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES);
+    
+    expect(await collection.getTokenBalance(token.tokenId, {Substrate: alice.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
+    
+    await collection.transferToken(alice, token.tokenId, {Substrate: bob.address}, MAX_REFUNGIBLE_PIECES);
+    expect(await collection.getTokenBalance(token.tokenId, {Substrate: bob.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
+    expect(await token.getTotalPieces()).to.be.equal(MAX_REFUNGIBLE_PIECES);
+    
+    await expect(collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES + 1n))
+      .to.eventually.be.rejectedWith(/refungible\.WrongRefungiblePieces/);
   });
   
-  it('RPC method tokenOnewrs for refungible collection and token', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
+  itSub('RPC method tokenOnewrs for refungible collection and token', async ({helper, privateKey}) => {
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
 
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
 
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 10_000n);
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 10_000n);
 
-      await token.transfer(alice, {Substrate: bob.address}, 1000n);
-      await token.transfer(alice, ethAcc, 900n);
-      
-      for (let i = 0; i < 7; i++) {
-        await token.transfer(alice, facelessCrowd[i], 50n * BigInt(i + 1));
-      } 
+    await token.transfer(alice, {Substrate: bob.address}, 1000n);
+    await token.transfer(alice, ethAcc, 900n);
+    
+    for (let i = 0; i < 7; i++) {
+      await token.transfer(alice, facelessCrowd[i], 50n * BigInt(i + 1));
+    } 
 
-      const owners = await token.getTop10Owners();
+    const owners = await token.getTop10Owners();
 
-      // What to expect
-      expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
-      expect(owners.length).to.be.equal(10);
-      
-      const eleven = privateKey('//ALice+11');
-      expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
-      expect((await token.getTop10Owners()).length).to.be.equal(10);
-    });
+    // What to expect
+    expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
+    expect(owners.length).to.be.equal(10);
+    
+    const eleven = privateKey('//ALice+11');
+    expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
+    expect((await token.getTop10Owners()).length).to.be.equal(10);
   });
   
-  it('Transfer token pieces', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+  itSub('Transfer token pieces', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
 
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
-      expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
-      
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
-      
-      await expect(token.transfer(alice, {Substrate: bob.address}, 41n)).to.eventually.be.rejected;
-    });
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+    expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
+    
+    await expect(token.transfer(alice, {Substrate: bob.address}, 41n))
+      .to.eventually.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('Create multiple tokens', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      // TODO: fix mintMultipleTokens
-      // await collection.mintMultipleTokens(alice, [
-      //   {owner: {Substrate: alice.address}, pieces: 1n},
-      //   {owner: {Substrate: alice.address}, pieces: 2n},
-      //   {owner: {Substrate: alice.address}, pieces: 100n},
-      // ]);
-      await helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, [
-        {pieces: 1n}, 
-        {pieces: 2n}, 
-        {pieces: 100n},
-      ]);
-      const lastTokenId = await collection.getLastTokenId();
-      expect(lastTokenId).to.be.equal(3);
-      expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);
-    });
+  itSub('Create multiple tokens', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    // TODO: fix mintMultipleTokens
+    // await collection.mintMultipleTokens(alice, [
+    //   {owner: {Substrate: alice.address}, pieces: 1n},
+    //   {owner: {Substrate: alice.address}, pieces: 2n},
+    //   {owner: {Substrate: alice.address}, pieces: 100n},
+    // ]);
+    await helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, [
+      {pieces: 1n}, 
+      {pieces: 2n}, 
+      {pieces: 100n},
+    ]);
+    const lastTokenId = await collection.getLastTokenId();
+    expect(lastTokenId).to.be.equal(3);
+    expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);
   });
 
-  it('Burn some pieces', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
-      expect((await token.burn(alice, 99n)).success).to.be.true;
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);
-    });
+  itSub('Burn some pieces', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+    expect((await token.burn(alice, 99n)).success).to.be.true;
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 
-  it('Burn all pieces', async () => {
-    await usingPlaygrounds(async helper => {   
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+  itSub('Burn all pieces', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+    
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
 
-      expect((await token.burn(alice, 100n)).success).to.be.true;
-      expect(await collection.isTokenExists(token.tokenId)).to.be.false;
-    });
+    expect((await token.burn(alice, 100n)).success).to.be.true;
+    expect(await collection.isTokenExists(token.tokenId)).to.be.false;
   });
 
-  it('Burn some pieces for multiple users', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+  itSub('Burn some pieces for multiple users', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
 
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
-      expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+    expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
 
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
 
-      expect((await token.burn(alice, 40n)).success).to.be.true;
+    expect((await token.burn(alice, 40n)).success).to.be.true;
 
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
 
-      expect((await token.burn(bob, 59n)).success).to.be.true;
+    expect((await token.burn(bob, 59n)).success).to.be.true;
 
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(1n);
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(1n);
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
 
-      expect((await token.burn(bob, 1n)).success).to.be.true;
+    expect((await token.burn(bob, 1n)).success).to.be.true;
 
-      expect(await collection.isTokenExists(token.tokenId)).to.be.false;
-    });
+    expect(await collection.isTokenExists(token.tokenId)).to.be.false;
   });
 
-  it('Set allowance for token', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+  itSub('Set allowance for token', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+    
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
 
-      expect(await token.approve(alice, {Substrate: bob.address}, 60n)).to.be.true;
-      expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
+    expect(await token.approve(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
 
-      expect(await token.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);
-      expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
-    });
+    expect(await token.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);
+    expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
   });
 
-  it('Repartition', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+  itSub('Repartition', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
 
-      expect(await token.repartition(alice, 200n)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(200n);
-      expect(await token.getTotalPieces()).to.be.equal(200n);
-      
-      expect(await token.transfer(alice, {Substrate: bob.address}, 110n)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);
-      
-      await expect(token.repartition(alice, 80n)).to.eventually.be.rejected;
-      
-      expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);
-
-      expect(await token.repartition(bob, 150n)).to.be.true;
-      await expect(token.transfer(bob, {Substrate: alice.address}, 160n)).to.eventually.be.rejected;
+    expect(await token.repartition(alice, 200n)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(200n);
+    expect(await token.getTotalPieces()).to.be.equal(200n);
+    
+    expect(await token.transfer(alice, {Substrate: bob.address}, 110n)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);
+    
+    await expect(token.repartition(alice, 80n))
+      .to.eventually.be.rejectedWith(/refungible\.RepartitionWhileNotOwningAllPieces/);
+    
+    expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);
 
-    });
+    expect(await token.repartition(bob, 150n)).to.be.true;
+    await expect(token.transfer(bob, {Substrate: alice.address}, 160n))
+      .to.eventually.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('Repartition with increased amount', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      await token.repartition(alice, 200n);
-      const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
-      expect(chainEvents).to.include.deep.members([{
-        method: 'ItemCreated',
-        section: 'common',
-        index: '0x4202',
-        data: [ 
-          helper.api!.createType('u32', collection.collectionId).toHuman(), 
-          helper.api!.createType('u32', token.tokenId).toHuman(),
-          {Substrate: alice.address}, 
-          '100',
-        ],
-      }]);
-    });
+  itSub('Repartition with increased amount', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+    await token.repartition(alice, 200n);
+    const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
+    expect(chainEvents).to.include.deep.members([{
+      method: 'ItemCreated',
+      section: 'common',
+      index: '0x4202',
+      data: [ 
+        helper.api!.createType('u32', collection.collectionId).toHuman(), 
+        helper.api!.createType('u32', token.tokenId).toHuman(),
+        {Substrate: alice.address}, 
+        '100',
+      ],
+    }]);
   });
 
-  it('Repartition with decreased amount', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      await token.repartition(alice, 50n);
-      const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
-      expect(chainEvents).to.include.deep.members([{
-        method: 'ItemDestroyed',
-        section: 'common',
-        index: '0x4203',
-        data: [ 
-          helper.api!.createType('u32', collection.collectionId).toHuman(), 
-          helper.api!.createType('u32', token.tokenId).toHuman(),
-          {Substrate: alice.address}, 
-          '50',
-        ],
-      }]);
-    });
+  itSub('Repartition with decreased amount', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+    await token.repartition(alice, 50n);
+    const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
+    expect(chainEvents).to.include.deep.members([{
+      method: 'ItemDestroyed',
+      section: 'common',
+      index: '0x4203',
+      data: [ 
+        helper.api!.createType('u32', collection.collectionId).toHuman(), 
+        helper.api!.createType('u32', token.tokenId).toHuman(),
+        {Substrate: alice.address}, 
+        '50',
+      ],
+    }]);
   });
   
-  it('Create new collection with properties', async () => {
-    await usingPlaygrounds(async helper => {
-      const properties = [{key: 'key1', value: 'val1'}];
-      const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});
-      const info = await collection.getData();
-      expect(info?.raw.properties).to.be.deep.equal(properties);
-      expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);
-    });
+  itSub('Create new collection with properties', async ({helper}) => {
+    const properties = [{key: 'key1', value: 'val1'}];
+    const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});
+    const info = await collection.getData();
+    expect(info?.raw.properties).to.be.deep.equal(properties);
+    expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);
   });
 });
 
modifiedtests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/removeCollectionAdmin.test.ts
+++ b/tests/src/removeCollectionAdmin.test.ts
@@ -16,113 +16,102 @@
 
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import {usingPlaygrounds} from './util/playgrounds';
+import {IKeyringPair} from '@polkadot/types/types';
+import {itSub, usingPlaygrounds} from './util/playgrounds';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
 
 describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
-  it('Remove collection admin.', async () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
+  before(async () => {
     await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      
-      const collectionInfo = await collection.getData();
-      expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);
-      // first - add collection admin Bob
-      await collection.addAdmin(alice, {Substrate: bob.address});
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
+    });
+  });
 
-      const adminListAfterAddAdmin = await collection.getAdmins();
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
+  itSub('Remove collection admin', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-1', tokenPrefix: 'RCA'});
+    const collectionInfo = await collection.getData();
+    expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);
+    // first - add collection admin Bob
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    const adminListAfterAddAdmin = await collection.getAdmins();
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
 
-      // then remove bob from admins of collection
-      await collection.removeAdmin(alice, {Substrate: bob.address});
+    // then remove bob from admins of collection
+    await collection.removeAdmin(alice, {Substrate: bob.address});
 
-      const adminListAfterRemoveAdmin = await collection.getAdmins();
-      expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
-    });
+    const adminListAfterRemoveAdmin = await collection.getAdmins();
+    expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: bob.address});
   });
 
-  it('Remove admin from collection that has no admins', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  itSub('Remove admin from collection that has no admins', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-2', tokenPrefix: 'RCA'});
 
-      const adminListBeforeAddAdmin = await collection.getAdmins();
-      expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
+    const adminListBeforeAddAdmin = await collection.getAdmins();
+    expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
 
-      // await expect(collection.removeAdmin(alice, {Substrate: alice.address})).to.be.rejectedWith('Unable to remove collection admin');
-      await collection.removeAdmin(alice, {Substrate: alice.address});
-    });
+    await collection.removeAdmin(alice, {Substrate: alice.address});
   });
 });
 
 describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
-  it('Can\'t remove collection admin from not existing collection', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = (1 << 32) - 1;
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-
-      await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address})).to.be.rejected;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  let charlie: IKeyringPair;
 
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  before(async () => {
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
     });
   });
 
-  it('Can\'t remove collection admin from deleted collection', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  itSub('Can\'t remove collection admin from not existing collection', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
 
-      expect(await collection.burn(alice)).to.be.true;
+    await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
+  });
 
-      await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address})).to.be.rejected;
+  itSub('Can\'t remove collection admin from deleted collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-2', tokenPrefix: 'RCA'});
 
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-    });
-  });
+    expect(await collection.burn(alice)).to.be.true;
 
-  it('Regular user can\'t remove collection admin', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const charlie = privateKey('//Charlie');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
+  });
 
-      await collection.addAdmin(alice, {Substrate: bob.address});
+  itSub('Regular user can\'t remove collection admin', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-3', tokenPrefix: 'RCA'});
 
-      await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;
+    await collection.addAdmin(alice, {Substrate: bob.address});
 
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-    });
+    await expect(collection.removeAdmin(charlie, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('Admin can\'t remove collection admin.', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const charlie = privateKey('//Charlie');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      
-      await collection.addAdmin(alice, {Substrate: bob.address});
-      await collection.addAdmin(alice, {Substrate: charlie.address});
+  itSub('Admin can\'t remove collection admin.', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-4', tokenPrefix: 'RCA'});
+    
+    await collection.addAdmin(alice, {Substrate: bob.address});
+    await collection.addAdmin(alice, {Substrate: charlie.address});
 
-      const adminListAfterAddAdmin = await collection.getAdmins();
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});
+    const adminListAfterAddAdmin = await collection.getAdmins();
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: charlie.address});
 
-      await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;
+    await expect(collection.removeAdmin(charlie, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.NoPermission/);
 
-      const adminListAfterRemoveAdmin = await collection.getAdmins();
-      expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
-      expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});
-    });
+    const adminListAfterRemoveAdmin = await collection.getAdmins();
+    expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: bob.address});
+    expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: charlie.address});
   });
 });
modifiedtests/src/removeCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/removeCollectionSponsor.test.ts
+++ b/tests/src/removeCollectionSponsor.test.ts
@@ -16,136 +16,115 @@
 
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi, submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess,
-  setCollectionSponsorExpectSuccess,
-  destroyCollectionExpectSuccess,
-  confirmSponsorshipExpectSuccess,
-  confirmSponsorshipExpectFailure,
-  createItemExpectSuccess,
-  findUnusedAddress,
-  removeCollectionSponsorExpectSuccess,
-  removeCollectionSponsorExpectFailure,
-  normalizeAccountId,
-  addCollectionAdminExpectSuccess,
-  getCreatedCollectionCount,
-} from './util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
+import {itSub, usingPlaygrounds} from './util/playgrounds';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
 
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-
 describe('integration test: ext. removeCollectionSponsor():', () => {
+  let donor: IKeyringPair;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
     });
   });
 
-  it('Removing NFT collection sponsor stops sponsorship', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
-    await removeCollectionSponsorExpectSuccess(collectionId);
+  itSub('Removing NFT collection sponsor stops sponsorship', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-1', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.confirmSponsorship(bob);
+    await collection.removeSponsor(alice);
 
-    await usingApi(async (api, privateKeyWrapper) => {
-      // Find unused address
-      const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
+    // Find unused address
+    const [zeroBalance] = await helper.arrange.createAccounts([0n], donor);
 
-      // Mint token for unused address
-      const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);
+    // Mint token for unused address
+    const token = await collection.mintToken(alice, {Substrate: zeroBalance.address});
 
-      // Transfer this tokens from unused address to Alice - should fail
-      const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
-      const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);
-      const badTransaction = async function () {
-        await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);
-      };
-      await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');
-      const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
+    // Transfer this tokens from unused address to Alice - should fail
+    const sponsorBalanceBefore = await helper.balance.getSubstrate(bob.address);
+    await expect(token.transfer(zeroBalance, {Substrate: alice.address}))
+      .to.be.rejectedWith('Inability to pay some fees');
+    const sponsorBalanceAfter = await helper.balance.getSubstrate(bob.address);
 
-      expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
-    });
+    expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
   });
 
-  it('Remove a sponsor after it was already removed', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
-    await removeCollectionSponsorExpectSuccess(collectionId);
-    await removeCollectionSponsorExpectSuccess(collectionId);
+  itSub('Remove a sponsor after it was already removed', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-2', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.confirmSponsorship(bob);
+    await expect(collection.removeSponsor(alice)).to.not.be.rejected;
+    await expect(collection.removeSponsor(alice)).to.not.be.rejected;
   });
 
-  it('Remove sponsor in a collection that never had the sponsor set', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await removeCollectionSponsorExpectSuccess(collectionId);
+  itSub('Remove sponsor in a collection that never had the sponsor set', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-3', tokenPrefix: 'RCS'});
+    await expect(collection.removeSponsor(alice)).to.not.be.rejected;
   });
 
-  it('Remove sponsor for a collection that had the sponsor set, but not confirmed', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await removeCollectionSponsorExpectSuccess(collectionId);
+  itSub('Remove sponsor for a collection that had the sponsor set, but not confirmed', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-4', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await expect(collection.removeSponsor(alice)).to.not.be.rejected;
   });
 
 });
 
 describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  let charlie: IKeyringPair;
+
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
     });
   });
 
-  it('(!negative test!) Remove sponsor for a collection that never existed', async () => {
-    // Find the collection that never existed
-    let collectionId = 0;
-    await usingApi(async (api) => {
-      collectionId = await getCreatedCollectionCount(api) + 1;
-    });
-
-    await removeCollectionSponsorExpectFailure(collectionId);
+  itSub('(!negative test!) Remove sponsor for a collection that never existed', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.removeSponsor(alice, collectionId)).to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('(!negative test!) Remove sponsor for a collection with collection admin permissions', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-    await removeCollectionSponsorExpectFailure(collectionId, '//Bob');
+  itSub('(!negative test!) Remove sponsor for a collection with collection admin permissions', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-1', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.addAdmin(alice, {Substrate: charlie.address});
+    await expect(collection.removeSponsor(charlie)).to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('(!negative test!) Remove sponsor for a collection by regular user', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await removeCollectionSponsorExpectFailure(collectionId, '//Bob');
+  itSub('(!negative test!) Remove sponsor for a collection by regular user', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-2', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await expect(collection.removeSponsor(charlie)).to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('(!negative test!) Remove sponsor in a destroyed collection', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await destroyCollectionExpectSuccess(collectionId);
-    await removeCollectionSponsorExpectFailure(collectionId);
+  itSub('(!negative test!) Remove sponsor in a destroyed collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-3', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.burn(alice);
+    await expect(collection.removeSponsor(alice)).to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('Set - remove - confirm: fails', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await removeCollectionSponsorExpectSuccess(collectionId);
-    await confirmSponsorshipExpectFailure(collectionId, '//Bob');
+  itSub('Set - remove - confirm: fails', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-4', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.removeSponsor(alice);
+    await expect(collection.confirmSponsorship(bob)).to.be.rejectedWith(/unique\.ConfirmUnsetSponsorFail/);
   });
 
-  it('Set - confirm - remove - confirm: Sponsor cannot come back', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
-    await removeCollectionSponsorExpectSuccess(collectionId);
-    await confirmSponsorshipExpectFailure(collectionId, '//Bob');
+  itSub('Set - confirm - remove - confirm: Sponsor cannot come back', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-5', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.confirmSponsorship(bob);
+    await collection.removeSponsor(alice);
+    await expect(collection.confirmSponsorship(bob)).to.be.rejectedWith(/unique\.ConfirmUnsetSponsorFail/);
   });
-
 });
modifiedtests/src/removeFromAllowList.test.tsdiffbeforeafterboth
--- a/tests/src/removeFromAllowList.test.ts
+++ b/tests/src/removeFromAllowList.test.ts
@@ -16,21 +16,8 @@
 
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi} from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess,
-  destroyCollectionExpectSuccess,
-  enableAllowListExpectSuccess,
-  addToAllowListExpectSuccess,
-  removeFromAllowListExpectSuccess,
-  isAllowlisted,
-  findNotExistingCollection,
-  removeFromAllowListExpectFailure,
-  disableAllowListExpectSuccess,
-  normalizeAccountId,
-  addCollectionAdminExpectSuccess,
-} from './util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
+import {itSub, usingPlaygrounds} from './util/playgrounds';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
@@ -40,32 +27,37 @@
   let bob: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
     });
   });
 
-  it('ensure bob is not in allowlist after removal', async () => {
-    await usingApi(async api => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await addToAllowListExpectSuccess(alice, collectionId, bob.address);
+  itSub('ensure bob is not in allowlist after removal', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-1', tokenPrefix: 'RFAL'});
 
-      await removeFromAllowListExpectSuccess(alice, collectionId, normalizeAccountId(bob.address));
-      expect(await isAllowlisted(api, collectionId, bob.address)).to.be.false;
-    });
+    const collectionInfo = await collection.getData();
+    expect(collectionInfo!.raw.permissions.access).to.not.equal('AllowList');
+
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addToAllowList(alice, {Substrate: bob.address});
+    expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address});
+    
+    await collection.removeFromAllowList(alice, {Substrate: bob.address});
+    expect(await collection.getAllowList()).to.be.empty;
   });
 
-  it('allows removal from collection with unset allowlist status', async () => {
-    await usingApi(async () => {
-      const collectionWithoutAllowlistId = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);
-      await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, bob.address);
-      await disableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);
+  itSub('allows removal from collection with unset allowlist status', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-2', tokenPrefix: 'RFAL'});
 
-      await removeFromAllowListExpectSuccess(alice, collectionWithoutAllowlistId, normalizeAccountId(bob.address));
-    });
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addToAllowList(alice, {Substrate: bob.address});
+    expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address});
+
+    await collection.setPermissions(alice, {access: 'Normal'});
+    
+    await collection.removeFromAllowList(alice, {Substrate: bob.address});
+    expect(await collection.getAllowList()).to.be.empty;
   });
 });
 
@@ -74,29 +66,26 @@
   let bob: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
     });
   });
 
-  it('fails on removal from not existing collection', async () => {
-    await usingApi(async (api) => {
-      const collectionId = await findNotExistingCollection(api);
-
-      await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(bob.address));
-    });
+  itSub('fails on removal from not existing collection', async ({helper}) => {
+    const nonExistentCollectionId = (1 << 32) - 1;
+    await expect(helper.collection.removeFromAllowList(alice, nonExistentCollectionId, {Substrate: alice.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('fails on removal from removed collection', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await addToAllowListExpectSuccess(alice, collectionId, bob.address);
-      await destroyCollectionExpectSuccess(collectionId);
+  itSub('fails on removal from removed collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-3', tokenPrefix: 'RFAL'});
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addToAllowList(alice, {Substrate: bob.address});
 
-      await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(bob.address));
-    });
+    await collection.burn(alice);
+    await expect(collection.removeFromAllowList(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 });
 
@@ -106,41 +95,45 @@
   let charlie: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
     });
   });
 
-  it('ensure address is not in allowlist after removal', async () => {
-    await usingApi(async api => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      await addToAllowListExpectSuccess(alice, collectionId, charlie.address);
-      await removeFromAllowListExpectSuccess(bob, collectionId, normalizeAccountId(charlie.address));
-      expect(await isAllowlisted(api, collectionId, charlie.address)).to.be.false;
-    });
+  itSub('ensure address is not in allowlist after removal', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-4', tokenPrefix: 'RFAL'});
+    
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    await collection.addToAllowList(bob, {Substrate: charlie.address});
+    await collection.removeFromAllowList(bob, {Substrate: charlie.address});
+
+    expect(await collection.getAllowList()).to.be.empty;
   });
 
-  it('Collection admin allowed to remove from allowlist with unset allowlist status', async () => {
-    await usingApi(async () => {
-      const collectionWithoutAllowlistId = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);
-      await addCollectionAdminExpectSuccess(alice, collectionWithoutAllowlistId, bob.address);
-      await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, charlie.address);
-      await disableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);
-      await removeFromAllowListExpectSuccess(bob, collectionWithoutAllowlistId, normalizeAccountId(charlie.address));
-    });
+  itSub('Collection admin allowed to remove from allowlist with unset allowlist status', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-5', tokenPrefix: 'RFAL'});
+
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+    await collection.addToAllowList(alice, {Substrate: charlie.address});
+
+    await collection.setPermissions(bob, {access: 'Normal'});
+    await collection.removeFromAllowList(bob, {Substrate: charlie.address});
+
+    expect(await collection.getAllowList()).to.be.empty;
   });
 
-  it('Regular user can`t remove from allowlist', async () => {
-    await usingApi(async () => {
-      const collectionWithoutAllowlistId = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);
-      await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, charlie.address);
-      await removeFromAllowListExpectFailure(bob, collectionWithoutAllowlistId, normalizeAccountId(charlie.address));
-    });
+  itSub('Regular user can`t remove from allowlist', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-6', tokenPrefix: 'RFAL'});
+
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addToAllowList(alice, {Substrate: charlie.address});
+
+    await expect(collection.removeFromAllowList(bob, {Substrate: charlie.address}))
+      .to.be.rejectedWith(/common\.NoPermission/);
+    expect(await collection.getAllowList()).to.deep.contain({Substrate: charlie.address});
   });
 });
modifiedtests/src/removeFromContractAllowList.test.tsdiffbeforeafterboth
--- a/tests/src/removeFromContractAllowList.test.ts
+++ b/tests/src/removeFromContractAllowList.test.ts
@@ -20,6 +20,7 @@
 import {IKeyringPair} from '@polkadot/types/types';
 import {expect} from 'chai';
 
+// todo:playgrounds skipped again
 describe.skip('Integration Test removeFromContractAllowList', () => {
   let bob: IKeyringPair;
 
modifiedtests/src/rpc.test.tsdiffbeforeafterboth
--- a/tests/src/rpc.test.ts
+++ b/tests/src/rpc.test.ts
@@ -1,57 +1,57 @@
 import {IKeyringPair} from '@polkadot/types/types';
-import {expect} from 'chai';
-import usingApi from './substrate/substrate-api';
-import {createCollection, createCollectionExpectSuccess, createFungibleItemExpectSuccess, CrossAccountId, getTokenOwner, normalizeAccountId, transfer, U128_MAX} from './util/helpers';
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import {usingPlaygrounds, itSub} from './util/playgrounds';
+import {crossAccountIdFromLower} from './util/playgrounds/unique';
 
-let alice: IKeyringPair;
-let bob: IKeyringPair;
+chai.use(chaiAsPromised);
+const expect = chai.expect;
 
+describe('integration test: RPC methods', () => {
+  let donor: IKeyringPair;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
 
-describe('integration test: RPC methods', () => {
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
     });
   });
 
-  
-  it('returns None for fungible collection', async () => {
-    await usingApi(async api => {
-      const collection = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      await expect(getTokenOwner(api, collection, 0)).to.be.rejectedWith(/^owner == null$/);
-    });
+  itSub('returns None for fungible collection', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'RPC-1', tokenPrefix: 'RPC'});
+    const owner = (await helper.callRpc('api.rpc.unique.tokenOwner', [collection.collectionId, 0])).toJSON() as any;
+    expect(owner).to.be.null;
   });
   
-  it('RPC method tokenOwners for fungible collection and token', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));
-      
-      const createCollectionResult = await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}});
-      const collectionId = createCollectionResult.collectionId;
-      const aliceTokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: U128_MAX}, alice.address);
-     
-      await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);
-      await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);
-            
-      for (let i = 0; i < 7; i++) {
-        await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 1);
-      } 
-      
-      const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);
-      const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));
-      const aliceID = normalizeAccountId(alice);
-      const bobId = normalizeAccountId(bob);
+  itSub('RPC method tokenOwners for fungible collection and token', async ({helper}) => {
+    // Set-up a few token owners of all stripes
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    const facelessCrowd = (await helper.arrange.createAccounts([0n, 0n, 0n, 0n, 0n, 0n, 0n], donor))
+      .map(i => {return {Substrate: i.address};});
+    
+    const collection = await helper.ft.mintCollection(alice, {name: 'RPC-2', tokenPrefix: 'RPC'});
+    // mint some maximum (u128) amounts of tokens possible
+    await collection.mint(alice, {Substrate: alice.address}, (1n << 128n) - 1n);
+    
+    await collection.transfer(alice, {Substrate: bob.address}, 1000n);
+    await collection.transfer(alice, ethAcc, 900n);
+          
+    for (let i = 0; i < facelessCrowd.length; i++) {
+      await collection.transfer(alice, facelessCrowd[i], 1n);
+    }
+    // Set-up over
+
+    const owners = await helper.callRpc('api.rpc.unique.tokenOwners', [collection.collectionId, 0]);
+    const ids = (owners.toJSON() as any[]).map(crossAccountIdFromLower);
 
-      // What to expect
-      // tslint:disable-next-line:no-unused-expression
-      expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);
-      expect(owners.length == 10).to.be.true;
-      
-      const eleven = privateKeyWrapper('11');
-      expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;
-      expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);
-    });
+    expect(ids).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
+    expect(owners.length == 10).to.be.true;
+    
+    // Make sure only 10 results are returned with this RPC
+    const [eleven] = await helper.arrange.createAccounts([0n], donor);
+    expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
+    expect((await helper.callRpc('api.rpc.unique.tokenOwners', [collection.collectionId, 0])).length).to.be.equal(10);
   });
 });
\ No newline at end of file
modifiedtests/src/scheduler.test.tsdiffbeforeafterboth
--- a/tests/src/scheduler.test.ts
+++ b/tests/src/scheduler.test.ts
@@ -44,6 +44,7 @@
 
 chai.use(chaiAsPromised);
 
+// todo:playgrounds skipped ~ postponed
 describe.skip('Scheduling token and balance transfers', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
modifiedtests/src/setChainLimits.test.tsdiffbeforeafterboth
--- a/tests/src/setChainLimits.test.ts
+++ b/tests/src/setChainLimits.test.ts
@@ -23,6 +23,7 @@
   IChainLimits,
 } from './util/helpers';
 
+// todo:playgrounds skipped ~ postponed
 describe.skip('Negative Integration Test setChainLimits', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
modifiedtests/src/setCollectionLimits.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionLimits.test.ts
+++ b/tests/src/setCollectionLimits.test.ts
@@ -15,26 +15,13 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 // https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits
-import {ApiPromise} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import usingApi, {submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess, getCreatedCollectionCount,
-  getCreateItemResult,
-  setCollectionLimitsExpectFailure,
-  setCollectionLimitsExpectSuccess,
-  addCollectionAdminExpectSuccess,
-  queryCollectionExpectSuccess,
-} from './util/helpers';
+import {itSub, usingPlaygrounds} from './util/playgrounds';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-let collectionIdForTesting: number;
 
 const accountTokenOwnershipLimit = 0;
 const sponsoredDataSize = 0;
@@ -42,197 +29,177 @@
 const tokenLimit = 10;
 
 describe('setCollectionLimits positive', () => {
-  let tx;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
-    });
-  });
-  it('execute setCollectionLimits with predefined params ', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      tx = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        {
-          accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-          sponsoredDataSize: sponsoredDataSize,
-          tokenLimit: tokenLimit,
-          sponsorTransferTimeout,
-          ownerCanTransfer: true,
-          ownerCanDestroy: true,
-        },
-      );
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateItemResult(events);
-
-      // get collection limits defined previously
-      const collectionInfo = await queryCollectionExpectSuccess(api, collectionIdForTesting);
-
-      // tslint:disable-next-line:no-unused-expression
-      expect(result.success).to.be.true;
-      expect(collectionInfo.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.be.equal(accountTokenOwnershipLimit);
-      expect(collectionInfo.limits.sponsoredDataSize.unwrap().toNumber()).to.be.equal(sponsoredDataSize);
-      expect(collectionInfo.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);
-      expect(collectionInfo.limits.sponsorTransferTimeout.unwrap().toNumber()).to.be.equal(sponsorTransferTimeout);
-      expect(collectionInfo.limits.ownerCanTransfer.unwrap().toJSON()).to.be.true;
-      expect(collectionInfo.limits.ownerCanDestroy.unwrap().toJSON()).to.be.true;
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
     });
   });
 
-  it('Set the same token limit twice', async () => {
-    await usingApi(async (api: ApiPromise) => {
+  itSub('execute setCollectionLimits with predefined params', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-1', tokenPrefix: 'SCL'});
 
-      const collectionLimits = {
-        accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-        sponsoredMintSize: sponsoredDataSize,
-        tokenLimit: tokenLimit,
+    await collection.setLimits(
+      alice,
+      {
+        accountTokenOwnershipLimit,
+        sponsoredDataSize,
+        tokenLimit,
         sponsorTransferTimeout,
         ownerCanTransfer: true,
         ownerCanDestroy: true,
-      };
+      },
+    );
 
-      // The first time
-      const tx1 = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        collectionLimits,
-      );
-      const events1 = await submitTransactionAsync(alice, tx1);
-      const result1 = getCreateItemResult(events1);
-      expect(result1.success).to.be.true;
-      const collectionInfo1 = await queryCollectionExpectSuccess(api, collectionIdForTesting);
-      expect(collectionInfo1.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);
+    // get collection limits defined previously
+    const collectionInfo = await collection.getEffectiveLimits();
 
-      // The second time
-      const tx2 = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        collectionLimits,
-      );
-      const events2 = await submitTransactionAsync(alice, tx2);
-      const result2 = getCreateItemResult(events2);
-      expect(result2.success).to.be.true;
-      const collectionInfo2 = await queryCollectionExpectSuccess(api, collectionIdForTesting);
-      expect(collectionInfo2.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);
-    });
+    expect(collectionInfo.accountTokenOwnershipLimit).to.be.equal(accountTokenOwnershipLimit);
+    expect(collectionInfo.sponsoredDataSize).to.be.equal(sponsoredDataSize);
+    expect(collectionInfo.tokenLimit).to.be.equal(tokenLimit);
+    expect(collectionInfo.sponsorTransferTimeout).to.be.equal(sponsorTransferTimeout);
+    expect(collectionInfo.ownerCanTransfer).to.be.true;
+    expect(collectionInfo.ownerCanDestroy).to.be.true;
   });
 
-  it('execute setCollectionLimits from admin collection', async () => {
-    await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob.address);
-    await usingApi(async (api: ApiPromise) => {
-      tx = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        {
-          accountTokenOwnershipLimit,
-          sponsoredDataSize,
-          // sponsoredMintSize,
-          tokenLimit,
-        },
-      );
-      await expect(submitTransactionAsync(bob, tx)).to.be.not.rejected;
-    });
+  itSub('Set the same token limit twice', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-2', tokenPrefix: 'SCL'});
+
+    const collectionLimits = {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
+      sponsorTransferTimeout,
+      ownerCanTransfer: true,
+      ownerCanDestroy: true,
+    };
+
+    await collection.setLimits(alice, collectionLimits);
+
+    const collectionInfo1 = await collection.getEffectiveLimits();
+      
+    expect(collectionInfo1.tokenLimit).to.be.equal(tokenLimit);
+
+    await collection.setLimits(alice, collectionLimits);
+    const collectionInfo2 = await collection.getEffectiveLimits();
+    expect(collectionInfo2.tokenLimit).to.be.equal(tokenLimit);
   });
+
+  itSub('execute setCollectionLimits from admin collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-3', tokenPrefix: 'SCL'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    const collectionLimits = {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      // sponsoredMintSize,
+      tokenLimit,
+    };
+
+    await expect(collection.setLimits(alice, collectionLimits)).to.not.be.rejected;
+  });
 });
 
 describe('setCollectionLimits negative', () => {
-  let tx;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
     });
   });
-  it('execute setCollectionLimits for not exists collection', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const collectionCount = await getCreatedCollectionCount(api);
-      const nonExistedCollectionId = collectionCount + 1;
-      tx = api.tx.unique.setCollectionLimits(
-        nonExistedCollectionId,
-        {
-          accountTokenOwnershipLimit,
-          sponsoredDataSize,
-          // sponsoredMintSize,
-          tokenLimit,
-        },
-      );
-      await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
-    });
+  
+  itSub('execute setCollectionLimits for not exists collection', async ({helper}) => {
+    const nonExistentCollectionId = (1 << 32) - 1;
+    await expect(helper.collection.setLimits(
+      alice,
+      nonExistentCollectionId,
+      {
+        accountTokenOwnershipLimit,
+        sponsoredDataSize,
+        // sponsoredMintSize,
+        tokenLimit,
+      },
+    )).to.be.rejectedWith(/common\.CollectionNotFound/);
   });
-  it('execute setCollectionLimits from user who is not owner of this collection', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      tx = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        {
-          accountTokenOwnershipLimit,
-          sponsoredDataSize,
-          // sponsoredMintSize,
-          tokenLimit,
-        },
-      );
-      await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
-    });
+
+  itSub('execute setCollectionLimits from user who is not owner of this collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-1', tokenPrefix: 'SCL'});
+
+    await expect(collection.setLimits(bob, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      // sponsoredMintSize,
+      tokenLimit,
+    })).to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('fails when trying to enable OwnerCanTransfer after it was disabled', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {
-      accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-      sponsoredMintSize: sponsoredDataSize,
-      tokenLimit: tokenLimit,
+  itSub('fails when trying to enable OwnerCanTransfer after it was disabled', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-2', tokenPrefix: 'SCL'});
+
+    await collection.setLimits(alice, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
       sponsorTransferTimeout,
       ownerCanTransfer: false,
       ownerCanDestroy: true,
     });
-    await setCollectionLimitsExpectFailure(alice, collectionId, {
-      accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-      sponsoredMintSize: sponsoredDataSize,
-      tokenLimit: tokenLimit,
+
+    await expect(collection.setLimits(alice, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
       sponsorTransferTimeout,
       ownerCanTransfer: true,
       ownerCanDestroy: true,
-    });
+    })).to.be.rejectedWith(/common\.OwnerPermissionsCantBeReverted/);
   });
 
-  it('fails when trying to enable OwnerCanDestroy after it was disabled', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {
-      accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-      sponsoredMintSize: sponsoredDataSize,
-      tokenLimit: tokenLimit,
+  itSub('fails when trying to enable OwnerCanDestroy after it was disabled', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-3', tokenPrefix: 'SCL'});
+
+    await collection.setLimits(alice, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
       sponsorTransferTimeout,
       ownerCanTransfer: true,
       ownerCanDestroy: false,
     });
-    await setCollectionLimitsExpectFailure(alice, collectionId, {
+
+    await expect(collection.setLimits(alice, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
+      sponsorTransferTimeout,
+      ownerCanTransfer: true,
+      ownerCanDestroy: true,
+    })).to.be.rejectedWith(/common\.OwnerPermissionsCantBeReverted/);
+  });
+
+  itSub('Setting the higher token limit fails', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-4', tokenPrefix: 'SCL'});
+      
+    const collectionLimits = {
       accountTokenOwnershipLimit: accountTokenOwnershipLimit,
       sponsoredMintSize: sponsoredDataSize,
       tokenLimit: tokenLimit,
       sponsorTransferTimeout,
       ownerCanTransfer: true,
       ownerCanDestroy: true,
-    });
-  });
+    };
 
-  it('Setting the higher token limit fails', async () => {
-    await usingApi(async () => {
+    // The first time
+    await collection.setLimits(alice, collectionLimits);
 
-      const collectionId = await createCollectionExpectSuccess();
-      const collectionLimits = {
-        accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-        sponsoredMintSize: sponsoredDataSize,
-        tokenLimit: tokenLimit,
-        sponsorTransferTimeout,
-        ownerCanTransfer: true,
-        ownerCanDestroy: true,
-      };
-
-      // The first time
-      await setCollectionLimitsExpectSuccess(alice, collectionId, collectionLimits);
-
-      // The second time - higher token limit
-      collectionLimits.tokenLimit += 1;
-      await setCollectionLimitsExpectFailure(alice, collectionId, collectionLimits);
-    });
+    // The second time - higher token limit
+    collectionLimits.tokenLimit += 1;
+    await expect(collection.setLimits(alice, collectionLimits)).to.be.rejectedWith(/common\.CollectionTokenLimitExceeded/);
   });
-
 });
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionSponsor.test.ts
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -16,91 +16,109 @@
 
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi} from './substrate/substrate-api';
-import {createCollectionExpectSuccess,
-  setCollectionSponsorExpectSuccess,
-  destroyCollectionExpectSuccess,
-  setCollectionSponsorExpectFailure,
-  addCollectionAdminExpectSuccess,
-  getCreatedCollectionCount,
-  requirePallets,
-  Pallets,
-} from './util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
+import {itSub, usingPlaygrounds, Pallets} from './util/playgrounds';
 
 chai.use(chaiAsPromised);
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-let charlie: IKeyringPair;
+const expect = chai.expect;
 
 describe('integration test: ext. setCollectionSponsor():', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  let charlie: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
     });
   });
 
-  it('Set NFT collection sponsor', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+  itSub('Set NFT collection sponsor', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-1-NFT', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: bob.address,
+    });
   });
-  it('Set Fungible collection sponsor', async () => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+  
+  itSub('Set Fungible collection sponsor', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'SetCollectionSponsor-1-FT', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: bob.address,
+    });
   });
-  it('Set ReFungible collection sponsor', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
 
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+  itSub.ifWithPallets('Set ReFungible collection sponsor', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'SetCollectionSponsor-1-RFT', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: bob.address,
+    });
   });
 
-  it('Set the same sponsor repeatedly', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+  itSub('Set the same sponsor repeatedly', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-2', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: bob.address,
+    });
   });
-  it('Replace collection sponsor', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await setCollectionSponsorExpectSuccess(collectionId, charlie.address);
+
+  itSub('Replace collection sponsor', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-3', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+    await expect(collection.setSponsor(alice, charlie.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: charlie.address,
+    });
   });
-  it('Collection admin add sponsor', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-    await setCollectionSponsorExpectSuccess(collectionId, charlie.address, '//Bob');
+  
+  itSub('Collection admin add sponsor', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-4', tokenPrefix: 'SCS'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+    await expect(collection.setSponsor(bob, charlie.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: charlie.address,
+    });
   });
 });
 
 describe('(!negative test!) integration test: ext. setCollectionSponsor():', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 5n], donor);
     });
   });
 
-  it('(!negative test!) Add sponsor with a non-owner', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectFailure(collectionId, bob.address, '//Bob');
+  itSub('(!negative test!) Add sponsor with a non-owner', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-Neg-1', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(bob, bob.address))
+      .to.be.rejectedWith(/common\.NoPermission/);
   });
-  it('(!negative test!) Add sponsor to a collection that never existed', async () => {
-    // Find the collection that never existed
-    let collectionId = 0;
-    await usingApi(async (api) => {
-      collectionId = await getCreatedCollectionCount(api) + 1;
-    });
 
-    await setCollectionSponsorExpectFailure(collectionId, bob.address);
+  itSub('(!negative test!) Add sponsor to a collection that never existed', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.setSponsor(alice, collectionId, bob.address))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
-  it('(!negative test!) Add sponsor to a collection that was destroyed', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await destroyCollectionExpectSuccess(collectionId);
-    await setCollectionSponsorExpectFailure(collectionId, bob.address);
+
+  itSub('(!negative test!) Add sponsor to a collection that was destroyed', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-Neg-2', tokenPrefix: 'SCS'});
+    await collection.burn(alice);
+    await expect(collection.setSponsor(alice, bob.address))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 });
modifiedtests/src/setContractSponsoringRateLimit.test.tsdiffbeforeafterboth
--- a/tests/src/setContractSponsoringRateLimit.test.ts
+++ b/tests/src/setContractSponsoringRateLimit.test.ts
@@ -25,6 +25,7 @@
   setContractSponsoringRateLimitExpectSuccess,
 } from './util/helpers';
 
+// todo:playgrounds postponed skipped test
 describe.skip('Integration Test setContractSponsoringRateLimit', () => {
   it('ensure sponsored contract can\'t be called twice without pause for free', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
modifiedtests/src/setMintPermission.test.tsdiffbeforeafterboth
--- a/tests/src/setMintPermission.test.ts
+++ b/tests/src/setMintPermission.test.ts
@@ -15,65 +15,62 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {IKeyringPair} from '@polkadot/types/types';
-import usingApi from './substrate/substrate-api';
-import {
-  addToAllowListExpectSuccess,
-  createCollectionExpectSuccess,
-  createItemExpectFailure,
-  createItemExpectSuccess,
-  destroyCollectionExpectSuccess,
-  enableAllowListExpectSuccess,
-  findNotExistingCollection,
-  setMintPermissionExpectFailure,
-  setMintPermissionExpectSuccess,
-  addCollectionAdminExpectSuccess,
-} from './util/helpers';
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import {itSub, usingPlaygrounds} from './util/playgrounds';
 
+chai.use(chaiAsPromised);
+const expect = chai.expect;
+
 describe('Integration Test setMintPermission', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
     });
   });
 
-  it('ensure allow-listed non-privileged address can mint tokens', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
-      await addToAllowListExpectSuccess(alice, collectionId, bob.address);
+  itSub('ensure allow-listed non-privileged address can mint tokens', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-1', description: '', tokenPrefix: 'SMP'});
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addToAllowList(alice, {Substrate: bob.address});
 
-      await createItemExpectSuccess(bob, collectionId, 'NFT');
-    });
+    await expect(collection.mintToken(bob, {Substrate: bob.address})).to.not.be.rejected;
   });
 
-  it('can be enabled twice', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
-    });
+  itSub('can be enabled twice', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-2', description: '', tokenPrefix: 'SMP'});
+    expect((await collection.getData())?.raw.permissions.access).to.not.equal('AllowList');
+
+    await collection.setPermissions(alice, {mintMode: true});
+    await collection.setPermissions(alice, {mintMode: true});
+    expect((await collection.getData())?.raw.permissions.mintMode).to.be.true;
   });
 
-  it('can be disabled twice', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
-      await setMintPermissionExpectSuccess(alice, collectionId, false);
-      await setMintPermissionExpectSuccess(alice, collectionId, false);
-    });
+  itSub('can be disabled twice', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-3', description: '', tokenPrefix: 'SMP'});
+    expect((await collection.getData())?.raw.permissions.access).to.equal('Normal');
+
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList');
+    expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true);
+
+    await collection.setPermissions(alice, {access: 'Normal', mintMode: false});
+    await collection.setPermissions(alice, {access: 'Normal', mintMode: false});
+    expect((await collection.getData())?.raw.permissions.access).to.equal('Normal');
+    expect((await collection.getData())?.raw.permissions.mintMode).to.equal(false);
   });
 
-  it('Collection admin success on set', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      await setMintPermissionExpectSuccess(bob, collectionId, true);
-    });
+  itSub('Collection admin success on set', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-4', description: '', tokenPrefix: 'SMP'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+    await collection.setPermissions(bob, {access: 'AllowList', mintMode: true});
+    
+    expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList');
+    expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true);
   });
 });
 
@@ -82,41 +79,38 @@
   let bob: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
     });
   });
 
-  it('fails on not existing collection', async () => {
-    await usingApi(async (api) => {
-      const nonExistingCollection = await findNotExistingCollection(api);
-      await setMintPermissionExpectFailure(alice, nonExistingCollection, true);
-    });
+  itSub('fails on not existing collection', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.setPermissions(alice, collectionId, {mintMode: true}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('fails on removed collection', async () => {
-    await usingApi(async () => {
-      const removedCollectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await destroyCollectionExpectSuccess(removedCollectionId);
+  itSub('fails on removed collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-1', tokenPrefix: 'SMP'});
+    await collection.burn(alice);
 
-      await setMintPermissionExpectFailure(alice, removedCollectionId, true);
-    });
+    await expect(collection.setPermissions(alice, {mintMode: true}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('fails when not collection owner tries to set mint status', async () => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    await enableAllowListExpectSuccess(alice, collectionId);
-    await setMintPermissionExpectFailure(bob, collectionId, true);
+  itSub('fails when non-owner tries to set mint status', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-2', tokenPrefix: 'SMP'});
+
+    await expect(collection.setPermissions(bob, {mintMode: true}))
+      .to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('ensure non-allow-listed non-privileged address can\'t mint tokens', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
+  itSub('ensure non-allow-listed non-privileged address can\'t mint tokens', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-3', tokenPrefix: 'SMP'});
+    await collection.setPermissions(alice, {mintMode: true});
 
-      await createItemExpectFailure(bob, collectionId, 'NFT');
-    });
+    await expect(collection.mintToken(bob, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.AddressNotInAllowlist/);
   });
 });
modifiedtests/src/setPublicAccessMode.test.tsdiffbeforeafterboth
--- a/tests/src/setPublicAccessMode.test.ts
+++ b/tests/src/setPublicAccessMode.test.ts
@@ -15,111 +15,84 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 // https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion
-import {ApiPromise} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import usingApi, {submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {
-  addToAllowListExpectSuccess,
-  createCollectionExpectSuccess,
-  createItemExpectSuccess,
-  destroyCollectionExpectSuccess,
-  enablePublicMintingExpectSuccess,
-  enableAllowListExpectSuccess,
-  normalizeAccountId,
-  addCollectionAdminExpectSuccess,
-  getCreatedCollectionCount,
-} from './util/helpers';
+import {itSub, usingPlaygrounds} from './util/playgrounds';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
 
 describe('Integration Test setPublicAccessMode(): ', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
     });
   });
 
-  it('Run extrinsic with collection id parameters, set the allowlist mode for the collection', async () => {
-    await usingApi(async () => {
-      const collectionId: number = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await enablePublicMintingExpectSuccess(alice, collectionId);
-      await addToAllowListExpectSuccess(alice, collectionId, bob.address);
-      await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
-    });
+  itSub('Runs extrinsic with collection id parameters, sets the allowlist mode for the collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-1', tokenPrefix: 'TF'});
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addToAllowList(alice, {Substrate: bob.address});
+    
+    await expect(collection.mintToken(bob, {Substrate: bob.address})).to.be.not.rejected;
+  });
+
+  itSub('Allowlisted collection limits', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-2', tokenPrefix: 'TF'});
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    
+    await expect(collection.mintToken(bob, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.AddressNotInAllowlist/);
   });
 
-  it('Allowlisted collection limits', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const collectionId = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await enablePublicMintingExpectSuccess(alice, collectionId);
-      const tx = api.tx.unique.createItem(collectionId, normalizeAccountId(bob.address), 'NFT');
-      await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
-    });
+  itSub('setPublicAccessMode by collection admin', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-4', tokenPrefix: 'TF'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    await expect(collection.setPermissions(bob, {access: 'AllowList'})).to.be.not.rejected;
   });
 });
 
 describe('Negative Integration Test ext. setPublicAccessMode(): ', () => {
-  it('Set a non-existent collection', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      // tslint:disable-next-line: radix
-      const collectionId = await getCreatedCollectionCount(api) + 1;
-      const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
-      await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  
+  before(async () => {
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
     });
   });
 
-  it('Set the collection that has been deleted', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = await createCollectionExpectSuccess();
-      await destroyCollectionExpectSuccess(collectionId);
-      const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
-      await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
-    });
+  itSub('Sets a non-existent collection', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.setPermissions(alice, collectionId, {access: 'AllowList'}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('Re-set the list mode already set in quantity', async () => {
-    await usingApi(async () => {
-      const collectionId: number = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await enableAllowListExpectSuccess(alice, collectionId);
-    });
+  itSub('Sets the collection that has been deleted', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-1', tokenPrefix: 'TF'});
+    await collection.burn(alice);
+
+    await expect(collection.setPermissions(alice, {access: 'AllowList'}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('Execute method not on behalf of the collection owner', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = await createCollectionExpectSuccess();
-      const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
-      await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
-    });
+  itSub('Re-sets the list mode already set in quantity', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-2', tokenPrefix: 'TF'});
+    await collection.setPermissions(alice, {access: 'AllowList'});
+    await collection.setPermissions(alice, {access: 'AllowList'});
   });
 
-  it('setPublicAccessMode by collection admin', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = await createCollectionExpectSuccess();
-      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
-      await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.not.rejected;
-    });
-  });
-});
+  itSub('Executes method as a malefactor', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-3', tokenPrefix: 'TF'});
 
-describe('Negative Integration Test ext. collection admin setPublicAccessMode(): ', () => {
-  before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-    });
+    await expect(collection.setPermissions(bob, {access: 'AllowList'}))
+      .to.be.rejectedWith(/common\.NoPermission/);
   });
 });
modifiedtests/src/toggleContractAllowList.test.tsdiffbeforeafterboth
--- a/tests/src/toggleContractAllowList.test.ts
+++ b/tests/src/toggleContractAllowList.test.ts
@@ -31,6 +31,7 @@
 const value = 0;
 const gasLimit = 3000n * 1000000n;
 
+// todo:playgrounds skipped ~ postpone
 describe.skip('Integration Test toggleContractAllowList', () => {
 
   it('Enable allow list contract mode', async () => {
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
before · tests/src/transfer.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {ApiPromise} from '@polkadot/api';18import {IKeyringPair} from '@polkadot/types/types';19import {expect} from 'chai';20import getBalance from './substrate/get-balance';21import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';22import {23  burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess,24  destroyCollectionExpectSuccess,25  findUnusedAddress,26  getCreateCollectionResult,27  getCreateItemResult,28  transferExpectFailure,29  transferExpectSuccess,30  addCollectionAdminExpectSuccess,31  getCreatedCollectionCount,32  toSubstrateAddress,33  getTokenOwner,34  normalizeAccountId,35  getBalance as getTokenBalance,36  transferFromExpectSuccess,37  transferFromExpectFail,38  requirePallets,39  Pallets,40} from './util/helpers';41import {42  subToEth,43  itWeb3, 44} from './eth/util/helpers';45import {request} from 'https';4647let alice: IKeyringPair;48let bob: IKeyringPair;49let charlie: IKeyringPair;5051describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {52  before(async () => {53    await usingApi(async (api, privateKeyWrapper) => {54      alice = privateKeyWrapper('//Alice');55      bob = privateKeyWrapper('//Bob');56    });57  });58  59  it('Balance transfers and check balance', async () => {60    await usingApi(async (api, privateKeyWrapper) => {61      const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alice.address, bob.address]);6263      const transfer = api.tx.balances.transfer(bob.address, 1n);64      const events = await submitTransactionAsync(alice, transfer);65      const result = getCreateItemResult(events);66      // tslint:disable-next-line:no-unused-expression67      expect(result.success).to.be.true;6869      const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alice.address, bob.address]);7071      // tslint:disable-next-line:no-unused-expression72      expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;73      // tslint:disable-next-line:no-unused-expression74      expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;75    });76  });7778  it('Inability to pay fees error message is correct', async () => {79    await usingApi(async (api, privateKeyWrapper) => {80      // Find unused address81      const pk = await findUnusedAddress(api, privateKeyWrapper);8283      const badTransfer = api.tx.balances.transfer(bob.address, 1n);84      // const events = await submitTransactionAsync(pk, badTransfer);85      const badTransaction = async () => {86        const events = await submitTransactionAsync(pk, badTransfer);87        const result = getCreateCollectionResult(events);88        // tslint:disable-next-line:no-unused-expression89        expect(result.success).to.be.false;90      };91      await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');92    });93  });9495  it('[nft] User can transfer owned token', async () => {96    const nftCollectionId = await createCollectionExpectSuccess();97    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');98    await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');99  });100101  it('[fungible] User can transfer owned token', async () => {102    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});103    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');104    await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');105  });106107  it('[refungible] User can transfer owned token', async function() {108    await requirePallets(this, [Pallets.ReFungible]);109110    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});111    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');112    await transferExpectSuccess(113      reFungibleCollectionId,114      newReFungibleTokenId,115      alice,116      bob,117      100,118      'ReFungible',119    );120  });121122  it('[nft] Collection admin can transfer owned token', async () => {123    const nftCollectionId = await createCollectionExpectSuccess();124    await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);125    const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);126    await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');127  });128129  it('[fungible] Collection admin can transfer owned token', async () => {130    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});131    await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);132    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);133    await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');134  });135136  it('[refungible] Collection admin can transfer owned token', async function() {137    await requirePallets(this, [Pallets.ReFungible]);138139    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});140    await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);141    const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);142    await transferExpectSuccess(143      reFungibleCollectionId,144      newReFungibleTokenId,145      bob,146      alice,147      100,148      'ReFungible',149    );150  });151});152153describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {154  before(async () => {155    await usingApi(async (api, privateKeyWrapper) => {156      alice = privateKeyWrapper('//Alice');157      bob = privateKeyWrapper('//Bob');158      charlie = privateKeyWrapper('//Charlie');159    });160  });161162  it('[nft] Transfer with not existed collection_id', async () => {163    await usingApi(async (api) => {164      const nftCollectionCount = await getCreatedCollectionCount(api);165      await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);166    });167  });168169  it('[fungible] Transfer with not existed collection_id', async () => {170    await usingApi(async (api) => {171      const fungibleCollectionCount = await getCreatedCollectionCount(api);172      await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);173    });174  });175176  it('[refungible] Transfer with not existed collection_id', async function() {177    await requirePallets(this, [Pallets.ReFungible]);178179    await usingApi(async (api) => {180      const reFungibleCollectionCount = await getCreatedCollectionCount(api);181      await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);182    });183  });184185  it('[nft] Transfer with deleted collection_id', async () => {186    const nftCollectionId = await createCollectionExpectSuccess();187    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');188    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);189    await destroyCollectionExpectSuccess(nftCollectionId);190    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);191  });192193  it('[fungible] Transfer with deleted collection_id', async () => {194    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});195    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');196    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);197    await destroyCollectionExpectSuccess(fungibleCollectionId);198    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);199  });200201  it('[refungible] Transfer with deleted collection_id', async function() {202    await requirePallets(this, [Pallets.ReFungible]);203204    const reFungibleCollectionId = await205    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});206    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');207    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);208    await destroyCollectionExpectSuccess(reFungibleCollectionId);209    await transferExpectFailure(210      reFungibleCollectionId,211      newReFungibleTokenId,212      alice,213      bob,214      1,215    );216  });217218  it('[nft] Transfer with not existed item_id', async () => {219    const nftCollectionId = await createCollectionExpectSuccess();220    await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);221  });222223  it('[fungible] Transfer with not existed item_id', async () => {224    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});225    await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);226  });227228  it('[refungible] Transfer with not existed item_id', async function() {229    await requirePallets(this, [Pallets.ReFungible]);230231    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});232    await transferExpectFailure(233      reFungibleCollectionId,234      2,235      alice,236      bob,237      1,238    );239  });240241  it('[nft] Transfer with deleted item_id', async () => {242    const nftCollectionId = await createCollectionExpectSuccess();243    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');244    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);245    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);246  });247248  it('[fungible] Transfer with deleted item_id', async () => {249    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});250    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');251    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);252    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);253  });254255  it('[refungible] Transfer with deleted item_id', async function() {256    await requirePallets(this, [Pallets.ReFungible]);257258    const reFungibleCollectionId = await259    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});260    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');261    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);262    await transferExpectFailure(263      reFungibleCollectionId,264      newReFungibleTokenId,265      alice,266      bob,267      1,268    );269  });270271  it('[nft] Transfer with recipient that is not owner', async () => {272    const nftCollectionId = await createCollectionExpectSuccess();273    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');274    await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);275  });276277  it('[fungible] Transfer with recipient that is not owner', async () => {278    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});279    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');280    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);281  });282283  it('[refungible] Transfer with recipient that is not owner', async function() {284    await requirePallets(this, [Pallets.ReFungible]);285286    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});287    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');288    await transferExpectFailure(289      reFungibleCollectionId,290      newReFungibleTokenId,291      charlie,292      bob,293      1,294    );295  });296});297298describe('Zero value transfer(From)', () => {299  before(async () => {300    await usingApi(async (api, privateKeyWrapper) => {301      alice = privateKeyWrapper('//Alice');302      bob = privateKeyWrapper('//Bob');303    });304  });305306  it('NFT', async () => {307    await usingApi(async (api: ApiPromise) => {308      const nftCollectionId = await createCollectionExpectSuccess();309      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');310311      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), nftCollectionId, newNftTokenId, 0);312      await submitTransactionAsync(alice, transferTx);313      const address = normalizeAccountId(await getTokenOwner(api, nftCollectionId, newNftTokenId));314315      expect(toSubstrateAddress(address)).to.be.equal(alice.address);316    });317  });318319  it('RFT', async function() {320    await requirePallets(this, [Pallets.ReFungible]);321322    await usingApi(async (api: ApiPromise) => {323      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});324      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');325      const balanceBeforeAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);326      const balanceBeforeBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);327328      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), reFungibleCollectionId, newReFungibleTokenId, 0);329      await submitTransactionAsync(alice, transferTx);330331      const balanceAfterAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);332      const balanceAfterBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);333334      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);335      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);336    });337  });338339  it('Fungible', async () => {340    await usingApi(async (api: ApiPromise) => {341      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});342      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');343      const balanceBeforeAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);344      const balanceBeforeBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);345346      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), fungibleCollectionId, newFungibleTokenId, 0);347      await submitTransactionAsync(alice, transferTx);348349      const balanceAfterAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);350      const balanceAfterBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);351352      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);353      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);354    });355  });356});357358describe('Transfers to self (potentially over substrate-evm boundary)', () => {359  itWeb3('Transfers to self. In case of same frontend', async ({api, privateKeyWrapper}) => {360    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});361    const aliceProxy = subToEth(alice.address);362    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});363    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, 10, 'Fungible');364    const balanceAliceBefore = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);365    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, {Ethereum: aliceProxy}, 10, 'Fungible');366    const balanceAliceAfter = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);367    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);368  });369370  itWeb3('Transfers to self. In case of substrate-evm boundary', async ({api, privateKeyWrapper}) => {371    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});372    const aliceProxy = subToEth(alice.address);373    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});374    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);375    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy} , 10, 'Fungible');376    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, alice, 10, 'Fungible');377    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);378    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);379  });380381  itWeb3('Transfers to self. In case of inside substrate-evm', async ({api, privateKeyWrapper}) => {382    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});383    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});384    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);385    await transferExpectSuccess(collectionId, tokenId, alice, alice , 10, 'Fungible');386    await transferFromExpectSuccess(collectionId, tokenId, alice, alice, alice, 10, 'Fungible');387    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);388    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);389  });390391  itWeb3('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({api, privateKeyWrapper}) => {392    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});393    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});394    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);395    await transferExpectFailure(collectionId, tokenId, alice, alice , 11);396    await transferFromExpectFail(collectionId, tokenId, alice, alice, alice, 11);397    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);398    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);399  });400});
after · tests/src/transfer.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {IKeyringPair} from '@polkadot/types/types';18import chai from 'chai';19import chaiAsPromised from 'chai-as-promised';20import {itEth, usingEthPlaygrounds} from './eth/util/playgrounds';21import {itSub, Pallets, usingPlaygrounds} from './util/playgrounds';2223chai.use(chaiAsPromised);24const expect = chai.expect;2526describe.skip('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {27  let alice: IKeyringPair;28  let bob: IKeyringPair;2930  before(async () => {31    await usingPlaygrounds(async (helper, privateKey) => {32      const donor = privateKey('//Alice');33      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);34    });35  });36  37  itSub('Balance transfers and check balance', async ({helper}) => {38    const alicesBalanceBefore = await helper.balance.getSubstrate(alice.address);39    const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);4041    expect(await helper.balance.transferToSubstrate(alice, bob.address, 1n)).to.be.true;4243    const alicesBalanceAfter = await helper.balance.getSubstrate(alice.address);44    const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);4546    expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;47    expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;48  });4950  itSub('Inability to pay fees error message is correct', async ({helper, privateKey}) => {51    const donor = privateKey('//Alice');52    const [zero] = await helper.arrange.createAccounts([0n], donor);5354    // console.error = () => {};55    // The following operation throws an error into the console and the logs. Pay it no heed as long as the test succeeds.56    await expect(helper.balance.transferToSubstrate(zero, donor.address, 1n))57      .to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');58  });5960  itSub('[nft] User can transfer owned token', async ({helper}) => {61    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-1-NFT', description: '', tokenPrefix: 'T'});62    const nft = await collection.mintToken(alice, {Substrate: alice.address});6364    await nft.transfer(alice, {Substrate: bob.address});65    expect(await nft.getOwner()).to.be.deep.equal({Substrate: bob.address});66  });6768  itSub('[fungible] User can transfer owned token', async ({helper}) => {69    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-1-FT', description: '', tokenPrefix: 'T'});70    await collection.mint(alice, {Substrate: alice.address}, 10n);7172    await collection.transfer(alice, {Substrate: bob.address}, 9n);73    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);74    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);75  });7677  itSub.ifWithPallets('[refungible] User can transfer owned token', [Pallets.ReFungible], async ({helper}) => {78    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});79    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);8081    await rft.transfer(alice, {Substrate: bob.address}, 9n);82    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);83    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);84  });8586  itSub('[nft] Collection admin can transfer owned token', async ({helper}) => {87    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-2-NFT', description: '', tokenPrefix: 'T'});88    await collection.addAdmin(alice, {Substrate: bob.address});8990    const nft = await collection.mintToken(bob, {Substrate: bob.address});91    await nft.transfer(bob, {Substrate: alice.address});9293    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});94  });9596  itSub('[fungible] Collection admin can transfer owned token', async ({helper}) => {97    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-2-FT', description: '', tokenPrefix: 'T'});98    await collection.addAdmin(alice, {Substrate: bob.address});99100    await collection.mint(bob, {Substrate: bob.address}, 10n);101    await collection.transfer(bob, {Substrate: alice.address}, 1n);102103    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);104    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);105  });106107  itSub.ifWithPallets('[refungible] Collection admin can transfer owned token', [Pallets.ReFungible], async ({helper}) => {108    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-2-RFT', description: '', tokenPrefix: 'T'});109    await collection.addAdmin(alice, {Substrate: bob.address});110111    const rft = await collection.mintToken(bob, {Substrate: bob.address}, 10n);112    await rft.transfer(bob, {Substrate: alice.address}, 1n);113114    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);115    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);116  });117});118119describe.skip('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {120  let alice: IKeyringPair;121  let bob: IKeyringPair;122123  before(async () => {124    await usingPlaygrounds(async (helper, privateKey) => {125      const donor = privateKey('//Alice');126      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);127    });128  });129130  itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {131    const collectionId = (1 << 32) - 1;132    await expect(helper.nft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))133      .to.be.rejectedWith(/common\.CollectionNotFound/);134  });135136  itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {137    const collectionId = (1 << 32) - 1;138    await expect(helper.ft.transfer(alice, collectionId, {Substrate: bob.address}))139      .to.be.rejectedWith(/common\.CollectionNotFound/);140  });141142  itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {143    const collectionId = (1 << 32) - 1;144    await expect(helper.rft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))145      .to.be.rejectedWith(/common\.CollectionNotFound/);146  });147148  itSub('[nft] Transfer with deleted collection_id', async ({helper}) => {149    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-1-NFT', description: '', tokenPrefix: 'T'});150    const nft = await collection.mintToken(alice, {Substrate: alice.address});151152    await nft.burn(alice);153    await collection.burn(alice);154155    await expect(nft.transfer(alice, {Substrate: bob.address}))156      .to.be.rejectedWith(/common\.CollectionNotFound/);157  });158159  itSub('[fungible] Transfer with deleted collection_id', async ({helper}) => {160    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-1-FT', description: '', tokenPrefix: 'T'});161    await collection.mint(alice, {Substrate: alice.address}, 10n);162163    await collection.burnTokens(alice, 10n);164    await collection.burn(alice);165166    await expect(collection.transfer(alice, {Substrate: bob.address}))167      .to.be.rejectedWith(/common\.CollectionNotFound/);168  });169  170  itSub.ifWithPallets('[refungible] Transfer with deleted collection_id', [Pallets.ReFungible], async ({helper}) => {171    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-1-RFT', description: '', tokenPrefix: 'T'});172    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);173174    await rft.burn(alice, 10n);175    await collection.burn(alice);176177    await expect(rft.transfer(alice, {Substrate: bob.address}))178      .to.be.rejectedWith(/common\.CollectionNotFound/);179  });180181  itSub('[nft] Transfer with not existed item_id', async ({helper}) => {182    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-2-NFT', description: '', tokenPrefix: 'T'});183    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))184      .to.be.rejectedWith(/common\.TokenNotFound/);185  });186187  itSub('[fungible] Transfer with not existed item_id', async ({helper}) => {188    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-2-FT', description: '', tokenPrefix: 'T'});189    await expect(collection.transfer(alice, {Substrate: bob.address}))190      .to.be.rejectedWith(/common\.TokenValueTooLow/);191  });192193  itSub.ifWithPallets('[refungible] Transfer with not existed item_id', [Pallets.ReFungible], async ({helper}) => {194    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-2-RFT', description: '', tokenPrefix: 'T'});195    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))196      .to.be.rejectedWith(/common\.TokenValueTooLow/);197  });198199  itSub('[nft] Transfer with deleted item_id', async ({helper}) => {200    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});201    const nft = await collection.mintToken(alice, {Substrate: alice.address});202203    await nft.burn(alice);204205    await expect(nft.transfer(alice, {Substrate: bob.address}))206      .to.be.rejectedWith(/common\.TokenNotFound/);207  });208209  itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {210    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});211    await collection.mint(alice, {Substrate: alice.address}, 10n);212213    await collection.burnTokens(alice, 10n);214215    await expect(collection.transfer(alice, {Substrate: bob.address}))216      .to.be.rejectedWith(/common\.TokenValueTooLow/);217  });218219  itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {220    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});221    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);222223    await rft.burn(alice, 10n);224225    await expect(rft.transfer(alice, {Substrate: bob.address}))226      .to.be.rejectedWith(/common\.TokenValueTooLow/);227  });228229  itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {230    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});231    const nft = await collection.mintToken(alice, {Substrate: alice.address});232233    await expect(nft.transfer(bob, {Substrate: bob.address}))234      .to.be.rejectedWith(/common\.NoPermission/);235    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});236  });237238  itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {239    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});240    await collection.mint(alice, {Substrate: alice.address}, 10n);241242    await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))243      .to.be.rejectedWith(/common\.TokenValueTooLow/);244    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);245    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);246  });247248  itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {249    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});250    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);251252    await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))253      .to.be.rejectedWith(/common\.TokenValueTooLow/);254    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);255    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);256  });257});258259describe('Transfers to self (potentially over substrate-evm boundary)', () => {260  let donor: IKeyringPair;261262  before(async function() {263    await usingEthPlaygrounds(async (_, privateKey) => {264      donor = privateKey('//Alice');265    });266  });267  268  itEth('Transfers to self. In case of same frontend', async ({helper}) => {269    const [owner] = await helper.arrange.createAccounts([10n], donor);270    const collection = await helper.ft.mintCollection(owner, {});271    await collection.mint(owner, {Substrate: owner.address}, 100n);272273    const ownerProxy = helper.address.substrateToEth(owner.address);274275    // transfer to own proxy276    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);277    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);278    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);279280    // transfer-from own proxy to own proxy again281    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);282    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);283    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);284  });285286  itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {287    const [owner] = await helper.arrange.createAccounts([10n], donor);288    const collection = await helper.ft.mintCollection(owner, {});289    await collection.mint(owner, {Substrate: owner.address}, 100n);290291    const ownerProxy = helper.address.substrateToEth(owner.address);292293    // transfer to own proxy294    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);295    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);296    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);297298    // transfer-from own proxy to self299    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);300    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);301    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);302  });303304  itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {305    const [owner] = await helper.arrange.createAccounts([10n], donor);306    const collection = await helper.ft.mintCollection(owner, {});307    await collection.mint(owner, {Substrate: owner.address}, 100n);308309    // transfer to self again310    await collection.transfer(owner, {Substrate: owner.address}, 10n);311    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);312313    // transfer-from self to self again314    await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);315    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);316  });317318  itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {319    const [owner] = await helper.arrange.createAccounts([10n], donor);320    const collection = await helper.ft.mintCollection(owner, {});321    await collection.mint(owner, {Substrate: owner.address}, 10n);322323    // transfer to self again324    await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))325      .to.be.rejectedWith(/common\.TokenValueTooLow/);326327    // transfer-from self to self again328    await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))329      .to.be.rejectedWith(/common\.TokenValueTooLow/);330    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);331  });332});
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
--- a/tests/src/transferFrom.test.ts
+++ b/tests/src/transferFrom.test.ts
@@ -14,26 +14,10 @@
 // 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 {ApiPromise} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi} from './substrate/substrate-api';
-import {
-  approveExpectFail,
-  approveExpectSuccess,
-  createCollectionExpectSuccess,
-  createFungibleItemExpectSuccess,
-  createItemExpectSuccess,
-  getAllowance,
-  transferFromExpectFail,
-  transferFromExpectSuccess,
-  burnItemExpectSuccess,
-  setCollectionLimitsExpectSuccess,
-  getCreatedCollectionCount,
-  requirePallets,
-  Pallets,
-} from './util/helpers';
+import {itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
 
 chai.use(chaiAsPromised);
 const expect = chai.expect;
@@ -44,67 +28,64 @@
   let charlie: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
     });
   });
 
-  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);
+  itSub('[nft] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-1', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
+    await nft.approve(alice, {Substrate: bob.address});
+    expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
 
-    await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');
+    await nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address});
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
   });
 
-  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');
+  itSub('[fungible] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-2', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, {Substrate: alice.address}, 10n);
+    await collection.approveTokens(alice, {Substrate: bob.address}, 7n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
+    
+    await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
+    expect(await collection.getBalance({Substrate: charlie.address})).to.be.equal(6n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(4n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
   });
 
-  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',
-    );
+  itSub.ifWithPallets('[refungible] Execute the extrinsic and check nftItemList - owner of token', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-3', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
+    await rft.approve(alice, {Substrate: bob.address}, 7n);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
+    
+    await rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
+    expect(await rft.getBalance({Substrate: charlie.address})).to.be.equal(6n);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(4n);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
   });
 
-  it('Should reduce allowance if value is big', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const alice = privateKeyWrapper('//Alice');
-      const bob = privateKeyWrapper('//Bob');
-      const charlie = privateKeyWrapper('//Charlie');
+  itSub('Should reduce allowance if value is big', async ({helper}) => {
+    // fungible
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-4', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, {Substrate: alice.address}, 500000n);
 
-      // fungible
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: 500000n});
-
-      await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 500000n);
-      await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 500000n, 'Fungible');
-      expect(await getAllowance(api, fungibleCollectionId, alice.address, bob.address, newFungibleTokenId)).to.equal(0n);
-    });
+    await collection.approveTokens(alice, {Substrate: bob.address}, 500000n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(500000n);
+    await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 500000n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(0n);
   });
 
-  it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
-    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
+  itSub('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-5', description: '', tokenPrefix: 'TF'});
+    await collection.setLimits(alice, {ownerCanTransfer: true});
 
-    await transferFromExpectSuccess(collectionId, itemId, alice, bob, charlie);
+    const nft = await collection.mintToken(alice, {Substrate: bob.address});
+    await nft.transferFrom(alice, {Substrate: bob.address}, {Substrate: charlie.address});
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
   });
 });
 
@@ -114,245 +95,263 @@
   let charlie: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([50n, 10n, 10n], donor);
     });
   });
 
-  it('[nft] transferFrom for a collection that does not exist', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const nftCollectionCount = await getCreatedCollectionCount(api);
-      await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
+  itSub('transferFrom for a collection that does not exist', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.approveToken(alice, collectionId, 0, {Substrate: bob.address}, 1n))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
+    await expect(helper.collection.transferTokenFrom(bob, collectionId, 0, {Substrate: alice.address}, {Substrate: bob.address}, 1n))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
+  });
+
+  /* itSub('transferFrom for a collection that was destroyed', async ({helper}) => {
+      this test copies approve negative test
+  }); */
+
+  /* itSub('transferFrom a token that does not exist', async ({helper}) => {
+    this test copies approve negative test
+  }); */
+
+  /* itSub('transferFrom a token that was deleted', async ({helper}) => {
+    this test copies approve negative test
+  }); */
+
+  itSub('[nft] transferFrom for not approved address', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
+
+    await expect(nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
+  });
+
+  itSub('[fungible] transferFrom for not approved address', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, {Substrate: alice.address}, 10n);
 
-      await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);
-    });
+    await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  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);
+  itSub.ifWithPallets('[refungible] transferFrom for not approved address', [Pallets.ReFungible], async({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-3', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
 
-      await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);
-    });
+    await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  it('[refungible] transferFrom for a collection that does not exist', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub('[nft] transferFrom incorrect token count', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-4', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
 
-    await usingApi(async (api: ApiPromise) => {
-      const reFungibleCollectionCount = await getCreatedCollectionCount(api);
-      await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
+    await nft.approve(alice, {Substrate: bob.address});
+    expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
 
-      await transferFromExpectFail(reFungibleCollectionCount + 1, 1, bob, alice, charlie, 1);
-    });
+    await expect(helper.collection.transferTokenFrom(
+      bob, 
+      collection.collectionId, 
+      nft.tokenId, 
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address}, 
+      2n,
+    )).to.be.rejectedWith(/nonfungible\.NonfungibleItemsHaveNoAmount/);
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
   });
 
-  /* it('transferFrom for a collection that was destroyed', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      this test copies approve negative test
-    });
-  }); */
+  itSub('[fungible] transferFrom incorrect token count', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-5', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, {Substrate: alice.address}, 10n);
 
-  /* it('transferFrom a token that does not exist', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      this test copies approve negative test
-    });
-  }); */
+    await collection.approveTokens(alice, {Substrate: bob.address}, 2n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(2n);
 
-  /* it('transferFrom a token that was deleted', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      this test copies approve negative test
-    });
-  }); */
+    await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
+  });
 
-  it('[nft] transferFrom for not approved address', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+  itSub.ifWithPallets('[refungible] transferFrom incorrect token count', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-6', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
 
-    await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
-  });
+    await rft.approve(alice, {Substrate: bob.address}, 5n);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(5n);
 
-  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);
+    await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 7n))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  it('[refungible] transferFrom for not approved address', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub('[nft] execute transferFrom from account that is not owner of collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-7', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
 
-    const reFungibleCollectionId = await
-    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await transferFromExpectFail(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      bob,
-      alice,
+    await expect(nft.approve(charlie, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
+    expect(await nft.isApproved({Substrate: bob.address})).to.be.false;
+
+    await expect(nft.transferFrom(
       charlie,
-      1,
-    );
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
   });
 
-  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);
+  itSub('[fungible] execute transferFrom from account that is not owner of collection', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-8', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, {Substrate: alice.address}, 10000n);
 
-    await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);
-  });
+    await expect(collection.approveTokens(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
+    expect(await collection.getApprovedTokens({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
 
-  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 expect(collection.transferFrom(
+      charlie,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  it('[refungible] transferFrom incorrect token count', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] execute transferFrom from account that is not owner of collection', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-9', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10000n);
+
+    await expect(rft.approve(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
+    expect(await rft.getApprovedPieces({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
 
-    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,
+    await expect(rft.transferFrom(
       charlie,
-      2,
-    );
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  it('[nft] execute transferFrom from account that is not owner of collection', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const dave = privateKeyWrapper('//Dave');
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      try {
-        await approveExpectFail(nftCollectionId, newNftTokenId, dave, bob);
-        await transferFromExpectFail(nftCollectionId, newNftTokenId, dave, alice, charlie, 1);
-      } catch (e) {
-        // tslint:disable-next-line:no-unused-expression
-        expect(e).to.be.exist;
-      }
+  itSub('transferFrom burnt token before approve NFT', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-10', description: '', tokenPrefix: 'TF'});
+    await collection.setLimits(alice, {ownerCanTransfer: true});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
+
+    await nft.burn(alice);
+    await expect(nft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.TokenNotFound/);
 
-      // await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);
-    });
+    await expect(nft.transferFrom(
+      bob,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
 
-  it('[fungible] execute transferFrom from account that is not owner of collection', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const dave = privateKeyWrapper('//Dave');
+  itSub('transferFrom burnt token before approve Fungible', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-11', description: '', tokenPrefix: 'TF'});
+    await collection.setLimits(alice, {ownerCanTransfer: true});
+    await collection.mint(alice, {Substrate: alice.address}, 10n);
 
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      try {
-        await approveExpectFail(fungibleCollectionId, newFungibleTokenId, dave, bob);
-        await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, dave, alice, charlie, 1);
-      } catch (e) {
-        // tslint:disable-next-line:no-unused-expression
-        expect(e).to.be.exist;
-      }
-    });
+    await collection.burnTokens(alice, 10n);
+    await expect(collection.approveTokens(alice, {Substrate: bob.address})).to.be.not.rejected;
+
+    await expect(collection.transferFrom(
+      alice,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[refungible] execute transferFrom from account that is not owner of collection', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('transferFrom burnt token before approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-12', description: '', tokenPrefix: 'TF'});
+    await collection.setLimits(alice, {ownerCanTransfer: true});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
 
-    await usingApi(async (api, privateKeyWrapper) => {
-      const dave = privateKeyWrapper('//Dave');
-      const reFungibleCollectionId = await
-      createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      try {
-        await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, bob);
-        await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, alice, charlie, 1);
-      } catch (e) {
-        // tslint:disable-next-line:no-unused-expression
-        expect(e).to.be.exist;
-      }
-    });
-  });
-  it('transferFrom burnt token before approve NFT', async () => {
-    await usingApi(async () => {
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      await setCollectionLimitsExpectSuccess(alice, nftCollectionId, {ownerCanTransfer: true});
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
-      await approveExpectFail(nftCollectionId, newNftTokenId, alice, bob);
-      await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
-    });
-  });
-  it('transferFrom burnt token before approve Fungible', async () => {
-    await usingApi(async () => {
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      await setCollectionLimitsExpectSuccess(alice, fungibleCollectionId, {ownerCanTransfer: true});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
-      await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
-      await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
+    await rft.burn(alice, 10n);
+    await expect(rft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
 
-    });
+    await expect(rft.transferFrom(
+      alice,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
-  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});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
-      await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, alice, bob);
-      await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
+  itSub('transferFrom burnt token after approve NFT', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-13', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
 
-    });
-  });
+    await nft.approve(alice, {Substrate: bob.address});
+    expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
 
-  it('transferFrom burnt token after approve NFT', async () => {
-    await usingApi(async () => {
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
-      await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
-      await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
-    });
+    await nft.burn(alice);
+
+    await expect(nft.transferFrom(
+      bob,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
-  it('transferFrom burnt token after approve Fungible', async () => {
-    await usingApi(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 burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
-      await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
 
-    });
+  itSub('transferFrom burnt token after approve Fungible', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-14', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, {Substrate: alice.address}, 10n);
+
+    await collection.approveTokens(alice, {Substrate: bob.address});
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(1n);
+
+    await collection.burnTokens(alice, 10n);
+
+    await expect(collection.transferFrom(
+      bob,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
-  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');
-      await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
-      await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
-      await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
+  itSub.ifWithPallets('transferFrom burnt token after approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-15', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
+
+    await rft.approve(alice, {Substrate: bob.address}, 10n);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(10n);
+
+    await rft.burn(alice, 10n);
 
-    });
+    await expect(rft.transferFrom(
+      bob,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
 
-  it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});
+  itSub('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-16', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice, {Substrate: bob.address});
 
-    await transferFromExpectFail(collectionId, itemId, alice, bob, charlie);
+    await collection.setLimits(alice, {ownerCanTransfer: false});
+
+    await expect(nft.transferFrom(
+      alice,
+      {Substrate: bob.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
 });
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -2128,10 +2128,6 @@
     return await this.helper.collection.addAdmin(signer, this.collectionId, adminAddressObj);
   }
 
-  async enableCertainPermissions(signer: TSigner, accessMode: 'AllowList' | 'Normal' | undefined = 'AllowList', mintMode: boolean | undefined = true) {
-    return await this.setPermissions(signer, {access: accessMode, mintMode: mintMode});
-  }
-
   async addToAllowList(signer: TSigner, addressObj: ICrossAccountId) {
     return await this.helper.collection.addToAllowList(signer, this.collectionId, addressObj);
   }
modifiedtests/src/xcmTransfer.test.tsdiffbeforeafterboth
--- a/tests/src/xcmTransfer.test.ts
+++ b/tests/src/xcmTransfer.test.ts
@@ -33,6 +33,7 @@
 const KARURA_PORT = '9946';
 const TRANSFER_AMOUNT = 2000000000000000000000000n;
 
+// todo:playgrounds refit when XCM drops
 describe.skip('Integration test: Exchanging QTZ with Karura', () => {
   let alice: IKeyringPair;