--- a/tests/src/eth/collectionAdmin.test.ts +++ b/tests/src/eth/collectionAdmin.test.ts @@ -39,80 +39,94 @@ }); }); - // Soft-deprecated - itEth('Add admin by owner', async ({helper}) => { + itEth('can add account admin by owner', async ({helper, privateKey}) => { + // arrange const owner = await helper.eth.createAccountWithBalance(donor); + const adminSub = await privateKey('//admin2'); + const adminEth = helper.eth.createAccount().toLowerCase(); + + const adminDeprecated = helper.eth.createAccount().toLowerCase(); + const adminCrossSub = helper.ethCrossAccount.fromKeyringPair(adminSub); + const adminCrossEth = helper.ethCrossAccount.fromAddress(adminEth); + const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C'); const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true); - const newAdmin = helper.eth.createAccount(); + // Soft-deprecated: can addCollectionAdmin + await collectionEvm.methods.addCollectionAdmin(adminDeprecated).send(); + // Can addCollectionAdminCross for substrate and ethereum address + await collectionEvm.methods.addCollectionAdminCross(adminCrossSub).send(); + await collectionEvm.methods.addCollectionAdminCross(adminCrossEth).send(); + + // 1. Expect api.rpc.unique.adminlist returns admins: + const adminListRpc = await helper.collection.getAdmins(collectionId); + expect(adminListRpc).to.has.length(3); + expect(adminListRpc).to.be.deep.contain.members([{Substrate: adminSub.address}, {Ethereum: adminEth}, {Ethereum: adminDeprecated}]); - await collectionEvm.methods.addCollectionAdmin(newAdmin).send(); - const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); - expect(adminList[0].asEthereum.toString().toLocaleLowerCase()) - .to.be.eq(newAdmin.toLocaleLowerCase()); + // 2. Expect methods.collectionAdmins == api.rpc.unique.adminlist + let adminListEth = await collectionEvm.methods.collectionAdmins().call(); + adminListEth = adminListEth.map((element: IEthCrossAccountId) => { + return helper.address.convertCrossAccountFromEthCrossAccount(element); + }); + expect(adminListRpc).to.be.like(adminListEth); }); - itEth('Add cross account admin by owner', async ({helper, privateKey}) => { + itEth('cross account admin can mint', async ({helper}) => { + // arrange: create collection and accounts const owner = await helper.eth.createAccountWithBalance(donor); - - const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C'); - const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', 'a', 'b', 'uri'); + const adminEth = (await helper.eth.createAccountWithBalance(donor)).toLowerCase(); + const adminCrossEth = helper.ethCrossAccount.fromAddress(adminEth); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true); - const newAdmin = await privateKey('//Bob'); - const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin); - await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send(); + // cannot mint while not admin + await expect(collectionEvm.methods.mint(owner).call({from: adminEth})).to.be.rejectedWith('PublicMintingNotAllowed'); + + // admin can mint token: + await collectionEvm.methods.addCollectionAdminCross(adminCrossEth).send(); + const result = await collectionEvm.methods.mint(owner).call({from: adminEth}); - const adminList = await helper.collection.getAdmins(collectionId); - expect(adminList).to.be.like([{Substrate: newAdmin.address}]); + // TODO: Why fail + expect(await helper.collection.getLastTokenId(collectionId)).to.eq(1); }); - itEth('Check adminlist', async ({helper, privateKey}) => { + itEth('cannot add invalid cross account admin', async ({helper}) => { const owner = await helper.eth.createAccountWithBalance(donor); - - const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C'); - const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true); + const [admin] = await helper.arrange.createAccounts([100n, 100n], donor); - const admin1 = helper.eth.createAccount(); - const admin2 = await privateKey('admin'); - const admin2Cross = helper.ethCrossAccount.fromKeyringPair(admin2); - - // Soft-deprecated - await collectionEvm.methods.addCollectionAdmin(admin1).send(); - await collectionEvm.methods.addCollectionAdminCross(admin2Cross).send(); + const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - const adminListRpc = await helper.collection.getAdmins(collectionId); - let adminListEth = await collectionEvm.methods.collectionAdmins().call(); - adminListEth = adminListEth.map((element: IEthCrossAccountId) => { - return helper.address.convertCrossAccountFromEthCrossAcoount(element); - }); - expect(adminListRpc).to.be.like(adminListEth); + const adminCross = { + eth: helper.address.substrateToEth(admin.address), + sub: admin.addressRaw, + }; + await expect(collectionEvm.methods.addCollectionAdminCross(adminCross).send()).to.be.rejected; }); - // Soft-deprecated - itEth('Verify owner or admin', async ({helper}) => { + itEth('can verify owner with methods.isOwnerOrAdmin[Cross]', async ({helper, privateKey}) => { const owner = await helper.eth.createAccountWithBalance(donor); const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C'); - const newAdmin = helper.eth.createAccount(); + const adminDeprecated = helper.eth.createAccount(); + const admin1Cross = helper.ethCrossAccount.fromKeyringPair(await privateKey('admin')); + const admin2Cross = helper.ethCrossAccount.fromAddress(helper.address.substrateToEth((await privateKey('admin3')).address)); const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true); - expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false; - await collectionEvm.methods.addCollectionAdmin(newAdmin).send(); - expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true; - }); + // Soft-deprecated: + expect(await collectionEvm.methods.isOwnerOrAdmin(adminDeprecated).call()).to.be.false; + expect(await collectionEvm.methods.isOwnerOrAdminCross(admin1Cross).call()).to.be.false; + expect(await collectionEvm.methods.isOwnerOrAdminCross(admin2Cross).call()).to.be.false; - itEth('Verify owner or admin cross', async ({helper, privateKey}) => { - const owner = await helper.eth.createAccountWithBalance(donor); - const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C'); + await collectionEvm.methods.addCollectionAdmin(adminDeprecated).send(); + await collectionEvm.methods.addCollectionAdminCross(admin1Cross).send(); + await collectionEvm.methods.addCollectionAdminCross(admin2Cross).send(); - const newAdmin = await privateKey('admin'); - const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin); - const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - - expect(await collectionEvm.methods.isOwnerOrAdminCross(newAdminCross).call()).to.be.false; - await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send(); - expect(await collectionEvm.methods.isOwnerOrAdminCross(newAdminCross).call()).to.be.true; + // Soft-deprecated: isOwnerOrAdmin returns true + expect(await collectionEvm.methods.isOwnerOrAdmin(adminDeprecated).call()).to.be.true; + // Expect isOwnerOrAdminCross return true + expect(await collectionEvm.methods.isOwnerOrAdminCross(admin1Cross).call()).to.be.true; + expect(await collectionEvm.methods.isOwnerOrAdminCross(admin2Cross).call()).to.be.true; }); // Soft-deprecated @@ -154,12 +168,11 @@ const owner = await helper.eth.createAccountWithBalance(donor); const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C'); - const [admin] = await helper.arrange.createAccounts([10n], donor); + const [admin, notAdmin] = await helper.arrange.createAccounts([10n, 10n], donor); const adminCross = helper.ethCrossAccount.fromKeyringPair(admin); const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); await collectionEvm.methods.addCollectionAdminCross(adminCross).send(); - const [notAdmin] = await helper.arrange.createAccounts([10n], donor); const notAdminCross = helper.ethCrossAccount.fromKeyringPair(notAdmin); await expect(collectionEvm.methods.addCollectionAdminCross(notAdminCross).call({from: adminCross.eth})) .to.be.rejectedWith('NoPermission'); --- a/tests/src/util/playgrounds/unique.ts +++ b/tests/src/util/playgrounds/unique.ts @@ -2429,7 +2429,7 @@ * @param ethCrossAccount etherium cross account * @returns substrate cross account id */ - convertCrossAccountFromEthCrossAcoount(ethCrossAccount: IEthCrossAccountId): ICrossAccountId { + convertCrossAccountFromEthCrossAccount(ethCrossAccount: IEthCrossAccountId): ICrossAccountId { if (ethCrossAccount.sub === '0') { return {Ethereum: ethCrossAccount.eth.toLocaleLowerCase()}; }