From 903c7da37bfa36909876c11355476224142a09cb Mon Sep 17 00:00:00 2001 From: Fahrrader Date: Wed, 17 May 2023 12:04:14 +0000 Subject: [PATCH] test(sub/nesting): children checking + orderliness --- --- a/tests/package.json +++ b/tests/package.json @@ -39,12 +39,14 @@ "testParallelFull": "yarn testParallel && yarn testSequential", "testParallel": "yarn _testParallel './src/**/*.test.ts'", "testSequential": "yarn _test './src/**/*.seqtest.ts'", - "testStructure": "yarn setup && yarn _test ./**/nesting/*.*test.ts", - "testEth": "yarn setup && yarn _test './**/eth/**/*.*test.ts'", - "testEthNesting": "yarn setup && yarn _test './**/eth/nesting/**/*.*test.ts'", - "testEthFractionalizer": "yarn setup && yarn _test './**/eth/fractionalizer/**/*.*test.ts'", - "testEthMarketplace": "yarn setup && yarn _test './**/eth/marketplace/**/*.*test.ts'", - "testEvent": "yarn setup && yarn _test ./src/check-event/*.*test.ts", + "testStructure": "yarn _test ./**/nesting/*.*test.ts", + "testEth": "yarn _test './**/eth/**/*.*test.ts'", + "testEthNesting": "yarn _test './**/eth/nesting/**/*.*test.ts'", + "testEthFractionalizer": "yarn _test './**/eth/fractionalizer/**/*.*test.ts'", + "testEthMarketplace": "yarn _test './**/eth/marketplace/**/*.*test.ts'", + "testSub": "yarn _test './**/sub/**/*.*test.ts'", + "testSubNesting": "yarn _test './**/sub/nesting/**/*.*test.ts'", + "testEvent": "yarn _test ./src/check-event/*.*test.ts", "testEthPayable": "yarn _test './**/eth/payable.test.ts'", "testEvmCoder": "yarn _test './**/eth/evmCoder.test.ts'", "testNesting": "yarn _test ./**/nest.test.ts", --- a/tests/src/sub/nesting/admin.test.ts +++ b/tests/src/sub/nesting/admin.test.ts @@ -17,7 +17,7 @@ import {IKeyringPair} from '@polkadot/types/types'; import {expect, itSub, usingPlaygrounds} from '../../util'; -describe('Collection admin', () => { +describe('Nesting by collection admin', () => { let alice: IKeyringPair; let bob: IKeyringPair; let charlie: IKeyringPair; @@ -84,4 +84,3 @@ expect(await newToken.getOwner()).to.be.deep.equal(targetToken.nestingAccount().toLowerCase()); }); }); - --- a/tests/src/sub/nesting/common.test.ts +++ b/tests/src/sub/nesting/common.test.ts @@ -21,130 +21,143 @@ let alice: IKeyringPair; let bob: IKeyringPair; -before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = await privateKey({url: import.meta.url}); - [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor); +describe('Common nesting tests', () => { + before(async () => { + await usingPlaygrounds(async (helper, privateKey) => { + const donor = await privateKey({url: import.meta.url}); + [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor); + }); }); -}); -[ - {mode: 'nft' as const, restrictedMode: true, requiredPallets: []}, - {mode: 'nft' as const, restrictedMode: false, requiredPallets: []}, - {mode: 'rft' as const, restrictedMode: true, requiredPallets: [Pallets.ReFungible]}, - {mode: 'rft' as const, restrictedMode: false, requiredPallets: [Pallets.ReFungible]}, -].map(testCase => { - itSub.ifWithPallets(`Token owner can nest ${testCase.mode.toUpperCase()} in NFT if "tokenOwner" permission set ${testCase.restrictedMode ? 'in restricted mode': ''}`, testCase.requiredPallets, async ({helper}) => { - // Only NFT can be target for nesting in - const targetNFTCollection = await helper.nft.mintCollection(alice); - const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address}); + [ + {mode: 'nft' as const, restrictedMode: true, requiredPallets: []}, + {mode: 'nft' as const, restrictedMode: false, requiredPallets: []}, + {mode: 'rft' as const, restrictedMode: true, requiredPallets: [Pallets.ReFungible]}, + {mode: 'rft' as const, restrictedMode: false, requiredPallets: [Pallets.ReFungible]}, + ].map(testCase => { + itSub.ifWithPallets(`Token owner can nest ${testCase.mode.toUpperCase()} in NFT if "tokenOwner" permission set ${testCase.restrictedMode ? 'in restricted mode': ''}`, testCase.requiredPallets, async ({helper}) => { + // Only NFT can be target for nesting in + const targetNFTCollection = await helper.nft.mintCollection(alice); + const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address}); - const collectionForNesting = await helper[testCase.mode].mintCollection(bob); - // permissions should be set: - await targetNFTCollection.setPermissions(alice, { - nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionForNesting.collectionId] : null}, - }); + const collectionForNesting = await helper[testCase.mode].mintCollection(bob); + // permissions should be set: + await targetNFTCollection.setPermissions(alice, { + nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionForNesting.collectionId] : null}, + }); - // 1. Bob can immediately create nested token: - const nestedToken1 = testCase.mode === 'nft' - ? await (collectionForNesting as UniqueNFTCollection).mintToken(bob, targetTokenBob.nestingAccount()) - : await (collectionForNesting as UniqueRFTCollection).mintToken(bob, 10n, targetTokenBob.nestingAccount()); - expect(await nestedToken1.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address}); - expect(await nestedToken1.getOwner()).to.be.deep.equal(targetTokenBob.nestingAccount().toLowerCase()); + // 1. Bob can immediately create nested token: + const nestedToken1 = testCase.mode === 'nft' + ? await (collectionForNesting as UniqueNFTCollection).mintToken(bob, targetTokenBob.nestingAccount()) + : await (collectionForNesting as UniqueRFTCollection).mintToken(bob, 10n, targetTokenBob.nestingAccount()); + expect(await nestedToken1.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address}); + expect(await nestedToken1.getOwner()).to.be.deep.equal(targetTokenBob.nestingAccount().toLowerCase()); - // 2. Bob can mint and nest token: - const nestedToken2 = await collectionForNesting.mintToken(bob); - await nestedToken2.nest(bob, targetTokenBob); - expect(await nestedToken2.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address}); - expect(await nestedToken2.getOwner()).to.be.deep.equal(targetTokenBob.nestingAccount().toLowerCase()); + // 2. Bob can mint and nest token: + const nestedToken2 = await collectionForNesting.mintToken(bob); + await nestedToken2.nest(bob, targetTokenBob); + expect(await nestedToken2.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address}); + expect(await nestedToken2.getOwner()).to.be.deep.equal(targetTokenBob.nestingAccount().toLowerCase()); + }); }); -}); -[ - {restrictedMode: true}, - {restrictedMode: false}, -].map(testCase => { - itSub(`Token owner can nest FT in NFT if "tokenOwner" permission set ${testCase.restrictedMode ? 'in restricted mode': ''}`, async ({helper}) => { - // Only NFT allows nesting, permissions should be set: - const targetNFTCollection = await helper.nft.mintCollection(alice); - const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address}); + [ + {restrictedMode: true}, + {restrictedMode: false}, + ].map(testCase => { + itSub(`Token owner can nest FT in NFT if "tokenOwner" permission set ${testCase.restrictedMode ? 'in restricted mode': ''}`, async ({helper}) => { + // Only NFT allows nesting, permissions should be set: + const targetNFTCollection = await helper.nft.mintCollection(alice); + const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address}); - const collectionForNesting = await helper.ft.mintCollection(bob); - // permissions should be set: - await targetNFTCollection.setPermissions(alice, { - nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionForNesting.collectionId] : null}, - }); + const collectionForNesting = await helper.ft.mintCollection(bob); + // permissions should be set: + await targetNFTCollection.setPermissions(alice, { + nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionForNesting.collectionId] : null}, + }); - // 1. Alice can immediately create nested tokens: - await collectionForNesting.mint(bob, 100n, targetTokenBob.nestingAccount()); - expect(await collectionForNesting.getTop10Owners()).deep.eq([targetTokenBob.nestingAccount().toLowerCase()]); - expect(await collectionForNesting.getBalance(targetTokenBob.nestingAccount())).eq(100n); + // 1. Alice can immediately create nested tokens: + await collectionForNesting.mint(bob, 100n, targetTokenBob.nestingAccount()); + expect(await collectionForNesting.getTop10Owners()).deep.eq([targetTokenBob.nestingAccount().toLowerCase()]); + expect(await collectionForNesting.getBalance(targetTokenBob.nestingAccount())).eq(100n); - // 2. Alice can mint and nest token: - await collectionForNesting.mint(bob, 100n); - await collectionForNesting.transfer(bob, targetTokenBob.nestingAccount(), 50n); - expect(await collectionForNesting.getBalance(targetTokenBob.nestingAccount())).eq(150n); + // 2. Alice can mint and nest token: + await collectionForNesting.mint(bob, 100n); + await collectionForNesting.transfer(bob, targetTokenBob.nestingAccount(), 50n); + expect(await collectionForNesting.getBalance(targetTokenBob.nestingAccount())).eq(150n); + expect(await targetTokenBob.getChildren()).to.be.deep.equal([{collectionId: collectionForNesting.collectionId, tokenId: 0}]); + }); }); -}); -[ - {restrictedMode: true}, - {restrictedMode: false}, -].map(testCase => { - itSub(`Token owner can nest Native FT in NFT if "tokenOwner" permission set ${testCase.restrictedMode ? 'in restricted mode': ''}`, async ({helper}) => { - // Only NFT allows nesting, permissions should be set: - const targetNFTCollection = await helper.nft.mintCollection(alice); - const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address}); + [ + {restrictedMode: true}, + {restrictedMode: false}, + ].map(testCase => { + itSub(`Token owner can nest Native FT in NFT if "tokenOwner" permission set ${testCase.restrictedMode ? 'in restricted mode': ''}`, async ({helper}) => { + // Only NFT allows nesting, permissions should be set: + const targetNFTCollection = await helper.nft.mintCollection(alice); + const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address}); + expect(await targetTokenBob.getChildren()).to.be.empty; - const collectionForNesting = helper.ft.getCollectionObject(0); - // permissions should be set: - await targetNFTCollection.setPermissions(alice, { - nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionForNesting.collectionId] : null}, + const collectionForNesting = helper.ft.getCollectionObject(0); + // permissions should be set: + await targetNFTCollection.setPermissions(alice, { + nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionForNesting.collectionId] : null}, + }); + + // Bob can nest Native FT into their NFT: + await collectionForNesting.transfer(bob, targetTokenBob.nestingAccount(), 50n); + expect(await collectionForNesting.getBalance(targetTokenBob.nestingAccount())).eq(50n); + expect(await targetTokenBob.getChildren()).to.be.deep.equal([{collectionId: 0, tokenId: 0}]); }); - - // Bob can nest Native FT into their NFT: - await collectionForNesting.transfer(bob, targetTokenBob.nestingAccount(), 50n); - expect(await collectionForNesting.getBalance(targetTokenBob.nestingAccount())).eq(50n); }); -}); -itSub.ifWithPallets('Owner can unnest tokens using transferFrom', [Pallets.ReFungible], async ({helper}) => { - const collectionToNest = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); - const tokenA = await collectionToNest.mintToken(alice); - const tokenB = await collectionToNest.mintToken(alice); + itSub.ifWithPallets('Owner can unnest tokens using transferFrom', [Pallets.ReFungible], async ({helper}) => { + const collectionToNest = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); + const tokenA = await collectionToNest.mintToken(alice); + const tokenB = await collectionToNest.mintToken(alice); - // Create a nested token - const nftCollectionToBeNested = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); - const rftCollectionToBeNested = await helper.rft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); - const ftCollectionToBeNested = await helper.ft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); - const nativeFtCollectionToBeNested = helper.ft.getCollectionObject(0); + // Create a nested token + const nftCollectionToBeNested = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); + const rftCollectionToBeNested = await helper.rft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); + const ftCollectionToBeNested = await helper.ft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); + const nativeFtCollectionToBeNested = helper.ft.getCollectionObject(0); - const nestedNFT = await nftCollectionToBeNested.mintToken(alice, tokenA.nestingAccount()); - const nestedRFT = await rftCollectionToBeNested.mintToken(alice, 100n, tokenA.nestingAccount()); - const _nestedFT = await ftCollectionToBeNested.mint(alice, 100n, tokenA.nestingAccount()); - await nativeFtCollectionToBeNested.transfer(alice, tokenA.nestingAccount(), 100n); - expect(await nestedNFT.getOwner()).to.be.deep.equal(tokenA.nestingAccount().toLowerCase()); - expect(await nestedRFT.getOwner()).to.be.deep.equal(tokenA.nestingAccount().toLowerCase()); - expect(await ftCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(100n); - expect(await nativeFtCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(100n); + const nestedNFT = await nftCollectionToBeNested.mintToken(alice, tokenA.nestingAccount()); + const nestedRFT = await rftCollectionToBeNested.mintToken(alice, 100n, tokenA.nestingAccount()); + const _nestedFT = await ftCollectionToBeNested.mint(alice, 100n, tokenA.nestingAccount()); + await nativeFtCollectionToBeNested.transfer(alice, tokenA.nestingAccount(), 100n); + expect(await nestedNFT.getOwner()).to.be.deep.equal(tokenA.nestingAccount().toLowerCase()); + expect(await nestedRFT.getOwner()).to.be.deep.equal(tokenA.nestingAccount().toLowerCase()); + expect(await ftCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(100n); + expect(await nativeFtCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(100n); - // Transfer the nested token to another token - await nestedNFT.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount()); - await nestedRFT.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount(), 25n); - await ftCollectionToBeNested.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount(), 25n); - await nativeFtCollectionToBeNested.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount(), 25n); + expect(await tokenA.getChildren()).to.be.length(4); + expect(await tokenB.getChildren()).to.be.length(0); - expect(await nestedNFT.getTopmostOwner()).to.be.deep.equal({Substrate: alice.address}); - expect(await nestedNFT.getOwner()).to.be.deep.equal(tokenB.nestingAccount().toLowerCase()); + // Transfer the nested token to another token + await nestedNFT.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount()); + await nestedRFT.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount(), 25n); + await ftCollectionToBeNested.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount(), 25n); + await nativeFtCollectionToBeNested.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount(), 25n); - expect(await nestedRFT.getBalance(tokenB.nestingAccount())).to.equal(25n); - expect(await nestedRFT.getBalance(tokenA.nestingAccount())).to.equal(75n); + expect(await nestedNFT.getTopmostOwner()).to.be.deep.equal({Substrate: alice.address}); + expect(await nestedNFT.getOwner()).to.be.deep.equal(tokenB.nestingAccount().toLowerCase()); + + expect(await nestedRFT.getBalance(tokenB.nestingAccount())).to.equal(25n); + expect(await nestedRFT.getBalance(tokenA.nestingAccount())).to.equal(75n); + + expect(await ftCollectionToBeNested.getBalance(tokenB.nestingAccount())).to.equal(25n); + expect(await ftCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(75n); - expect(await ftCollectionToBeNested.getBalance(tokenB.nestingAccount())).to.equal(25n); - expect(await ftCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(75n); + expect(await nativeFtCollectionToBeNested.getBalance(tokenB.nestingAccount())).to.equal(25n); + expect(await nativeFtCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(75n); - expect(await nativeFtCollectionToBeNested.getBalance(tokenB.nestingAccount())).to.equal(25n); - expect(await nativeFtCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(75n); + // RFT, FT, and native FT + expect(await tokenA.getChildren()).to.be.length(3); + // NFT, RFT, FT, and native FT + expect(await tokenB.getChildren()).to.be.length(4); + }); }); --- a/tests/src/sub/nesting/e2e.test.ts +++ b/tests/src/sub/nesting/e2e.test.ts @@ -32,7 +32,7 @@ const collectionA = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); const collectionB = await helper.ft.mintCollection(alice); const collectionC = await helper.rft.mintCollection(alice); - const collectionD = helper.ft.getCollectionObject(0); + const collectionNative = helper.ft.getCollectionObject(0); const targetToken = await collectionA.mintToken(alice); expect((await targetToken.getChildren()).length).to.be.equal(0, 'Children length check at creation'); @@ -75,12 +75,12 @@ ]).and.has.length(3); // Nest native fungible token into another collection - await collectionD.transfer(alice, targetToken.nestingAccount(), 2n); + await collectionNative.transfer(alice, targetToken.nestingAccount(), 2n); expect(await targetToken.getChildren()).to.have.deep.members([ {tokenId: tokenA.tokenId, collectionId: collectionA.collectionId}, {tokenId: 0, collectionId: collectionB.collectionId}, {tokenId: tokenC.tokenId, collectionId: collectionC.collectionId}, - {tokenId: 0, collectionId: collectionD.collectionId}, + {tokenId: 0, collectionId: collectionNative.collectionId}, ]).and.has.length(4); // Burn all nested pieces @@ -88,7 +88,7 @@ expect(await targetToken.getChildren()).to.have.deep.members([ {tokenId: tokenA.tokenId, collectionId: collectionA.collectionId}, {tokenId: 0, collectionId: collectionB.collectionId}, - {tokenId: 0, collectionId: collectionD.collectionId}, + {tokenId: 0, collectionId: collectionNative.collectionId}, ]) .and.has.length(3); @@ -97,7 +97,7 @@ expect(await targetToken.getChildren()).to.be.have.deep.members([ {tokenId: tokenA.tokenId, collectionId: collectionA.collectionId}, {tokenId: 0, collectionId: collectionB.collectionId}, - {tokenId: 0, collectionId: collectionD.collectionId}, + {tokenId: 0, collectionId: collectionNative.collectionId}, ]).and.has.length(3); // Nested token also has children now: expect(await tokenA.getChildren()).to.have.deep.members([ @@ -108,7 +108,7 @@ await collectionB.transferFrom(alice, targetToken.nestingAccount(), tokenA.nestingAccount(), 1n); expect(await targetToken.getChildren()).to.have.deep.members([ {tokenId: tokenA.tokenId, collectionId: collectionA.collectionId}, - {tokenId: 0, collectionId: collectionD.collectionId}, + {tokenId: 0, collectionId: collectionNative.collectionId}, ]).and.has.length(2); expect(await tokenA.getChildren()).to.have.deep.members([ {tokenId: 0, collectionId: collectionB.collectionId}, --- a/tests/src/sub/nesting/nesting.negative.test.ts +++ b/tests/src/sub/nesting/nesting.negative.test.ts @@ -23,263 +23,265 @@ let bob: IKeyringPair; let charlie: IKeyringPair; -before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = await privateKey({url: import.meta.url}); - [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor); +describe('Negative Test: Nesting', () => { + before(async () => { + await usingPlaygrounds(async (helper, privateKey) => { + const donor = await privateKey({url: import.meta.url}); + [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor); + }); }); -}); -[ - {mode: 'nft' as const, requiredPallets: []}, - {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]}, -].map(testCase => { - itSub.ifWithPallets(`Owner cannot nest ${testCase.mode.toUpperCase()} if nesting is disabled`, testCase.requiredPallets, async ({helper}) => { - // Create default collection, permissions are not set: - const aliceNFTCollection = await helper.nft.mintCollection(alice); - const targetToken = await aliceNFTCollection.mintToken(alice); + [ + {mode: 'nft' as const, requiredPallets: []}, + {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]}, + ].map(testCase => { + itSub.ifWithPallets(`Owner cannot nest ${testCase.mode.toUpperCase()} if nesting is disabled`, testCase.requiredPallets, async ({helper}) => { + // Create default collection, permissions are not set: + const aliceNFTCollection = await helper.nft.mintCollection(alice); + const targetToken = await aliceNFTCollection.mintToken(alice); - const collectionForNesting = await helper[testCase.mode].mintCollection(alice); + const collectionForNesting = await helper[testCase.mode].mintCollection(alice); - // 1. Alice cannot create immediately nested tokens: - const nestingTx = testCase.mode === 'nft' - ? (collectionForNesting as UniqueNFTCollection).mintToken(alice, targetToken.nestingAccount()) - : (collectionForNesting as UniqueRFTCollection).mintToken(alice, 10n, targetToken.nestingAccount()); - await expect(nestingTx).to.be.rejectedWith('common.UserIsNotAllowedToNest'); + // 1. Alice cannot create immediately nested tokens: + const nestingTx = testCase.mode === 'nft' + ? (collectionForNesting as UniqueNFTCollection).mintToken(alice, targetToken.nestingAccount()) + : (collectionForNesting as UniqueRFTCollection).mintToken(alice, 10n, targetToken.nestingAccount()); + await expect(nestingTx).to.be.rejectedWith('common.UserIsNotAllowedToNest'); - // 2. Alice cannot mint and nest token: - const nestedToken2 = await collectionForNesting.mintToken(alice); - await expect(nestedToken2.nest(alice, targetToken)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); + // 2. Alice cannot mint and nest token: + const nestedToken2 = await collectionForNesting.mintToken(alice); + await expect(nestedToken2.nest(alice, targetToken)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); + }); }); -}); -[ - {mode: 'ft'}, - {mode: 'nativeFt'}, -].map(testCase => { - itSub(`Owner cannot nest [${testCase.mode}] if nesting is disabled`, async ({helper}) => { - // Create default collection, permissions are not set: - const aliceNFTCollection = await helper.nft.mintCollection(alice); - const targetToken = await aliceNFTCollection.mintToken(alice); + [ + {mode: 'ft'}, + {mode: 'nativeFt'}, + ].map(testCase => { + itSub(`Owner cannot nest [${testCase.mode}] if nesting is disabled`, async ({helper}) => { + // Create default collection, permissions are not set: + const aliceNFTCollection = await helper.nft.mintCollection(alice); + const targetToken = await aliceNFTCollection.mintToken(alice); - const collectionForNesting = testCase.mode === 'ft' ? await helper.ft.mintCollection(alice) : helper.ft.getCollectionObject(0); + const collectionForNesting = testCase.mode === 'ft' ? await helper.ft.mintCollection(alice) : helper.ft.getCollectionObject(0); - // Alice cannot create immediately nested tokens: - await expect(testCase.mode === 'ft' - ? collectionForNesting.mint(alice, 100n, targetToken.nestingAccount()) - : collectionForNesting.transfer(alice, targetToken.nestingAccount(), 100n)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); + // Alice cannot create immediately nested tokens: + await expect(testCase.mode === 'ft' + ? collectionForNesting.mint(alice, 100n, targetToken.nestingAccount()) + : collectionForNesting.transfer(alice, targetToken.nestingAccount(), 100n)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); - // Alice can't mint and nest tokens: - if (testCase.mode === 'ft') { - await collectionForNesting.mint(alice, 100n); - } - await expect(collectionForNesting.transfer(alice, targetToken.nestingAccount(), 50n)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); + // Alice can't mint and nest tokens: + if (testCase.mode === 'ft') { + await collectionForNesting.mint(alice, 100n); + } + await expect(collectionForNesting.transfer(alice, targetToken.nestingAccount(), 50n)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); + }); }); -}); -[ - {mode: 'nft' as const}, - {mode: 'rft' as const}, - {mode: 'ft' as const}, - {mode: 'native ft' as const}, -].map(testCase => { - itSub(`Non-owner and non-admin cannot nest ${testCase.mode.toUpperCase()} in someone else's tokens`, async ({helper}) => { - const targetCollection = await helper.nft.mintCollection(alice, {permissions: - {nesting: {tokenOwner: true, collectionAdmin: true}}, - }); - const targetToken = await targetCollection.mintToken(alice); + [ + {mode: 'nft' as const}, + {mode: 'rft' as const}, + {mode: 'ft' as const}, + {mode: 'native ft' as const}, + ].map(testCase => { + itSub(`Non-owner and non-admin cannot nest ${testCase.mode.toUpperCase()} in someone else's tokens`, async ({helper}) => { + const targetCollection = await helper.nft.mintCollection(alice, {permissions: + {nesting: {tokenOwner: true, collectionAdmin: true}}, + }); + const targetToken = await targetCollection.mintToken(alice); - const nestedCollectionBob = await ( - testCase.mode === 'native ft' - ? helper.ft.getCollectionObject(0) - : helper[testCase.mode].mintCollection(bob) - ); + const nestedCollectionBob = await ( + testCase.mode === 'native ft' + ? helper.ft.getCollectionObject(0) + : helper[testCase.mode].mintCollection(bob) + ); - let nestedTokenBob: UniqueNFToken | UniqueRFToken; - switch (testCase.mode) { - case 'nft': nestedTokenBob = await (nestedCollectionBob as UniqueNFTCollection).mintToken(bob); break; - case 'rft': nestedTokenBob = await (nestedCollectionBob as UniqueRFTCollection).mintToken(bob, 100n); break; - case 'ft': await (nestedCollectionBob as UniqueFTCollection).mint(bob, 100n); break; - case 'native ft': await expect((nestedCollectionBob as UniqueFTCollection).mint(bob, 100n)).to.be.rejectedWith('common.UnsupportedOperation'); break; - } + let nestedTokenBob: UniqueNFToken | UniqueRFToken; + switch (testCase.mode) { + case 'nft': nestedTokenBob = await (nestedCollectionBob as UniqueNFTCollection).mintToken(bob); break; + case 'rft': nestedTokenBob = await (nestedCollectionBob as UniqueRFTCollection).mintToken(bob, 100n); break; + case 'ft': await (nestedCollectionBob as UniqueFTCollection).mint(bob, 100n); break; + case 'native ft': await expect((nestedCollectionBob as UniqueFTCollection).mint(bob, 100n)).to.be.rejectedWith('common.UnsupportedOperation'); break; + } - // Bob non-owner of targetToken and non admin of targetCollection, so - // 1. cannot mint nested token: - switch (testCase.mode) { - case 'nft': await expect((nestedCollectionBob as UniqueNFTCollection).mintToken(bob, targetToken.nestingAccount())).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; - case 'rft': await expect((nestedCollectionBob as UniqueRFTCollection).mintToken(bob, 100n, targetToken.nestingAccount())).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; - case 'ft': await expect((nestedCollectionBob as UniqueFTCollection).mint(bob, 100n, targetToken.nestingAccount())).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; - case 'native ft': await expect((nestedCollectionBob as UniqueFTCollection).mint(bob, 100n, targetToken.nestingAccount())).to.be.rejectedWith('common.UnsupportedOperation'); break; - } + // Bob non-owner of targetToken and non admin of targetCollection, so + // 1. cannot mint nested token: + switch (testCase.mode) { + case 'nft': await expect((nestedCollectionBob as UniqueNFTCollection).mintToken(bob, targetToken.nestingAccount())).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; + case 'rft': await expect((nestedCollectionBob as UniqueRFTCollection).mintToken(bob, 100n, targetToken.nestingAccount())).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; + case 'ft': await expect((nestedCollectionBob as UniqueFTCollection).mint(bob, 100n, targetToken.nestingAccount())).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; + case 'native ft': await expect((nestedCollectionBob as UniqueFTCollection).mint(bob, 100n, targetToken.nestingAccount())).to.be.rejectedWith('common.UnsupportedOperation'); break; + } - // 2. cannot nest existing token: - switch (testCase.mode) { - case 'nft': - case 'rft': await expect(nestedTokenBob!.transfer(bob, targetToken.nestingAccount())).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; - case 'ft': await expect((nestedCollectionBob as UniqueFTCollection).transfer(bob, targetToken.nestingAccount(), 100n)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; - case 'native ft': await expect((nestedCollectionBob as UniqueFTCollection).transfer(bob, targetToken.nestingAccount(), 100n)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; - } + // 2. cannot nest existing token: + switch (testCase.mode) { + case 'nft': + case 'rft': await expect(nestedTokenBob!.transfer(bob, targetToken.nestingAccount())).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; + case 'ft': await expect((nestedCollectionBob as UniqueFTCollection).transfer(bob, targetToken.nestingAccount(), 100n)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; + case 'native ft': await expect((nestedCollectionBob as UniqueFTCollection).transfer(bob, targetToken.nestingAccount(), 100n)).to.be.rejectedWith('common.UserIsNotAllowedToNest'); break; + } + }); }); -}); -[ - {mode: 'nft' as const, nesting: {tokenOwner: true, collectionAdmin: false}}, - {mode: 'nft' as const, nesting: {tokenOwner: false, collectionAdmin: true}}, -].map(testCase => { - itSub(`${testCase.nesting.tokenOwner ? 'Admin' : 'Token owner'} cannot nest when only ${testCase.nesting.tokenOwner ? 'tokenOwner' : 'collectionAdmin'} is allowed`, async ({helper}) => { - // Create collection with tokenOwner or create collection with collectionAdmin permission: - const targetCollection = await helper.nft.mintCollection(alice, {permissions: {nesting: testCase.nesting}}); - const targetTokenCharlie = await targetCollection.mintToken(alice, {Substrate: charlie.address}); - await targetCollection.addAdmin(alice, {Substrate: bob.address}); + [ + {mode: 'nft' as const, nesting: {tokenOwner: true, collectionAdmin: false}}, + {mode: 'nft' as const, nesting: {tokenOwner: false, collectionAdmin: true}}, + ].map(testCase => { + itSub(`${testCase.nesting.tokenOwner ? 'Admin' : 'Token owner'} cannot nest when only ${testCase.nesting.tokenOwner ? 'tokenOwner' : 'collectionAdmin'} is allowed`, async ({helper}) => { + // Create collection with tokenOwner or create collection with collectionAdmin permission: + const targetCollection = await helper.nft.mintCollection(alice, {permissions: {nesting: testCase.nesting}}); + const targetTokenCharlie = await targetCollection.mintToken(alice, {Substrate: charlie.address}); + await targetCollection.addAdmin(alice, {Substrate: bob.address}); - const nestedCollectionCharlie = await helper[testCase.mode].mintCollection(charlie); - const nestedCollectionBob = await helper[testCase.mode].mintCollection(bob); - // if nesting permissions restricted for token owner – minter is bob (admin), - // if collectionAdmin – charlie (owner) - testCase.nesting.tokenOwner - ? await expect(nestedCollectionBob.mintToken(bob, targetTokenCharlie.nestingAccount())).to.be.rejectedWith(/common\.UserIsNotAllowedToNest/) - : await expect(nestedCollectionCharlie.mintToken(charlie, targetTokenCharlie.nestingAccount())).to.be.rejectedWith(/common\.UserIsNotAllowedToNest/); + const nestedCollectionCharlie = await helper[testCase.mode].mintCollection(charlie); + const nestedCollectionBob = await helper[testCase.mode].mintCollection(bob); + // if nesting permissions restricted for token owner – minter is bob (admin), + // if collectionAdmin – charlie (owner) + testCase.nesting.tokenOwner + ? await expect(nestedCollectionBob.mintToken(bob, targetTokenCharlie.nestingAccount())).to.be.rejectedWith(/common\.UserIsNotAllowedToNest/) + : await expect(nestedCollectionCharlie.mintToken(charlie, targetTokenCharlie.nestingAccount())).to.be.rejectedWith(/common\.UserIsNotAllowedToNest/); + }); }); -}); -itSub.ifWithPallets('Cannot nest in non existing token', [Pallets.ReFungible], async ({helper}) => { - const collection = await helper.nft.mintCollection(alice); - // To avoid UserIsNotAllowedToNest error - await helper.collection.setPermissions(alice, collection.collectionId, {nesting: {collectionAdmin: true}}); + itSub.ifWithPallets('Cannot nest in non existing token', [Pallets.ReFungible], async ({helper}) => { + const collection = await helper.nft.mintCollection(alice); + // To avoid UserIsNotAllowedToNest error + await helper.collection.setPermissions(alice, collection.collectionId, {nesting: {collectionAdmin: true}}); - // The list of non-existing tokens: - const tokenFromNonExistingCollection = helper.nft.getTokenObject(9999999, 1); - const tokenBurnt = await collection.mintToken(alice); - await tokenBurnt.burn(alice); - const tokenNotMintedYet = helper.nft.getTokenObject(collection.collectionId, 2); + // The list of non-existing tokens: + const tokenFromNonExistingCollection = helper.nft.getTokenObject(9999999, 1); + const tokenBurnt = await collection.mintToken(alice); + await tokenBurnt.burn(alice); + const tokenNotMintedYet = helper.nft.getTokenObject(collection.collectionId, 2); - // The list of collections to nest tokens from: - const nftCollectionForNesting = await helper.nft.mintCollection(alice); - const rftCollectionForNesting = await helper.rft.mintCollection(alice); - const ftCollectionForNesting = await helper.ft.mintCollection(alice); - const nativeFtCollectionForNesting = helper.ft.getCollectionObject(0); + // The list of collections to nest tokens from: + const nftCollectionForNesting = await helper.nft.mintCollection(alice); + const rftCollectionForNesting = await helper.rft.mintCollection(alice); + const ftCollectionForNesting = await helper.ft.mintCollection(alice); + const nativeFtCollectionForNesting = helper.ft.getCollectionObject(0); - const testCases = [ - {token: tokenFromNonExistingCollection, error: 'CollectionNotFound'}, - {token: tokenBurnt, error: 'TokenNotFound'}, - {token: tokenNotMintedYet, error: 'TokenNotFound'}, - ]; + const testCases = [ + {token: tokenFromNonExistingCollection, error: 'CollectionNotFound'}, + {token: tokenBurnt, error: 'TokenNotFound'}, + {token: tokenNotMintedYet, error: 'TokenNotFound'}, + ]; - for(const testCase of testCases) { - // 1. Alice cannot create nested token to non-existing token - await expect(nftCollectionForNesting.mintToken(alice, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); - await expect(rftCollectionForNesting.mintToken(alice, 10n, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); - await expect(ftCollectionForNesting.mint(alice, 10n, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); + for(const testCase of testCases) { + // 1. Alice cannot create nested token to non-existing token + await expect(nftCollectionForNesting.mintToken(alice, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); + await expect(rftCollectionForNesting.mintToken(alice, 10n, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); + await expect(ftCollectionForNesting.mint(alice, 10n, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); - // 2. Alice cannot mint and nest token: - const nft = await nftCollectionForNesting.mintToken(alice); - const rft = await rftCollectionForNesting.mintToken(alice, 100n); - const _ft = await ftCollectionForNesting.mint(alice, 100n); - await expect(nft.transfer(alice, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); - await expect(rft.transfer(alice, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); - await expect(ftCollectionForNesting.transfer(alice, testCase.token.nestingAccount(), 50n)).to.be.rejectedWith(testCase.error); - await expect(nativeFtCollectionForNesting.transfer(alice, testCase.token.nestingAccount(), 50n)).to.be.rejectedWith(testCase.error); - } -}); + // 2. Alice cannot mint and nest token: + const nft = await nftCollectionForNesting.mintToken(alice); + const rft = await rftCollectionForNesting.mintToken(alice, 100n); + const _ft = await ftCollectionForNesting.mint(alice, 100n); + await expect(nft.transfer(alice, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); + await expect(rft.transfer(alice, testCase.token.nestingAccount())).to.be.rejectedWith(testCase.error); + await expect(ftCollectionForNesting.transfer(alice, testCase.token.nestingAccount(), 50n)).to.be.rejectedWith(testCase.error); + await expect(nativeFtCollectionForNesting.transfer(alice, testCase.token.nestingAccount(), 50n)).to.be.rejectedWith(testCase.error); + } + }); -itEth.ifWithPallets('Cannot nest in collection address', [Pallets.ReFungible], async({helper}) => { - const existingCollection = await helper.nft.mintCollection(alice); - const existingCollectionAddress = helper.ethAddress.fromCollectionId(existingCollection.collectionId); - const futureCollectionAddress = helper.ethAddress.fromCollectionId(99999999); + itEth.ifWithPallets('Cannot nest in collection address', [Pallets.ReFungible], async({helper}) => { + const existingCollection = await helper.nft.mintCollection(alice); + const existingCollectionAddress = helper.ethAddress.fromCollectionId(existingCollection.collectionId); + const futureCollectionAddress = helper.ethAddress.fromCollectionId(99999999); - const nftCollectionForNesting = await helper.nft.mintCollection(alice); + const nftCollectionForNesting = await helper.nft.mintCollection(alice); - // 1. Alice cannot create nested token to collection address - await expect(nftCollectionForNesting.mintToken(alice, {Ethereum: existingCollectionAddress})).to.be.rejectedWith('CantNestTokenUnderCollection'); - await expect(nftCollectionForNesting.mintToken(alice, {Ethereum: futureCollectionAddress})).to.be.rejectedWith('CantNestTokenUnderCollection'); + // 1. Alice cannot create nested token to collection address + await expect(nftCollectionForNesting.mintToken(alice, {Ethereum: existingCollectionAddress})).to.be.rejectedWith('CantNestTokenUnderCollection'); + await expect(nftCollectionForNesting.mintToken(alice, {Ethereum: futureCollectionAddress})).to.be.rejectedWith('CantNestTokenUnderCollection'); - // 2. Alice cannot mint and nest token to collection address: - const nft = await nftCollectionForNesting.mintToken(alice); - await expect(nft.transfer(alice, {Ethereum: existingCollectionAddress})).to.be.rejectedWith('CantNestTokenUnderCollection'); - await expect(nft.transfer(alice, {Ethereum: futureCollectionAddress})).to.be.rejectedWith('CantNestTokenUnderCollection'); -}); + // 2. Alice cannot mint and nest token to collection address: + const nft = await nftCollectionForNesting.mintToken(alice); + await expect(nft.transfer(alice, {Ethereum: existingCollectionAddress})).to.be.rejectedWith('CantNestTokenUnderCollection'); + await expect(nft.transfer(alice, {Ethereum: futureCollectionAddress})).to.be.rejectedWith('CantNestTokenUnderCollection'); + }); -itEth.ifWithPallets('Cannot nest in RFT or FT', [Pallets.ReFungible], async ({helper}) => { - // Create default collection, permissions are not set: - const rftCollection = await helper.rft.mintCollection(alice); - const ftCollection = await helper.ft.mintCollection(alice); - const nativeFtCollection = helper.ft.getCollectionObject(0); + itEth.ifWithPallets('Cannot nest in RFT or FT', [Pallets.ReFungible], async ({helper}) => { + // Create default collection, permissions are not set: + const rftCollection = await helper.rft.mintCollection(alice); + const ftCollection = await helper.ft.mintCollection(alice); + const nativeFtCollection = helper.ft.getCollectionObject(0); - const rftToken = await rftCollection.mintToken(alice); - const _ftToken = await ftCollection.mint(alice, 100n); + const rftToken = await rftCollection.mintToken(alice); + const _ftToken = await ftCollection.mint(alice, 100n); - const collectionForNesting = await helper.nft.mintCollection(alice); + const collectionForNesting = await helper.nft.mintCollection(alice); - // 1. Alice cannot create immediately nested tokens: - await expect(collectionForNesting.mintToken(alice, rftToken.nestingAccount())).to.be.rejectedWith('refungible.RefungibleDisallowsNesting'); - await expect(collectionForNesting.mintToken(alice, {Ethereum: helper.ethAddress.fromTokenId(ftCollection.collectionId, 0)})).to.be.rejectedWith('fungible.FungibleDisallowsNesting'); - await expect(collectionForNesting.mintToken(alice, {Ethereum: helper.ethAddress.fromTokenId(nativeFtCollection.collectionId, 0)})).to.be.rejectedWith('common.UnsupportedOperation'); + // 1. Alice cannot create immediately nested tokens: + await expect(collectionForNesting.mintToken(alice, rftToken.nestingAccount())).to.be.rejectedWith('refungible.RefungibleDisallowsNesting'); + await expect(collectionForNesting.mintToken(alice, {Ethereum: helper.ethAddress.fromTokenId(ftCollection.collectionId, 0)})).to.be.rejectedWith('fungible.FungibleDisallowsNesting'); + await expect(collectionForNesting.mintToken(alice, {Ethereum: helper.ethAddress.fromTokenId(nativeFtCollection.collectionId, 0)})).to.be.rejectedWith('common.UnsupportedOperation'); - // 2. Alice cannot mint and nest token: - const nestedToken2 = await collectionForNesting.mintToken(alice); - await expect(nestedToken2.nest(alice, rftToken)).to.be.rejectedWith('refungible.RefungibleDisallowsNesting'); - await expect(ftCollection.transfer(alice, {Ethereum: helper.ethAddress.fromTokenId(ftCollection.collectionId, 0)})).to.be.rejectedWith('fungible.FungibleDisallowsNesting'); - await expect(nativeFtCollection.transfer(alice, {Ethereum: helper.ethAddress.fromTokenId(nativeFtCollection.collectionId, 0)})).to.be.rejectedWith('common.UnsupportedOperation'); -}); + // 2. Alice cannot mint and nest token: + const nestedToken2 = await collectionForNesting.mintToken(alice); + await expect(nestedToken2.nest(alice, rftToken)).to.be.rejectedWith('refungible.RefungibleDisallowsNesting'); + await expect(ftCollection.transfer(alice, {Ethereum: helper.ethAddress.fromTokenId(ftCollection.collectionId, 0)})).to.be.rejectedWith('fungible.FungibleDisallowsNesting'); + await expect(nativeFtCollection.transfer(alice, {Ethereum: helper.ethAddress.fromTokenId(nativeFtCollection.collectionId, 0)})).to.be.rejectedWith('common.UnsupportedOperation'); + }); -itSub('Cannot nest in restricted collection if collection is not in the list', async ({helper}) => { - const {collectionId: allowedCollectionId} = await helper.nft.mintCollection(alice); - const notAllowedCollectionNFT = await helper.nft.mintCollection(alice); - const notAllowedCollectionRFT = await helper.rft.mintCollection(alice); - const notAllowedCollectionFT = await helper.ft.mintCollection(alice); - const notAllowedCollectionNativeFT = helper.ft.getCollectionObject(0); + itSub('Cannot nest in restricted collection if collection is not in the list', async ({helper}) => { + const {collectionId: allowedCollectionId} = await helper.nft.mintCollection(alice); + const notAllowedCollectionNFT = await helper.nft.mintCollection(alice); + const notAllowedCollectionRFT = await helper.rft.mintCollection(alice); + const notAllowedCollectionFT = await helper.ft.mintCollection(alice); + const notAllowedCollectionNativeFT = helper.ft.getCollectionObject(0); - // Collection restricted to allowedCollectionId - const restrictedCollectionA = await helper.nft.mintCollection(alice, {permissions: - {nesting: {tokenOwner: true, restricted: [allowedCollectionId]}}, - }); - // Create collection with restricted nesting -- even self is not allowed - const restrictedCollectionB = await helper.nft.mintCollection(alice, {permissions: - {nesting: {tokenOwner: true, restricted: []}}, - }); + // Collection restricted to allowedCollectionId + const restrictedCollectionA = await helper.nft.mintCollection(alice, {permissions: + {nesting: {tokenOwner: true, restricted: [allowedCollectionId]}}, + }); + // Create collection with restricted nesting -- even self is not allowed + const restrictedCollectionB = await helper.nft.mintCollection(alice, {permissions: + {nesting: {tokenOwner: true, restricted: []}}, + }); - const targetTokenA = await restrictedCollectionA.mintToken(alice); - const targetTokenB = await restrictedCollectionB.mintToken(alice); + const targetTokenA = await restrictedCollectionA.mintToken(alice); + const targetTokenB = await restrictedCollectionB.mintToken(alice); - // 1. Cannot mint in own collection after allowlisting the accounts: - await expect(restrictedCollectionA.mintToken(alice, targetTokenA.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); - await expect(restrictedCollectionB.mintToken(alice, targetTokenB.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + // 1. Cannot mint in own collection after allowlisting the accounts: + await expect(restrictedCollectionA.mintToken(alice, targetTokenA.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + await expect(restrictedCollectionB.mintToken(alice, targetTokenB.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); - // 2. Cannot mint from notAllowedCollection: - await expect(notAllowedCollectionNFT.mintToken(alice, targetTokenA.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); - await expect(notAllowedCollectionNFT.mintToken(alice, targetTokenB.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); - await expect(notAllowedCollectionRFT.mintToken(alice, 100n, targetTokenA.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); - await expect(notAllowedCollectionRFT.mintToken(alice, 100n, targetTokenB.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); - await expect(notAllowedCollectionFT.mint(alice, 100n, targetTokenA.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); - await expect(notAllowedCollectionFT.mint(alice, 100n, targetTokenB.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); - await expect(notAllowedCollectionNativeFT.transfer(alice, targetTokenA.nestingAccount(), 100n)).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); - await expect(notAllowedCollectionNativeFT.transfer(alice, targetTokenB.nestingAccount(), 100n)).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); -}); + // 2. Cannot mint from notAllowedCollection: + await expect(notAllowedCollectionNFT.mintToken(alice, targetTokenA.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + await expect(notAllowedCollectionNFT.mintToken(alice, targetTokenB.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + await expect(notAllowedCollectionRFT.mintToken(alice, 100n, targetTokenA.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + await expect(notAllowedCollectionRFT.mintToken(alice, 100n, targetTokenB.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + await expect(notAllowedCollectionFT.mint(alice, 100n, targetTokenA.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + await expect(notAllowedCollectionFT.mint(alice, 100n, targetTokenB.nestingAccount())).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + await expect(notAllowedCollectionNativeFT.transfer(alice, targetTokenA.nestingAccount(), 100n)).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + await expect(notAllowedCollectionNativeFT.transfer(alice, targetTokenB.nestingAccount(), 100n)).to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/); + }); -itSub('Cannot create nesting chains greater than 5', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); - let token = await collection.mintToken(alice); + itSub('Cannot create nesting chains greater than 5', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}}); + let token = await collection.mintToken(alice); - const maxNestingLevel = 5; + const maxNestingLevel = 5; - // Create a nested-token matryoshka - for (let i = 0; i < maxNestingLevel; i++) { - token = await collection.mintToken(alice, token.nestingAccount()); - } + // Create a nested-token matryoshka + for (let i = 0; i < maxNestingLevel; i++) { + token = await collection.mintToken(alice, token.nestingAccount()); + } - // The nesting depth is limited by `maxNestingLevel` - // 1. Cannot mint: - await expect(collection.mintToken(alice, token.nestingAccount())) - .to.be.rejectedWith(/structure\.DepthLimit/); - // 2. Cannot transfer: - const anotherToken = await collection.mintToken(alice); - await expect(anotherToken.transfer(alice, token.nestingAccount())) - .to.be.rejectedWith(/structure\.DepthLimit/); - // 3. Cannot nest FT pieces: - const ftCollection = await helper.ft.mintCollection(alice); - await expect(ftCollection.mint(alice, 100n, token.nestingAccount())) - .to.be.rejectedWith(/structure\.DepthLimit/); + // The nesting depth is limited by `maxNestingLevel` + // 1. Cannot mint: + await expect(collection.mintToken(alice, token.nestingAccount())) + .to.be.rejectedWith(/structure\.DepthLimit/); + // 2. Cannot transfer: + const anotherToken = await collection.mintToken(alice); + await expect(anotherToken.transfer(alice, token.nestingAccount())) + .to.be.rejectedWith(/structure\.DepthLimit/); + // 3. Cannot nest FT pieces: + const ftCollection = await helper.ft.mintCollection(alice); + await expect(ftCollection.mint(alice, 100n, token.nestingAccount())) + .to.be.rejectedWith(/structure\.DepthLimit/); - expect(await token.getTopmostOwner()).to.be.deep.equal({Substrate: alice.address}); - expect(await token.getChildren()).to.has.length(0); + expect(await token.getTopmostOwner()).to.be.deep.equal({Substrate: alice.address}); + expect(await token.getChildren()).to.has.length(0); + }); }); --- a/tests/src/sub/nesting/refungible.test.ts +++ b/tests/src/sub/nesting/refungible.test.ts @@ -17,44 +17,45 @@ import {IKeyringPair} from '@polkadot/types/types'; import {expect, itSub, Pallets, usingPlaygrounds} from '../../util'; -// ReFungible specific nesting tests -let alice: IKeyringPair; +describe('ReFungible-specific nesting tests', () => { + let alice: IKeyringPair; -before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = await privateKey({url: import.meta.url}); - [alice] = await helper.arrange.createAccounts([200n], donor); + before(async () => { + await usingPlaygrounds(async (helper, privateKey) => { + const donor = await privateKey({url: import.meta.url}); + [alice] = await helper.arrange.createAccounts([200n], donor); + }); }); -}); -itSub.ifWithPallets('ReFungible: getTopmostOwner works correctly with Nesting', [Pallets.ReFungible], async({helper}) => { - const collectionNFT = await helper.nft.mintCollection(alice, { - permissions: { - nesting: { - tokenOwner: true, + itSub.ifWithPallets('ReFungible: getTopmostOwner works correctly with Nesting', [Pallets.ReFungible], async({helper}) => { + const collectionNFT = await helper.nft.mintCollection(alice, { + permissions: { + nesting: { + tokenOwner: true, + }, }, - }, - }); - const collectionRFT = await helper.rft.mintCollection(alice); + }); + const collectionRFT = await helper.rft.mintCollection(alice); - const nft = await collectionNFT.mintToken(alice, {Substrate: alice.address}); - const rft = await collectionRFT.mintToken(alice, 100n, {Substrate: alice.address}); + const nft = await collectionNFT.mintToken(alice, {Substrate: alice.address}); + const rft = await collectionRFT.mintToken(alice, 100n, {Substrate: alice.address}); - expect(await rft.getTopmostOwner()).deep.equal({Substrate: alice.address}); + expect(await rft.getTopmostOwner()).deep.equal({Substrate: alice.address}); - await rft.transfer(alice, nft.nestingAccount(), 40n); + await rft.transfer(alice, nft.nestingAccount(), 40n); - expect(await rft.getTopmostOwner()).deep.equal(null); + expect(await rft.getTopmostOwner()).deep.equal(null); - await rft.transfer(alice, nft.nestingAccount(), 60n); + await rft.transfer(alice, nft.nestingAccount(), 60n); - expect(await rft.getTopmostOwner()).deep.equal({Substrate: alice.address}); + expect(await rft.getTopmostOwner()).deep.equal({Substrate: alice.address}); - await rft.transferFrom(alice, nft.nestingAccount(), {Substrate: alice.address}, 30n); + await rft.transferFrom(alice, nft.nestingAccount(), {Substrate: alice.address}, 30n); - expect(await rft.getTopmostOwner()).deep.equal(null); + expect(await rft.getTopmostOwner()).deep.equal(null); - await rft.transferFrom(alice, nft.nestingAccount(), {Substrate: alice.address}, 70n); + await rft.transferFrom(alice, nft.nestingAccount(), {Substrate: alice.address}, 70n); - expect(await rft.getTopmostOwner()).deep.equal({Substrate: alice.address}); + expect(await rft.getTopmostOwner()).deep.equal({Substrate: alice.address}); + }); }); -- gitstuff