From a9dbb975b85293bc4c0cd50b30a063e217b87890 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Tue, 29 Dec 2020 11:50:12 +0000 Subject: [PATCH] Merge pull request #54 from usetech-llc/feature/NFTPAR-237 Feature/NFTPAR-237 --- --- /dev/null +++ b/tests/src/change-collection-owner.test.ts @@ -0,0 +1,59 @@ +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import privateKey from './substrate/privateKey'; +import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api"; +import { createCollectionExpectSuccess, createCollectionExpectFailure } from "./util/helpers"; + +chai.use(chaiAsPromised); +const expect = chai.expect; + +describe('Integration Test changeCollectionOwner(collection_id, new_owner):', () => { + it('Changing owner changes owner.', async () => { + await usingApi(async api => { + const collectionId = await createCollectionExpectSuccess(); + const alice = privateKey('//Alice'); + const bob = privateKey('//Bob'); + + const collection: any = (await api.query.nft.collection(collectionId)); + expect(collection.Owner.toString()).to.be.eq(alice.address); + + const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address); + await submitTransactionAsync(alice, changeOwnerTx); + + const collectionAfterOwnerChange: any = (await api.query.nft.collection(collectionId)); + expect(collectionAfterOwnerChange.Owner.toString()).to.be.eq(bob.address); + }); + }); +}); + +describe('Negative Integration Test changeCollectionOwner(collection_id, new_owner):', () => { + it(`Not owner can't change owner.`, async () => { + await usingApi(async api => { + const collectionId = await createCollectionExpectSuccess(); + const alice = privateKey('//Alice'); + const bob = privateKey('//Bob'); + + const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address); + await expect(submitTransactionExpectFailAsync(bob, changeOwnerTx)).to.be.rejected; + + const collectionAfterOwnerChange: any = (await api.query.nft.collection(collectionId)); + expect(collectionAfterOwnerChange.Owner.toString()).to.be.eq(alice.address); + + // Verifying that nothing bad happened (network is live, new collections can be created, etc.) + await createCollectionExpectSuccess(); + }); + }); + it(`Can't change owner of not existing collection.`, async () => { + await usingApi(async api => { + const collectionId = (1<<32) - 1; + const alice = privateKey('//Alice'); + const bob = privateKey('//Bob'); + + const changeOwnerTx = api.tx.nft.changeCollectionOwner(collectionId, bob.address); + await expect(submitTransactionExpectFailAsync(alice, changeOwnerTx)).to.be.rejected; + + // Verifying that nothing bad happened (network is live, new collections can be created, etc.) + await createCollectionExpectSuccess(); + }); + }); +}); --- a/tests/src/confirmSponsorship.test.ts +++ b/tests/src/confirmSponsorship.test.ts @@ -5,7 +5,7 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api"; +import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api"; import { createCollectionExpectSuccess, setCollectionSponsorExpectSuccess, @@ -44,25 +44,25 @@ }); it('Confirm collection sponsorship', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); }); it('Add sponsor to a collection after the same sponsor was already added and confirmed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); await setCollectionSponsorExpectSuccess(collectionId, bob.address); }); it('Add new sponsor to a collection after another sponsor was already added and confirmed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); await setCollectionSponsorExpectSuccess(collectionId, charlie.address); }); it('NFT: Transfer fees are paid by the sponsor after confirmation', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); @@ -89,7 +89,7 @@ }); it('Fungible: Transfer fees are paid by the sponsor after confirmation', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'Fungible'); + const collectionId = await createCollectionExpectSuccess({mode: 'Fungible'}); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); @@ -115,7 +115,7 @@ }); it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'ReFungible'); + const collectionId = await createCollectionExpectSuccess({mode: 'ReFungible'}); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); @@ -141,7 +141,7 @@ }); it('CreateItem fees are paid by the sponsor after confirmation', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); @@ -171,7 +171,7 @@ }); it('NFT: Sponsoring is rate limited', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); @@ -192,11 +192,7 @@ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString()); const zeroToAlice = api.tx.nft.transfer(alice.address, collectionId, itemId, 0); const badTransaction = async function () { - console.log = function () {}; - console.error = function () {}; - await submitTransactionAsync(zeroBalance, zeroToAlice); - delete console.log; - delete console.error; + await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice); }; await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees"); const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString()); @@ -214,7 +210,7 @@ }); it('Fungible: Sponsoring is rate limited', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'Fungible'); + const collectionId = await createCollectionExpectSuccess({mode: 'Fungible'}); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); @@ -233,11 +229,7 @@ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString()); const badTransaction = async function () { - console.log = function () {}; - console.error = function () {}; - await submitTransactionAsync(zeroBalance, zeroToAlice); - delete console.log; - delete console.error; + await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice); }; const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString()); @@ -255,7 +247,7 @@ }); it('ReFungible: Sponsoring is rate limited', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'ReFungible'); + const collectionId = await createCollectionExpectSuccess({mode: 'ReFungible'}); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); @@ -276,11 +268,7 @@ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString()); const zeroToAlice = api.tx.nft.transfer(alice.address, collectionId, itemId, 1); const badTransaction = async function () { - console.log = function () {}; - console.error = function () {}; - await submitTransactionAsync(zeroBalance, zeroToAlice); - delete console.log; - delete console.error; + await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice); }; await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees"); const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString()); @@ -320,7 +308,7 @@ }); it('(!negative test!) Confirm sponsorship using a non-sponsor address', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await usingApi(async (api) => { @@ -332,18 +320,18 @@ }); it('(!negative test!) Confirm sponsorship using owner address', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectFailure(collectionId, '//Alice'); }); it('(!negative test!) Confirm sponsorship without sponsor being set with setCollectionSponsor', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await confirmSponsorshipExpectFailure(collectionId, '//Bob'); }); it('(!negative test!) Confirm sponsorship in a collection that was destroyed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await destroyCollectionExpectSuccess(collectionId); await confirmSponsorshipExpectFailure(collectionId, '//Bob'); }); --- a/tests/src/connection.test.ts +++ b/tests/src/connection.test.ts @@ -21,6 +21,8 @@ }); it('Cannot connect to 255.255.255.255', async () => { + const log = console.log; + const error = console.error; console.log = function () {}; console.error = function () {}; @@ -31,7 +33,7 @@ }, { provider: neverConnectProvider }); })()).to.be.eventually.rejected; - delete console.log; - delete console.error; + console.log = log; + console.error = error; }); }); \ No newline at end of file --- a/tests/src/contracts.test.ts +++ b/tests/src/contracts.test.ts @@ -109,9 +109,6 @@ const bob = privateKey("//Bob"); const [contract, deployer] = await deployFlipper(api); - const consoleError = console.error; - console.error = (...data: any[]) => { - }; let expectedFlipValue = await getFlipValue(contract, deployer); @@ -166,7 +163,6 @@ const afterWhiteListDisabled = await getFlipValue(contract,deployer); expect(afterWhiteListDisabled).to.be.eq(expectedFlipValue, `Anyone can call contract with disabled whitelist.`); - console.error = consoleError; }); }); --- a/tests/src/createCollection.test.ts +++ b/tests/src/createCollection.test.ts @@ -6,37 +6,29 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { default as usingApi } from "./substrate/substrate-api"; -import { createCollectionExpectSuccess, createCollectionExpectFailure } from "./util/helpers"; +import { createCollectionExpectSuccess, createCollectionExpectFailure, CollectionMode } from "./util/helpers"; chai.use(chaiAsPromised); const expect = chai.expect; describe('integration test: ext. createCollection():', () => { it('Create new NFT collection', async () => { - await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: 'NFT'}); }); it('Create new NFT collection whith collection_name of maximum length (64 bytes)', async () => { - await createCollectionExpectSuccess( - 'ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCD', - '1', '1', 'NFT'); + await createCollectionExpectSuccess({name: 'A'.repeat(64)}); }); it('Create new NFT collection whith collection_description of maximum length (256 bytes)', async () => { - await createCollectionExpectSuccess( - 'A', - 'ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJabcdef', - '1', 'NFT'); + await createCollectionExpectSuccess({description: 'A'.repeat(256)}); }); it('Create new NFT collection whith token_prefix of maximum length (16 bytes)', async () => { - await createCollectionExpectSuccess( - '1', - '1', - 'ABCDEFGHIJABCDEF', 'NFT'); + await createCollectionExpectSuccess({tokenPrefix: 'A'.repeat(16)}); }); it('Create new Fungible collection', async () => { - await createCollectionExpectSuccess('1', '1', '1', 'Fungible'); + await createCollectionExpectSuccess({mode: 'Fungible'}); }); it('Create new ReFungible collection', async () => { - await createCollectionExpectSuccess('1', '1', '1', 'ReFungible'); + await createCollectionExpectSuccess({mode: 'ReFungible'}); }); }); @@ -46,7 +38,7 @@ const AcollectionCount = parseInt((await api.query.nft.collectionCount()).toString()); const badTransaction = async function () { - await createCollectionExpectSuccess('1', '1', '1', 'BadMode'); + await createCollectionExpectSuccess({mode: 'BadMode' as CollectionMode}); }; expect(badTransaction()).to.be.rejected; @@ -55,18 +47,12 @@ }); }); it('(!negative test!) create new NFT collection whith incorrect data (collection_name)', async () => { - await createCollectionExpectFailure( - 'ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDE', - '1', '1', 'NFT'); + await createCollectionExpectFailure({name: 'A'.repeat(65)}); }); it('(!negative test!) create new NFT collection whith incorrect data (collection_description)', async () => { - await createCollectionExpectFailure('1', - 'ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJabcdefg', - '1', 'NFT'); + await createCollectionExpectFailure({description: 'A'.repeat(257)}); }); it('(!negative test!) create new NFT collection whith incorrect data (token_prefix)', async () => { - await createCollectionExpectFailure('1', '1', - 'ABCDEFGHIJABCDEFG', - 'NFT'); + await createCollectionExpectFailure({tokenPrefix: 'A'.repeat(17)}); }); }); --- a/tests/src/createItem.test.ts +++ b/tests/src/createItem.test.ts @@ -18,17 +18,17 @@ it('Create new item in NFT collection', async () => { const createMode = 'NFT'; - const newCollectionID = await createCollectionExpectSuccess('0', '0', '0', createMode); + const newCollectionID = await createCollectionExpectSuccess({mode: createMode}); await createItemExpectSuccess(alice, newCollectionID, createMode); }); it('Create new item in Fungible collection', async () => { const createMode = 'Fungible'; - const newCollectionID = await createCollectionExpectSuccess('0', '0', '0', createMode); + const newCollectionID = await createCollectionExpectSuccess({mode: createMode}); await createItemExpectSuccess(alice, newCollectionID, createMode); }); it('Create new item in ReFungible collection', async () => { const createMode = 'ReFungible'; - const newCollectionID = await createCollectionExpectSuccess('0', '0', '0', createMode); + const newCollectionID = await createCollectionExpectSuccess({mode: createMode}); await createItemExpectSuccess(alice, newCollectionID, createMode); }); }); --- a/tests/src/creditFeesToTreasury.test.ts +++ b/tests/src/creditFeesToTreasury.test.ts @@ -5,7 +5,7 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api"; +import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api"; import { alicesPublicKey, bobsPublicKey } from "./accounts"; import privateKey from "./substrate/privateKey"; import { BigNumber } from 'bignumber.js'; @@ -63,14 +63,13 @@ const bobBalanceBefore = new BigNumber((await api.query.system.account(bobsPublicKey)).data.free.toString()); const badTx = api.tx.balances.setBalance(alicesPublicKey, 0, 0); - const result = getGenericResult(await submitTransactionAsync(bobPrivateKey, badTx)); + await expect(submitTransactionExpectFailAsync(bobPrivateKey, badTx)).to.be.rejected; const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString()); const bobBalanceAfter = new BigNumber((await api.query.system.account(bobsPublicKey)).data.free.toString()); const fee = bobBalanceBefore.minus(bobBalanceAfter); const treasuryIncrease = treasuryBalanceAfter.minus(treasuryBalanceBefore); - expect(result.success).to.be.false; expect(treasuryIncrease.toFixed()).to.be.equal(fee.toFixed()); }); }); @@ -80,7 +79,7 @@ const treasuryBalanceBefore = new BigNumber((await api.query.system.account(Treasury)).data.free.toString()); const aliceBalanceBefore = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString()); - await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + await createCollectionExpectSuccess(); const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString()); const aliceBalanceAfter = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString()); @@ -96,7 +95,7 @@ const treasuryBalanceBefore = new BigNumber((await api.query.system.account(Treasury)).data.free.toString()); const aliceBalanceBefore = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString()); - await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + await createCollectionExpectSuccess(); const treasuryBalanceAfter = new BigNumber((await api.query.system.account(Treasury)).data.free.toString()); const aliceBalanceAfter = new BigNumber((await api.query.system.account(alicesPublicKey)).data.free.toString()); --- a/tests/src/destroyCollection.test.ts +++ b/tests/src/destroyCollection.test.ts @@ -10,15 +10,15 @@ describe('integration test: ext. destroyCollection():', () => { it('NFT collection can be destroyed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await destroyCollectionExpectSuccess(collectionId); }); it('Fungible collection can be destroyed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'Fungible'); + const collectionId = await createCollectionExpectSuccess({ mode: 'Fungible' }); await destroyCollectionExpectSuccess(collectionId); }); it('ReFungible collection can be destroyed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'ReFungible'); + const collectionId = await createCollectionExpectSuccess({ mode: 'ReFungible' }); await destroyCollectionExpectSuccess(collectionId); }); }); @@ -32,12 +32,12 @@ }); }); it('(!negative test!) Destroy a collection that has already been destroyed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await destroyCollectionExpectSuccess(collectionId); await destroyCollectionExpectFailure(collectionId); }); it('(!negative test!) Destroy a collection using non-owner account', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await destroyCollectionExpectFailure(collectionId, '//Bob'); await destroyCollectionExpectSuccess(collectionId, '//Alice'); }); --- a/tests/src/removeCollectionSponsor.test.ts +++ b/tests/src/removeCollectionSponsor.test.ts @@ -5,7 +5,7 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api"; +import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from "./substrate/substrate-api"; import { createCollectionExpectSuccess, setCollectionSponsorExpectSuccess, @@ -46,7 +46,7 @@ }); it('Remove NFT collection sponsor stops sponsorship', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); await removeCollectionSponsorExpectSuccess(collectionId); @@ -62,11 +62,7 @@ const AsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString()); const zeroToAlice = api.tx.nft.transfer(alice.address, collectionId, itemId, 0); const badTransaction = async function () { - console.log = function () {}; - console.error = function () {}; - await submitTransactionAsync(zeroBalance, zeroToAlice); - delete console.log; - delete console.error; + await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice); }; await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees"); const BsponsorBalance = new BigNumber((await api.query.system.account(bob.address)).data.free.toString()); @@ -76,7 +72,7 @@ }); it('Remove a sponsor after it was already removed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); await removeCollectionSponsorExpectSuccess(collectionId); @@ -84,12 +80,12 @@ }); it('Remove sponsor in a collection that never had the sponsor set', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await removeCollectionSponsorExpectSuccess(collectionId); }); it('Remove sponsor for a collection that had the sponsor set, but not confirmed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await removeCollectionSponsorExpectSuccess(collectionId); }); @@ -117,21 +113,21 @@ }); it('(!negative test!) Remove sponsor in a destroyed collection', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await destroyCollectionExpectSuccess(collectionId); await removeCollectionSponsorExpectFailure(collectionId); }); it('Set - remove - confirm: fails', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await removeCollectionSponsorExpectSuccess(collectionId); await confirmSponsorshipExpectFailure(collectionId, '//Bob'); }); it('Set - confirm - remove - confirm: Sponsor cannot come back', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await confirmSponsorshipExpectSuccess(collectionId, '//Bob'); await removeCollectionSponsorExpectSuccess(collectionId); --- a/tests/src/setCollectionSponsor.test.ts +++ b/tests/src/setCollectionSponsor.test.ts @@ -26,25 +26,25 @@ }); it('Set NFT collection sponsor', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); }); it('Set Fungible collection sponsor', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'Fungible'); + const collectionId = await createCollectionExpectSuccess({ mode: 'Fungible' }); await setCollectionSponsorExpectSuccess(collectionId, bob.address); }); it('Set ReFungible collection sponsor', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'ReFungible'); + const collectionId = await createCollectionExpectSuccess({ mode: 'ReFungible' }); await setCollectionSponsorExpectSuccess(collectionId, bob.address); }); it('Set the same sponsor repeatedly', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectSuccess(collectionId, bob.address); await setCollectionSponsorExpectSuccess(collectionId, bob.address); }); it('Replace collection sponsor', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); const keyring = new Keyring({ type: 'sr25519' }); const charlie = keyring.addFromUri(`//Charlie`); @@ -62,7 +62,7 @@ }); it('(!negative test!) Add sponsor with a non-owner', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await setCollectionSponsorExpectFailure(collectionId, bob.address, '//Bob'); }); it('(!negative test!) Add sponsor to a collection that never existed', async () => { @@ -75,7 +75,7 @@ await setCollectionSponsorExpectFailure(collectionId, bob.address); }); it('(!negative test!) Add sponsor to a collection that was destroyed', async () => { - const collectionId = await createCollectionExpectSuccess('A', 'B', 'C', 'NFT'); + const collectionId = await createCollectionExpectSuccess(); await destroyCollectionExpectSuccess(collectionId); await setCollectionSponsorExpectFailure(collectionId, bob.address); }); --- a/tests/src/substrate/substrate-api.ts +++ b/tests/src/substrate/substrate-api.ts @@ -33,21 +33,42 @@ } } +enum TransactionStatus { + Success, + Fail, + NotReady +} + +function getTransactionStatus(events: EventRecord[], status: ExtrinsicStatus): TransactionStatus { + if (status.isReady) { + return TransactionStatus.NotReady; + } + if (status.isBroadcast) { + return TransactionStatus.NotReady; + } + if (status.isInBlock || status.isFinalized) { + if(events.filter(e => e.event.data.method === 'ExtrinsicFailed').length > 0) { + return TransactionStatus.Fail; + } + if(events.filter(e => e.event.data.method === 'ExtrinsicSuccess').length > 0) { + return TransactionStatus.Success; + } + } + + return TransactionStatus.Fail; +} + export function submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic): Promise { return new Promise(async function(resolve, reject) { try { await transaction.signAndSend(sender, ({ events = [], status }) => { - if (status.isReady) { - // nothing to do - // console.log(`Current tx status is Ready`); - } else if (status.isBroadcast) { - // nothing to do - // console.log(`Current tx status is Broadcast`); - } else if (status.isInBlock || status.isFinalized) { + const transactionStatus = getTransactionStatus(events, status); + + if (transactionStatus == TransactionStatus.Success) { resolve(events); - } else { + } else if (transactionStatus == TransactionStatus.Fail) { console.log(`Something went wrong with transaction. Status: ${status}`); - reject("Transaction failed"); + reject(events); } }); } catch (e) { @@ -58,19 +79,35 @@ } export function submitTransactionExpectFailAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic): Promise { - return new Promise(async function(resolve, reject) { + const consoleError = console.error; + const consoleLog = console.log; + console.error = () => {}; + console.log = () => {}; + + return new Promise(async function(res, rej) { + const resolve = (rec: EventRecord[]) => { + setTimeout(() => { + res(rec); + console.error = consoleError; + console.log = consoleLog; + + }); + }; + const reject = (errror: any) => { + setTimeout(() => { + rej(errror); + console.error = consoleError; + console.log = consoleLog; + }); + }; try { await transaction.signAndSend(sender, ({ events = [], status }) => { - if (status.isReady) { - // nothing to do - // console.log(`Current tx status is Ready`); - } else if (status.isBroadcast) { - // nothing to do - // console.log(`Current tx status is Broadcast`); - } else if (status.isInBlock || status.isFinalized) { + const transactionStatus = getTransactionStatus(events, status); + + if (transactionStatus == TransactionStatus.Success) { resolve(events); - } else { - reject("Transaction failed"); + } else if (transactionStatus == TransactionStatus.Fail) { + reject(events); } }); } catch (e) { --- a/tests/src/transfer.test.ts +++ b/tests/src/transfer.test.ts @@ -33,6 +33,8 @@ // Find unused address const pk = await findUnusedAddress(api); + const error = console.error; + const log = console.log; console.log = function () {}; console.error = function () {}; @@ -42,8 +44,8 @@ }; await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees"); - delete console.log; - delete console.error; + console.log = log; + console.error = error; }); }); }); --- a/tests/src/util/helpers.ts +++ b/tests/src/util/helpers.ts @@ -7,7 +7,7 @@ import chaiAsPromised from 'chai-as-promised'; import type { AccountId, EventRecord } from '@polkadot/types/interfaces'; import { ApiPromise, Keyring } from "@polkadot/api"; -import { default as usingApi, submitTransactionAsync } from "../substrate/substrate-api"; +import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from "../substrate/substrate-api"; import privateKey from '../substrate/privateKey'; import { alicesPublicKey, nullPublicKey } from "../accounts"; import { strToUTF16, utf16ToStr, hexToStr } from '../util/util'; @@ -86,7 +86,24 @@ return result; } -export async function createCollectionExpectSuccess(name: string, description: string, tokenPrefix: string, mode: string): Promise { +export type CollectionMode = 'NFT' | 'Fungible' | 'ReFungible'; +export type CreateCollectionParams = { + mode: CollectionMode, + name: string, + description: string, + tokenPrefix: string +}; + +const defaultCreateCollectionParams: CreateCollectionParams = { + name: 'name', + description: 'description', + mode: 'NFT', + tokenPrefix: 'prefix' +} + +export async function createCollectionExpectSuccess(params: Partial = {}): Promise { + const {name, description, mode, tokenPrefix } = {...defaultCreateCollectionParams, ...params}; + let collectionId: number = 0; await usingApi(async (api) => { // Get number of collections before the transaction @@ -120,15 +137,17 @@ return collectionId; } -export async function createCollectionExpectFailure(name: string, description: string, tokenPrefix: string, mode: string) { +export async function createCollectionExpectFailure(params: Partial = {}) { + const {name, description, mode, tokenPrefix } = {...defaultCreateCollectionParams, ...params}; + await usingApi(async (api) => { // Get number of collections before the transaction const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString()); // Run the CreateCollection transaction const alicePrivateKey = privateKey('//Alice'); - const tx = api.tx.nft.createCollection(name, description, tokenPrefix, mode); - const events = await submitTransactionAsync(alicePrivateKey, tx); + const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), mode); + const events = await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected; const result = getCreateCollectionResult(events); // Get number of collections after the transaction @@ -168,11 +187,7 @@ // Run the DestroyCollection transaction const alicePrivateKey = privateKey(senderSeed); const tx = api.tx.nft.destroyCollection(collectionId); - const events = await submitTransactionAsync(alicePrivateKey, tx); - const result = getDestroyResult(events); - - // What to expect - expect(result).to.be.false; + await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected; }); } @@ -238,11 +253,7 @@ // Run the transaction const alicePrivateKey = privateKey('//Alice'); const tx = api.tx.nft.removeCollectionSponsor(collectionId); - const events = await submitTransactionAsync(alicePrivateKey, tx); - const result = getGenericResult(events); - - // What to expect - expect(result.success).to.be.false; + await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected; }); } @@ -252,11 +263,7 @@ // Run the transaction const alicePrivateKey = privateKey(senderSeed); const tx = api.tx.nft.setCollectionSponsor(collectionId, sponsor); - const events = await submitTransactionAsync(alicePrivateKey, tx); - const result = getGenericResult(events); - - // What to expect - expect(result.success).to.be.false; + await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected; }); } @@ -285,11 +292,7 @@ // Run the transaction const sender = privateKey(senderSeed); const tx = api.tx.nft.confirmSponsorship(collectionId); - const events = await submitTransactionAsync(sender, tx); - const result = getGenericResult(events); - - // What to expect - expect(result.success).to.be.false; + await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected; }); } -- gitstuff