1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, Pallets, usingPlaygrounds} from '../util';1920describe('Integration Test: Composite nesting tests', () => {21 let alice: IKeyringPair;22 let bob: IKeyringPair;2324 before(async () => {25 await usingPlaygrounds(async (helper, privateKey) => {26 const donor = await privateKey({filename: __filename});27 [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);28 });29 });3031 32 itSub('Performs the full suite: bundles a token, transfers, and unnests', async ({helper}) => {33 const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});34 const targetToken = await collection.mintToken(alice);3536 37 const nestedToken = await collection.mintToken(alice, targetToken.nestingAccount());38 expect(await nestedToken.getTopmostOwner()).to.be.deep.equal({Substrate: alice.address});39 expect(await nestedToken.getOwner()).to.be.deep.equal(targetToken.nestingAccount().toLowerCase());4041 42 const newToken = await collection.mintToken(alice);4344 45 await newToken.nest(alice, targetToken);46 expect(await newToken.getTopmostOwner()).to.be.deep.equal({Substrate: alice.address});47 expect(await newToken.getOwner()).to.be.deep.equal(targetToken.nestingAccount().toLowerCase());4849 50 await targetToken.transfer(alice, {Substrate: bob.address});51 expect(await nestedToken.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address});52 expect(await nestedToken.getOwner()).to.be.deep.equal(targetToken.nestingAccount().toLowerCase());53 expect(await newToken.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address});54 expect(await newToken.getOwner()).to.be.deep.equal(targetToken.nestingAccount().toLowerCase());5556 57 await newToken.unnest(bob, targetToken, {Substrate: bob.address});58 expect(await newToken.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address});59 expect(await newToken.getOwner()).to.be.deep.equal({Substrate: bob.address});60 });61});6263describe('Integration Test: Various token type nesting', () => {64 let alice: IKeyringPair;65 let bob: IKeyringPair;66 let charlie: IKeyringPair;6768 before(async () => {69 await usingPlaygrounds(async (helper, privateKey) => {70 const donor = await privateKey({filename: __filename});71 [alice, bob, charlie] = await helper.arrange.createAccounts([200n, 10n, 10n], donor);72 });73 });7475 itSub.ifWithPallets('ReFungible: getTopmostOwner works correctly with Nesting', [Pallets.ReFungible], async({helper}) => {76 const collectionNFT = await helper.nft.mintCollection(alice, {77 permissions: {78 nesting: {79 tokenOwner: true,80 },81 },82 });83 const collectionRFT = await helper.rft.mintCollection(alice);8485 const nft = await collectionNFT.mintToken(alice, {Substrate: alice.address});86 const rft = await collectionRFT.mintToken(alice, 100n, {Substrate: alice.address});8788 expect(await rft.getTopmostOwner()).deep.equal({Substrate: alice.address});8990 await rft.transfer(alice, nft.nestingAccount(), 40n);9192 expect(await rft.getTopmostOwner()).deep.equal(null);9394 await rft.transfer(alice, nft.nestingAccount(), 60n);9596 expect(await rft.getTopmostOwner()).deep.equal({Substrate: alice.address});9798 await rft.transferFrom(alice, nft.nestingAccount(), {Substrate: alice.address}, 30n);99100 expect(await rft.getTopmostOwner()).deep.equal(null);101102 await rft.transferFrom(alice, nft.nestingAccount(), {Substrate: alice.address}, 70n);103104 expect(await rft.getTopmostOwner()).deep.equal({Substrate: alice.address});105 });106});107108describe('Negative Test: Nesting', () => {109 let alice: IKeyringPair;110 let bob: IKeyringPair;111112 before(async () => {113 await usingPlaygrounds(async (helper, privateKey) => {114 const donor = await privateKey({filename: __filename});115 [alice, bob] = await helper.arrange.createAccounts([100n, 50n], donor);116 });117 });118119 itSub('Admin (NFT): disallows an Admin to operate nesting when only TokenOwner is allowed', async ({helper}) => {120 const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});121 await collection.addAdmin(alice, {Substrate: bob.address});122 const targetToken = await collection.mintToken(alice);123124 125 await expect(collection.mintToken(bob, targetToken.nestingAccount()))126 .to.be.rejectedWith(/common\.UserIsNotAllowedToNest/);127128 129 const newToken = await collection.mintToken(bob);130 await expect(newToken.nest(bob, targetToken))131 .to.be.rejectedWith(/common\.UserIsNotAllowedToNest/);132133 expect(await targetToken.getChildren()).to.be.length(0);134 expect(await newToken.getOwner()).to.be.deep.equal({Substrate: bob.address});135 });136137 itSub('Admin (NFT): disallows a Token Owner to operate nesting when only Admin is allowed', async ({helper}) => {138 const collectionAlice = await helper.nft.mintCollection(alice, {permissions: {access: 'AllowList', mintMode: true, nesting: {collectionAdmin: true}}});139 const targetTokenBob = await collectionAlice.mintToken(alice, {Substrate: bob.address});140 await collectionAlice.addToAllowList(alice, {Substrate: bob.address});141 await collectionAlice.addToAllowList(alice, targetTokenBob.nestingAccount());142143 144 await expect(collectionAlice.mintToken(bob, targetTokenBob.nestingAccount()))145 .to.be.rejectedWith(/common\.UserIsNotAllowedToNest/);146147 148 const newToken = await collectionAlice.mintToken(bob);149 await expect(newToken.nest(bob, targetTokenBob))150 .to.be.rejectedWith(/common\.UserIsNotAllowedToNest/);151152 expect(await targetTokenBob.getChildren()).to.be.length(0);153 expect(await newToken.getOwner()).to.be.deep.equal({Substrate: bob.address});154 });155156 itSub('Admin (NFT): disallows an Admin to unnest someone else\'s token', async ({helper}) => {157 const collection = await helper.nft.mintCollection(alice, {limits: {ownerCanTransfer: true}, permissions: {access: 'AllowList', mintMode: true, nesting: {collectionAdmin: true}}});158 159 const targetToken = await collection.mintToken(alice, {Substrate: bob.address});160 await collection.addToAllowList(alice, {Substrate: bob.address});161 await collection.addToAllowList(alice, targetToken.nestingAccount());162163 164 const newToken = await collection.mintToken(bob);165 await expect(newToken.nest(alice, targetToken))166 .to.be.rejectedWith(/common\.NoPermission/);167168 169 const nestedToken = await collection.mintToken(alice, targetToken.nestingAccount());170 await expect(nestedToken.unnest(alice, targetToken, {Substrate: bob.address}))171 .to.be.rejectedWith(/common\.AddressNotInAllowlist/);172173 expect(await targetToken.getChildren()).to.be.length(1);174 expect(await nestedToken.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address});175 expect(await nestedToken.getOwner()).to.be.deep.equal(targetToken.nestingAccount().toLowerCase());176 });177178 itSub('Fungible: disallows a non-Owner to unnest someone else\'s token', async ({helper}) => {179 const collectionNFT = await helper.nft.mintCollection(alice, {permissions: {nesting: {collectionAdmin: true, tokenOwner: true}}});180 const collectionFT = await helper.ft.mintCollection(alice);181 const targetToken = await collectionNFT.mintToken(alice, {Substrate: bob.address});182183 184 await collectionFT.mint(alice, 5n, targetToken.nestingAccount());185186 187 await expect(collectionFT.transferFrom(alice, targetToken.nestingAccount(), {Substrate: bob.address}, 1n))188 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);189 expect(await collectionFT.getBalance(targetToken.nestingAccount())).to.be.equal(5n);190 });191192 itSub('Fungible: disallows a non-Owner to unnest someone else\'s token (Restricted nesting)', async ({helper}) => {193 const collectionNFT = await helper.nft.mintCollection(alice);194 const collectionFT = await helper.ft.mintCollection(alice);195 const targetToken = await collectionNFT.mintToken(alice, {Substrate: bob.address});196197 await collectionNFT.setPermissions(alice, {nesting: {collectionAdmin: true, tokenOwner: true, restricted: [collectionFT.collectionId]}});198199 200 await collectionFT.mint(alice, 5n, targetToken.nestingAccount());201202 203 await expect(collectionFT.transferFrom(alice, targetToken.nestingAccount(), {Substrate: bob.address}, 1n))204 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);205 expect(await collectionFT.getBalance(targetToken.nestingAccount())).to.be.equal(5n);206 });207208});