--- a/tests/package.json +++ b/tests/package.json @@ -48,7 +48,6 @@ "testConfirmSponsorship": "mocha --timeout 9999999 -r ts-node/register ./**/confirmSponsorship.test.ts", "testRemoveCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionAdmin.test.ts", "testRemoveCollectionSponsor": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionSponsor.test.ts", - "testRemoveFromAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/removeFromAllowList.test.ts", "testAllowLists": "mocha --timeout 9999999 -r ts-node/register ./**/allowLists.test.ts", "testConnection": "mocha --timeout 9999999 -r ts-node/register ./**/connection.test.ts", "testContracts": "mocha --timeout 9999999 -r ts-node/register ./**/contracts.test.ts", @@ -64,8 +63,7 @@ "testTransfer": "mocha --timeout 9999999 -r ts-node/register ./**/transfer.test.ts", "testBurnItem": "mocha --timeout 9999999 -r ts-node/register ./**/burnItem.test.ts", "testAdminTransferAndBurn": "mocha --timeout 9999999 -r ts-node/register ./**/adminTransferAndBurn.test.ts", - "testSetMintPermission": "mocha --timeout 9999999 -r ts-node/register ./**/setMintPermission.test.ts", - "testSetPublicAccessMode": "mocha --timeout 9999999 -r ts-node/register ./**/setPublicAccessMode.test.ts", + "testSetPermissions": "mocha --timeout 9999999 -r ts-node/register ./**/setPermissions.test.ts", "testCreditFeesToTreasury": "mocha --timeout 9999999 -r ts-node/register ./**/creditFeesToTreasury.test.ts", "testContractSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/contractSponsoring.test.ts", "testEnableContractSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/enableContractSponsoring.test.ts", --- a/tests/src/addToAllowList.test.ts +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -import {IKeyringPair} from '@polkadot/types/types'; -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import usingApi, {submitTransactionExpectFailAsync} from './substrate/substrate-api'; -import { - addToAllowListExpectSuccess, - createCollectionExpectSuccess, - createItemExpectSuccess, - destroyCollectionExpectSuccess, - enablePublicMintingExpectSuccess, - enableAllowListExpectSuccess, - normalizeAccountId, - addCollectionAdminExpectSuccess, - addToAllowListExpectFail, - getCreatedCollectionCount, -} from './util/helpers'; - -chai.use(chaiAsPromised); -const expect = chai.expect; - -let alice: IKeyringPair; -let bob: IKeyringPair; -let charlie: IKeyringPair; - -describe('Integration Test ext. addToAllowList()', () => { - - before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - bob = privateKeyWrapper('//Bob'); - }); - }); - - it('Execute the extrinsic with parameters: Collection ID and address to add to the allow list', async () => { - const collectionId = await createCollectionExpectSuccess(); - await addToAllowListExpectSuccess(alice, collectionId, bob.address); - }); - - it('Allowlisted minting: list restrictions', async () => { - const collectionId = await createCollectionExpectSuccess(); - await addToAllowListExpectSuccess(alice, collectionId, bob.address); - await enableAllowListExpectSuccess(alice, collectionId); - await enablePublicMintingExpectSuccess(alice, collectionId); - await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address); - }); -}); - -describe('Negative Integration Test ext. addToAllowList()', () => { - - it('Allow list an address in the collection that does not exist', async () => { - await usingApi(async (api, privateKeyWrapper) => { - // tslint:disable-next-line: no-bitwise - const collectionId = await getCreatedCollectionCount(api) + 1; - const bob = privateKeyWrapper('//Bob'); - - const tx = api.tx.unique.addToAllowList(collectionId, normalizeAccountId(bob.address)); - await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected; - }); - }); - - it('Allow list an address in the collection that was destroyed', async () => { - await usingApi(async (api, privateKeyWrapper) => { - const alice = privateKeyWrapper('//Alice'); - const bob = privateKeyWrapper('//Bob'); - // tslint:disable-next-line: no-bitwise - const collectionId = await createCollectionExpectSuccess(); - await destroyCollectionExpectSuccess(collectionId); - const tx = api.tx.unique.addToAllowList(collectionId, normalizeAccountId(bob.address)); - await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected; - }); - }); - - it('Allow list an address in the collection that does not have allow list access enabled', async () => { - await usingApi(async (api, privateKeyWrapper) => { - const alice = privateKeyWrapper('//Alice'); - const ferdie = privateKeyWrapper('//Ferdie'); - const collectionId = await createCollectionExpectSuccess(); - await enableAllowListExpectSuccess(alice, collectionId); - await enablePublicMintingExpectSuccess(alice, collectionId); - const tx = api.tx.unique.createItem(collectionId, normalizeAccountId(ferdie.address), 'NFT'); - await expect(submitTransactionExpectFailAsync(ferdie, tx)).to.be.rejected; - }); - }); - -}); - -describe('Integration Test ext. addToAllowList() with collection admin permissions:', () => { - - before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - bob = privateKeyWrapper('//Bob'); - charlie = privateKeyWrapper('//Charlie'); - }); - }); - - it('Negative. Add to the allow list by regular user', async () => { - const collectionId = await createCollectionExpectSuccess(); - await addToAllowListExpectFail(bob, collectionId, charlie.address); - }); - - it('Execute the extrinsic with parameters: Collection ID and address to add to the allow list', async () => { - const collectionId = await createCollectionExpectSuccess(); - await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); - await addToAllowListExpectSuccess(bob, collectionId, charlie.address); - }); - - it('Allowlisted minting: list restrictions', async () => { - const collectionId = await createCollectionExpectSuccess(); - await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); - await addToAllowListExpectSuccess(bob, collectionId, charlie.address); - - // allowed only for collection owner - await enableAllowListExpectSuccess(alice, collectionId); - await enablePublicMintingExpectSuccess(alice, collectionId); - - await createItemExpectSuccess(charlie, collectionId, 'NFT', charlie.address); - }); -}); --- a/tests/src/allowLists.test.ts +++ b/tests/src/allowLists.test.ts @@ -15,85 +15,85 @@ // along with Unique Network. If not, see . import {IKeyringPair} from '@polkadot/types/types'; -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import {usingPlaygrounds} from './util/playgrounds'; +import {usingPlaygrounds, expect, itSub} from './util/playgrounds'; +import {ICollectionPermissions} from './util/playgrounds/types'; -chai.use(chaiAsPromised); -const expect = chai.expect; - -let donor: IKeyringPair; - -let alice: IKeyringPair; -let bob: IKeyringPair; -let charlie: IKeyringPair; +describe('Integration Test ext. Add to Allow List', () => { + let alice: IKeyringPair; + let bob: IKeyringPair; + let charlie: IKeyringPair; -describe('Integration Test ext. Allow list tests', () => { - before(async () => { await usingPlaygrounds(async (helper, privateKey) => { - donor = privateKey('//Alice'); - [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor); + const donor = privateKey('//Alice'); + [alice, bob, charlie] = await helper.arrange.createAccounts([30n, 10n, 10n], donor); }); }); - it('Owner can add address to allow list', async () => { - await usingPlaygrounds(async (helper) => { + describe('Positive', async () => { + itSub('Owner can add address to allow list', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); + // allow list does not need to be enabled to add someone in advance await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); const allowList = await helper.nft.getAllowList(collectionId); - expect(allowList).to.be.deep.contains({Substrate: bob.address}); + expect(allowList).to.deep.contain({Substrate: bob.address}); }); - }); - - it('Admin can add address to allow list', async () => { - await usingPlaygrounds(async (helper) => { + + itSub('Admin can add address to allow list', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address}); + // allow list does not need to be enabled to add someone in advance await helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address}); const allowList = await helper.nft.getAllowList(collectionId); - expect(allowList).to.be.deep.contains({Substrate: charlie.address}); + expect(allowList).to.deep.contain({Substrate: charlie.address}); }); - }); - it('Non-privileged user cannot add address to allow list', async () => { - await usingPlaygrounds(async (helper) => { + itSub('If address is already added to allow list, nothing happens', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - const addToAllowListTx = async () => helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address}); - await expect(addToAllowListTx()).to.be.rejected; + await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); + await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); + const allowList = await helper.nft.getAllowList(collectionId); + expect(allowList).to.deep.contain({Substrate: bob.address}); }); }); - it('Nobody can add address to allow list of non-existing collection', async () => { - const collectionId = (1<<32) - 1; - await usingPlaygrounds(async (helper) => { - const addToAllowListTx = async () => helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address}); - await expect(addToAllowListTx()).to.be.rejected; + describe('Negative', async () => { + itSub('Nobody can add address to allow list of non-existing collection', async ({helper}) => { + const collectionId = (1<<32) - 1; + await expect(helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address})) + .to.be.rejectedWith(/common\.CollectionNotFound/); }); - }); - - it('Nobody can add address to allow list of destroyed collection', async () => { - await usingPlaygrounds(async (helper) => { + + itSub('Nobody can add address to allow list of destroyed collection', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); await helper.collection.burn(alice, collectionId); - const addToAllowListTx = async () => helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); - await expect(addToAllowListTx()).to.be.rejected; + await expect(helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address})) + .to.be.rejectedWith(/common\.CollectionNotFound/); }); - }); - it('If address is already added to allow list, nothing happens', async () => { - await usingPlaygrounds(async (helper) => { + itSub('Non-privileged user cannot add address to allow list', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); - await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); - const allowList = await helper.nft.getAllowList(collectionId); - expect(allowList).to.be.deep.contains({Substrate: bob.address}); + await expect(helper.nft.addToAllowList(bob, collectionId, {Substrate: charlie.address})) + .to.be.rejectedWith(/common\.NoPermission/); }); }); +}); - it('Owner can remove address from allow list', async () => { - await usingPlaygrounds(async (helper) => { +describe('Integration Test ext. Remove from Allow List', () => { + let alice: IKeyringPair; + let bob: IKeyringPair; + let charlie: IKeyringPair; + + before(async () => { + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice, bob, charlie] = await helper.arrange.createAccounts([30n, 10n, 10n], donor); + }); + }); + + describe('Positive', async () => { + itSub('Owner can remove address from allow list', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); @@ -101,279 +101,260 @@ const allowList = await helper.nft.getAllowList(collectionId); - expect(allowList).to.be.not.deep.contains({Substrate: bob.address}); + expect(allowList).to.not.deep.contain({Substrate: bob.address}); }); - }); - it('Admin can remove address from allow list', async () => { - await usingPlaygrounds(async (helper) => { + itSub('Admin can remove address from allow list', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); await helper.nft.addAdmin(alice, collectionId, {Substrate: charlie.address}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); await helper.collection.removeFromAllowList(charlie, collectionId, {Substrate: bob.address}); const allowList = await helper.nft.getAllowList(collectionId); + expect(allowList).to.not.deep.contain({Substrate: bob.address}); + }); - expect(allowList).to.be.not.deep.contains({Substrate: bob.address}); + itSub('If address is already removed from allow list, nothing happens', async ({helper}) => { + const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); + await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); + await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address}); + const allowListBefore = await helper.nft.getAllowList(collectionId); + expect(allowListBefore).to.not.deep.contain({Substrate: bob.address}); + + await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address}); + + const allowListAfter = await helper.nft.getAllowList(collectionId); + expect(allowListAfter).to.not.deep.contain({Substrate: bob.address}); }); }); - it('Non-privileged user cannot remove address from allow list', async () => { - await usingPlaygrounds(async (helper) => { + describe('Negative', async () => { + itSub('Non-privileged user cannot remove address from allow list', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); - const removeTx = async () => helper.collection.removeFromAllowList(bob, collectionId, {Substrate: charlie.address}); - await expect(removeTx()).to.be.rejected; + await expect(helper.collection.removeFromAllowList(charlie, collectionId, {Substrate: charlie.address})) + .to.be.rejectedWith(/common\.NoPermission/); + const allowList = await helper.nft.getAllowList(collectionId); - - expect(allowList).to.be.deep.contains({Substrate: charlie.address}); + expect(allowList).to.deep.contain({Substrate: charlie.address}); }); - }); - - it('Nobody can remove address from allow list of non-existing collection', async () => { - const collectionId = (1<<32) - 1; - await usingPlaygrounds(async (helper) => { - const removeTx = async () => helper.collection.removeFromAllowList(bob, collectionId, {Substrate: charlie.address}); - await expect(removeTx()).to.be.rejected; + + itSub('Nobody can remove address from allow list of non-existing collection', async ({helper}) => { + const collectionId = (1<<32) - 1; + await expect(helper.collection.removeFromAllowList(bob, collectionId, {Substrate: charlie.address})) + .to.be.rejectedWith(/common\.CollectionNotFound/); }); - }); - - it('Nobody can remove address from allow list of deleted collection', async () => { - await usingPlaygrounds(async (helper) => { + + itSub('Nobody can remove address from allow list of deleted collection', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); await helper.collection.burn(alice, collectionId); - const removeTx = async () => helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address}); - - await expect(removeTx()).to.be.rejected; + + await expect(helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address})) + .to.be.rejectedWith(/common\.CollectionNotFound/); }); }); +}); - it('If address is already removed from allow list, nothing happens', async () => { - await usingPlaygrounds(async (helper) => { - const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); - await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address}); - const allowListBefore = await helper.nft.getAllowList(collectionId); - expect(allowListBefore).to.be.not.deep.contains({Substrate: bob.address}); +describe('Integration Test ext. Transfer if included in Allow List', () => { + let alice: IKeyringPair; + let bob: IKeyringPair; + let charlie: IKeyringPair; - await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: bob.address}); - - const allowListAfter = await helper.nft.getAllowList(collectionId); - expect(allowListAfter).to.be.not.deep.contains({Substrate: bob.address}); + before(async () => { + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice, bob, charlie] = await helper.arrange.createAccounts([30n, 10n, 10n], donor); }); }); - it('If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom. Test1', async () => { - await usingPlaygrounds(async (helper) => { + describe('Positive', async () => { + itSub('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transfer.', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); + await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); - - const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - await expect(transferResult()).to.be.rejected; + await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}); + const owner = await helper.nft.getTokenOwner(collectionId, tokenId); + expect(owner.Substrate).to.be.equal(charlie.address); }); - }); - - it('If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom. Test2', async () => { - await usingPlaygrounds(async (helper) => { + + itSub('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transferFrom.', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: alice.address}); - - const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - await expect(transferResult()).to.be.rejected; + + await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address}); + const owner = await helper.nft.getTokenOwner(collectionId, tokenId); + expect(owner.Substrate).to.be.equal(charlie.address); }); - }); - - it('If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom. Test1', async () => { - await usingPlaygrounds(async (helper) => { + + itSub('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address}); - - const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - await expect(transferResult()).to.be.rejected; + await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); + + await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}); + const owner = await helper.nft.getTokenOwner(collectionId, tokenId); + expect(owner.Substrate).to.be.equal(charlie.address); }); - }); - - it('If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom. Test2', async () => { - await usingPlaygrounds(async (helper) => { + + itSub('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transferFrom', async ({helper}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); - await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: alice.address}); - - const transferResult = async () => helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - await expect(transferResult()).to.be.rejected; + + await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address}); + const owner = await helper.nft.getTokenOwner(collectionId, tokenId); + expect(owner.Substrate).to.be.equal(charlie.address); }); }); - it('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 () => { - await usingPlaygrounds(async (helper) => { + describe('Negative', async () => { + 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}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); - const burnTx = async () => helper.nft.burnToken(bob, collectionId, tokenId); - await expect(burnTx()).to.be.rejected; + await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); + + await expect(helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address})) + .to.be.rejectedWith(/common\.AddressNotInAllowlist/); }); - }); - - it('If Public Access mode is set to AllowList, token transfers can’t be Approved by a non-allowlisted address (see Approve method)', async () => { - await usingPlaygrounds(async (helper) => { + + 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}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); - const approveTx = async () => helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address}); - await expect(approveTx()).to.be.rejected; + await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address}); + await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); + await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address}); + await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: alice.address}); + + await expect(helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address})) + .to.be.rejectedWith(/common\.AddressNotInAllowlist/); }); - }); - - it('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transfer.', async () => { - await usingPlaygrounds(async (helper) => { + + 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}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address}); - await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); - await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - const owner = await helper.nft.getTokenOwner(collectionId, tokenId); - expect(owner.Substrate).to.be.equal(charlie.address); + + await expect(helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address})) + .to.be.rejectedWith(/common\.AddressNotInAllowlist/); }); - }); - - it('If Public Access mode is set to AllowList, tokens can be transferred to a allowlisted address with transferFrom.', async () => { - await usingPlaygrounds(async (helper) => { + + 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}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address}); await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); + await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - - await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address}); - const owner = await helper.nft.getTokenOwner(collectionId, tokenId); - expect(owner.Substrate).to.be.equal(charlie.address); + await helper.collection.removeFromAllowList(alice, collectionId, {Substrate: alice.address}); + + await expect(helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address})) + .to.be.rejectedWith(/common\.AddressNotInAllowlist/); }); - }); - - it('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer', async () => { - await usingPlaygrounds(async (helper) => { + + 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}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); - await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address}); - await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); - - await helper.nft.transferToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - const owner = await helper.nft.getTokenOwner(collectionId, tokenId); - expect(owner.Substrate).to.be.equal(charlie.address); + await expect(helper.nft.burnToken(bob, collectionId, tokenId)) + .to.be.rejectedWith(/common\.NoPermission/); }); - }); - - it('If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transferFrom', async () => { - await usingPlaygrounds(async (helper) => { + + 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}) => { const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList'}); - await helper.nft.addToAllowList(alice, collectionId, {Substrate: alice.address}); - await helper.nft.addToAllowList(alice, collectionId, {Substrate: charlie.address}); - await helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: charlie.address}); - - await helper.nft.transferTokenFrom(alice, collectionId, tokenId, {Substrate: alice.address}, {Substrate: charlie.address}); - const owner = await helper.nft.getTokenOwner(collectionId, tokenId); - expect(owner.Substrate).to.be.equal(charlie.address); + await expect(helper.nft.approveToken(alice, collectionId, tokenId, {Substrate: bob.address})) + .to.be.rejectedWith(/common\.AddressNotInAllowlist/); }); }); +}); - it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by owner', async () => { - await usingPlaygrounds(async (helper) => { - const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false}); - const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); - const token = await helper.nft.getToken(collectionId, tokenId); - expect(token).to.be.not.null; +describe('Integration Test ext. Mint if included in Allow List', () => { + let alice: IKeyringPair; + let bob: IKeyringPair; + + before(async () => { + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor); }); }); - it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by admin', async () => { - await usingPlaygrounds(async (helper) => { - const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false}); - await helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address}); - const {tokenId} = await helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address}); - const token = await helper.nft.getToken(collectionId, tokenId); - expect(token).to.be.not.null; - }); - }); + const permissionSet: ICollectionPermissions[] = [ + {access: 'Normal', mintMode: false}, + {access: 'Normal', mintMode: true}, + {access: 'AllowList', mintMode: false}, + {access: 'AllowList', mintMode: true}, + ]; + + const testPermissionSuite = async (permissions: ICollectionPermissions) => { + const allowlistedMintingShouldFail = !permissions.mintMode!; - it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and allow-listed address', async () => { - await usingPlaygrounds(async (helper) => { - const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false}); - await helper.collection.addToAllowList(alice, collectionId, {Substrate: bob.address}); - const mintTokenTx = async () => helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address}); - await expect(mintTokenTx()).to.be.rejected; - }); - }); + const appropriateRejectionMessage = permissions.mintMode! ? /common\.AddressNotInAllowlist/ : /common\.PublicMintingNotAllowed/; - it('If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-allow listed address', async () => { - await usingPlaygrounds(async (helper) => { - const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: false}); - const mintTokenTx = async () => helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address}); - await expect(mintTokenTx()).to.be.rejected; - }); - }); + const allowlistedMintingTest = () => itSub( + `With the condtions above, tokens can${allowlistedMintingShouldFail ? '\'t' : ''} be created by allow-listed addresses`, + async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {}); + await collection.setPermissions(alice, permissions); + await collection.addToAllowList(alice, {Substrate: bob.address}); + + if (allowlistedMintingShouldFail) + await expect(collection.mintToken(bob, {Substrate: bob.address})).to.be.rejectedWith(appropriateRejectionMessage); + else + await expect(collection.mintToken(bob, {Substrate: bob.address})).to.not.be.rejected; + }, + ); + + + describe(`Public Access Mode = ${permissions.access}, Mint Mode = ${permissions.mintMode}`, async () => { + describe('Positive', async () => { + itSub('With the condtions above, tokens can be created by owner', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {}); + await collection.setPermissions(alice, permissions); + await expect(collection.mintToken(alice, {Substrate: alice.address})).to.not.be.rejected; + }); + + itSub('With the condtions above, tokens can be created by admin', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {}); + await collection.setPermissions(alice, permissions); + await collection.addAdmin(alice, {Substrate: bob.address}); + await expect(collection.mintToken(bob, {Substrate: bob.address})).to.not.be.rejected; + }); - it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by owner', async () => { - await usingPlaygrounds(async (helper) => { - const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true}); - const {tokenId} = await helper.nft.mintToken(alice, {collectionId: collectionId, owner: alice.address}); - const owner = await helper.nft.getTokenOwner(collectionId, tokenId); - expect(owner.Substrate).to.be.equal(alice.address); - }); - }); + if (!allowlistedMintingShouldFail) allowlistedMintingTest(); + }); - it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by admin', async () => { - await usingPlaygrounds(async (helper) => { - const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true}); - await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address}); - const {tokenId} = await helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address}); - const owner = await helper.nft.getTokenOwner(collectionId, tokenId); - expect(owner.Substrate).to.be.equal(bob.address); - }); - }); + describe('Negative', async () => { + itSub('With the condtions above, tokens can\'t be created by non-priviliged non-allow-listed address', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); + await collection.setPermissions(alice, permissions); + await expect(collection.mintToken(bob, {Substrate: bob.address})) + .to.be.rejectedWith(appropriateRejectionMessage); + }); - it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-allow listed address', async () => { - await usingPlaygrounds(async (helper) => { - const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true}); - const mintTokenTx = async () => helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address}); - await expect(mintTokenTx()).to.be.rejected; + if (allowlistedMintingShouldFail) allowlistedMintingTest(); + }); }); - }); + }; - it('If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by non-privileged and allow listed address', async () => { - await usingPlaygrounds(async (helper) => { - const {collectionId} = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}); - await helper.nft.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true}); - await helper.nft.addToAllowList(alice, collectionId, {Substrate: bob.address}); - const {tokenId} = await helper.nft.mintToken(bob, {collectionId: collectionId, owner: bob.address}); - const owner = await helper.nft.getTokenOwner(collectionId, tokenId); - expect(owner.Substrate).to.be.equal(bob.address); - }); - }); + for (const permissions of permissionSet) { + testPermissionSuite(permissions); + } }); --- a/tests/src/mintModes.test.ts +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -import {IKeyringPair} from '@polkadot/types/types'; -import usingApi from './substrate/substrate-api'; -import { - addToAllowListExpectSuccess, - createCollectionExpectSuccess, - createItemExpectFailure, - createItemExpectSuccess, - enableAllowListExpectSuccess, - setMintPermissionExpectSuccess, - addCollectionAdminExpectSuccess, - disableAllowListExpectSuccess, -} from './util/helpers'; - -describe('Integration Test public minting', () => { - let alice: IKeyringPair; - let bob: IKeyringPair; - - before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - bob = privateKeyWrapper('//Bob'); - }); - }); - - it('If the AllowList mode is enabled, then the address added to the allowlist and not the owner or administrator can create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await enableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, true); - await addToAllowListExpectSuccess(alice, collectionId, bob.address); - - await createItemExpectSuccess(bob, collectionId, 'NFT'); - }); - }); - - it('If the AllowList mode is enabled, address not included in allowlist that is regular user cannot create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await enableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, true); - await createItemExpectFailure(bob, collectionId, 'NFT'); - }); - }); - - it('If the AllowList mode is enabled, address not included in allowlist that is admin can create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await enableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, true); - await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); - await createItemExpectSuccess(bob, collectionId, 'NFT'); - }); - }); - - it('If the AllowList mode is enabled, address not included in allowlist that is owner can create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await enableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, true); - await createItemExpectSuccess(alice, collectionId, 'NFT'); - }); - }); - - it('If the AllowList mode is disabled, owner can create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await disableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, true); - await createItemExpectSuccess(alice, collectionId, 'NFT'); - }); - }); - - it('If the AllowList mode is disabled, collection admin can create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await disableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, true); - await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); - await createItemExpectSuccess(bob, collectionId, 'NFT'); - }); - }); - - it('If the AllowList mode is disabled, regular user can`t create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await disableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, true); - await createItemExpectFailure(bob, collectionId, 'NFT'); - }); - }); -}); - -describe('Integration Test private minting', () => { - let alice: IKeyringPair; - let bob: IKeyringPair; - - before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - bob = privateKeyWrapper('//Bob'); - }); - }); - - it('Address that is the not owner or not admin cannot create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await enableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, false); - await addToAllowListExpectSuccess(alice, collectionId, bob.address); - await createItemExpectFailure(bob, collectionId, 'NFT'); - }); - }); - - it('Address that is collection owner can create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await disableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, false); - await createItemExpectSuccess(alice, collectionId, 'NFT'); - }); - }); - - it('Address that is admin can create tokens', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await disableAllowListExpectSuccess(alice, collectionId); - await setMintPermissionExpectSuccess(alice, collectionId, false); - await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); - await createItemExpectSuccess(bob, collectionId, 'NFT'); - }); - }); -}); --- a/tests/src/removeFromAllowList.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -import {IKeyringPair} from '@polkadot/types/types'; -import {itSub, usingPlaygrounds, expect} from './util/playgrounds'; - -describe('Integration Test removeFromAllowList', () => { - let alice: IKeyringPair; - let bob: IKeyringPair; - - before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = privateKey('//Alice'); - [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); - }); - }); - - itSub('ensure bob is not in allowlist after removal', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-1', tokenPrefix: 'RFAL'}); - - const collectionInfo = await collection.getData(); - expect(collectionInfo!.raw.permissions.access).to.not.equal('AllowList'); - - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - await collection.addToAllowList(alice, {Substrate: bob.address}); - expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address}); - - await collection.removeFromAllowList(alice, {Substrate: bob.address}); - expect(await collection.getAllowList()).to.be.empty; - }); - - itSub('allows removal from collection with unset allowlist status', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-2', tokenPrefix: 'RFAL'}); - - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - await collection.addToAllowList(alice, {Substrate: bob.address}); - expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address}); - - await collection.setPermissions(alice, {access: 'Normal'}); - - await collection.removeFromAllowList(alice, {Substrate: bob.address}); - expect(await collection.getAllowList()).to.be.empty; - }); -}); - -describe('Negative Integration Test removeFromAllowList', () => { - let alice: IKeyringPair; - let bob: IKeyringPair; - - before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = privateKey('//Alice'); - [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); - }); - }); - - itSub('fails on removal from not existing collection', async ({helper}) => { - const nonExistentCollectionId = (1 << 32) - 1; - await expect(helper.collection.removeFromAllowList(alice, nonExistentCollectionId, {Substrate: alice.address})) - .to.be.rejectedWith(/common\.CollectionNotFound/); - }); - - itSub('fails on removal from removed collection', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-3', tokenPrefix: 'RFAL'}); - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - await collection.addToAllowList(alice, {Substrate: bob.address}); - - await collection.burn(alice); - await expect(collection.removeFromAllowList(alice, {Substrate: bob.address})) - .to.be.rejectedWith(/common\.CollectionNotFound/); - }); -}); - -describe('Integration Test removeFromAllowList with collection admin permissions', () => { - let alice: IKeyringPair; - let bob: IKeyringPair; - let charlie: IKeyringPair; - - before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = privateKey('//Alice'); - [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor); - }); - }); - - itSub('ensure address is not in allowlist after removal', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-4', tokenPrefix: 'RFAL'}); - - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - await collection.addAdmin(alice, {Substrate: bob.address}); - - await collection.addToAllowList(bob, {Substrate: charlie.address}); - await collection.removeFromAllowList(bob, {Substrate: charlie.address}); - - expect(await collection.getAllowList()).to.be.empty; - }); - - itSub('Collection admin allowed to remove from allowlist with unset allowlist status', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-5', tokenPrefix: 'RFAL'}); - - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - await collection.addAdmin(alice, {Substrate: bob.address}); - await collection.addToAllowList(alice, {Substrate: charlie.address}); - - await collection.setPermissions(bob, {access: 'Normal'}); - await collection.removeFromAllowList(bob, {Substrate: charlie.address}); - - expect(await collection.getAllowList()).to.be.empty; - }); - - itSub('Regular user can`t remove from allowlist', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-6', tokenPrefix: 'RFAL'}); - - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - await collection.addToAllowList(alice, {Substrate: charlie.address}); - - await expect(collection.removeFromAllowList(bob, {Substrate: charlie.address})) - .to.be.rejectedWith(/common\.NoPermission/); - expect(await collection.getAllowList()).to.deep.contain({Substrate: charlie.address}); - }); -}); --- a/tests/src/setMintPermission.test.ts +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -import {IKeyringPair} from '@polkadot/types/types'; -import {itSub, usingPlaygrounds, expect} from './util/playgrounds'; - -describe('Integration Test setMintPermission', () => { - let alice: IKeyringPair; - let bob: IKeyringPair; - - before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = privateKey('//Alice'); - [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); - }); - }); - - itSub('ensure allow-listed non-privileged address can mint tokens', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-1', description: '', tokenPrefix: 'SMP'}); - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - await collection.addToAllowList(alice, {Substrate: bob.address}); - - await expect(collection.mintToken(bob, {Substrate: bob.address})).to.not.be.rejected; - }); - - itSub('can be enabled twice', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-2', description: '', tokenPrefix: 'SMP'}); - expect((await collection.getData())?.raw.permissions.access).to.not.equal('AllowList'); - - await collection.setPermissions(alice, {mintMode: true}); - await collection.setPermissions(alice, {mintMode: true}); - expect((await collection.getData())?.raw.permissions.mintMode).to.be.true; - }); - - itSub('can be disabled twice', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-3', description: '', tokenPrefix: 'SMP'}); - expect((await collection.getData())?.raw.permissions.access).to.equal('Normal'); - - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList'); - expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true); - - await collection.setPermissions(alice, {access: 'Normal', mintMode: false}); - await collection.setPermissions(alice, {access: 'Normal', mintMode: false}); - expect((await collection.getData())?.raw.permissions.access).to.equal('Normal'); - expect((await collection.getData())?.raw.permissions.mintMode).to.equal(false); - }); - - itSub('Collection admin success on set', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-4', description: '', tokenPrefix: 'SMP'}); - await collection.addAdmin(alice, {Substrate: bob.address}); - await collection.setPermissions(bob, {access: 'AllowList', mintMode: true}); - - expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList'); - expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true); - }); -}); - -describe('Negative Integration Test setMintPermission', () => { - let alice: IKeyringPair; - let bob: IKeyringPair; - - before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = privateKey('//Alice'); - [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); - }); - }); - - itSub('fails on not existing collection', async ({helper}) => { - const collectionId = (1 << 32) - 1; - await expect(helper.collection.setPermissions(alice, collectionId, {mintMode: true})) - .to.be.rejectedWith(/common\.CollectionNotFound/); - }); - - itSub('fails on removed collection', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-1', tokenPrefix: 'SMP'}); - await collection.burn(alice); - - await expect(collection.setPermissions(alice, {mintMode: true})) - .to.be.rejectedWith(/common\.CollectionNotFound/); - }); - - itSub('fails when non-owner tries to set mint status', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-2', tokenPrefix: 'SMP'}); - - await expect(collection.setPermissions(bob, {mintMode: true})) - .to.be.rejectedWith(/common\.NoPermission/); - }); - - itSub('ensure non-allow-listed non-privileged address can\'t mint tokens', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-3', tokenPrefix: 'SMP'}); - await collection.setPermissions(alice, {mintMode: true}); - - await expect(collection.mintToken(bob, {Substrate: bob.address})) - .to.be.rejectedWith(/common\.AddressNotInAllowlist/); - }); -}); --- /dev/null +++ b/tests/src/setPermissions.test.ts @@ -0,0 +1,107 @@ +// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. +// This file is part of Unique Network. + +// Unique Network is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Unique Network is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Unique Network. If not, see . + +import {IKeyringPair} from '@polkadot/types/types'; +import {itSub, usingPlaygrounds, expect} from './util/playgrounds'; + +describe('Integration Test: Set Permissions', () => { + let alice: IKeyringPair; + let bob: IKeyringPair; + + before(async () => { + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); + }); + }); + + itSub('can all be enabled twice', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'SetPermissions-1', tokenPrefix: 'SP'}); + expect((await collection.getData())?.raw.permissions.access).to.not.equal('AllowList'); + + await collection.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {collectionAdmin: true, tokenOwner: true, restricted: [1, 2]}}); + await collection.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {collectionAdmin: true, tokenOwner: true, restricted: [1, 2]}}); + + const permissions = (await collection.getData())?.raw.permissions; + expect(permissions).to.be.deep.equal({ + access: 'AllowList', + mintMode: true, + nesting: {collectionAdmin: true, tokenOwner: true, restricted: [1, 2]}, + }); + }); + + itSub('can all be disabled twice', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'SetPermissions-2', tokenPrefix: 'SP'}); + expect((await collection.getData())?.raw.permissions.access).to.equal('Normal'); + + await collection.setPermissions(alice, {access: 'AllowList', nesting: {collectionAdmin: false, tokenOwner: true, restricted: [1, 2]}}); + expect((await collection.getData())?.raw.permissions).to.be.deep.equal({ + access: 'AllowList', + mintMode: false, + nesting: {collectionAdmin: false, tokenOwner: true, restricted: [1, 2]}, + }); + + await collection.setPermissions(alice, {access: 'Normal', mintMode: false, nesting: {}}); + await collection.setPermissions(alice, {access: 'Normal', mintMode: false, nesting: {}}); + expect((await collection.getData())?.raw.permissions).to.be.deep.equal({ + access: 'Normal', + mintMode: false, + nesting: {collectionAdmin: false, tokenOwner: false, restricted: null}, + }); + }); + + itSub('collection admin can set permissions', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'SetPermissions-2', tokenPrefix: 'SP'}); + await collection.addAdmin(alice, {Substrate: bob.address}); + await collection.setPermissions(bob, {access: 'AllowList', mintMode: true}); + + expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList'); + expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true); + }); +}); + +describe('Negative Integration Test: Set Permissions', () => { + let alice: IKeyringPair; + let bob: IKeyringPair; + + before(async () => { + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); + }); + }); + + itSub('fails on not existing collection', async ({helper}) => { + const collectionId = (1 << 32) - 1; + await expect(helper.collection.setPermissions(alice, collectionId, {access: 'AllowList', mintMode: true})) + .to.be.rejectedWith(/common\.CollectionNotFound/); + }); + + itSub('fails on removed collection', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'SetPermissions-Neg-1', tokenPrefix: 'SP'}); + await collection.burn(alice); + + await expect(collection.setPermissions(alice, {access: 'AllowList', mintMode: true})) + .to.be.rejectedWith(/common\.CollectionNotFound/); + }); + + itSub('fails when non-owner tries to set permissions', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'SetPermissions-Neg-2', tokenPrefix: 'SP'}); + + await expect(collection.setPermissions(bob, {access: 'AllowList', mintMode: true})) + .to.be.rejectedWith(/common\.NoPermission/); + }); +}); \ No newline at end of file --- a/tests/src/setPublicAccessMode.test.ts +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -// https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion -import {IKeyringPair} from '@polkadot/types/types'; -import {itSub, usingPlaygrounds, expect} from './util/playgrounds'; - -describe('Integration Test setPublicAccessMode(): ', () => { - let alice: IKeyringPair; - let bob: IKeyringPair; - - before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = privateKey('//Alice'); - [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); - }); - }); - - itSub('Runs extrinsic with collection id parameters, sets the allowlist mode for the collection', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-1', tokenPrefix: 'TF'}); - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - await collection.addToAllowList(alice, {Substrate: bob.address}); - - await expect(collection.mintToken(bob, {Substrate: bob.address})).to.be.not.rejected; - }); - - itSub('Allowlisted collection limits', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-2', tokenPrefix: 'TF'}); - await collection.setPermissions(alice, {access: 'AllowList', mintMode: true}); - - await expect(collection.mintToken(bob, {Substrate: bob.address})) - .to.be.rejectedWith(/common\.AddressNotInAllowlist/); - }); - - itSub('setPublicAccessMode by collection admin', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-4', tokenPrefix: 'TF'}); - await collection.addAdmin(alice, {Substrate: bob.address}); - - await expect(collection.setPermissions(bob, {access: 'AllowList'})).to.be.not.rejected; - }); -}); - -describe('Negative Integration Test ext. setPublicAccessMode(): ', () => { - let alice: IKeyringPair; - let bob: IKeyringPair; - - before(async () => { - await usingPlaygrounds(async (helper, privateKey) => { - const donor = privateKey('//Alice'); - [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); - }); - }); - - itSub('Sets a non-existent collection', async ({helper}) => { - const collectionId = (1 << 32) - 1; - await expect(helper.collection.setPermissions(alice, collectionId, {access: 'AllowList'})) - .to.be.rejectedWith(/common\.CollectionNotFound/); - }); - - itSub('Sets the collection that has been deleted', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-1', tokenPrefix: 'TF'}); - await collection.burn(alice); - - await expect(collection.setPermissions(alice, {access: 'AllowList'})) - .to.be.rejectedWith(/common\.CollectionNotFound/); - }); - - itSub('Re-sets the list mode already set in quantity', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-2', tokenPrefix: 'TF'}); - await collection.setPermissions(alice, {access: 'AllowList'}); - await collection.setPermissions(alice, {access: 'AllowList'}); - }); - - itSub('Executes method as a malefactor', async ({helper}) => { - const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-3', tokenPrefix: 'TF'}); - - await expect(collection.setPermissions(bob, {access: 'AllowList'})) - .to.be.rejectedWith(/common\.NoPermission/); - }); -});