difftreelog
Add zero transfer[From], burn[From] tests
in: master
3 files changed
tests/src/burnItem.test.tsdiffbeforeafterboth1// 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 {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, Pallets, usingPlaygrounds} from './util';192021describe('integration test: ext. burnItem():', () => {22 let donor: IKeyringPair;23 let alice: IKeyringPair;24 let bob: IKeyringPair;2526 before(async () => {27 await usingPlaygrounds(async (helper, privateKey) => {28 donor = await privateKey({filename: __filename});29 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);30 });31 });3233 itSub('Burn item in NFT collection', async ({helper}) => {34 const collection = await helper.nft.mintCollection(alice);35 const token = await collection.mintToken(alice);3637 await token.burn(alice);38 expect(await token.doesExist()).to.be.false;39 });4041 itSub('Burn item in Fungible collection', async ({helper}) => {42 const collection = await helper.ft.mintCollection(alice, {}, 10);43 await collection.mint(alice, 10n);4445 await collection.burnTokens(alice, 1n);46 expect(await collection.getBalance({Substrate: alice.address})).to.eq(9n);47 });4849 itSub.ifWithPallets('Burn item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {50 const collection = await helper.rft.mintCollection(alice);51 const token = await collection.mintToken(alice, 100n);5253 await token.burn(alice, 90n);54 expect(await token.getBalance({Substrate: alice.address})).to.eq(10n);5556 await token.burn(alice, 10n);57 expect(await token.getBalance({Substrate: alice.address})).to.eq(0n);58 });5960 itSub.ifWithPallets('Burn owned portion of item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {61 const collection = await helper.rft.mintCollection(alice);62 const token = await collection.mintToken(alice, 100n);6364 await token.transfer(alice, {Substrate: bob.address}, 1n);6566 expect(await token.getBalance({Substrate: alice.address})).to.eq(99n);67 expect(await token.getBalance({Substrate: bob.address})).to.eq(1n);6869 await token.burn(bob, 1n);7071 expect(await token.getBalance({Substrate: alice.address})).to.eq(99n);72 expect(await token.getBalance({Substrate: bob.address})).to.eq(0n);73 });74});7576describe('integration test: ext. burnItem() with admin permissions:', () => {77 let donor: IKeyringPair;78 let alice: IKeyringPair;79 let bob: IKeyringPair;8081 before(async () => {82 await usingPlaygrounds(async (helper, privateKey) => {83 donor = await privateKey({filename: __filename});84 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);85 });86 });8788 itSub('Burn item in NFT collection', async ({helper}) => {89 const collection = await helper.nft.mintCollection(alice);90 await collection.setLimits(alice, {ownerCanTransfer: true});91 await collection.addAdmin(alice, {Substrate: bob.address});92 const token = await collection.mintToken(alice);9394 await token.burnFrom(bob, {Substrate: alice.address});95 expect(await token.doesExist()).to.be.false;96 });9798 itSub('Burn item in Fungible collection', async ({helper}) => {99 const collection = await helper.ft.mintCollection(alice, {}, 0);100 await collection.setLimits(alice, {ownerCanTransfer: true});101 await collection.addAdmin(alice, {Substrate: bob.address});102 await collection.mint(alice, 10n);103104 await collection.burnTokensFrom(bob, {Substrate: alice.address}, 1n);105 expect(await collection.getBalance({Substrate: alice.address})).to.eq(9n);106 });107108 itSub.ifWithPallets('Burn item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {109 const collection = await helper.rft.mintCollection(alice);110 await collection.setLimits(alice, {ownerCanTransfer: true});111 await collection.addAdmin(alice, {Substrate: bob.address});112 const token = await collection.mintToken(alice, 100n);113114 await token.burnFrom(bob, {Substrate: alice.address}, 100n);115 expect(await token.doesExist()).to.be.false;116 });117});118119describe('Negative integration test: ext. burnItem():', () => {120 let donor: IKeyringPair;121 let alice: IKeyringPair;122 let bob: IKeyringPair;123124 before(async () => {125 await usingPlaygrounds(async (helper, privateKey) => {126 donor = await privateKey({filename: __filename});127 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);128 });129 });130131 itSub('Burn a token that was never created', async ({helper}) => {132 const collection = await helper.nft.mintCollection(alice);133 await expect(collection.burnToken(alice, 10)).to.be.rejectedWith('common.TokenNotFound');134 });135136 itSub('Burn a token using the address that does not own it', async ({helper}) => {137 const collection = await helper.nft.mintCollection(alice);138 const token = await collection.mintToken(alice);139140 await expect(token.burn(bob)).to.be.rejectedWith('common.NoPermission');141 });142143 itSub('Transfer a burned token', async ({helper}) => {144 const collection = await helper.nft.mintCollection(alice);145 const token = await collection.mintToken(alice);146 await token.burn(alice);147148 await expect(token.transfer(alice, {Substrate: bob.address})).to.be.rejectedWith('common.TokenNotFound');149 });150151 itSub('Burn more than owned in Fungible collection', async ({helper}) => {152 const collection = await helper.ft.mintCollection(alice, {}, 0);153 await collection.mint(alice, 10n);154155 await expect(collection.burnTokens(alice, 11n)).to.be.rejectedWith('common.TokenValueTooLow');156 expect(await collection.getBalance({Substrate: alice.address})).to.eq(10n);157 });158});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 {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, Pallets, usingPlaygrounds} from './util';192021describe('integration test: ext. burnItem():', () => {22 let donor: IKeyringPair;23 let alice: IKeyringPair;24 let bob: IKeyringPair;2526 before(async () => {27 await usingPlaygrounds(async (helper, privateKey) => {28 donor = await privateKey({filename: __filename});29 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);30 });31 });3233 itSub('Burn item in NFT collection', async ({helper}) => {34 const collection = await helper.nft.mintCollection(alice);35 const token = await collection.mintToken(alice);3637 await token.burn(alice);38 expect(await token.doesExist()).to.be.false;39 });4041 itSub('Burn item in Fungible collection', async ({helper}) => {42 const collection = await helper.ft.mintCollection(alice, {}, 10);43 await collection.mint(alice, 10n);4445 await collection.burnTokens(alice, 1n);46 expect(await collection.getBalance({Substrate: alice.address})).to.eq(9n);47 });4849 itSub.ifWithPallets('Burn item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {50 const collection = await helper.rft.mintCollection(alice);51 const token = await collection.mintToken(alice, 100n);5253 await token.burn(alice, 90n);54 expect(await token.getBalance({Substrate: alice.address})).to.eq(10n);5556 await token.burn(alice, 10n);57 expect(await token.getBalance({Substrate: alice.address})).to.eq(0n);58 });5960 itSub.ifWithPallets('Burn owned portion of item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {61 const collection = await helper.rft.mintCollection(alice);62 const token = await collection.mintToken(alice, 100n);6364 await token.transfer(alice, {Substrate: bob.address}, 1n);6566 expect(await token.getBalance({Substrate: alice.address})).to.eq(99n);67 expect(await token.getBalance({Substrate: bob.address})).to.eq(1n);6869 await token.burn(bob, 1n);7071 expect(await token.getBalance({Substrate: alice.address})).to.eq(99n);72 expect(await token.getBalance({Substrate: bob.address})).to.eq(0n);73 });74});7576describe('integration test: ext. burnItem() with admin permissions:', () => {77 let donor: IKeyringPair;78 let alice: IKeyringPair;79 let bob: IKeyringPair;8081 before(async () => {82 await usingPlaygrounds(async (helper, privateKey) => {83 donor = await privateKey({filename: __filename});84 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);85 });86 });8788 itSub('Burn item in NFT collection', async ({helper}) => {89 const collection = await helper.nft.mintCollection(alice);90 await collection.setLimits(alice, {ownerCanTransfer: true});91 await collection.addAdmin(alice, {Substrate: bob.address});92 const token = await collection.mintToken(alice);9394 await token.burnFrom(bob, {Substrate: alice.address});95 expect(await token.doesExist()).to.be.false;96 });9798 itSub('Burn item in Fungible collection', async ({helper}) => {99 const collection = await helper.ft.mintCollection(alice, {}, 0);100 await collection.setLimits(alice, {ownerCanTransfer: true});101 await collection.addAdmin(alice, {Substrate: bob.address});102 await collection.mint(alice, 10n);103104 await collection.burnTokensFrom(bob, {Substrate: alice.address}, 1n);105 expect(await collection.getBalance({Substrate: alice.address})).to.eq(9n);106 });107108 itSub.ifWithPallets('Burn item in ReFungible collection', [Pallets.ReFungible], async function({helper}) {109 const collection = await helper.rft.mintCollection(alice);110 await collection.setLimits(alice, {ownerCanTransfer: true});111 await collection.addAdmin(alice, {Substrate: bob.address});112 const token = await collection.mintToken(alice, 100n);113114 await token.burnFrom(bob, {Substrate: alice.address}, 100n);115 expect(await token.doesExist()).to.be.false;116 });117});118119describe('Negative integration test: ext. burnItem():', () => {120 let donor: IKeyringPair;121 let alice: IKeyringPair;122 let bob: IKeyringPair;123124 before(async () => {125 await usingPlaygrounds(async (helper, privateKey) => {126 donor = await privateKey({filename: __filename});127 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);128 });129 });130131 itSub('Burn a token that was never created', async ({helper}) => {132 const collection = await helper.nft.mintCollection(alice);133 await expect(collection.burnToken(alice, 10)).to.be.rejectedWith('common.TokenNotFound');134 });135136 itSub('Burn a token using the address that does not own it', async ({helper}) => {137 const collection = await helper.nft.mintCollection(alice);138 const token = await collection.mintToken(alice);139140 await expect(token.burn(bob)).to.be.rejectedWith('common.NoPermission');141 });142143 itSub('Transfer a burned token', async ({helper}) => {144 const collection = await helper.nft.mintCollection(alice);145 const token = await collection.mintToken(alice);146 await token.burn(alice);147148 await expect(token.transfer(alice, {Substrate: bob.address})).to.be.rejectedWith('common.TokenNotFound');149 });150151 itSub('Burn more than owned in Fungible collection', async ({helper}) => {152 const collection = await helper.ft.mintCollection(alice, {}, 0);153 await collection.mint(alice, 10n);154155 await expect(collection.burnTokens(alice, 11n)).to.be.rejectedWith('common.TokenValueTooLow');156 expect(await collection.getBalance({Substrate: alice.address})).to.eq(10n);157 });158159 itSub('Zero burn NFT', async ({helper}) => {160 const api = helper.getApi();161 const collection = await helper.nft.mintCollection(alice, {name: 'Coll', description: 'Desc', tokenPrefix: 'T'});162 const tokenAlice = await collection.mintToken(alice, {Substrate: alice.address});163 const tokenBob = await collection.mintToken(alice, {Substrate: bob.address});164 165 // 1. Zero burn of own tokens allowed:166 await helper.signTransaction(alice, api.tx.unique.burnItem(collection.collectionId, tokenAlice.tokenId, 0));167 // 2. Zero burn of non-owned tokens not allowed:168 await expect(helper.signTransaction(alice, api.tx.unique.burnItem(collection.collectionId, tokenBob.tokenId, 0))).to.be.rejectedWith('common.NoPermission');169 // 3. Zero burn of non-existing tokens not allowed:170 await expect(helper.signTransaction(alice, api.tx.unique.burnItem(collection.collectionId, 9999, 0))).to.be.rejectedWith('common.TokenNotFound');171 expect(await tokenAlice.doesExist()).to.be.true;172 expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: alice.address});173 expect(await tokenBob.getOwner()).to.deep.eq({Substrate: bob.address});174 // 4. Storage is not corrupted:175 await tokenAlice.transfer(alice, {Substrate: bob.address});176 await tokenBob.transfer(alice, {Substrate: alice.address});177 expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: bob.address});178 expect(await tokenBob.getOwner()).to.deep.eq({Substrate: alice.address});179 });180181 itSub('zero burnFrom NFT', async ({helper}) => {182 const api = helper.getApi();183 const collection = await helper.nft.mintCollection(alice, {name: 'Zero', description: 'Zero transfer', tokenPrefix: 'TF'});184 const notApprovedNft = await collection.mintToken(alice, {Substrate: bob.address});185 const approvedNft = await collection.mintToken(alice, {Substrate: bob.address});186 await approvedNft.approve(bob, {Substrate: alice.address});187188 // 1. Zero burnFrom of non-existing tokens not allowed:189 await expect(helper.signTransaction(alice, api.tx.unique.burnFrom(collection.collectionId, {Substrate: bob.address}, 9999, 0))).to.be.rejectedWith('common.ApprovedValueTooLow');190 // 2. Zero burnFrom of not approved tokens not allowed:191 await expect(helper.signTransaction(alice, api.tx.unique.burnFrom(collection.collectionId, {Substrate: bob.address}, notApprovedNft.tokenId, 0))).to.be.rejectedWith('common.NoPermission');192 // 3. Zero burnFrom of approved tokens allowed:193 await helper.signTransaction(alice, api.tx.unique.burnFrom(collection.collectionId, {Substrate: bob.address}, approvedNft.tokenId, 0));194195 // 4.1 approvedNft still approved:196 expect(await approvedNft.isApproved({Substrate: alice.address})).to.be.true;197 // 4.2 bob is still the owner:198 expect(await approvedNft.getOwner()).to.deep.eq({Substrate: bob.address});199 expect(await notApprovedNft.getOwner()).to.deep.eq({Substrate: bob.address});200 // 4.3 Alice can burn approved nft:201 await approvedNft.burnFrom(alice, {Substrate: bob.address});202 expect(await approvedNft.doesExist()).to.be.false;203 });204});tests/src/transfer.test.tsdiffbeforeafterboth--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -122,6 +122,7 @@
});
});
+
itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {
const collectionId = (1 << 32) - 1;
await expect(helper.nft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
@@ -191,6 +192,26 @@
.to.be.rejectedWith(/common\.TokenValueTooLow/);
});
+ itSub('Zero transfer NFT', async ({helper}) => {
+ const api = helper.getApi();
+ const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});
+ const tokenAlice = await collection.mintToken(alice, {Substrate: alice.address});
+ const tokenBob = await collection.mintToken(alice, {Substrate: bob.address});
+ // 1. Zero transfer of own tokens allowed:
+ await helper.signTransaction(alice, api.tx.unique.transfer({Substrate: bob.address}, collection.collectionId, tokenAlice.tokenId, 0));
+ // 2. Zero transfer of non-owned tokens not allowed:
+ await expect(helper.signTransaction(alice, api.tx.unique.transfer({Substrate: alice.address}, collection.collectionId, tokenBob.tokenId, 0))).to.be.rejectedWith('common.NoPermission');
+ // 3. Zero transfer of non-existing tokens not allowed:
+ await expect(helper.signTransaction(alice, api.tx.unique.transfer({Substrate: alice.address}, collection.collectionId, 10, 0))).to.be.rejectedWith('common.TokenNotFound');
+ expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: alice.address});
+ expect(await tokenBob.getOwner()).to.deep.eq({Substrate: bob.address});
+ // 4. Storage is not corrupted:
+ await tokenAlice.transfer(alice, {Substrate: bob.address});
+ await tokenBob.transfer(alice, {Substrate: alice.address});
+ expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: bob.address});
+ expect(await tokenBob.getOwner()).to.deep.eq({Substrate: alice.address});
+ });
+
itSub('[nft] Transfer with deleted item_id', async ({helper}) => {
const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});
const nft = await collection.mintToken(alice);
tests/src/transferFrom.test.tsdiffbeforeafterboth--- a/tests/src/transferFrom.test.ts
+++ b/tests/src/transferFrom.test.ts
@@ -349,4 +349,28 @@
{Substrate: charlie.address},
)).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
});
+
+ itSub('zero transfer NFT', async ({helper}) => {
+ const api = helper.getApi();
+ const collection = await helper.nft.mintCollection(alice, {name: 'Zero', description: 'Zero transfer', tokenPrefix: 'TF'});
+ const notApprovedNft = await collection.mintToken(alice, {Substrate: bob.address});
+ const approvedNft = await collection.mintToken(alice, {Substrate: bob.address});
+ await approvedNft.approve(bob, {Substrate: alice.address});
+
+ // 1. Cannot zero transferFrom (non-existing token)
+ await expect(helper.signTransaction(alice, api.tx.unique.transferFrom({Substrate: bob.address}, {Substrate: alice.address}, collection.collectionId, 9999, 0))).to.be.rejectedWith('common.ApprovedValueTooLow');
+ // 2. Cannot zero transferFrom (not approved token)
+ await expect(helper.signTransaction(alice, api.tx.unique.transferFrom({Substrate: bob.address}, {Substrate: alice.address}, collection.collectionId, notApprovedNft.tokenId, 0))).to.be.rejectedWith('common.NoPermission');
+ // 3. Can zero transferFrom (approved token):
+ await helper.signTransaction(alice, api.tx.unique.transferFrom({Substrate: bob.address}, {Substrate: alice.address}, collection.collectionId, approvedNft.tokenId, 0));
+
+ // 4.1 approvedNft still approved:
+ expect(await approvedNft.isApproved({Substrate: alice.address})).to.be.true;
+ // 4.2 bob is still the owner:
+ expect(await approvedNft.getOwner()).to.deep.eq({Substrate: bob.address});
+ expect(await notApprovedNft.getOwner()).to.deep.eq({Substrate: bob.address});
+ // 4.3 Alice can transfer approved nft:
+ await approvedNft.transferFrom(alice, {Substrate: bob.address}, {Substrate: alice.address});
+ expect(await approvedNft.getOwner()).to.deep.eq({Substrate: alice.address});
+ });
});