git.delta.rocks / unique-network / refs/commits / 085263ef21aa

difftreelog

fix tests

Trubnikov Sergey2022-11-01parent: #ff83dec.patch.diff
in: master

3 files changed

modifiedtests/src/eth/base.test.tsdiffbeforeafterboth
--- a/tests/src/eth/base.test.ts
+++ b/tests/src/eth/base.test.ts
@@ -117,7 +117,7 @@
   });
 
   itEth('ERC721UniqueExtensions support', async ({helper}) => {
-    await checkInterface(helper, '0xb76006ac', true, true);
+    await checkInterface(helper, '0x244543ee', true, true);
   });
 
   itEth('ERC721Burnable - 0x42966c68 - support', async ({helper}) => {
modifiedtests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth
before · tests/src/eth/collectionAdmin.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.3// Unique Network is free software: you can redistribute it and/or modify4// it under the terms of the GNU General Public License as published by5// the Free Software Foundation, either version 3 of the License, or6// (at your option) any later version.7//8// Unique Network is distributed in the hope that it will be useful,9// but WITHOUT ANY WARRANTY; without even the implied warranty of10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the11// GNU General Public License for more details.1213// You should have received a copy of the GNU General Public License14// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1516import {IKeyringPair} from '@polkadot/types/types';17import {expect} from 'chai';18import {IEthCrossAccountId} from '../util/playgrounds/types';19import {usingEthPlaygrounds, itEth} from './util';20import {EthUniqueHelper} from './util/playgrounds/unique.dev';2122async function recordEthFee(helper: EthUniqueHelper, userAddress: string, call: () => Promise<any>) {23  const before = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));24  await call();25  await helper.wait.newBlocks(1);26  const after = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));2728  expect(after < before).to.be.true;2930  return before - after;31}3233describe('Add collection admins', () => {34  let donor: IKeyringPair;3536  before(async function() {37    await usingEthPlaygrounds(async (_helper, privateKey) => {38      donor = await privateKey({filename: __filename});39    });40  });4142  itEth('Add admin by owner', async ({helper}) => {43    const owner = await helper.eth.createAccountWithBalance(donor);44    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');45    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);4647    const newAdmin = helper.eth.createAccount();4849    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();50    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);51    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())52      .to.be.eq(newAdmin.toLocaleLowerCase());53  });5455  itEth('Add cross account admin by owner', async ({helper, privateKey}) => {56    const owner = await helper.eth.createAccountWithBalance(donor);57        58    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');59    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);60    61    const newAdmin = await privateKey('//Bob');62    const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin);63    await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send();6465    const adminList = await helper.collection.getAdmins(collectionId);66    expect(adminList).to.be.like([{Substrate: newAdmin.address}]);67  });6869  itEth('Check adminlist', async ({helper, privateKey}) => {70    const owner = await helper.eth.createAccountWithBalance(donor);71        72    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');73    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);7475    const admin1 = helper.eth.createAccount();76    const admin2 = await privateKey('admin');77    await collectionEvm.methods.addCollectionAdmin(admin1).send();78    await collectionEvm.methods.addCollectionAdminSubstrate(admin2.addressRaw).send();7980    const adminListRpc = await helper.collection.getAdmins(collectionId);81    let adminListEth = await collectionEvm.methods.collectionAdmins().call();82    adminListEth = adminListEth.map((element: IEthCrossAccountId) => {83      return helper.address.convertCrossAccountFromEthCrossAcoount(element);84    });85    expect(adminListRpc).to.be.like(adminListEth);86  });8788  itEth('Verify owner or admin', async ({helper}) => {89    const owner = await helper.eth.createAccountWithBalance(donor);90    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');9192    const newAdmin = helper.eth.createAccount();93    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);94  95    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;96    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();97    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;98  });99    100  itEth('(!negative tests!) Add admin by ADMIN is not allowed', async ({helper}) => {101    const owner = await helper.eth.createAccountWithBalance(donor);102    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');103104    const admin = await helper.eth.createAccountWithBalance(donor);105    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);106    await collectionEvm.methods.addCollectionAdmin(admin).send();107108    const user = helper.eth.createAccount();109    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin}))110      .to.be.rejectedWith('NoPermission');111112    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);113    expect(adminList.length).to.be.eq(1);114    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())115      .to.be.eq(admin.toLocaleLowerCase());116  });117118  itEth('(!negative tests!) Add admin by USER is not allowed', async ({helper}) => {119    const owner = await helper.eth.createAccountWithBalance(donor);120    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');121122    const notAdmin = await helper.eth.createAccountWithBalance(donor);123    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);124125    const user = helper.eth.createAccount();126    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin}))127      .to.be.rejectedWith('NoPermission');128129    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);130    expect(adminList.length).to.be.eq(0);131  });132133  itEth.skip('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({helper}) => {134    const owner = await helper.eth.createAccountWithBalance(donor);135    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');136137    const admin = await helper.eth.createAccountWithBalance(donor);138    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);139    await collectionEvm.methods.addCollectionAdmin(admin).send();140141    const [notAdmin] = await helper.arrange.createAccounts([10n], donor);142    await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin}))143      .to.be.rejectedWith('NoPermission');144145    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);146    expect(adminList.length).to.be.eq(1);147    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())148      .to.be.eq(admin.toLocaleLowerCase());149  });150151  itEth.skip('(!negative tests!) Add substrate admin by USER is not allowed', async ({helper}) => {152    const owner = await helper.eth.createAccountWithBalance(donor);153    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');154155    const notAdmin0 = await helper.eth.createAccountWithBalance(donor);156    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);157    const [notAdmin1] = await helper.arrange.createAccounts([10n], donor);158    await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0}))159      .to.be.rejectedWith('NoPermission');160161    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);162    expect(adminList.length).to.be.eq(0);163  });164});165166describe('Remove collection admins', () => {167  let donor: IKeyringPair;168169  before(async function() {170    await usingEthPlaygrounds(async (_helper, privateKey) => {171      donor = await privateKey({filename: __filename});172    });173  });174175  itEth('Remove admin by owner', async ({helper}) => {176    const owner = await helper.eth.createAccountWithBalance(donor);177    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');178179    const newAdmin = helper.eth.createAccount();180    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);181    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();182183    {184      const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);185      expect(adminList.length).to.be.eq(1);186      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())187        .to.be.eq(newAdmin.toLocaleLowerCase());188    }189190    await collectionEvm.methods.removeCollectionAdmin(newAdmin).send();191    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);192    expect(adminList.length).to.be.eq(0);193  });194195  itEth.skip('Remove substrate admin by owner', async ({helper}) => {196    const owner = await helper.eth.createAccountWithBalance(donor);197    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');198199    const [newAdmin] = await helper.arrange.createAccounts([10n], donor);200    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);201    await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();202    {203      const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);204      expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())205        .to.be.eq(newAdmin.address.toLocaleLowerCase());206    }207208    await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send();209    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);210    expect(adminList.length).to.be.eq(0);211  });212213  itEth('(!negative tests!) Remove admin by ADMIN is not allowed', async ({helper}) => {214    const owner = await helper.eth.createAccountWithBalance(donor);215    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');216217    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);218219    const admin0 = await helper.eth.createAccountWithBalance(donor);220    await collectionEvm.methods.addCollectionAdmin(admin0).send();221    const admin1 = await helper.eth.createAccountWithBalance(donor);222    await collectionEvm.methods.addCollectionAdmin(admin1).send();223224    await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0}))225      .to.be.rejectedWith('NoPermission');226    {227      const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);228      expect(adminList.length).to.be.eq(2);229      expect(adminList.toString().toLocaleLowerCase())230        .to.be.deep.contains(admin0.toLocaleLowerCase())231        .to.be.deep.contains(admin1.toLocaleLowerCase());232    }233  });234235  itEth('(!negative tests!) Remove admin by USER is not allowed', async ({helper}) => {236    const owner = await helper.eth.createAccountWithBalance(donor);237    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');238239    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);240241    const admin = await helper.eth.createAccountWithBalance(donor);242    await collectionEvm.methods.addCollectionAdmin(admin).send();243    const notAdmin = helper.eth.createAccount();244245    await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin}))246      .to.be.rejectedWith('NoPermission');247    {248      const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);249      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())250        .to.be.eq(admin.toLocaleLowerCase());251      expect(adminList.length).to.be.eq(1);252    }253  });254255  itEth.skip('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({helper}) => {256    const owner = await helper.eth.createAccountWithBalance(donor);257    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');258259    const [adminSub] = await helper.arrange.createAccounts([10n], donor);260    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);261    await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();262    const adminEth = await helper.eth.createAccountWithBalance(donor);263    await collectionEvm.methods.addCollectionAdmin(adminEth).send();264265    await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth}))266      .to.be.rejectedWith('NoPermission');267268    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);269    expect(adminList.length).to.be.eq(2);270    expect(adminList.toString().toLocaleLowerCase())271      .to.be.deep.contains(adminSub.address.toLocaleLowerCase())272      .to.be.deep.contains(adminEth.toLocaleLowerCase());273  });274275  itEth.skip('(!negative tests!) Remove substrate admin by USER is not allowed', async ({helper}) => {276    const owner = await helper.eth.createAccountWithBalance(donor);277    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');278279    const [adminSub] = await helper.arrange.createAccounts([10n], donor);280    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);281    await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();282    const notAdminEth = await helper.eth.createAccountWithBalance(donor);283284    await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth}))285      .to.be.rejectedWith('NoPermission');286287    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);288    expect(adminList.length).to.be.eq(1);289    expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())290      .to.be.eq(adminSub.address.toLocaleLowerCase());291  });292});293294describe('Change owner tests', () => {295  let donor: IKeyringPair;296297  before(async function() {298    await usingEthPlaygrounds(async (_helper, privateKey) => {299      donor = await privateKey({filename: __filename});300    });301  });302303  itEth('Change owner', async ({helper}) => {304    const owner = await helper.eth.createAccountWithBalance(donor);305    const newOwner = await helper.eth.createAccountWithBalance(donor);306    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');307    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);308309    await collectionEvm.methods.changeCollectionOwner(newOwner).send();310311    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;312    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;313  });314315  itEth('change owner call fee', async ({helper}) => {316    const owner = await helper.eth.createAccountWithBalance(donor);317    const newOwner = await helper.eth.createAccountWithBalance(donor);318    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');319    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);320    const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.changeCollectionOwner(newOwner).send());321    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));322    expect(cost > 0);323  });324325  itEth('(!negative tests!) call setOwner by non owner', async ({helper}) => {326    const owner = await helper.eth.createAccountWithBalance(donor);327    const newOwner = await helper.eth.createAccountWithBalance(donor);328    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');329    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);330331    await expect(collectionEvm.methods.changeCollectionOwner(newOwner).send({from: newOwner})).to.be.rejected;332    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;333  });334});335336describe('Change substrate owner tests', () => {337  let donor: IKeyringPair;338339  before(async function() {340    await usingEthPlaygrounds(async (_helper, privateKey) => {341      donor = await privateKey({filename: __filename});342    });343  });344345  itEth.skip('Change owner', async ({helper}) => {346    const owner = await helper.eth.createAccountWithBalance(donor);347    const [newOwner] = await helper.arrange.createAccounts([10n], donor);348    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');349    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);350351    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true;352    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;353354    await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send();355356    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;357    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true;358  });359360  itEth.skip('change owner call fee', async ({helper}) => {361    const owner = await helper.eth.createAccountWithBalance(donor);362    const [newOwner] = await helper.arrange.createAccounts([10n], donor);363    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');364    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);365366    const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());367    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));368    expect(cost > 0);369  });370371  itEth.skip('(!negative tests!) call setOwner by non owner', async ({helper}) => {372    const owner = await helper.eth.createAccountWithBalance(donor);373    const otherReceiver = await helper.eth.createAccountWithBalance(donor);374    const [newOwner] = await helper.arrange.createAccounts([10n], donor);375    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');376    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);377378    await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected;379    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;380  });381});
after · tests/src/eth/collectionAdmin.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.3// Unique Network is free software: you can redistribute it and/or modify4// it under the terms of the GNU General Public License as published by5// the Free Software Foundation, either version 3 of the License, or6// (at your option) any later version.7//8// Unique Network is distributed in the hope that it will be useful,9// but WITHOUT ANY WARRANTY; without even the implied warranty of10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the11// GNU General Public License for more details.1213// You should have received a copy of the GNU General Public License14// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1516import {IKeyringPair} from '@polkadot/types/types';17import {expect} from 'chai';18import {IEthCrossAccountId} from '../util/playgrounds/types';19import {usingEthPlaygrounds, itEth} from './util';20import {EthUniqueHelper} from './util/playgrounds/unique.dev';2122async function recordEthFee(helper: EthUniqueHelper, userAddress: string, call: () => Promise<any>) {23  const before = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));24  await call();25  await helper.wait.newBlocks(1);26  const after = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));2728  expect(after < before).to.be.true;2930  return before - after;31}3233describe('Add collection admins', () => {34  let donor: IKeyringPair;3536  before(async function() {37    await usingEthPlaygrounds(async (_helper, privateKey) => {38      donor = await privateKey({filename: __filename});39    });40  });4142  itEth('Add admin by owner', async ({helper}) => {43    const owner = await helper.eth.createAccountWithBalance(donor);44    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');45    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);4647    const newAdmin = helper.eth.createAccount();4849    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();50    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);51    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())52      .to.be.eq(newAdmin.toLocaleLowerCase());53  });5455  itEth('Add cross account admin by owner', async ({helper, privateKey}) => {56    const owner = await helper.eth.createAccountWithBalance(donor);57        58    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');59    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);60    61    const newAdmin = await privateKey('//Bob');62    const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin);63    await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send();6465    const adminList = await helper.collection.getAdmins(collectionId);66    expect(adminList).to.be.like([{Substrate: newAdmin.address}]);67  });6869  itEth('Check adminlist', async ({helper, privateKey}) => {70    const owner = await helper.eth.createAccountWithBalance(donor);71        72    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');73    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);7475    const admin1 = helper.eth.createAccount();76    const admin2 = await privateKey('admin');77    const admin2Cross = helper.ethCrossAccount.fromKeyringPair(admin2);78    await collectionEvm.methods.addCollectionAdmin(admin1).send();79    await collectionEvm.methods.addCollectionAdminCross(admin2Cross).send();8081    const adminListRpc = await helper.collection.getAdmins(collectionId);82    let adminListEth = await collectionEvm.methods.collectionAdmins().call();83    adminListEth = adminListEth.map((element: IEthCrossAccountId) => {84      return helper.address.convertCrossAccountFromEthCrossAcoount(element);85    });86    expect(adminListRpc).to.be.like(adminListEth);87  });8889  itEth('Verify owner or admin', async ({helper}) => {90    const owner = await helper.eth.createAccountWithBalance(donor);91    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');9293    const newAdmin = helper.eth.createAccount();94    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);95  96    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;97    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();98    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;99  });100    101  itEth('(!negative tests!) Add admin by ADMIN is not allowed', async ({helper}) => {102    const owner = await helper.eth.createAccountWithBalance(donor);103    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');104105    const admin = await helper.eth.createAccountWithBalance(donor);106    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);107    await collectionEvm.methods.addCollectionAdmin(admin).send();108109    const user = helper.eth.createAccount();110    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin}))111      .to.be.rejectedWith('NoPermission');112113    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);114    expect(adminList.length).to.be.eq(1);115    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())116      .to.be.eq(admin.toLocaleLowerCase());117  });118119  itEth('(!negative tests!) Add admin by USER is not allowed', async ({helper}) => {120    const owner = await helper.eth.createAccountWithBalance(donor);121    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');122123    const notAdmin = await helper.eth.createAccountWithBalance(donor);124    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);125126    const user = helper.eth.createAccount();127    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin}))128      .to.be.rejectedWith('NoPermission');129130    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);131    expect(adminList.length).to.be.eq(0);132  });133134  itEth.skip('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({helper}) => {135    const owner = await helper.eth.createAccountWithBalance(donor);136    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');137138    const admin = await helper.eth.createAccountWithBalance(donor);139    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);140    await collectionEvm.methods.addCollectionAdmin(admin).send();141142    const [notAdmin] = await helper.arrange.createAccounts([10n], donor);143    await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin}))144      .to.be.rejectedWith('NoPermission');145146    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);147    expect(adminList.length).to.be.eq(1);148    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())149      .to.be.eq(admin.toLocaleLowerCase());150  });151152  itEth.skip('(!negative tests!) Add substrate admin by USER is not allowed', async ({helper}) => {153    const owner = await helper.eth.createAccountWithBalance(donor);154    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');155156    const notAdmin0 = await helper.eth.createAccountWithBalance(donor);157    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);158    const [notAdmin1] = await helper.arrange.createAccounts([10n], donor);159    await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0}))160      .to.be.rejectedWith('NoPermission');161162    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);163    expect(adminList.length).to.be.eq(0);164  });165});166167describe('Remove collection admins', () => {168  let donor: IKeyringPair;169170  before(async function() {171    await usingEthPlaygrounds(async (_helper, privateKey) => {172      donor = await privateKey({filename: __filename});173    });174  });175176  itEth('Remove admin by owner', async ({helper}) => {177    const owner = await helper.eth.createAccountWithBalance(donor);178    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');179180    const newAdmin = helper.eth.createAccount();181    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);182    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();183184    {185      const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);186      expect(adminList.length).to.be.eq(1);187      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())188        .to.be.eq(newAdmin.toLocaleLowerCase());189    }190191    await collectionEvm.methods.removeCollectionAdmin(newAdmin).send();192    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);193    expect(adminList.length).to.be.eq(0);194  });195196  itEth.skip('Remove substrate admin by owner', async ({helper}) => {197    const owner = await helper.eth.createAccountWithBalance(donor);198    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');199200    const [newAdmin] = await helper.arrange.createAccounts([10n], donor);201    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);202    await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();203    {204      const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);205      expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())206        .to.be.eq(newAdmin.address.toLocaleLowerCase());207    }208209    await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send();210    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);211    expect(adminList.length).to.be.eq(0);212  });213214  itEth('(!negative tests!) Remove admin by ADMIN is not allowed', async ({helper}) => {215    const owner = await helper.eth.createAccountWithBalance(donor);216    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');217218    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);219220    const admin0 = await helper.eth.createAccountWithBalance(donor);221    await collectionEvm.methods.addCollectionAdmin(admin0).send();222    const admin1 = await helper.eth.createAccountWithBalance(donor);223    await collectionEvm.methods.addCollectionAdmin(admin1).send();224225    await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0}))226      .to.be.rejectedWith('NoPermission');227    {228      const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);229      expect(adminList.length).to.be.eq(2);230      expect(adminList.toString().toLocaleLowerCase())231        .to.be.deep.contains(admin0.toLocaleLowerCase())232        .to.be.deep.contains(admin1.toLocaleLowerCase());233    }234  });235236  itEth('(!negative tests!) Remove admin by USER is not allowed', async ({helper}) => {237    const owner = await helper.eth.createAccountWithBalance(donor);238    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');239240    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);241242    const admin = await helper.eth.createAccountWithBalance(donor);243    await collectionEvm.methods.addCollectionAdmin(admin).send();244    const notAdmin = helper.eth.createAccount();245246    await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin}))247      .to.be.rejectedWith('NoPermission');248    {249      const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);250      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())251        .to.be.eq(admin.toLocaleLowerCase());252      expect(adminList.length).to.be.eq(1);253    }254  });255256  itEth.skip('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({helper}) => {257    const owner = await helper.eth.createAccountWithBalance(donor);258    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');259260    const [adminSub] = await helper.arrange.createAccounts([10n], donor);261    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);262    await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();263    const adminEth = await helper.eth.createAccountWithBalance(donor);264    await collectionEvm.methods.addCollectionAdmin(adminEth).send();265266    await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth}))267      .to.be.rejectedWith('NoPermission');268269    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);270    expect(adminList.length).to.be.eq(2);271    expect(adminList.toString().toLocaleLowerCase())272      .to.be.deep.contains(adminSub.address.toLocaleLowerCase())273      .to.be.deep.contains(adminEth.toLocaleLowerCase());274  });275276  itEth.skip('(!negative tests!) Remove substrate admin by USER is not allowed', async ({helper}) => {277    const owner = await helper.eth.createAccountWithBalance(donor);278    const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');279280    const [adminSub] = await helper.arrange.createAccounts([10n], donor);281    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);282    await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();283    const notAdminEth = await helper.eth.createAccountWithBalance(donor);284285    await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth}))286      .to.be.rejectedWith('NoPermission');287288    const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);289    expect(adminList.length).to.be.eq(1);290    expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())291      .to.be.eq(adminSub.address.toLocaleLowerCase());292  });293});294295describe('Change owner tests', () => {296  let donor: IKeyringPair;297298  before(async function() {299    await usingEthPlaygrounds(async (_helper, privateKey) => {300      donor = await privateKey({filename: __filename});301    });302  });303304  itEth('Change owner', async ({helper}) => {305    const owner = await helper.eth.createAccountWithBalance(donor);306    const newOwner = await helper.eth.createAccountWithBalance(donor);307    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');308    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);309310    await collectionEvm.methods.changeCollectionOwner(newOwner).send();311312    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;313    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;314  });315316  itEth('change owner call fee', async ({helper}) => {317    const owner = await helper.eth.createAccountWithBalance(donor);318    const newOwner = await helper.eth.createAccountWithBalance(donor);319    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');320    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);321    const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.changeCollectionOwner(newOwner).send());322    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));323    expect(cost > 0);324  });325326  itEth('(!negative tests!) call setOwner by non owner', async ({helper}) => {327    const owner = await helper.eth.createAccountWithBalance(donor);328    const newOwner = await helper.eth.createAccountWithBalance(donor);329    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');330    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);331332    await expect(collectionEvm.methods.changeCollectionOwner(newOwner).send({from: newOwner})).to.be.rejected;333    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;334  });335});336337describe('Change substrate owner tests', () => {338  let donor: IKeyringPair;339340  before(async function() {341    await usingEthPlaygrounds(async (_helper, privateKey) => {342      donor = await privateKey({filename: __filename});343    });344  });345346  itEth.skip('Change owner', async ({helper}) => {347    const owner = await helper.eth.createAccountWithBalance(donor);348    const [newOwner] = await helper.arrange.createAccounts([10n], donor);349    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');350    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);351352    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true;353    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;354355    await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send();356357    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;358    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true;359  });360361  itEth.skip('change owner call fee', async ({helper}) => {362    const owner = await helper.eth.createAccountWithBalance(donor);363    const [newOwner] = await helper.arrange.createAccounts([10n], donor);364    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');365    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);366367    const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());368    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));369    expect(cost > 0);370  });371372  itEth.skip('(!negative tests!) call setOwner by non owner', async ({helper}) => {373    const owner = await helper.eth.createAccountWithBalance(donor);374    const otherReceiver = await helper.eth.createAccountWithBalance(donor);375    const [newOwner] = await helper.arrange.createAccounts([10n], donor);376    const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');377    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);378379    await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected;380    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;381  });382});
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -338,6 +338,40 @@
     }
   });
 
+  itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {
+    const minter = await privateKey('//Alice');
+    const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+    const owner = await privateKey('//Bob');
+    const spender = await helper.eth.createAccountWithBalance(donor);
+    const receiver = await privateKey('//Charlie');
+
+    const token = await collection.mintToken(minter, {Substrate: owner.address});
+
+    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
+    const contract = helper.ethNativeContract.collection(address, 'nft');
+
+    await token.approve(owner, {Ethereum: spender});
+
+    {
+      const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
+      const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
+      const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender});
+      const event = result.events.Transfer;
+      expect(event).to.be.like({
+        address: helper.ethAddress.fromCollectionId(collection.collectionId),
+        event: 'Transfer',
+        returnValues: {
+          from: helper.address.substrateToEth(owner.address),
+          to: helper.address.substrateToEth(receiver.address),
+          tokenId: token.tokenId.toString(),
+        },
+      });
+    }
+
+    expect(await token.getOwner()).to.be.like({Substrate: receiver.address});
+  });
+
   itEth('Can perform transfer()', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice, {});
     const owner = await helper.eth.createAccountWithBalance(donor);
@@ -407,40 +441,6 @@
 
     const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, tokenId).send({from: spender}));
     expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
-  });
-
-  itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {
-    const minter = await privateKey('//Alice');
-    const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});
-
-    const owner = await privateKey('//Bob');
-    const spender = await helper.eth.createAccountWithBalance(donor);
-    const receiver = await privateKey('//Charlie');
-
-    const token = await collection.mintToken(donor, {Substrate: owner.address});
-
-    const address = helper.ethAddress.fromCollectionId(collection.collectionId);
-    const contract = helper.ethNativeContract.collection(address, 'nft');
-
-    await token.approve(owner, {Ethereum: spender});
-
-    {
-      const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);
-      const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);
-      const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender});
-      const event = result.events.Transfer;
-      expect(event).to.be.like({
-        address: helper.ethAddress.fromCollectionId(collection.collectionId),
-        event: 'Transfer',
-        returnValues: {
-          from: helper.address.substrateToEth(owner.address),
-          to: helper.address.substrateToEth(receiver.address),
-          tokenId: token.tokenId.toString(),
-        },
-      });
-    }
-
-    expect(await token.getOwner()).to.be.like({Substrate: receiver.address});
   });
 
   itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {