git.delta.rocks / unique-network / refs/commits / 2976d69d82a2

difftreelog

source

tests/src/nesting/unnest.test.ts5.9 KiBsourcehistory
1import {expect} from 'chai';2import {tokenIdToAddress} from '../eth/util/helpers';3import privateKey from '../substrate/privateKey';4import usingApi, {executeTransaction} from '../substrate/substrate-api';5import {6  createCollectionExpectSuccess,7  createItemExpectFailure, 8  createItemExpectSuccess,9  getTokenOwner, 10  getTopmostTokenOwner, 11  normalizeAccountId, 12  setCollectionLimitsExpectSuccess, 13  transferExpectSuccess, 14} from '../util/helpers';15import {IKeyringPair} from '@polkadot/types/types';1617let alice: IKeyringPair;18let bob: IKeyringPair;1920describe('Integration Test: Unnesting', () => {21  before(async () => {22    await usingApi(async api => {23      alice = privateKey('//Alice');24      bob = privateKey('//Bob');25    });26  });2728  it('Allows the owner to successfully unnest a token', async () => {29    await usingApi(async api => {30      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});31      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});32      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');33      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};3435      // Create a nested token36      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', targetAddress);3738      // Unnest39      await expect(executeTransaction(40        api, 41        alice, 42        api.tx.unique.transferFrom(normalizeAccountId(targetAddress), normalizeAccountId(alice), collection, nestedToken, 1),43      )).to.not.be.rejected;44      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Substrate: alice.address});4546      // Nest and burn47      await transferExpectSuccess(collection, nestedToken, alice, targetAddress);48      await expect(executeTransaction(49        api, 50        alice, 51        api.tx.unique.burnFrom(collection, normalizeAccountId(alice.address), nestedToken, 1),52      )).to.not.be.rejected;53      await expect(getTokenOwner(api, collection, nestedToken)).to.be.rejected; // 'owner == null'54    });55  });5657  // todo refungible-fungible test just in case58});5960describe('Negative Test: Unnesting', () => {61  before(async () => {62    await usingApi(async api => {63      alice = privateKey('//Alice');64      bob = privateKey('//Bob');65    });66  });67  68  it('Disallows a non-owner to unnest/burn a token', async () => {69    await usingApi(async api => {70      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});71      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});72      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');73      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};7475      // Create a nested token76      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', targetAddress);7778      // Try to unnest79      await expect(executeTransaction(80        api, 81        bob, 82        api.tx.unique.transferFrom(normalizeAccountId(targetAddress), normalizeAccountId(bob), collection, nestedToken, 1),83      )).to.be.rejectedWith(/^common\.ApprovedValueTooLow$/);84      //await transferFromExpectSuccess(collection, nestedToken, bob, targetAddress, {Substrate: bob.address});85      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});8687      // Try to burn88      await expect(executeTransaction(89        api, 90        bob, 91        api.tx.unique.burnFrom(collection, normalizeAccountId(bob.address), nestedToken, 1),92      )).to.not.be.rejectedWith(/^common\.ApprovedValueTooLow$/);93      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});94    });95  });96  97  it('Disallows excessive token nesting', async () => {98    await usingApi(async api => {99      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});100      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});101      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');102103      // Create a nested token matryoshka104      const nestedToken1 = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});105      const nestedToken2 = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, nestedToken1)});106      // The nesting depth is limited by 2107      await createItemExpectFailure(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, nestedToken2)});108109      expect(await getTopmostTokenOwner(api, collection, nestedToken2)).to.be.deep.equal({Substrate: alice.address});110    });111  });112113  // todo another test for creating excessive depth matryoshka with Ethereum, move this one to nest ^114  115  // Recursive nesting116  it('Prevents Ouroboros-nested operations', async () => { 117    await usingApi(async api => {118      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});119      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});120      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');121122      // Create a nested token ouroboros123      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});124      await transferExpectSuccess(collection, targetToken, alice, {Ethereum: tokenIdToAddress(collection, nestedToken)});125126      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});127128      // Make sure the ouroboros is detected129      await expect(getTopmostTokenOwner(api, collection, nestedToken)).to.be.rejected; // With(/^common\.DepthLimit$/);130      // todo transferFrom, must exit with Ouroboros error131    });132  });133});