difftreelog
fix eth tests
in: master
5 files changed
tests/src/eth/base.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {18 ethBalanceViaSub,19 GAS_ARGS,20 recordEthFee,21} from './util/helpers';22import {Contract} from 'web3-eth-contract';2324import {IKeyringPair} from '@polkadot/types/types';25import {EthUniqueHelper, itEth, usingEthPlaygrounds, expect} from './util/playgrounds';26import {UNIQUE} from '../util/helpers';2728describe('Contract calls', () => {29 let donor: IKeyringPair;3031 before(async function() {32 await usingEthPlaygrounds(async (_helper, privateKey) => {33 donor = privateKey('//Alice');34 });35 });3637 itEth('Call of simple contract fee is less than 0.2 UNQ', async ({helper}) => {38 const deployer = await helper.eth.createAccountWithBalance(donor);39 const flipper = await helper.eth.deployFlipper(deployer);4041 const cost = await recordEthFee(helper.api!, deployer, () => flipper.methods.flip().send({from: deployer}));42 expect(cost < BigInt(0.2 * Number(UNIQUE))).to.be.true;43 });4445 itEth('Balance transfer fee is less than 0.2 UNQ', async ({helper}) => {46 const userA = await helper.eth.createAccountWithBalance(donor);47 const userB = helper.eth.createAccount();48 const cost = await recordEthFee(helper.api!, userA, () => helper.web3!.eth.sendTransaction({from: userA, to: userB, value: '1000000', ...GAS_ARGS}));49 const balanceB = await ethBalanceViaSub(helper.api!, userB);50 expect(cost - balanceB < BigInt(0.2 * Number(UNIQUE))).to.be.true;51 });5253 itEth('NFT transfer is close to 0.15 UNQ', async ({helper}) => {54 const caller = await helper.eth.createAccountWithBalance(donor);55 const receiver = helper.eth.createAccount();5657 const [alice] = await helper.arrange.createAccounts([10n], donor);58 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});59 const {tokenId} = await collection.mintToken(alice, {Ethereum: caller});6061 const address = helper.ethAddress.fromCollectionId(collection.collectionId);62 const contract = helper.ethNativeContract.collection(address, 'nft', caller);6364 const cost = await recordEthFee(helper.api!, caller, () => contract.methods.transfer(receiver, tokenId).send(caller));6566 const fee = Number(cost) / Number(UNIQUE);67 const expectedFee = 0.15;68 const tolerance = 0.001;6970 expect(Math.abs(fee - expectedFee)).to.be.lessThan(tolerance);71 });72});7374describe('ERC165 tests', async () => {75 // https://eips.ethereum.org/EIPS/eip-1657677 let collection: number;78 let minter: string;7980 function contract(helper: EthUniqueHelper): Contract {81 return helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection), 'nft', minter);82 }8384 before(async () => {85 await usingEthPlaygrounds(async (helper, privateKey) => {86 const donor = privateKey('//Alice');87 const [alice] = await helper.arrange.createAccounts([10n], donor);88 ({collectionId: collection} = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}));89 minter = helper.eth.createAccount();90 });91 });9293 itEth('interfaceID == 0xffffffff always false', async ({helper}) => {94 expect(await contract(helper).methods.supportsInterface('0xffffffff').call()).to.be.false;95 });9697 itEth('ERC721 support', async ({helper}) => {98 expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true;99 });100101 itEth('ERC721Metadata support', async ({helper}) => {102 expect(await contract(helper).methods.supportsInterface('0x5b5e139f').call()).to.be.true;103 });104105 itEth('ERC721Mintable support', async ({helper}) => {106 expect(await contract(helper).methods.supportsInterface('0x68ccfe89').call()).to.be.true;107 });108109 itEth('ERC721Enumerable support', async ({helper}) => {110 expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true;111 });112113 itEth('ERC721UniqueExtensions support', async ({helper}) => {114 expect(await contract(helper).methods.supportsInterface('0xd74d154f').call()).to.be.true;115 });116117 itEth('ERC721Burnable support', async ({helper}) => {118 expect(await contract(helper).methods.supportsInterface('0x42966c68').call()).to.be.true;119 });120121 itEth('ERC165 support', async ({helper}) => {122 expect(await contract(helper).methods.supportsInterface('0x01ffc9a7').call()).to.be.true;123 });124});1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {18 ethBalanceViaSub,19 GAS_ARGS,20 recordEthFee,21} from './util/helpers';22import {Contract} from 'web3-eth-contract';2324import {IKeyringPair} from '@polkadot/types/types';25import {EthUniqueHelper, itEth, usingEthPlaygrounds, expect} from './util/playgrounds';2627describe('Contract calls', () => {28 let donor: IKeyringPair;2930 before(async function() {31 await usingEthPlaygrounds(async (_helper, privateKey) => {32 donor = privateKey('//Alice');33 });34 });3536 itEth('Call of simple contract fee is less than 0.2 UNQ', async ({helper}) => {37 const deployer = await helper.eth.createAccountWithBalance(donor);38 const flipper = await helper.eth.deployFlipper(deployer);3940 const cost = await recordEthFee(helper.api!, deployer, () => flipper.methods.flip().send({from: deployer}));41 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal()))).to.be.true;42 });4344 itEth('Balance transfer fee is less than 0.2 UNQ', async ({helper}) => {45 const userA = await helper.eth.createAccountWithBalance(donor);46 const userB = helper.eth.createAccount();47 const cost = await recordEthFee(helper.api!, userA, () => helper.web3!.eth.sendTransaction({from: userA, to: userB, value: '1000000', ...GAS_ARGS}));48 const balanceB = await ethBalanceViaSub(helper.api!, userB);49 expect(cost - balanceB < BigInt(0.2 * Number(helper.balance.getOneTokenNominal()))).to.be.true;50 });5152 itEth('NFT transfer is close to 0.15 UNQ', async ({helper}) => {53 const caller = await helper.eth.createAccountWithBalance(donor);54 const receiver = helper.eth.createAccount();5556 const [alice] = await helper.arrange.createAccounts([10n], donor);57 const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});58 const {tokenId} = await collection.mintToken(alice, {Ethereum: caller});5960 const address = helper.ethAddress.fromCollectionId(collection.collectionId);61 const contract = helper.ethNativeContract.collection(address, 'nft', caller);6263 const cost = await recordEthFee(helper.api!, caller, () => contract.methods.transfer(receiver, tokenId).send(caller));6465 const fee = Number(cost) / Number(helper.balance.getOneTokenNominal());66 const expectedFee = 0.15;67 const tolerance = 0.001;6869 expect(Math.abs(fee - expectedFee)).to.be.lessThan(tolerance);70 });71});7273describe('ERC165 tests', async () => {74 // https://eips.ethereum.org/EIPS/eip-1657576 let collection: number;77 let minter: string;7879 function contract(helper: EthUniqueHelper): Contract {80 return helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection), 'nft', minter);81 }8283 before(async () => {84 await usingEthPlaygrounds(async (helper, privateKey) => {85 const donor = privateKey('//Alice');86 const [alice] = await helper.arrange.createAccounts([10n], donor);87 ({collectionId: collection} = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}));88 minter = helper.eth.createAccount();89 });90 });9192 itEth('interfaceID == 0xffffffff always false', async ({helper}) => {93 expect(await contract(helper).methods.supportsInterface('0xffffffff').call()).to.be.false;94 });9596 itEth('ERC721 support', async ({helper}) => {97 expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true;98 });99100 itEth('ERC721Metadata support', async ({helper}) => {101 expect(await contract(helper).methods.supportsInterface('0x5b5e139f').call()).to.be.true;102 });103104 itEth('ERC721Mintable support', async ({helper}) => {105 expect(await contract(helper).methods.supportsInterface('0x68ccfe89').call()).to.be.true;106 });107108 itEth('ERC721Enumerable support', async ({helper}) => {109 expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true;110 });111112 itEth('ERC721UniqueExtensions support', async ({helper}) => {113 expect(await contract(helper).methods.supportsInterface('0xd74d154f').call()).to.be.true;114 });115116 itEth('ERC721Burnable support', async ({helper}) => {117 expect(await contract(helper).methods.supportsInterface('0x42966c68').call()).to.be.true;118 });119120 itEth('ERC165 support', async ({helper}) => {121 expect(await contract(helper).methods.supportsInterface('0x01ffc9a7').call()).to.be.true;122 });123});tests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionAdmin.test.ts
+++ b/tests/src/eth/collectionAdmin.test.ts
@@ -14,11 +14,32 @@
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
import {IKeyringPair} from '@polkadot/types/types';
-import {UNIQUE} from '../util/helpers';
-import {
- recordEthFee,
-} from './util/helpers';
-import {usingEthPlaygrounds, itEth, expect} from './util/playgrounds';
+import {usingEthPlaygrounds, itEth, expect, EthUniqueHelper} from './util/playgrounds';
+
+async function waitNewBlocks(helper: EthUniqueHelper, count: number) {
+ // eslint-disable-next-line no-async-promise-executor
+ return new Promise<void>(async (resolve) => {
+ const unsubscribe = await helper.callRpc('api.rpc.chain.subscribeNewHeads', [() => {
+ if (count > 0) {
+ count--;
+ } else {
+ unsubscribe();
+ resolve();
+ }
+ }]);
+ });
+}
+
+async function recordEthFee(helper: EthUniqueHelper, userAddress: string, call: () => Promise<any>) {
+ const before = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));
+ await call();
+ waitNewBlocks(helper, 1);
+ const after = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));
+
+ expect(after < before).to.be.true;
+
+ return before - after;
+}
describe('Add collection admins', () => {
let donor: IKeyringPair;
@@ -37,7 +58,7 @@
const newAdmin = helper.eth.createAccount();
await collectionEvm.methods.addCollectionAdmin(newAdmin).send();
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList[0].asEthereum.toString().toLocaleLowerCase())
.to.be.eq(newAdmin.toLocaleLowerCase());
});
@@ -50,12 +71,11 @@
const [newAdmin] = await helper.arrange.createAccounts([10n], donor);
await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())
.to.be.eq(newAdmin.address.toLocaleLowerCase());
});
- //FIXME:
itEth('Verify owner or admin', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
@@ -79,7 +99,7 @@
await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin}))
.to.be.rejectedWith('NoPermission');
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(1);
expect(adminList[0].asEthereum.toString().toLocaleLowerCase())
.to.be.eq(admin.toLocaleLowerCase());
@@ -96,7 +116,7 @@
await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin}))
.to.be.rejectedWith('NoPermission');
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(0);
});
@@ -112,7 +132,7 @@
await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin}))
.to.be.rejectedWith('NoPermission');
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(1);
expect(adminList[0].asEthereum.toString().toLocaleLowerCase())
.to.be.eq(admin.toLocaleLowerCase());
@@ -128,7 +148,7 @@
await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0}))
.to.be.rejectedWith('NoPermission');
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(0);
});
});
@@ -151,14 +171,14 @@
await collectionEvm.methods.addCollectionAdmin(newAdmin).send();
{
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(1);
expect(adminList[0].asEthereum.toString().toLocaleLowerCase())
.to.be.eq(newAdmin.toLocaleLowerCase());
}
await collectionEvm.methods.removeCollectionAdmin(newAdmin).send();
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(0);
});
@@ -170,13 +190,13 @@
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();
{
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())
.to.be.eq(newAdmin.address.toLocaleLowerCase());
}
await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send();
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(0);
});
@@ -194,7 +214,7 @@
await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0}))
.to.be.rejectedWith('NoPermission');
{
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(2);
expect(adminList.toString().toLocaleLowerCase())
.to.be.deep.contains(admin0.toLocaleLowerCase())
@@ -215,7 +235,7 @@
await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin}))
.to.be.rejectedWith('NoPermission');
{
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList[0].asEthereum.toString().toLocaleLowerCase())
.to.be.eq(admin.toLocaleLowerCase());
expect(adminList.length).to.be.eq(1);
@@ -235,7 +255,7 @@
await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth}))
.to.be.rejectedWith('NoPermission');
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(2);
expect(adminList.toString().toLocaleLowerCase())
.to.be.deep.contains(adminSub.address.toLocaleLowerCase())
@@ -254,7 +274,7 @@
await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth}))
.to.be.rejectedWith('NoPermission');
- const adminList = await helper.api!.rpc.unique.adminlist(collectionId);
+ const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
expect(adminList.length).to.be.eq(1);
expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())
.to.be.eq(adminSub.address.toLocaleLowerCase());
@@ -287,13 +307,11 @@
const newOwner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
-
- const cost = await recordEthFee(helper.api!, owner, () => collectionEvm.methods.setOwner(newOwner).send());
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwner(newOwner).send());
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
expect(cost > 0);
});
- //FIXME
itEth('(!negative tests!) call setOwner by non owner', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const newOwner = await helper.eth.createAccountWithBalance(donor);
@@ -314,7 +332,6 @@
});
});
- //FIXME
itEth.skip('Change owner', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const [newOwner] = await helper.arrange.createAccounts([10n], donor);
@@ -336,12 +353,11 @@
const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
- const cost = await recordEthFee(helper.api!, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());
- expect(cost < BigInt(0.2 * Number(UNIQUE)));
+ const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());
+ expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
expect(cost > 0);
});
- //FIXME
itEth.skip('(!negative tests!) call setOwner by non owner', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const otherReceiver = await helper.eth.createAccountWithBalance(donor);
tests/src/eth/collectionProperties.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionProperties.test.ts
+++ b/tests/src/eth/collectionProperties.test.ts
@@ -51,6 +51,6 @@
const contract = helper.ethNativeContract.collection(address, 'nft', caller);
const value = await contract.methods.collectionProperty('testKey').call();
- expect(value).to.equal(helper.web3?.utils.toHex('testValue'));
+ expect(value).to.equal(helper.getWeb3().utils.toHex('testValue'));
});
});
tests/src/eth/proxy/fungibleProxy.test.tsdiffbeforeafterboth--- a/tests/src/eth/proxy/fungibleProxy.test.ts
+++ b/tests/src/eth/proxy/fungibleProxy.test.ts
@@ -23,7 +23,8 @@
async function proxyWrap(helper: EthUniqueHelper, wrapped: any, donor: IKeyringPair) {
// Proxy owner has no special privilegies, we don't need to reuse them
const owner = await helper.eth.createAccountWithBalance(donor);
- const proxyContract = new helper.web3!.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueFungibleProxy.abi`)).toString()), undefined, {
+ const web3 = helper.getWeb3();
+ const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueFungibleProxy.abi`)).toString()), undefined, {
from: owner,
...GAS_ARGS,
});
tests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth--- a/tests/src/eth/proxy/nonFungibleProxy.test.ts
+++ b/tests/src/eth/proxy/nonFungibleProxy.test.ts
@@ -23,7 +23,8 @@
async function proxyWrap(helper: EthUniqueHelper, wrapped: any, donor: IKeyringPair) {
// Proxy owner has no special privilegies, we don't need to reuse them
const owner = await helper.eth.createAccountWithBalance(donor);
- const proxyContract = new helper.web3!.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {
+ const web3 = helper.getWeb3();
+ const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {
from: owner,
...GAS_ARGS,
});