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
--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -14,387 +14,319 @@
 // 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 {expect} from 'chai';
-import getBalance from './substrate/get-balance';
-import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';
-import {
-  burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess,
-  destroyCollectionExpectSuccess,
-  findUnusedAddress,
-  getCreateCollectionResult,
-  getCreateItemResult,
-  transferExpectFailure,
-  transferExpectSuccess,
-  addCollectionAdminExpectSuccess,
-  getCreatedCollectionCount,
-  toSubstrateAddress,
-  getTokenOwner,
-  normalizeAccountId,
-  getBalance as getTokenBalance,
-  transferFromExpectSuccess,
-  transferFromExpectFail,
-  requirePallets,
-  Pallets,
-} from './util/helpers';
-import {
-  subToEth,
-  itWeb3, 
-} from './eth/util/helpers';
-import {request} from 'https';
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import {itEth, usingEthPlaygrounds} from './eth/util/playgrounds';
+import {itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
+
+chai.use(chaiAsPromised);
+const expect = chai.expect;
 
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-let charlie: IKeyringPair;
+describe.skip('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
 
-describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
   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([50n, 10n], donor);
     });
   });
   
-  it('Balance transfers and check balance', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alice.address, bob.address]);
+  itSub('Balance transfers and check balance', async ({helper}) => {
+    const alicesBalanceBefore = await helper.balance.getSubstrate(alice.address);
+    const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);
 
-      const transfer = api.tx.balances.transfer(bob.address, 1n);
-      const events = await submitTransactionAsync(alice, transfer);
-      const result = getCreateItemResult(events);
-      // tslint:disable-next-line:no-unused-expression
-      expect(result.success).to.be.true;
+    expect(await helper.balance.transferToSubstrate(alice, bob.address, 1n)).to.be.true;
 
-      const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alice.address, bob.address]);
+    const alicesBalanceAfter = await helper.balance.getSubstrate(alice.address);
+    const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);
 
-      // tslint:disable-next-line:no-unused-expression
-      expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
-      // tslint:disable-next-line:no-unused-expression
-      expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
-    });
+    expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
+    expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
   });
 
-  it('Inability to pay fees error message is correct', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      // Find unused address
-      const pk = await findUnusedAddress(api, privateKeyWrapper);
+  itSub('Inability to pay fees error message is correct', async ({helper, privateKey}) => {
+    const donor = privateKey('//Alice');
+    const [zero] = await helper.arrange.createAccounts([0n], donor);
 
-      const badTransfer = api.tx.balances.transfer(bob.address, 1n);
-      // const events = await submitTransactionAsync(pk, badTransfer);
-      const badTransaction = async () => {
-        const events = await submitTransactionAsync(pk, badTransfer);
-        const result = getCreateCollectionResult(events);
-        // tslint:disable-next-line:no-unused-expression
-        expect(result.success).to.be.false;
-      };
-      await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');
-    });
+    // console.error = () => {};
+    // The following operation throws an error into the console and the logs. Pay it no heed as long as the test succeeds.
+    await expect(helper.balance.transferToSubstrate(zero, donor.address, 1n))
+      .to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');
   });
 
-  it('[nft] User can transfer owned token', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');
+  itSub('[nft] User can transfer owned token', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-1-NFT', description: '', tokenPrefix: 'T'});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
+
+    await nft.transfer(alice, {Substrate: bob.address});
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: bob.address});
   });
 
-  it('[fungible] User can transfer owned token', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');
+  itSub('[fungible] User can transfer owned token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-1-FT', description: '', tokenPrefix: 'T'});
+    await collection.mint(alice, {Substrate: alice.address}, 10n);
+
+    await collection.transfer(alice, {Substrate: bob.address}, 9n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 
-  it('[refungible] User can transfer owned token', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] User can transfer owned token', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
 
-    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await transferExpectSuccess(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      alice,
-      bob,
-      100,
-      'ReFungible',
-    );
+    await rft.transfer(alice, {Substrate: bob.address}, 9n);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 
-  it('[nft] Collection admin can transfer owned token', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
-    const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);
-    await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');
+  itSub('[nft] Collection admin can transfer owned token', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-2-NFT', description: '', tokenPrefix: 'T'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    const nft = await collection.mintToken(bob, {Substrate: bob.address});
+    await nft.transfer(bob, {Substrate: alice.address});
+
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
   });
 
-  it('[fungible] Collection admin can transfer owned token', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);
-    await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');
+  itSub('[fungible] Collection admin can transfer owned token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-2-FT', description: '', tokenPrefix: 'T'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    await collection.mint(bob, {Substrate: bob.address}, 10n);
+    await collection.transfer(bob, {Substrate: alice.address}, 1n);
+
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 
-  it('[refungible] Collection admin can transfer owned token', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] Collection admin can transfer owned token', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-2-RFT', description: '', tokenPrefix: 'T'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    const rft = await collection.mintToken(bob, {Substrate: bob.address}, 10n);
+    await rft.transfer(bob, {Substrate: alice.address}, 1n);
 
-    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);
-    const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);
-    await transferExpectSuccess(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      bob,
-      alice,
-      100,
-      'ReFungible',
-    );
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 });
 
-describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
+describe.skip('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
+  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([50n, 10n], donor);
     });
   });
 
-  it('[nft] Transfer with not existed collection_id', async () => {
-    await usingApi(async (api) => {
-      const nftCollectionCount = await getCreatedCollectionCount(api);
-      await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);
-    });
+  itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.nft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('[fungible] Transfer with not existed collection_id', async () => {
-    await usingApi(async (api) => {
-      const fungibleCollectionCount = await getCreatedCollectionCount(api);
-      await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);
-    });
+  itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.ft.transfer(alice, collectionId, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('[refungible] Transfer with not existed collection_id', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.rft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
+  });
+
+  itSub('[nft] Transfer with deleted collection_id', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-1-NFT', description: '', tokenPrefix: 'T'});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
+
+    await nft.burn(alice);
+    await collection.burn(alice);
 
-    await usingApi(async (api) => {
-      const reFungibleCollectionCount = await getCreatedCollectionCount(api);
-      await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);
-    });
+    await expect(nft.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('[nft] Transfer with deleted collection_id', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);
-    await destroyCollectionExpectSuccess(nftCollectionId);
-    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
+  itSub('[fungible] Transfer with deleted collection_id', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-1-FT', description: '', tokenPrefix: 'T'});
+    await collection.mint(alice, {Substrate: alice.address}, 10n);
+
+    await collection.burnTokens(alice, 10n);
+    await collection.burn(alice);
+
+    await expect(collection.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
+  
+  itSub.ifWithPallets('[refungible] Transfer with deleted collection_id', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-1-RFT', description: '', tokenPrefix: 'T'});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
+
+    await rft.burn(alice, 10n);
+    await collection.burn(alice);
 
-  it('[fungible] Transfer with deleted collection_id', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
-    await destroyCollectionExpectSuccess(fungibleCollectionId);
-    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
+    await expect(rft.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('[refungible] Transfer with deleted collection_id', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
-
-    const reFungibleCollectionId = await
-    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
-    await destroyCollectionExpectSuccess(reFungibleCollectionId);
-    await transferExpectFailure(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      alice,
-      bob,
-      1,
-    );
+  itSub('[nft] Transfer with not existed item_id', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-2-NFT', description: '', tokenPrefix: 'T'});
+    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenNotFound/);
   });
 
-  it('[nft] Transfer with not existed item_id', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);
+  itSub('[fungible] Transfer with not existed item_id', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-2-FT', description: '', tokenPrefix: 'T'});
+    await expect(collection.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[fungible] Transfer with not existed item_id', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);
+  itSub.ifWithPallets('[refungible] Transfer with not existed item_id', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-2-RFT', description: '', tokenPrefix: 'T'});
+    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[refungible] Transfer with not existed item_id', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub('[nft] Transfer with deleted item_id', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
+
+    await nft.burn(alice);
 
-    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await transferExpectFailure(
-      reFungibleCollectionId,
-      2,
-      alice,
-      bob,
-      1,
-    );
+    await expect(nft.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenNotFound/);
   });
 
-  it('[nft] Transfer with deleted item_id', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
-    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
-  });
+  itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});
+    await collection.mint(alice, {Substrate: alice.address}, 10n);
+
+    await collection.burnTokens(alice, 10n);
 
-  it('[fungible] Transfer with deleted item_id', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
-    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
+    await expect(collection.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[refungible] Transfer with deleted item_id', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
+
+    await rft.burn(alice, 10n);
 
-    const reFungibleCollectionId = await
-    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
-    await transferExpectFailure(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      alice,
-      bob,
-      1,
-    );
+    await expect(rft.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[nft] Transfer with recipient that is not owner', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);
+  itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});
+    const nft = await collection.mintToken(alice, {Substrate: alice.address});
+
+    await expect(nft.transfer(bob, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.NoPermission/);
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
   });
 
-  it('[fungible] Transfer with recipient that is not owner', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);
+  itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});
+    await collection.mint(alice, {Substrate: alice.address}, 10n);
+
+    await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);
   });
 
-  it('[refungible] Transfer with recipient that is not owner', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});
+    const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
 
-    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await transferExpectFailure(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      charlie,
-      bob,
-      1,
-    );
+    await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);
   });
 });
 
-describe('Zero value transfer(From)', () => {
-  before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+describe('Transfers to self (potentially over substrate-evm boundary)', () => {
+  let donor: IKeyringPair;
+
+  before(async function() {
+    await usingEthPlaygrounds(async (_, privateKey) => {
+      donor = privateKey('//Alice');
     });
   });
+  
+  itEth('Transfers to self. In case of same frontend', async ({helper}) => {
+    const [owner] = await helper.arrange.createAccounts([10n], donor);
+    const collection = await helper.ft.mintCollection(owner, {});
+    await collection.mint(owner, {Substrate: owner.address}, 100n);
 
-  it('NFT', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+    const ownerProxy = helper.address.substrateToEth(owner.address);
 
-      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), nftCollectionId, newNftTokenId, 0);
-      await submitTransactionAsync(alice, transferTx);
-      const address = normalizeAccountId(await getTokenOwner(api, nftCollectionId, newNftTokenId));
+    // transfer to own proxy
+    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
+    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
 
-      expect(toSubstrateAddress(address)).to.be.equal(alice.address);
-    });
+    // transfer-from own proxy to own proxy again
+    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
+    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
   });
 
-  it('RFT', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {
+    const [owner] = await helper.arrange.createAccounts([10n], donor);
+    const collection = await helper.ft.mintCollection(owner, {});
+    await collection.mint(owner, {Substrate: owner.address}, 100n);
 
-    await usingApi(async (api: ApiPromise) => {
-      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      const balanceBeforeAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);
-      const balanceBeforeBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);
-
-      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), reFungibleCollectionId, newReFungibleTokenId, 0);
-      await submitTransactionAsync(alice, transferTx);
+    const ownerProxy = helper.address.substrateToEth(owner.address);
 
-      const balanceAfterAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);
-      const balanceAfterBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);
+    // transfer to own proxy
+    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
+    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
 
-      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);
-      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);
-    });
+    // transfer-from own proxy to self
+    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);
+    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);
   });
-
-  it('Fungible', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      const balanceBeforeAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);
-      const balanceBeforeBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);
-
-      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), fungibleCollectionId, newFungibleTokenId, 0);
-      await submitTransactionAsync(alice, transferTx);
 
-      const balanceAfterAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);
-      const balanceAfterBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);
+  itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {
+    const [owner] = await helper.arrange.createAccounts([10n], donor);
+    const collection = await helper.ft.mintCollection(owner, {});
+    await collection.mint(owner, {Substrate: owner.address}, 100n);
 
-      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);
-      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);
-    });
-  });
-});
+    // transfer to self again
+    await collection.transfer(owner, {Substrate: owner.address}, 10n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);
 
-describe('Transfers to self (potentially over substrate-evm boundary)', () => {
-  itWeb3('Transfers to self. In case of same frontend', async ({api, privateKeyWrapper}) => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const aliceProxy = subToEth(alice.address);
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
-    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, 10, 'Fungible');
-    const balanceAliceBefore = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);
-    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, {Ethereum: aliceProxy}, 10, 'Fungible');
-    const balanceAliceAfter = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);
-    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
+    // transfer-from self to self again
+    await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);
   });
 
-  itWeb3('Transfers to self. In case of substrate-evm boundary', async ({api, privateKeyWrapper}) => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const aliceProxy = subToEth(alice.address);
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
-    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy} , 10, 'Fungible');
-    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, alice, 10, 'Fungible');
-    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
-  });
+  itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {
+    const [owner] = await helper.arrange.createAccounts([10n], donor);
+    const collection = await helper.ft.mintCollection(owner, {});
+    await collection.mint(owner, {Substrate: owner.address}, 10n);
 
-  itWeb3('Transfers to self. In case of inside substrate-evm', async ({api, privateKeyWrapper}) => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
-    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    await transferExpectSuccess(collectionId, tokenId, alice, alice , 10, 'Fungible');
-    await transferFromExpectSuccess(collectionId, tokenId, alice, alice, alice, 10, 'Fungible');
-    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
-  });
+    // transfer to self again
+    await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
 
-  itWeb3('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({api, privateKeyWrapper}) => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
-    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    await transferExpectFailure(collectionId, tokenId, alice, alice , 11);
-    await transferFromExpectFail(collectionId, tokenId, alice, alice, alice, 11);
-    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
+    // transfer-from self to self again
+    await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);
   });
 });
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {ApiPromise} from '@polkadot/api';
18import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
19import chai from 'chai';18import chai from 'chai';
20import chaiAsPromised from 'chai-as-promised';19import chaiAsPromised from 'chai-as-promised';
21import {default as usingApi} from './substrate/substrate-api';20import {itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
22import {
23 approveExpectFail,
24 approveExpectSuccess,
25 createCollectionExpectSuccess,
26 createFungibleItemExpectSuccess,
27 createItemExpectSuccess,
28 getAllowance,
29 transferFromExpectFail,
30 transferFromExpectSuccess,
31 burnItemExpectSuccess,
32 setCollectionLimitsExpectSuccess,
33 getCreatedCollectionCount,
34 requirePallets,
35 Pallets,
36} from './util/helpers';
3721
38chai.use(chaiAsPromised);22chai.use(chaiAsPromised);
39const expect = chai.expect;23const expect = chai.expect;
44 let charlie: IKeyringPair;28 let charlie: IKeyringPair;
4529
46 before(async () => {30 before(async () => {
47 await usingApi(async (api, privateKeyWrapper) => {31 await usingPlaygrounds(async (helper, privateKey) => {
48 alice = privateKeyWrapper('//Alice');32 const donor = privateKey('//Alice');
49 bob = privateKeyWrapper('//Bob');33 [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
50 charlie = privateKeyWrapper('//Charlie');
51 });34 });
52 });35 });
5336
54 it('[nft] Execute the extrinsic and check nftItemList - owner of token', async () => {37 itSub('[nft] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
55 const nftCollectionId = await createCollectionExpectSuccess();38 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-1', description: '', tokenPrefix: 'TF'});
56 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');39 const nft = await collection.mintToken(alice, {Substrate: alice.address});
57 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);40 await nft.approve(alice, {Substrate: bob.address});
41 expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
5842
59 await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');43 await nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address});
44 expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
60 });45 });
6146
62 it('[fungible] Execute the extrinsic and check nftItemList - owner of token', async () => {47 itSub('[fungible] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
63 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});48 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-2', description: '', tokenPrefix: 'TF'});
64 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');49 await collection.mint(alice, {Substrate: alice.address}, 10n);
50 await collection.approveTokens(alice, {Substrate: bob.address}, 7n);
65 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);51 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
66 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');52
53 await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
54 expect(await collection.getBalance({Substrate: charlie.address})).to.be.equal(6n);
55 expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(4n);
56 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
67 });57 });
6858
69 it('[refungible] Execute the extrinsic and check nftItemList - owner of token', async function() {59 itSub.ifWithPallets('[refungible] Execute the extrinsic and check nftItemList - owner of token', [Pallets.ReFungible], async ({helper}) => {
70 await requirePallets(this, [Pallets.ReFungible]);60 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-3', description: '', tokenPrefix: 'TF'});
71
72 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
73 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');61 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
74 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);62 await rft.approve(alice, {Substrate: bob.address}, 7n);
75 await transferFromExpectSuccess(63 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
76 reFungibleCollectionId,
77 newReFungibleTokenId,64
78 bob,65 await rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
79 alice,
80 charlie,66 expect(await rft.getBalance({Substrate: charlie.address})).to.be.equal(6n);
81 100,67 expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(4n);
82 'ReFungible',68 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
83 );
84 });69 });
8570
86 it('Should reduce allowance if value is big', async () => {71 itSub('Should reduce allowance if value is big', async ({helper}) => {
87 await usingApi(async (api, privateKeyWrapper) => {72 // fungible
88 const alice = privateKeyWrapper('//Alice');73 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-4', description: '', tokenPrefix: 'TF'});
89 const bob = privateKeyWrapper('//Bob');
90 const charlie = privateKeyWrapper('//Charlie');74 await collection.mint(alice, {Substrate: alice.address}, 500000n);
9175
92 // fungible76 await collection.approveTokens(alice, {Substrate: bob.address}, 500000n);
93 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
94 const newFungibleTokenId = await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: 500000n});77 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(500000n);
95
96 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 500000n);
97 await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 500000n, 'Fungible');78 await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 500000n);
98 expect(await getAllowance(api, fungibleCollectionId, alice.address, bob.address, newFungibleTokenId)).to.equal(0n);79 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(0n);
99 });
100 });80 });
10181
102 it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {82 itSub('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async ({helper}) => {
103 const collectionId = await createCollectionExpectSuccess();83 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-5', description: '', tokenPrefix: 'TF'});
104 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
105 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);84 await collection.setLimits(alice, {ownerCanTransfer: true});
10685
107 await transferFromExpectSuccess(collectionId, itemId, alice, bob, charlie);86 const nft = await collection.mintToken(alice, {Substrate: bob.address});
87 await nft.transferFrom(alice, {Substrate: bob.address}, {Substrate: charlie.address});
88 expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
108 });89 });
109});90});
11091
114 let charlie: IKeyringPair;95 let charlie: IKeyringPair;
11596
116 before(async () => {97 before(async () => {
117 await usingApi(async (api, privateKeyWrapper) => {98 await usingPlaygrounds(async (helper, privateKey) => {
118 alice = privateKeyWrapper('//Alice');99 const donor = privateKey('//Alice');
119 bob = privateKeyWrapper('//Bob');100 [alice, bob, charlie] = await helper.arrange.createAccounts([50n, 10n, 10n], donor);
120 charlie = privateKeyWrapper('//Charlie');
121 });101 });
122 });102 });
123103
124 it('[nft] transferFrom for a collection that does not exist', async () => {104 itSub('transferFrom for a collection that does not exist', async ({helper}) => {
125 await usingApi(async (api: ApiPromise) => {105 const collectionId = (1 << 32) - 1;
126 const nftCollectionCount = await getCreatedCollectionCount(api);106 await expect(helper.collection.approveToken(alice, collectionId, 0, {Substrate: bob.address}, 1n))
127 await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);107 .to.be.rejectedWith(/common\.CollectionNotFound/);
128
129 await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);108 await expect(helper.collection.transferTokenFrom(bob, collectionId, 0, {Substrate: alice.address}, {Substrate: bob.address}, 1n))
130 });109 .to.be.rejectedWith(/common\.CollectionNotFound/);
131 });110 });
132111
133 it('[fungible] transferFrom for a collection that does not exist', async () => {112 /* itSub('transferFrom for a collection that was destroyed', async ({helper}) => {
134 await usingApi(async (api: ApiPromise) => {
135 const fungibleCollectionCount = await getCreatedCollectionCount(api);113 this test copies approve negative test
136 await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);114 }); */
137115
138 await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);116 /* itSub('transferFrom a token that does not exist', async ({helper}) => {
117 this test copies approve negative test
118 }); */
119
120 /* itSub('transferFrom a token that was deleted', async ({helper}) => {
121 this test copies approve negative test
122 }); */
123
124 itSub('[nft] transferFrom for not approved address', async ({helper}) => {
125 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
126 const nft = await collection.mintToken(alice, {Substrate: alice.address});
127
128 await expect(nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
129 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
139 });130 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
140 });131 });
141132
142 it('[refungible] transferFrom for a collection that does not exist', async function() {133 itSub('[fungible] transferFrom for not approved address', async ({helper}) => {
143 await requirePallets(this, [Pallets.ReFungible]);134 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
135 await collection.mint(alice, {Substrate: alice.address}, 10n);
144136
145 await usingApi(async (api: ApiPromise) => {137 await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
146 const reFungibleCollectionCount = await getCreatedCollectionCount(api);138 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
139 expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
147 await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);140 expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
141 expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
142 });
148143
149 await transferFromExpectFail(reFungibleCollectionCount + 1, 1, bob, alice, charlie, 1);144 itSub.ifWithPallets('[refungible] transferFrom for not approved address', [Pallets.ReFungible], async({helper}) => {
145 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-3', description: '', tokenPrefix: 'TF'});
146 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
147
148 await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
149 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
150 });150 expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
151 expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
152 expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
151 });153 });
152154
153 /* it('transferFrom for a collection that was destroyed', async () => {155 itSub('[nft] transferFrom incorrect token count', async ({helper}) => {
154 await usingApi(async (api: ApiPromise) => {156 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-4', description: '', tokenPrefix: 'TF'});
155 this test copies approve negative test157 const nft = await collection.mintToken(alice, {Substrate: alice.address});
156 });
157 }); */
158158
159 /* it('transferFrom a token that does not exist', async () => {159 await nft.approve(alice, {Substrate: bob.address});
160 await usingApi(async (api: ApiPromise) => {160 expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
161 this test copies approve negative test
162 });
163 }); */
164161
165 /* it('transferFrom a token that was deleted', async () => {162 await expect(helper.collection.transferTokenFrom(
163 bob,
164 collection.collectionId,
166 await usingApi(async (api: ApiPromise) => {165 nft.tokenId,
166 {Substrate: alice.address},
167 this test copies approve negative test167 {Substrate: charlie.address},
168 2n,
168 });169 )).to.be.rejectedWith(/nonfungible\.NonfungibleItemsHaveNoAmount/);
170 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
169 }); */171 });
170172
171 it('[nft] transferFrom for not approved address', async () => {173 itSub('[fungible] transferFrom incorrect token count', async ({helper}) => {
172 const nftCollectionId = await createCollectionExpectSuccess();174 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-5', description: '', tokenPrefix: 'TF'});
173 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');175 await collection.mint(alice, {Substrate: alice.address}, 10n);
174176
175 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);177 await collection.approveTokens(alice, {Substrate: bob.address}, 2n);
178 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(2n);
179
180 await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
181 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
182 expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
183 expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
184 expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
176 });185 });
177186
178 it('[fungible] transferFrom for not approved address', async () => {187 itSub.ifWithPallets('[refungible] transferFrom incorrect token count', [Pallets.ReFungible], async ({helper}) => {
179 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});188 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-6', description: '', tokenPrefix: 'TF'});
180 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');189 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
190
181 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);191 await rft.approve(alice, {Substrate: bob.address}, 5n);
192 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(5n);
193
194 await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 7n))
195 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
196 expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
197 expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
198 expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
182 });199 });
183200
184 it('[refungible] transferFrom for not approved address', async function() {201 itSub('[nft] execute transferFrom from account that is not owner of collection', async ({helper}) => {
185 await requirePallets(this, [Pallets.ReFungible]);202 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-7', description: '', tokenPrefix: 'TF'});
203 const nft = await collection.mintToken(alice, {Substrate: alice.address});
186204
187 const reFungibleCollectionId = await205 await expect(nft.approve(charlie, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
188 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
189 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');206 expect(await nft.isApproved({Substrate: bob.address})).to.be.false;
207
190 await transferFromExpectFail(208 await expect(nft.transferFrom(
191 reFungibleCollectionId,
192 newReFungibleTokenId,
193 bob,
194 alice,
195 charlie,209 charlie,
196 1,210 {Substrate: alice.address},
197 );211 {Substrate: charlie.address},
212 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
213 expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
198 });214 });
199215
200 it('[nft] transferFrom incorrect token count', async () => {216 itSub('[fungible] execute transferFrom from account that is not owner of collection', async ({helper}) => {
201 const nftCollectionId = await createCollectionExpectSuccess();217 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-8', description: '', tokenPrefix: 'TF'});
202 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
203 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);218 await collection.mint(alice, {Substrate: alice.address}, 10000n);
204219
205 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);220 await expect(collection.approveTokens(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
221 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
206 });222 expect(await collection.getApprovedTokens({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
207223
208 it('[fungible] transferFrom incorrect token count', async () => {224 await expect(collection.transferFrom(
225 charlie,
209 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});226 {Substrate: alice.address},
227 {Substrate: charlie.address},
228 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
210 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');229 expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
211 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);230 expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
212 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);231 expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
213 });232 });
214233
215 it('[refungible] transferFrom incorrect token count', async function() {234 itSub.ifWithPallets('[refungible] execute transferFrom from account that is not owner of collection', [Pallets.ReFungible], async ({helper}) => {
216 await requirePallets(this, [Pallets.ReFungible]);235 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-9', description: '', tokenPrefix: 'TF'});
236 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10000n);
217237
218 const reFungibleCollectionId = await238 await expect(rft.approve(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
219 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
220 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');239 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
221 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);240 expect(await rft.getApprovedPieces({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
241
222 await transferFromExpectFail(242 await expect(rft.transferFrom(
223 reFungibleCollectionId,
224 newReFungibleTokenId,
225 bob,
226 alice,
227 charlie,243 charlie,
228 2,244 {Substrate: alice.address},
229 );245 {Substrate: charlie.address},
246 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
247 expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
248 expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
249 expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
230 });250 });
231251
232 it('[nft] execute transferFrom from account that is not owner of collection', async () => {252 itSub('transferFrom burnt token before approve NFT', async ({helper}) => {
233 await usingApi(async (api, privateKeyWrapper) => {
234 const dave = privateKeyWrapper('//Dave');253 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-10', description: '', tokenPrefix: 'TF'});
235 const nftCollectionId = await createCollectionExpectSuccess();
236 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
237 try {254 await collection.setLimits(alice, {ownerCanTransfer: true});
238 await approveExpectFail(nftCollectionId, newNftTokenId, dave, bob);
239 await transferFromExpectFail(nftCollectionId, newNftTokenId, dave, alice, charlie, 1);255 const nft = await collection.mintToken(alice, {Substrate: alice.address});
240 } catch (e) {
241 // tslint:disable-next-line:no-unused-expression
242 expect(e).to.be.exist;
243 }
244256
245 // await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);257 await nft.burn(alice);
258 await expect(nft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.TokenNotFound/);
259
260 await expect(nft.transferFrom(
261 bob,
262 {Substrate: alice.address},
246 });263 {Substrate: charlie.address},
264 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
247 });265 });
248266
249 it('[fungible] execute transferFrom from account that is not owner of collection', async () => {267 itSub('transferFrom burnt token before approve Fungible', async ({helper}) => {
250 await usingApi(async (api, privateKeyWrapper) => {268 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-11', description: '', tokenPrefix: 'TF'});
269 await collection.setLimits(alice, {ownerCanTransfer: true});
251 const dave = privateKeyWrapper('//Dave');270 await collection.mint(alice, {Substrate: alice.address}, 10n);
252271
253 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});272 await collection.burnTokens(alice, 10n);
254 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');273 await expect(collection.approveTokens(alice, {Substrate: bob.address})).to.be.not.rejected;
255 try {274
256 await approveExpectFail(fungibleCollectionId, newFungibleTokenId, dave, bob);275 await expect(collection.transferFrom(
257 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, dave, alice, charlie, 1);276 alice,
258 } catch (e) {277 {Substrate: alice.address},
259 // tslint:disable-next-line:no-unused-expression278 {Substrate: charlie.address},
260 expect(e).to.be.exist;279 )).to.be.rejectedWith(/common\.TokenValueTooLow/);
261 }
262 });
263 });280 });
264281
265 it('[refungible] execute transferFrom from account that is not owner of collection', async function() {282 itSub.ifWithPallets('transferFrom burnt token before approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
283 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-12', description: '', tokenPrefix: 'TF'});
284 await collection.setLimits(alice, {ownerCanTransfer: true});
266 await requirePallets(this, [Pallets.ReFungible]);285 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
267286
268 await usingApi(async (api, privateKeyWrapper) => {287 await rft.burn(alice, 10n);
269 const dave = privateKeyWrapper('//Dave');
270 const reFungibleCollectionId = await288 await expect(rft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
271 createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
272 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
273 try {
274 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, bob);
275 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, alice, charlie, 1);
276 } catch (e) {
277 // tslint:disable-next-line:no-unused-expression
278 expect(e).to.be.exist;
279 }
280 });
281 });
282 it('transferFrom burnt token before approve NFT', async () => {
283 await usingApi(async () => {
284 // nft
285 const nftCollectionId = await createCollectionExpectSuccess();
286 await setCollectionLimitsExpectSuccess(alice, nftCollectionId, {ownerCanTransfer: true});
287 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
288 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
289 await approveExpectFail(nftCollectionId, newNftTokenId, alice, bob);
290 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
291 });
292 });
293 it('transferFrom burnt token before approve Fungible', async () => {
294 await usingApi(async () => {
295 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
296 await setCollectionLimitsExpectSuccess(alice, fungibleCollectionId, {ownerCanTransfer: true});
297 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
298 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
299 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
300 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
301289
302 });290 await expect(rft.transferFrom(
291 alice,
292 {Substrate: alice.address},
293 {Substrate: charlie.address},
294 )).to.be.rejectedWith(/common\.TokenValueTooLow/);
303 });295 });
304 it('transferFrom burnt token before approve ReFungible', async function() {
305 await requirePallets(this, [Pallets.ReFungible]);
306296
307 await usingApi(async () => {297 itSub('transferFrom burnt token after approve NFT', async ({helper}) => {
308 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});298 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-13', description: '', tokenPrefix: 'TF'});
309 await setCollectionLimitsExpectSuccess(alice, reFungibleCollectionId, {ownerCanTransfer: true});
310 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');299 const nft = await collection.mintToken(alice, {Substrate: alice.address});
311 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
312 await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, alice, bob);
313 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
314300
315 });301 await nft.approve(alice, {Substrate: bob.address});
316 });302 expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
317303
318 it('transferFrom burnt token after approve NFT', async () => {304 await nft.burn(alice);
319 await usingApi(async () => {305
320 // nft
321 const nftCollectionId = await createCollectionExpectSuccess();306 await expect(nft.transferFrom(
322 const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');307 bob,
323 await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);308 {Substrate: alice.address},
324 await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
325 await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);309 {Substrate: charlie.address},
326 });310 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
327 });311 });
328 it('transferFrom burnt token after approve Fungible', async () => {
329 await usingApi(async () => {
330 const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
331 const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
332 await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
333 await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
334 await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
335312
336 });313 itSub('transferFrom burnt token after approve Fungible', async ({helper}) => {
314 const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-14', description: '', tokenPrefix: 'TF'});
315 await collection.mint(alice, {Substrate: alice.address}, 10n);
316
317 await collection.approveTokens(alice, {Substrate: bob.address});
318 expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(1n);
319
320 await collection.burnTokens(alice, 10n);
321
322 await expect(collection.transferFrom(
323 bob,
324 {Substrate: alice.address},
325 {Substrate: charlie.address},
326 )).to.be.rejectedWith(/common\.TokenValueTooLow/);
337 });327 });
338 it('transferFrom burnt token after approve ReFungible', async function() {
339 await requirePallets(this, [Pallets.ReFungible]);
340328
341 await usingApi(async () => {329 itSub.ifWithPallets('transferFrom burnt token after approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
342 const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});330 const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-15', description: '', tokenPrefix: 'TF'});
343 const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
344 await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
345 await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);331 const rft = await collection.mintToken(alice, {Substrate: alice.address}, 10n);
346 await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
347332
348 });333 await rft.approve(alice, {Substrate: bob.address}, 10n);
334 expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(10n);
335
336 await rft.burn(alice, 10n);
337
338 await expect(rft.transferFrom(
339 bob,
340 {Substrate: alice.address},
341 {Substrate: charlie.address},
342 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
349 });343 });
350344
351 it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {345 itSub('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async ({helper}) => {
352 const collectionId = await createCollectionExpectSuccess();346 const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-16', description: '', tokenPrefix: 'TF'});
353 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
354 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});347 const nft = await collection.mintToken(alice, {Substrate: bob.address});
355348
356 await transferFromExpectFail(collectionId, itemId, alice, bob, charlie);349 await collection.setLimits(alice, {ownerCanTransfer: false});
350
351 await expect(nft.transferFrom(
352 alice,
353 {Substrate: bob.address},
354 {Substrate: charlie.address},
355 )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
357 });356 });
358});357});
359358
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;