1import {IKeyringPair} from '@polkadot/types/types';2import {Contract} from 'web3-eth-contract';34import {itEth, EthUniqueHelper, usingEthPlaygrounds, expect} from '../util';56const createNestingCollection = async (7 helper: EthUniqueHelper,8 owner: string,9): Promise<{ collectionId: number, collectionAddress: string, contract: Contract }> => {10 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');1112 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);13 await contract.methods.setCollectionNesting(true).send({from: owner});1415 return {collectionId, collectionAddress, contract};16};171819describe('EVM nesting tests group', () => {20 let donor: IKeyringPair;2122 before(async function() {23 await usingEthPlaygrounds(async (_, privateKey) => {24 donor = await privateKey({filename: __filename});25 });26 });2728 describe('Integration Test: EVM Nesting', () => {29 itEth('NFT: allows an Owner to nest/unnest their token', async ({helper}) => {30 const owner = await helper.eth.createAccountWithBalance(donor);31 const {collectionId, contract} = await createNestingCollection(helper, owner);3233 34 const mintingTargetNFTTokenIdResult = await contract.methods.mint(owner).send({from: owner});35 const targetNFTTokenId = mintingTargetNFTTokenIdResult.events.Transfer.returnValues.tokenId;36 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNFTTokenId);3738 39 const mintingFirstTokenIdResult = await contract.methods.mint(targetNftTokenAddress).send({from: owner});40 const firstTokenId = mintingFirstTokenIdResult.events.Transfer.returnValues.tokenId;41 expect(await contract.methods.ownerOf(firstTokenId).call()).to.be.equal(targetNftTokenAddress);4243 44 const mintingSecondTokenIdResult = await contract.methods.mint(owner).send({from: owner});45 const secondTokenId = mintingSecondTokenIdResult.events.Transfer.returnValues.tokenId;4647 await contract.methods.transfer(targetNftTokenAddress, secondTokenId).send({from: owner});48 expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(targetNftTokenAddress);4950 51 await contract.methods.transferFrom(targetNftTokenAddress, owner, secondTokenId).send({from: owner});52 expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(owner);53 });54 55 itEth('NFT: collectionNestingRestrictedCollectionIds()', async ({helper}) => {56 const owner = await helper.eth.createAccountWithBalance(donor);57 const {collectionId: unnestedCollsectionId, collectionAddress: unnsetedCollectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');58 const unnestedContract = helper.ethNativeContract.collection(unnsetedCollectionAddress, 'nft', owner);59 expect(await unnestedContract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([false, []]);60 61 const {contract} = await createNestingCollection(helper, owner);62 expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, []]);63 await contract.methods.setCollectionNesting(true, [unnsetedCollectionAddress]).send({from: owner});64 expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, [unnestedCollsectionId.toString()]]);65 66 });67 68 itEth('NFT: allows an Owner to nest/unnest their token (Restricted nesting)', async ({helper}) => {69 const owner = await helper.eth.createAccountWithBalance(donor);7071 const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);72 const {collectionAddress: collectionAddressB, contract: contractB} = await createNestingCollection(helper, owner);73 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});7475 76 const mintingtargetNftTokenIdResult = await contractA.methods.mint(owner).send({from: owner});77 const targetNftTokenId = mintingtargetNftTokenIdResult.events.Transfer.returnValues.tokenId;78 const nftTokenAddressA1 = helper.ethAddress.fromTokenId(collectionIdA, targetNftTokenId);7980 81 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});82 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;8384 85 const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});86 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;8788 89 await contractA.methods.transfer(nftTokenAddressA1, nftTokenIdA).send({from: owner});90 expect(await contractA.methods.ownerOf(nftTokenIdA).call()).to.be.equal(nftTokenAddressA1);9192 await contractB.methods.transfer(nftTokenAddressA1, nftTokenIdB).send({from: owner});93 expect(await contractB.methods.ownerOf(nftTokenIdB).call()).to.be.equal(nftTokenAddressA1);94 });95 });9697 describe('Negative Test: EVM Nesting', () => {98 itEth('NFT: disallows to nest token if nesting is disabled', async ({helper}) => {99 const owner = await helper.eth.createAccountWithBalance(donor);100101 const {collectionId, contract} = await createNestingCollection(helper, owner);102 await contract.methods.setCollectionNesting(false).send({from: owner});103104 105 const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});106 const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;107 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);108109 110 const mintingNftTokenIdResult = await contract.methods.mint(owner).send({from: owner});111 const nftTokenId = mintingNftTokenIdResult.events.Transfer.returnValues.tokenId;112113 114 await expect(contract.methods115 .transfer(targetNftTokenAddress, nftTokenId)116 .call({from: owner})).to.be.rejectedWith('UserIsNotAllowedToNest');117 });118119 itEth('NFT: disallows a non-Owner to nest someone else\'s token', async ({helper}) => {120 const owner = await helper.eth.createAccountWithBalance(donor);121 const malignant = await helper.eth.createAccountWithBalance(donor);122123 const {collectionId, contract} = await createNestingCollection(helper, owner);124125 126 const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});127 const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;128 const targetTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);129130 131 const mintingTokenIdResult = await contract.methods.mint(malignant).send({from: owner});132 const tokenId = mintingTokenIdResult.events.Transfer.returnValues.tokenId;133134 135 await expect(contract.methods136 .transfer(targetTokenAddress, tokenId)137 .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');138 });139140 itEth('NFT: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async ({helper}) => {141 const owner = await helper.eth.createAccountWithBalance(donor);142 const malignant = await helper.eth.createAccountWithBalance(donor);143144 const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);145 const {collectionAddress: collectionAddressB, contract: contractB} = await createNestingCollection(helper, owner);146147 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});148149 150 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});151 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;152 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);153154 155 const mintingTokenIdBResult = await contractB.methods.mint(malignant).send({from: owner});156 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;157158 159 await expect(contractB.methods160 .transfer(nftTokenAddressA, nftTokenIdB)161 .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');162 });163164 itEth('NFT: disallows to nest token in an unlisted collection', async ({helper}) => {165 const owner = await helper.eth.createAccountWithBalance(donor);166167 const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);168 const {contract: contractB} = await createNestingCollection(helper, owner);169170 await contractA.methods.setCollectionNesting(true, [collectionAddressA]).send({from: owner});171172 173 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});174 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;175 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);176177 178 const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});179 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;180181182 183 await expect(contractB.methods184 .transfer(nftTokenAddressA, nftTokenIdB)185 .call()).to.be.rejectedWith('SourceCollectionIsNotAllowedToNest');186 });187 });188});