git.delta.rocks / unique-network / refs/commits / b1d3841dc4c5

difftreelog

source

tests/src/nesting/nest.test.ts30.4 KiBsourcehistory
1import {expect} from 'chai';2import {tokenIdToAddress} from '../eth/util/helpers';3import usingApi, {executeTransaction} from '../substrate/substrate-api';4import {5  addToAllowListExpectSuccess,6  createCollectionExpectSuccess,7  createItemExpectSuccess,8  enableAllowListExpectSuccess,9  enablePublicMintingExpectSuccess,10  getTokenOwner,11  getTopmostTokenOwner,12  normalizeAccountId,13  setCollectionPermissionsExpectSuccess,14  transferExpectFailure,15  transferExpectSuccess,16  transferFromExpectSuccess,17} from '../util/helpers';18import {IKeyringPair} from '@polkadot/types/types';1920let alice: IKeyringPair;21let bob: IKeyringPair;2223describe('Integration Test: Nesting', () => {24  before(async () => {25    await usingApi(async (api, privateKeyWrapper) => {26      alice = privateKeyWrapper!('//Alice');27      bob = privateKeyWrapper!('//Bob');28    });29  });3031  it('Performs the full suite: bundles a token, transfers, and unnests', async () => {32    await usingApi(async api => {33      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});34      await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: 'Owner'});35      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');3637      // Create a nested token38      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});39      expect(await getTopmostTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Substrate: alice.address});40      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});4142      // Create a token to be nested43      const newToken = await createItemExpectSuccess(alice, collection, 'NFT');4445      // Nest46      await transferExpectSuccess(collection, newToken, alice, {Ethereum: tokenIdToAddress(collection, targetToken)});47      expect(await getTopmostTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});48      expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});4950      // Move bundle to different user51      await transferExpectSuccess(collection, targetToken, alice, {Substrate: bob.address});52      expect(await getTopmostTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Substrate: bob.address});53      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});5455      // Unnest56      await transferFromExpectSuccess(collection, newToken, bob, {Ethereum: tokenIdToAddress(collection, targetToken)}, {Substrate: bob.address});57      expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: bob.address});58    });59  });6061  it('Transfers an already bundled token', async () => {62    await usingApi(async api => {63      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});64      await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: 'Owner'});6566      const tokenA = await createItemExpectSuccess(alice, collection, 'NFT');67      const tokenB = await createItemExpectSuccess(alice, collection, 'NFT');6869      // Create a nested token70      const tokenC = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, tokenA)});71      expect(await getTopmostTokenOwner(api, collection, tokenC)).to.be.deep.equal({Substrate: alice.address});72      expect(await getTokenOwner(api, collection, tokenC)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, tokenA).toLowerCase()});7374      // Transfer the nested token to another token75      await expect(executeTransaction(76        api,77        alice,78        api.tx.unique.transferFrom(79          normalizeAccountId({Ethereum: tokenIdToAddress(collection, tokenA)}), 80          normalizeAccountId({Ethereum: tokenIdToAddress(collection, tokenB)}), 81          collection,82          tokenC,83          1,84        ),85      )).to.not.be.rejected;86      expect(await getTopmostTokenOwner(api, collection, tokenC)).to.be.deep.equal({Substrate: alice.address});87      expect(await getTokenOwner(api, collection, tokenC)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, tokenB).toLowerCase()});88    });89  });9091  // ---------- Non-Fungible ----------9293  it('NFT: allows an Owner to nest/unnest their token', async () => {94    await usingApi(async api => {95      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});96      await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: 'Owner'});97      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');9899      // Create a nested token100      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});101      expect(await getTopmostTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Substrate: alice.address});102      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});103104      // Create a token to be nested and nest105      const newToken = await createItemExpectSuccess(alice, collection, 'NFT');106      await transferExpectSuccess(collection, newToken, alice, {Ethereum: tokenIdToAddress(collection, targetToken)});107      expect(await getTopmostTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});108      expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});109    });110  });111112  it('NFT: allows an Owner to nest/unnest their token (Restricted nesting)', async () => {113    await usingApi(async api => {114      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});115      await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: {OwnerRestricted:[collection]}});116      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');117118      // Create a nested token119      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});120      expect(await getTopmostTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Substrate: alice.address});121      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});122123      // Create a token to be nested and nest124      const newToken = await createItemExpectSuccess(alice, collection, 'NFT');125      await transferExpectSuccess(collection, newToken, alice, {Ethereum: tokenIdToAddress(collection, targetToken)});126      expect(await getTopmostTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});127      expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});128    });129  });130131  // ---------- Fungible ----------132133  it('Fungible: allows an Owner to nest/unnest their token', async () => {134    await usingApi(async api => {135      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});136      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: 'Owner'});137      const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT', {Substrate: alice.address});138      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};139140      const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});141142      // Create a nested token143      await expect(executeTransaction(api, alice, api.tx.unique.createItem(144        collectionFT,145        targetAddress,146        {Fungible: {Value: 10}},147      ))).to.not.be.rejected;148149      // Nest a new token150      const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');151      await transferExpectSuccess(collectionFT, newToken, alice, targetAddress, 1, 'Fungible');152    });153  });154155  it('Fungible: allows an Owner to nest/unnest their token (Restricted nesting)', async () => {156    await usingApi(async api => {157      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});158      const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT', {Substrate: alice.address});159      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};160161      const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});162163      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {OwnerRestricted: [collectionFT]}});164165      // Create a nested token166      await expect(executeTransaction(api, alice, api.tx.unique.createItem(167        collectionFT,168        targetAddress,169        {Fungible: {Value: 10}},170      ))).to.not.be.rejected;171172      // Nest a new token173      const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');174      await transferExpectSuccess(collectionFT, newToken, alice, targetAddress, 1, 'Fungible');175    });176  });177178  // ---------- Re-Fungible ----------179180  it('ReFungible: allows an Owner to nest/unnest their token', async () => {181    await usingApi(async api => {182      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});183      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: 'Owner'});184      const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT', {Substrate: alice.address});185      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};186187      const collectionRFT = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});188189      // Create a nested token190      await expect(executeTransaction(api, alice, api.tx.unique.createItem(191        collectionRFT,192        targetAddress,193        {ReFungible: {const_data: [], pieces: 100}},194      ))).to.not.be.rejected;195196      // Nest a new token197      const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');198      await transferExpectSuccess(collectionRFT, newToken, alice, targetAddress, 100, 'ReFungible');199    });200  });201202  it('ReFungible: allows an Owner to nest/unnest their token (Restricted nesting)', async () => {203    await usingApi(async api => {204      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});205      const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT', {Substrate: alice.address});206      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};207208      const collectionRFT = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});209210      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {OwnerRestricted:[collectionRFT]}});211212      // Create a nested token213      await expect(executeTransaction(api, alice, api.tx.unique.createItem(214        collectionRFT,215        targetAddress,216        {ReFungible: {const_data: [], pieces: 100}},217      ))).to.not.be.rejected;218219      // Nest a new token220      const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');221      await transferExpectSuccess(collectionRFT, newToken, alice, targetAddress, 100, 'ReFungible');222    });223  });224});225226describe('Negative Test: Nesting', async() => {227  before(async () => {228    await usingApi(async (api, privateKeyWrapper) => {229      alice = privateKeyWrapper!('//Alice');230      bob = privateKeyWrapper!('//Bob');231    });232  });233234  it('Disallows excessive token nesting', async () => {235    await usingApi(async api => {236      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});237      await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: 'Owner'});238      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');239240      const maxNestingLevel = 5;241      let prevToken = targetToken;242243      // Create a nested-token matryoshka244      for (let i = 0; i < maxNestingLevel; i++) {245        const nestedToken = await createItemExpectSuccess(246          alice,247          collection,248          'NFT',249          {Ethereum: tokenIdToAddress(collection, prevToken)},250        );251252        prevToken = nestedToken;253      }254255      // The nesting depth is limited by `maxNestingLevel`256      await expect(executeTransaction(api, alice, api.tx.unique.createItem(257        collection,258        {Ethereum: tokenIdToAddress(collection, prevToken)},259          {nft: {const_data: [], variable_data: []}} as any,260      )), 'while creating nested token').to.be.rejectedWith(/^structure\.DepthLimit$/);261262      expect(await getTopmostTokenOwner(api, collection, prevToken)).to.be.deep.equal({Substrate: alice.address});263    });264  });265266  // ---------- Non-Fungible ----------267268  it('NFT: disallows to nest token if nesting is disabled', async () => {269    await usingApi(async api => {270      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});271      await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: 'Disabled'});272      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');273274      // Try to create a nested token275      await expect(executeTransaction(api, alice, api.tx.unique.createItem(276        collection,277        {Ethereum: tokenIdToAddress(collection, targetToken)},278          {nft: {const_data: [], variable_data: []}} as any,279      )), 'while creating nested token').to.be.rejectedWith(/^common\.NestingIsDisabled$/);280281      // Create a token to be nested282      const newToken = await createItemExpectSuccess(alice, collection, 'NFT');283      // Try to nest284      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collection, targetToken)}, collection, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.NestingIsDisabled/);285      expect(await getTopmostTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});286      expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});287    });288  });289290  it('NFT: disallows a non-Owner to nest someone else\'s token', async () => {291    await usingApi(async api => {292      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});293      await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: 'Owner'});294295      await addToAllowListExpectSuccess(alice, collection, bob.address);296      await enableAllowListExpectSuccess(alice, collection);297      await enablePublicMintingExpectSuccess(alice, collection);298299      // Create a token to attempt to be nested into300      const targetToken = await createItemExpectSuccess(bob, collection, 'NFT');301302      // Try to create a nested token in the wrong collection303      await expect(executeTransaction(api, alice, api.tx.unique.createItem(304        collection,305        {Ethereum: tokenIdToAddress(collection, targetToken)},306          {nft: {const_data: [], variable_data: []}} as any,307      )), 'while creating nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);308309      // Try to create and nest a token in the wrong collection310      const newToken = await createItemExpectSuccess(alice, collection, 'NFT');311      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collection, targetToken)}, collection, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.AddressNotInAllowlist/);312      expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});313    });314  });315316  it('NFT: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async () => {317    await usingApi(async api => {318      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});319      await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: {OwnerRestricted:[collection]}});320321      await addToAllowListExpectSuccess(alice, collection, bob.address);322      await enableAllowListExpectSuccess(alice, collection);323      await enablePublicMintingExpectSuccess(alice, collection);324325      // Create a token to attempt to be nested into326      const targetToken = await createItemExpectSuccess(bob, collection, 'NFT');327328      // Try to create a nested token in the wrong collection329      await expect(executeTransaction(api, alice, api.tx.unique.createItem(330        collection,331        {Ethereum: tokenIdToAddress(collection, targetToken)},332          {nft: {const_data: [], variable_data: []}} as any,333      )), 'while creating nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);334335      // Try to create and nest a token in the wrong collection336      const newToken = await createItemExpectSuccess(alice, collection, 'NFT');337      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collection, targetToken)}, collection, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.AddressNotInAllowlist/);338      expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});339    });340  });341342  it('NFT: disallows to nest token in an unlisted collection', async () => {343    await usingApi(async api => {344      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});345      await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: {OwnerRestricted:[]}});346347      // Create a token to attempt to be nested into348      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');349350      // Try to create a nested token in the wrong collection351      await expect(executeTransaction(api, alice, api.tx.unique.createItem(352        collection,353        {Ethereum: tokenIdToAddress(collection, targetToken)},354          {nft: {const_data: [], variable_data: []}} as any,355      )), 'while creating nested token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);356357      // Try to create and nest a token in the wrong collection358      const newToken = await createItemExpectSuccess(alice, collection, 'NFT');359      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collection, targetToken)}, collection, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);360      expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: alice.address});361    });362  });363364  // ---------- Fungible ----------365366  it('Fungible: disallows to nest token if nesting is disabled', async () => {367    await usingApi(async api => {368      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});369      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: 'Disabled'});370      const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT');371      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};372373      const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});374375      // Try to create a nested token376      await expect(executeTransaction(api, alice, api.tx.unique.createItem(377        collectionFT,378        targetAddress,379        {Fungible: {Value: 10}},380      )), 'while creating nested token').to.be.rejectedWith(/^common\.NestingIsDisabled$/);381382      // Create a token to be nested383      const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');384      // Try to nest385      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.NestingIsDisabled/);386387      // Create another token to be nested388      const newToken2 = await createItemExpectSuccess(alice, collectionFT, 'Fungible');389      // Try to nest inside a fungible token390      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collectionFT, newToken)}, collectionFT, newToken2, 1)), 'while nesting new token inside fungible').to.be.rejectedWith(/fungible\.FungibleDisallowsNesting/);391    });392  });393394  it('Fungible: disallows a non-Owner to nest someone else\'s token', async () => {395    await usingApi(async api => {396      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});397      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: 'Owner'});398399      await addToAllowListExpectSuccess(alice, collectionNFT, bob.address);400      await enableAllowListExpectSuccess(alice, collectionNFT);401      await enablePublicMintingExpectSuccess(alice, collectionNFT);402403      // Create a token to attempt to be nested into404      const targetToken = await createItemExpectSuccess(bob, collectionNFT, 'NFT');405      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};406407      const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});408409      // Try to create a nested token in the wrong collection410      await expect(executeTransaction(api, alice, api.tx.unique.createItem(411        collectionFT,412        targetAddress,413        {Fungible: {Value: 10}},414      )), 'while creating nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);415416      // Try to create and nest a token in the wrong collection417      const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');418      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);419    });420  });421422  it('Fungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async () => {423    await usingApi(async api => {424      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});425      await addToAllowListExpectSuccess(alice, collectionNFT, bob.address);426      await enableAllowListExpectSuccess(alice, collectionNFT);427      await enablePublicMintingExpectSuccess(alice, collectionNFT);428429      // Create a token to attempt to be nested into430      const targetToken = await createItemExpectSuccess(bob, collectionNFT, 'NFT');431      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};432433      const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});434      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {OwnerRestricted:[collectionFT]}});435436      // Try to create a nested token in the wrong collection437      await expect(executeTransaction(api, alice, api.tx.unique.createItem(438        collectionFT,439        targetAddress,440        {Fungible: {Value: 10}},441      )), 'while creating nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);442443      // Try to create and nest a token in the wrong collection444      const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');445      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);446    });447  });448449  it('Fungible: disallows to nest token in an unlisted collection', async () => {450    await usingApi(async api => {451      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});452      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {OwnerRestricted:[]}});453454      // Create a token to attempt to be nested into455      const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT');456      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};457458      const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});459460      // Try to create a nested token in the wrong collection461      await expect(executeTransaction(api, alice, api.tx.unique.createItem(462        collectionFT,463        targetAddress,464        {Fungible: {Value: 10}},465      )), 'while creating a nested token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);466467      // Try to create and nest a token in the wrong collection468      const newToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');469      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);470    });471  });472473  // ---------- Re-Fungible ----------474475  it('ReFungible: disallows to nest token if nesting is disabled', async () => {476    await usingApi(async api => {477      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});478      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: 'Disabled'});479      const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT');480      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};481482      const collectionRFT = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});483484      // Create a nested token485      await expect(executeTransaction(api, alice, api.tx.unique.createItem(486        collectionRFT,487        targetAddress,488        {ReFungible: {const_data: [], pieces: 100}},489      )), 'while creating a nested token').to.be.rejectedWith(/^common\.NestingIsDisabled$/);490491      // Create a token to be nested492      const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');493      // Try to nest494      await transferExpectFailure(collectionRFT, newToken, alice, targetAddress, 100);495      // Try to nest496      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionRFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.NestingIsDisabled/);497498      // Create another token to be nested499      const newToken2 = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');500      // Try to nest inside a fungible token501      await expect(executeTransaction(api, alice, api.tx.unique.transfer({Ethereum: tokenIdToAddress(collectionRFT, newToken)}, collectionRFT, newToken2, 1)), 'while nesting new token inside refungible').to.be.rejectedWith(/refungible\.RefungibleDisallowsNesting/);502    });503  });504505  it('ReFungible: disallows a non-Owner to nest someone else\'s token', async () => {506    await usingApi(async api => {507      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});508      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: 'Owner'});509510      await addToAllowListExpectSuccess(alice, collectionNFT, bob.address);511      await enableAllowListExpectSuccess(alice, collectionNFT);512      await enablePublicMintingExpectSuccess(alice, collectionNFT);513514      // Create a token to attempt to be nested into515      const targetToken = await createItemExpectSuccess(bob, collectionNFT, 'NFT');516      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};517518      const collectionRFT = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});519520      // Try to create a nested token in the wrong collection521      await expect(executeTransaction(api, alice, api.tx.unique.createItem(522        collectionRFT,523        targetAddress,524        {ReFungible: {const_data: [], pieces: 100}},525      )), 'while creating a nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);526527      // Try to create and nest a token in the wrong collection528      const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');529      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionRFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);530    });531  });532533  it('ReFungible: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async () => {534    await usingApi(async api => {535      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});536      await addToAllowListExpectSuccess(alice, collectionNFT, bob.address);537      await enableAllowListExpectSuccess(alice, collectionNFT);538      await enablePublicMintingExpectSuccess(alice, collectionNFT);539540      // Create a token to attempt to be nested into541      const targetToken = await createItemExpectSuccess(bob, collectionNFT, 'NFT');542      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};543544      const collectionRFT = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});545      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {OwnerRestricted:[collectionRFT]}});546547      // Try to create a nested token in the wrong collection548      await expect(executeTransaction(api, alice, api.tx.unique.createItem(549        collectionRFT,550        targetAddress,551        {ReFungible: {const_data: [], pieces: 100}},552      )), 'while creating a nested token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);553554      // Try to create and nest a token in the wrong collection555      const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');556      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionRFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.OnlyOwnerAllowedToNest/);557    });558  });559560  it('ReFungible: disallows to nest token to an unlisted collection', async () => {561    await usingApi(async api => {562      const collectionNFT = await createCollectionExpectSuccess({mode: {type: 'NFT'}});563      await setCollectionPermissionsExpectSuccess(alice, collectionNFT, {nesting: {OwnerRestricted:[]}});564565      // Create a token to attempt to be nested into566      const targetToken = await createItemExpectSuccess(alice, collectionNFT, 'NFT');567      const targetAddress = {Ethereum: tokenIdToAddress(collectionNFT, targetToken)};568569      const collectionRFT = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});570571      // Try to create a nested token in the wrong collection572      await expect(executeTransaction(api, alice, api.tx.unique.createItem(573        collectionRFT,574        targetAddress,575        {ReFungible: {const_data: [], pieces: 100}},576      )), 'while creating a nested token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);577578      // Try to create and nest a token in the wrong collection579      const newToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');580      await expect(executeTransaction(api, alice, api.tx.unique.transfer(targetAddress, collectionRFT, newToken, 1)), 'while nesting new token').to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);581    });582  });583});