git.delta.rocks / unique-network / refs/commits / b0a74de7457b

difftreelog

Mint tests generalization

Max Andreev2023-01-13parent: #8a76dd7.patch.diff
in: master

8 files changed

deletedtests/src/eth/collections/callMethodsERC20.test.tsdiffbeforeafterboth
--- a/tests/src/eth/collections/callMethodsERC20.test.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-import {Pallets, requirePalletsOrSkip} from '../../util';
-import {expect, itEth, usingEthPlaygrounds} from '../util';
-import {IKeyringPair} from '@polkadot/types/types';
-
-[
-  {mode: 'ft' as const, requiredPallets: []},
-  {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
-].map(testCase => {
-  describe(`${testCase.mode.toUpperCase()}: ERC-20 call methods`, () => {
-    let donor: IKeyringPair;
-
-    before(async function() {
-      await usingEthPlaygrounds(async (helper, privateKey) => {
-        requirePalletsOrSkip(this, helper, testCase.requiredPallets);
-        donor = await privateKey({filename: __filename});
-      });
-    });
-
-    itEth('totalSupply', async ({helper}) => {
-      const caller = await helper.eth.createAccountWithBalance(donor);
-      const mintingParams = testCase.mode === 'ft' ? [caller, 200n] : [caller];
-
-      const {collection, collectionId} = await helper.eth.createCollection(testCase.mode, caller, 'TotalSupply', '6', '6');
-      if (testCase.mode === 'rft') await collection.methods.mint(caller).send({from: caller});
-
-      // Use collection contract for FT or token contract for RFT:
-      const contract = testCase.mode === 'ft'
-        ? collection
-        : await helper.ethNativeContract.rftTokenById(collectionId, 1, caller);
-
-      // Mint tokens:
-      testCase.mode === 'ft'
-        ? await contract.methods.mint(...mintingParams).send({from: caller})
-        : await contract.methods.repartition(200).send({from: caller});
-
-      const totalSupply = await contract.methods.totalSupply().call();
-      expect(totalSupply).to.equal('200');
-    });
-
-    itEth('balanceOf', async ({helper}) => {
-      const caller = await helper.eth.createAccountWithBalance(donor);
-      const mintingParams = testCase.mode === 'ft' ? [caller, 200n] : [caller];
-
-      const {collection, collectionId} = await helper.eth.createCollection(testCase.mode, caller, 'BalanceOf', 'Descroption', 'Prefix');
-      if (testCase.mode === 'rft') await collection.methods.mint(caller).send({from: caller});
-
-      // Use collection contract for FT or token contract for RFT:
-      const contract = testCase.mode === 'ft'
-        ? collection
-        : await helper.ethNativeContract.rftTokenById(collectionId, 1, caller);
-
-      // Mint tokens:
-      testCase.mode === 'ft'
-        ? await contract.methods.mint(...mintingParams).send({from: caller})
-        : await contract.methods.repartition(200).send({from: caller});
-
-      const balance = await contract.methods.balanceOf(caller).call();
-      expect(balance).to.equal('200');
-    });
-
-    itEth('decimals', async ({helper}) => {
-      const caller = await helper.eth.createAccountWithBalance(donor);
-      const {collection, collectionId} = await helper.eth.createCollection(testCase.mode, caller, 'BalanceOf', 'Descroption', 'Prefix');
-      if (testCase.mode === 'rft') await collection.methods.mint(caller).send({from: caller});
-
-      // Use collection contract for FT or token contract for RFT:
-      const contract = testCase.mode === 'ft'
-        ? collection
-        : await helper.ethNativeContract.rftTokenById(collectionId, 1, caller);
-
-      const decimals = await contract.methods.decimals().call();
-      expect(decimals).to.equal(testCase.mode === 'rft' ? '0' : '18');
-    });
-  });
-});
\ No newline at end of file
deletedtests/src/eth/collections/callMethodsERC721.test.tsdiffbeforeafterboth

no changes

modifiedtests/src/eth/fungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -29,24 +29,6 @@
     });
   });
 
-  itEth('Can perform mint()', async ({helper}) => {
-    const owner = await helper.eth.createAccountWithBalance(donor);
-    const receiver = helper.eth.createAccount();
-    const collection = await helper.ft.mintCollection(alice);
-    await collection.addAdmin(alice, {Ethereum: owner});
-
-    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
-    const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
-
-    const result = await contract.methods.mint(receiver, 100).send();
-
-    const event = result.events.Transfer;
-    expect(event.address).to.equal(collectionAddress);
-    expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
-    expect(event.returnValues.to).to.equal(receiver);
-    expect(event.returnValues.value).to.equal('100');
-  });
-
   [
     'substrate' as const,
     'ethereum' as const,
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -88,30 +88,6 @@
     });
   });
 
-  itEth('Can perform mint() & get crossOwner()', async ({helper}) => {
-    const owner = await helper.eth.createAccountWithBalance(donor);
-    const receiver = helper.eth.createAccount();
-
-    const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', '6', '6', '');
-    const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
-
-    const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();
-    const tokenId = result.events.Transfer.returnValues.tokenId;
-    expect(tokenId).to.be.equal('1');
-
-    const event = result.events.Transfer;
-    expect(event.address).to.be.equal(collectionAddress);
-    expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
-    expect(event.returnValues.to).to.be.equal(receiver);
-
-    expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
-    expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
-    // TODO: this wont work right now, need release 919000 first
-    // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();
-    // const tokenUri = await contract.methods.tokenURI(nextTokenId).call();
-    // expect(tokenUri).to.be.equal(`https://offchain-service.local/token-info/${nextTokenId}`);
-  });
-
   // TODO combine all minting tests in one place
   [
     'substrate' as const,
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -34,25 +34,6 @@
     });
   });
 
-  itEth('Can perform mint() & crossOwnerOf()', async ({helper}) => {
-    const owner = await helper.eth.createAccountWithBalance(donor);
-    const receiver = helper.eth.createAccount();
-    const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Minty', '6', '6', '');
-    const contract = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
-
-    const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();
-
-    const event = result.events.Transfer;
-    expect(event.address).to.equal(collectionAddress);
-    expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
-    expect(event.returnValues.to).to.equal(receiver);
-    const tokenId = event.returnValues.tokenId;
-    expect(tokenId).to.be.equal('1');
-
-    expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
-    expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
-  });
-
   [
     'substrate' as const,
     'ethereum' as const,
addedtests/src/eth/tokens/callMethodsERC20.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/tokens/callMethodsERC20.test.ts
@@ -0,0 +1,91 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+import {Pallets, requirePalletsOrSkip} from '../../util';
+import {expect, itEth, usingEthPlaygrounds} from '../util';
+import {IKeyringPair} from '@polkadot/types/types';
+
+[
+  {mode: 'ft' as const, requiredPallets: []},
+  {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+].map(testCase => {
+  describe(`${testCase.mode.toUpperCase()}: ERC-20 call methods`, () => {
+    let donor: IKeyringPair;
+
+    before(async function() {
+      await usingEthPlaygrounds(async (helper, privateKey) => {
+        requirePalletsOrSkip(this, helper, testCase.requiredPallets);
+        donor = await privateKey({filename: __filename});
+      });
+    });
+
+    itEth('totalSupply', async ({helper}) => {
+      const caller = await helper.eth.createAccountWithBalance(donor);
+      const mintingParams = testCase.mode === 'ft' ? [caller, 200n] : [caller];
+
+      const {collection, collectionId} = await helper.eth.createCollection(testCase.mode, caller, 'TotalSupply', '6', '6');
+      if (testCase.mode === 'rft') await collection.methods.mint(caller).send({from: caller});
+
+      // Use collection contract for FT or token contract for RFT:
+      const contract = testCase.mode === 'ft'
+        ? collection
+        : await helper.ethNativeContract.rftTokenById(collectionId, 1, caller);
+
+      // Mint tokens:
+      testCase.mode === 'ft'
+        ? await contract.methods.mint(...mintingParams).send({from: caller})
+        : await contract.methods.repartition(200).send({from: caller});
+
+      const totalSupply = await contract.methods.totalSupply().call();
+      expect(totalSupply).to.equal('200');
+    });
+
+    itEth('balanceOf', async ({helper}) => {
+      const caller = await helper.eth.createAccountWithBalance(donor);
+      const mintingParams = testCase.mode === 'ft' ? [caller, 200n] : [caller];
+
+      const {collection, collectionId} = await helper.eth.createCollection(testCase.mode, caller, 'BalanceOf', 'Descroption', 'Prefix');
+      if (testCase.mode === 'rft') await collection.methods.mint(caller).send({from: caller});
+
+      // Use collection contract for FT or token contract for RFT:
+      const contract = testCase.mode === 'ft'
+        ? collection
+        : await helper.ethNativeContract.rftTokenById(collectionId, 1, caller);
+
+      // Mint tokens:
+      testCase.mode === 'ft'
+        ? await contract.methods.mint(...mintingParams).send({from: caller})
+        : await contract.methods.repartition(200).send({from: caller});
+
+      const balance = await contract.methods.balanceOf(caller).call();
+      expect(balance).to.equal('200');
+    });
+
+    itEth('decimals', async ({helper}) => {
+      const caller = await helper.eth.createAccountWithBalance(donor);
+      const {collection, collectionId} = await helper.eth.createCollection(testCase.mode, caller, 'BalanceOf', 'Descroption', 'Prefix');
+      if (testCase.mode === 'rft') await collection.methods.mint(caller).send({from: caller});
+
+      // Use collection contract for FT or token contract for RFT:
+      const contract = testCase.mode === 'ft'
+        ? collection
+        : await helper.ethNativeContract.rftTokenById(collectionId, 1, caller);
+
+      const decimals = await contract.methods.decimals().call();
+      expect(decimals).to.equal(testCase.mode === 'rft' ? '0' : '18');
+    });
+  });
+});
\ No newline at end of file
addedtests/src/eth/tokens/callMethodsERC721.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/tokens/callMethodsERC721.test.ts
@@ -0,0 +1,143 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+import {Pallets} from '../../util';
+import {expect, itEth, usingEthPlaygrounds} from '../util';
+import {IKeyringPair} from '@polkadot/types/types';
+
+
+describe('ERC-721 call methods', () => {
+  let donor: IKeyringPair;
+
+  before(async function() {
+    await usingEthPlaygrounds(async (helper, privateKey) => {
+      donor = await privateKey({filename: __filename});
+    });
+  });
+
+  [
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+    {mode: 'nft' as const, requiredPallets: []},
+  ].map(testCase => {
+    itEth.ifWithPallets(`${testCase.mode.toUpperCase()}: name/symbol/description`, testCase.requiredPallets, async ({helper}) => {
+      const callerEth = await helper.eth.createAccountWithBalance(donor);
+      const [callerSub] = await helper.arrange.createAccounts([100n], donor);
+      const [name, description, tokenPrefix] = ['Name', 'Description', 'Symbol'];
+
+      const {collection: collectionEth} = await helper.eth.createCollection(testCase.mode, callerEth, name, description, tokenPrefix);
+      await collectionEth.methods.mint(callerEth).send({from: callerEth});
+      const {collectionId} = await helper[testCase.mode].mintCollection(callerSub, {name, description, tokenPrefix});
+      const collectionSub = await helper.ethNativeContract.collectionById(collectionId, testCase.mode, callerEth);
+
+      // Can get name/symbol/description for Eth collection
+      expect(await collectionEth.methods.name().call()).to.eq(name);
+      expect(await collectionEth.methods.symbol().call()).to.eq(tokenPrefix);
+      expect(await collectionEth.methods.description().call()).to.eq(description);
+      // Can get name/symbol/description for Sub collection
+      expect(await collectionSub.methods.name().call()).to.eq(name);
+      expect(await collectionSub.methods.symbol().call()).to.eq(tokenPrefix);
+      expect(await collectionSub.methods.description().call()).to.eq(description);
+    });
+  });
+
+  [
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+    {mode: 'nft' as const, requiredPallets: []},
+  ].map(testCase => {
+    itEth.ifWithPallets(`${testCase.mode.toUpperCase()}: totalSupply`, testCase.requiredPallets, async ({helper}) => {
+      const caller = await helper.eth.createAccountWithBalance(donor);
+
+      const {collection} = await helper.eth.createCollection(testCase.mode, caller, 'TotalSupply', '6', '6');
+      await collection.methods.mint(caller).send({from: caller});
+
+      const totalSupply = await collection.methods.totalSupply().call();
+      expect(totalSupply).to.equal('1');
+    });
+  });
+
+  [
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+    {mode: 'nft' as const, requiredPallets: []},
+  ].map(testCase => {
+    itEth.ifWithPallets(`${testCase.mode.toUpperCase()}: balanceOf`, testCase.requiredPallets, async ({helper}) => {
+      const caller = await helper.eth.createAccountWithBalance(donor);
+
+      const {collection} = await helper.eth.createCollection(testCase.mode, caller, 'BalanceOf', 'Descroption', 'Prefix');
+      await collection.methods.mint(caller).send({from: caller});
+      await collection.methods.mint(caller).send({from: caller});
+      await collection.methods.mint(caller).send({from: caller});
+
+      const balance = await collection.methods.balanceOf(caller).call();
+      expect(balance).to.equal('3');
+    });
+  });
+
+  [
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+    {mode: 'nft' as const, requiredPallets: []},
+  ].map(testCase => {
+    itEth.ifWithPallets(`${testCase.mode.toUpperCase()}: ownerOf`, testCase.requiredPallets, async ({helper}) => {
+      const caller = await helper.eth.createAccountWithBalance(donor);
+      const {collection} = await helper.eth.createCollection(testCase.mode, caller, 'OwnerOf', '6', '6');
+
+      const result = await collection.methods.mint(caller).send();
+      const tokenId = result.events.Transfer.returnValues.tokenId;
+
+      const owner = await collection.methods.ownerOf(tokenId).call();
+      expect(owner).to.equal(caller);
+    });
+  });
+
+  [
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+    // TODO {mode: 'nft' as const, requiredPallets: []},
+  ].map(testCase => {
+    itEth(`${testCase.mode.toUpperCase()}: ownerOf after burn`, async ({helper}) => {
+      const caller = await helper.eth.createAccountWithBalance(donor);
+      const receiver = helper.eth.createAccount();
+      const {collection, collectionId} = await helper.eth.createCollection(testCase.mode, caller, 'OwnerOf-AfterBurn', '6', '6');
+
+      const result = await collection.methods.mint(caller).send();
+      const tokenId = result.events.Transfer.returnValues.tokenId;
+      const tokenContract = await helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
+
+      await tokenContract.methods.repartition(2).send();
+      await tokenContract.methods.transfer(receiver, 1).send();
+
+      await tokenContract.methods.burnFrom(caller, 1).send();
+
+      const owner = await collection.methods.ownerOf(tokenId).call();
+      expect(owner).to.equal(receiver);
+    });
+  });
+
+  itEth('RFT: ownerOf for partial ownership', async ({helper}) => {
+    const caller = await helper.eth.createAccountWithBalance(donor);
+    const receiver = helper.eth.createAccount();
+    const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Partial-OwnerOf', '6', '6');
+    const contract = await helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
+
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
+    const tokenContract = await helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
+
+    await tokenContract.methods.repartition(2).send();
+    await tokenContract.methods.transfer(receiver, 1).send();
+
+    const owner = await contract.methods.ownerOf(tokenId).call();
+    expect(owner).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');
+  });
+});
addedtests/src/eth/tokens/minting.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/tokens/minting.test.ts
@@ -0,0 +1,167 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+import {IKeyringPair} from '@polkadot/types/types';
+import {Pallets} from '../../util';
+import {expect, itEth, usingEthPlaygrounds} from '../util';
+
+
+describe('Minting tokens', () => {
+  let donor: IKeyringPair;
+  let alice: IKeyringPair;
+
+  before(async function() {
+    await usingEthPlaygrounds(async (helper, privateKey) => {
+      donor = await privateKey({filename: __filename});
+      [alice] = await helper.arrange.createAccounts([30n, 20n], donor);
+    });
+  });
+
+  [
+    {mode: 'nft' as const, requiredPallets: []},
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+    {mode: 'ft' as const, requiredPallets: []},
+  ].map(testCase => {
+    itEth(`${testCase.mode.toUpperCase()}: Can mint() for Substrate collection`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+      const receiver = helper.eth.createAccount();
+      const mintingParams = testCase.mode === 'ft' ? [receiver, 100] : [receiver];
+
+      const collection = await helper[testCase.mode].mintCollection(alice);
+      await collection.addAdmin(alice, {Ethereum: owner});
+
+      const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+      const contract = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner);
+
+      const result = await contract.methods.mint(...mintingParams).send({from: owner});
+
+      // Check events:
+      const event = result.events.Transfer;
+      expect(event.address).to.equal(collectionAddress);
+      expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
+      expect(event.returnValues.to).to.equal(receiver);
+      if (testCase.mode === 'ft')
+        expect(event.returnValues.value).to.equal('100');
+
+      // Check token exist:
+      if(testCase.mode === 'ft') {
+        expect(await helper.ft.getBalance(collection.collectionId, {Ethereum: receiver})).to.eq(100n);
+      } else {
+        const tokenId = event.returnValues.tokenId;
+        expect(tokenId).to.be.equal('1');
+        expect(await helper.collection.getLastTokenId(collection.collectionId)).to.eq(1);
+        expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
+      }
+    });
+  });
+
+  [
+    {mode: 'nft' as const, requiredPallets: []},
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+    {mode: 'ft' as const, requiredPallets: []},
+  ].map(testCase => {
+    itEth(`${testCase.mode.toUpperCase()}: Can mint() for Ethereum collection`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+      const receiver = helper.eth.createAccount();
+      const mintingParams = testCase.mode === 'ft' ? [receiver, 100] : [receiver];
+
+      const {collection, collectionAddress, collectionId} = await helper.eth.createCollection(testCase.mode, owner, 'Name', 'Desc', 'Prefix');
+
+      const result = await collection.methods.mint(...mintingParams).send({from: owner});
+
+      // Check events:
+      const event = result.events.Transfer;
+      expect(event.address).to.equal(collectionAddress);
+      expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
+      expect(event.returnValues.to).to.equal(receiver);
+      if (testCase.mode === 'ft')
+        expect(event.returnValues.value).to.equal('100');
+
+      // Check token exist:
+      if(testCase.mode === 'ft') {
+        expect(await helper.ft.getBalance(collectionId, {Ethereum: receiver})).to.eq(100n);
+      } else {
+        const tokenId = event.returnValues.tokenId;
+        expect(tokenId).to.be.equal('1');
+        expect(await helper.collection.getLastTokenId(collectionId)).to.eq(1);
+        expect(await collection.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
+      }
+    });
+  });
+
+  [
+    {mode: 'nft' as const, requiredPallets: []},
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+    {mode: 'ft' as const, requiredPallets: []},
+  ].map(testCase => {
+    itEth(`${testCase.mode.toUpperCase()}: Can mint() for Ethereum collection`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+      const receiver = helper.eth.createAccount();
+      const mintingParams = testCase.mode === 'ft' ? [receiver, 100] : [receiver];
+
+      const {collection, collectionAddress, collectionId} = await helper.eth.createCollection(testCase.mode, owner, 'Name', 'Desc', 'Prefix');
+
+      const result = await collection.methods.mint(...mintingParams).send({from: owner});
+
+      // Check events:
+      const event = result.events.Transfer;
+      expect(event.address).to.equal(collectionAddress);
+      expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
+      expect(event.returnValues.to).to.equal(receiver);
+      if (testCase.mode === 'ft')
+        expect(event.returnValues.value).to.equal('100');
+
+      // Check token exist:
+      if(testCase.mode === 'ft') {
+        expect(await helper.ft.getBalance(collectionId, {Ethereum: receiver})).to.eq(100n);
+      } else {
+        const tokenId = event.returnValues.tokenId;
+        expect(tokenId).to.be.equal('1');
+        expect(await helper.collection.getLastTokenId(collectionId)).to.eq(1);
+        expect(await collection.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
+      }
+    });
+  });
+
+  [
+    {mode: 'nft' as const, requiredPallets: []},
+    {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},
+  ].map(testCase => {
+    itEth(`${testCase.mode.toUpperCase()}: Can mintWithTokenURI() for Ethereum collection`, async ({helper}) => {
+      const owner = await helper.eth.createAccountWithBalance(donor);
+      const receiver = helper.eth.createAccount();
+
+      const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', '6', '6', '');
+      const contract = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner);
+
+      const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();
+      const tokenId = result.events.Transfer.returnValues.tokenId;
+      expect(tokenId).to.be.equal('1');
+
+      const event = result.events.Transfer;
+      expect(event.address).to.be.equal(collectionAddress);
+      expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
+      expect(event.returnValues.to).to.be.equal(receiver);
+
+      expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
+      expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
+      // TODO: this wont work right now, need release 919000 first
+      // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();
+      // const tokenUri = await contract.methods.tokenURI(nextTokenId).call();
+      // expect(tokenUri).to.be.equal(`https://offchain-service.local/token-info/${nextTokenId}`);
+    });
+  });
+});
\ No newline at end of file