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

difftreelog

source

js-packages/tests/allowLists.test.ts20.2 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import type {IKeyringPair} from '@polkadot/types/types';18import {usingPlaygrounds, expect, itSub} from '@unique/test-utils/util.js';19import type {ICollectionPermissions} from '@unique-nft/playgrounds/types.js';20import {NON_EXISTENT_COLLECTION_ID} from '@unique-nft/playgrounds/types.js';2122describe('Integration Test ext. Allow list tests', () => {23  let alice: IKeyringPair;24  let bob: IKeyringPair;25  let charlie: IKeyringPair;2627  before(async () => {28    await usingPlaygrounds(async (helper, privateKey) => {29      const donor = await privateKey({url: import.meta.url});30      [alice, bob, charlie] = await helper.arrange.createAccounts([30n, 10n, 10n], donor);31    });32  });3334  describe('Positive', () => {35    itSub('Owner can add address to allow list', async ({helper}) => {36      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});37      // allow list does not need to be enabled to add someone in advance38      await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});39      const allowList = await helper.nft.getAllowList(collectionId);40      expect(allowList).to.deep.contain({Substrate: bob.address});41    });4243    itSub('Admin can add address to allow list', async ({helper}) => {44      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});45      await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});4647      // allow list does not need to be enabled to add someone in advance48      await helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address});49      const allowList = await helper.nft.getAllowList(collectionId);50      expect(allowList).to.deep.contain({Substrate: charlie.address});51    });5253    itSub('If address is already added to allow list, nothing happens', async ({helper}) => {54      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});55      await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});56      await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});57      const allowList = await helper.nft.getAllowList(collectionId);58      expect(allowList).to.deep.contain({Substrate: bob.address});59    });60  });6162  describe('Negative', () => {63    itSub('Nobody can add address to allow list of non-existing collection', async ({helper}) => {64      const collectionId = NON_EXISTENT_COLLECTION_ID;65      await expect(helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address}))66        .to.be.rejectedWith(/common\.CollectionNotFound/);67    });6869    itSub('Nobody can add address to allow list of destroyed collection', async ({helper}) => {70      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});71      await helper.collection.burn(alice, collectionId);72      await expect(helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}))73        .to.be.rejectedWith(/common\.CollectionNotFound/);74    });7576    itSub('Non-privileged user cannot add address to allow list', async ({helper}) => {77      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});78      await expect(helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address}))79        .to.be.rejectedWith(/common\.NoPermission/);80    });81  });82});8384describe('Integration Test ext. Remove from Allow List', () => {85  let alice: IKeyringPair;86  let bob: IKeyringPair;87  let charlie: IKeyringPair;8889  before(async () => {90    await usingPlaygrounds(async (helper, privateKey) => {91      const donor = await privateKey({url: import.meta.url});92      [alice, bob, charlie] = await helper.arrange.createAccounts([30n, 10n, 10n], donor);93    });94  });9596  describe('Positive', () => {97    itSub('Owner can remove address from allow list', async ({helper}) => {98      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});99      await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});100101      await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address});102103      const allowList = await helper.nft.getAllowList(collectionId);104105      expect(allowList).to.not.deep.contain({Substrate: bob.address});106    });107108    itSub('Admin can remove address from allow list', async ({helper}) => {109      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});110      await helper.nft.addAdmin(alice, collectionId, {Substrate: charlie.address});111      await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});112      await helper.collection.removeFromAllowList(charlie, collectionId, {Substrate: bob.address});113114      const allowList = await helper.nft.getAllowList(collectionId);115      expect(allowList).to.not.deep.contain({Substrate: bob.address});116    });117118    itSub('If address is already removed from allow list, nothing happens', async ({helper}) => {119      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});120      await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});121      await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address});122      const allowListBefore = await helper.nft.getAllowList(collectionId);123      expect(allowListBefore).to.not.deep.contain({Substrate: bob.address});124125      await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address});126127      const allowListAfter = await helper.nft.getAllowList(collectionId);128      expect(allowListAfter).to.not.deep.contain({Substrate: bob.address});129    });130  });131132  describe('Negative', () => {133    itSub('Non-privileged user cannot remove address from allow list', async ({helper}) => {134      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});135      await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});136      await expect(helper.collection.removeFromAllowList(charlie, collectionId, {Substrate: charlie.address}))137        .to.be.rejectedWith(/common\.NoPermission/);138139      const allowList = await helper.nft.getAllowList(collectionId);140      expect(allowList).to.deep.contain({Substrate: charlie.address});141    });142143    itSub('Nobody can remove address from allow list of non-existing collection', async ({helper}) => {144      const collectionId = NON_EXISTENT_COLLECTION_ID;145      await expect(helper.collection.removeFromAllowList(bob, collectionId, {Substrate: charlie.address}))146        .to.be.rejectedWith(/common\.CollectionNotFound/);147    });148149    itSub('Nobody can remove address from allow list of deleted collection', async ({helper}) => {150      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});151      await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address});152      await helper.collection.burn(alice, collectionId);153154      await expect(helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address}))155        .to.be.rejectedWith(/common\.CollectionNotFound/);156    });157  });158});159160describe('Integration Test ext. Transfer if included in Allow List', () => {161  let alice: IKeyringPair;162  let bob: IKeyringPair;163  let charlie: IKeyringPair;164165  before(async () => {166    await usingPlaygrounds(async (helper, privateKey) => {167      const donor = await privateKey({url: import.meta.url});168      [alice, bob, charlie] = await helper.arrange.createAccounts([30n, 10n, 10n], donor);169    });170  });171172  describe('Positive', () => {173    itSub('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transfer.', async ({helper}) => {174      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});175      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});176      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});177      await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});178      await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});179      await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});180      const owner = await helper.nft.getTokenOwner(collectionId, tokenId);181      expect(owner).to.be.deep.equal({Substrate: charlie.address});182    });183184    itSub('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transferFrom.', async ({helper}) => {185      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});186      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});187      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});188      await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});189      await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});190      await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});191192      await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address});193      const owner = await helper.nft.getTokenOwner(collectionId, tokenId);194      expect(owner).to.be.deep.equal({Substrate: charlie.address});195    });196197    itSub('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer', async ({helper}) => {198      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});199      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});200      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});201      await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});202      await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});203204      await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address});205      const owner = await helper.nft.getTokenOwner(collectionId, tokenId);206      expect(owner).to.be.deep.equal({Substrate: charlie.address});207    });208209    itSub('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transferFrom', async ({helper}) => {210      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});211      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});212      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});213      await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});214      await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});215      await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});216217      await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address});218      const owner = await helper.nft.getTokenOwner(collectionId, tokenId);219      expect(owner).to.be.deep.equal({Substrate: charlie.address});220    });221  });222223  describe('Negative', () => {224    itSub('If Public Access mode is set to AllowList, tokens can\'t be transferred from a non-allowlisted address with transfer or transferFrom. Test1', async ({helper}) => {225      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});226      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});227      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});228      await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});229230      await expect(helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}))231        .to.be.rejectedWith(/common\.AddressNotInAllowlist/);232    });233234    itSub('If Public Access mode is set to AllowList, tokens can\'t be transferred from a non-allowlisted address with transfer or transferFrom. Test2', async ({helper}) => {235      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});236      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});237      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});238      await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});239      await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});240      await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});241      await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: alice.address});242243      await expect(helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}))244        .to.be.rejectedWith(/common\.AddressNotInAllowlist/);245    });246247    itSub('If Public Access mode is set to AllowList, tokens can\'t be transferred to a non-allowlisted address with transfer or transferFrom. Test1', async ({helper}) => {248      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});249      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});250      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});251      await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});252253      await expect(helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}))254        .to.be.rejectedWith(/common\.AddressNotInAllowlist/);255    });256257    itSub('If Public Access mode is set to AllowList, tokens can\'t be transferred to a non-allowlisted address with transfer or transferFrom. Test2', async ({helper}) => {258      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});259      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});260      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});261      await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address});262      await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address});263264      await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address});265      await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: alice.address});266267      await expect(helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}))268        .to.be.rejectedWith(/common\.AddressNotInAllowlist/);269    });270271    itSub('If Public Access mode is set to AllowList, tokens can\'t be destroyed by a non-allowlisted address (even if it owned them before enabling AllowList mode)', async ({helper}) => {272      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});273      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});274      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});275      await expect(helper.nft.burnToken(bob, collectionId, tokenId))276        .to.be.rejectedWith(/common\.NoPermission/);277    });278279    itSub('If Public Access mode is set to AllowList, token transfers can\'t be Approved by a non-allowlisted address (see Approve method)', async ({helper}) => {280      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});281      const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address});282      await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'});283      await expect(helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}))284        .to.be.rejectedWith(/common\.AddressNotInAllowlist/);285    });286  });287});288289describe('Integration Test ext. Mint if included in Allow List', () => {290  let alice: IKeyringPair;291  let bob: IKeyringPair;292293  before(async () => {294    await usingPlaygrounds(async (helper, privateKey) => {295      const donor = await privateKey({url: import.meta.url});296      [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);297    });298  });299300  const permissionSet: ICollectionPermissions[] = [301    {access: 'Normal', mintMode: false},302    {access: 'Normal', mintMode: true},303    {access: 'AllowList', mintMode: false},304    {access: 'AllowList', mintMode: true},305  ];306307  const testPermissionSuite = (permissions: ICollectionPermissions) => {308    const allowlistedMintingShouldFail = !permissions.mintMode!;309310    const appropriateRejectionMessage = permissions.mintMode! ? /common\.AddressNotInAllowlist/ : /common\.PublicMintingNotAllowed/;311312    const allowlistedMintingTest = () => itSub(313      `With the condtions above, tokens can${allowlistedMintingShouldFail ? '\'t' : ''} be created by allow-listed addresses`,314      async ({helper}) => {315        const collection = await helper.nft.mintCollection(alice, {});316        await collection.setPermissions(alice, permissions);317        await collection.addToAllowList(alice, {Substrate: bob.address});318319        if(allowlistedMintingShouldFail)320          await expect(collection.mintToken(bob, {Substrate: bob.address})).to.be.rejectedWith(appropriateRejectionMessage);321        else322          await expect(collection.mintToken(bob, {Substrate: bob.address})).to.not.be.rejected;323      },324    );325326327    describe(`Public Access Mode = ${permissions.access}, Mint Mode = ${permissions.mintMode}`, () => {328      describe('Positive', () => {329        itSub('With the condtions above, tokens can be created by owner', async ({helper}) => {330          const collection = await helper.nft.mintCollection(alice, {});331          await collection.setPermissions(alice, permissions);332          await expect(collection.mintToken(alice, {Substrate: alice.address})).to.not.be.rejected;333        });334335        itSub('With the condtions above, tokens can be created by admin', async ({helper}) => {336          const collection = await helper.nft.mintCollection(alice, {});337          await collection.setPermissions(alice, permissions);338          await collection.addAdmin(alice, {Substrate: bob.address});339          await expect(collection.mintToken(bob, {Substrate: bob.address})).to.not.be.rejected;340        });341342        if(!allowlistedMintingShouldFail) allowlistedMintingTest();343      });344345      describe('Negative', () => {346        itSub('With the condtions above, tokens can\'t be created by non-priviliged non-allow-listed address', async ({helper}) => {347          const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});348          await collection.setPermissions(alice, permissions);349          await expect(collection.mintToken(bob, {Substrate: bob.address}))350            .to.be.rejectedWith(appropriateRejectionMessage);351        });352353        if(allowlistedMintingShouldFail) allowlistedMintingTest();354      });355    });356  };357358  for(const permissions of permissionSet) {359    testPermissionSuite(permissions);360  }361});