--- a/tests/package.json +++ b/tests/package.json @@ -21,7 +21,10 @@ "testSetSchemaVersion": "mocha --timeout 9999999 -r ts-node/register ./**/setSchemaVersion.test.ts", "testSetCollectionLimits": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionLimits.test.ts", "testConnection": "mocha --timeout 9999999 -r ts-node/register ./**/connection.test.ts", - "testCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts" + "testCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts", + "testApprove": "mocha --timeout 9999999 -r ts-node/register ./**/approve.test.ts", + "testTransferFrom": "mocha --timeout 9999999 -r ts-node/register ./**/transferFrom.test.ts", + "testCreateCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts" }, "author": "", "license": "Apache 2.0", --- a/tests/src/approve.test.ts +++ b/tests/src/approve.test.ts @@ -8,53 +8,151 @@ import chaiAsPromised from 'chai-as-promised'; import privateKey from './substrate/privateKey'; import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api'; -import {createCollectionExpectSuccess, destroyCollectionExpectSuccess} from './util/helpers'; +import { + approveExpectFail, + approveExpectSuccess, + createCollectionExpectSuccess, + createItemExpectSuccess, + destroyCollectionExpectSuccess, +} from './util/helpers'; chai.use(chaiAsPromised); const expect = chai.expect; -interface ITokenDataType { - Owner: number[]; - ConstData: number[]; - VariableData: number[]; -} - describe('Integration Test approve(spender, collection_id, item_id, amount):', () => { it('Execute the extrinsic and check approvedList', async () => { await usingApi(async (api: ApiPromise) => { + const Alice = privateKey('//Alice'); + const Bob = privateKey('//Bob'); + const nftCollectionId = await createCollectionExpectSuccess(); + // nft + const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT'); + await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob); + // fungible + const fungibleCollectionId = await createCollectionExpectSuccess({mode: 'Fungible'}); + const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible'); + await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob); + // reFungible + const reFungibleCollectionId = await createCollectionExpectSuccess({mode: 'ReFungible'}); + const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible'); + await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob); + // garbage collection :-D + await destroyCollectionExpectSuccess(nftCollectionId); + await destroyCollectionExpectSuccess(fungibleCollectionId); + await destroyCollectionExpectSuccess(reFungibleCollectionId); }); }); + + it('Remove approval by using 0 amount', async () => { + await usingApi(async (api: ApiPromise) => { + const Alice = privateKey('//Alice'); + const Bob = privateKey('//Bob'); + const nftCollectionId = await createCollectionExpectSuccess(); + // nft + const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT'); + await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 1); + await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 0); + // fungible + const fungibleCollectionId = await createCollectionExpectSuccess({mode: 'Fungible'}); + const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible'); + await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1); + await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 0); + // reFungible + const reFungibleCollectionId = await createCollectionExpectSuccess({mode: 'ReFungible'}); + const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible'); + await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 1); + await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob, 0); + + // garbage collection :-D + await destroyCollectionExpectSuccess(nftCollectionId); + await destroyCollectionExpectSuccess(fungibleCollectionId); + await destroyCollectionExpectSuccess(reFungibleCollectionId); + }); + }); }); describe('Negative Integration Test approve(spender, collection_id, item_id, amount):', () => { it('Approve for a collection that does not exist', async () => { await usingApi(async (api: ApiPromise) => { - + const Alice = privateKey('//Alice'); + const Bob = privateKey('//Bob'); + // nft + const nftCollectionId = await createCollectionExpectSuccess(); + await approveExpectFail(nftCollectionId + 1, 1, Alice, Bob); + // fungible + const fungibleCollectionId = await createCollectionExpectSuccess({mode: 'Fungible'}); + await approveExpectFail(fungibleCollectionId + 1, 1, Alice, Bob); + // reFungible + const reFungibleCollectionId = await createCollectionExpectSuccess({mode: 'ReFungible'}); + await approveExpectFail(reFungibleCollectionId + 1, 1, Alice, Bob); + // garbage collection :-D + await destroyCollectionExpectSuccess(nftCollectionId); + await destroyCollectionExpectSuccess(fungibleCollectionId); + await destroyCollectionExpectSuccess(reFungibleCollectionId); }); }); it('Approve for a collection that was destroyed', async () => { await usingApi(async (api: ApiPromise) => { - + const Alice = privateKey('//Alice'); + const Bob = privateKey('//Bob'); + // nft + const nftCollectionId = await createCollectionExpectSuccess(); + await destroyCollectionExpectSuccess(nftCollectionId); + await approveExpectFail(nftCollectionId, 1, Alice, Bob); + // fungible + const fungibleCollectionId = await createCollectionExpectSuccess({mode: 'Fungible'}); + await destroyCollectionExpectSuccess(fungibleCollectionId); + await approveExpectFail(fungibleCollectionId, 1, Alice, Bob); + // reFungible + const reFungibleCollectionId = await createCollectionExpectSuccess({mode: 'ReFungible'}); + await destroyCollectionExpectSuccess(reFungibleCollectionId); + await approveExpectFail(reFungibleCollectionId, 1, Alice, Bob); }); }); it('Approve transfer of a token that does not exist', async () => { await usingApi(async (api: ApiPromise) => { - + const Alice = privateKey('//Alice'); + const Bob = privateKey('//Bob'); + // nft + const nftCollectionId = await createCollectionExpectSuccess(); + await approveExpectFail(nftCollectionId, 2, Alice, Bob); + // fungible + const fungibleCollectionId = await createCollectionExpectSuccess({mode: 'Fungible'}); + await approveExpectFail(fungibleCollectionId, 2, Alice, Bob); + // reFungible + const reFungibleCollectionId = await createCollectionExpectSuccess({mode: 'ReFungible'}); + await approveExpectFail(reFungibleCollectionId, 2, Alice, Bob); + // garbage collection :-D + await destroyCollectionExpectSuccess(nftCollectionId); + await destroyCollectionExpectSuccess(fungibleCollectionId); + await destroyCollectionExpectSuccess(reFungibleCollectionId); }); }); it('Approve using the address that does not own the approved token', async () => { await usingApi(async (api: ApiPromise) => { + const Alice = privateKey('//Alice'); + const Bob = privateKey('//Bob'); + const nftCollectionId = await createCollectionExpectSuccess(); + // nft + const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT'); + await approveExpectFail(nftCollectionId, newNftTokenId, Bob, Alice); + // fungible + const fungibleCollectionId = await createCollectionExpectSuccess({mode: 'Fungible'}); + const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible'); + await approveExpectFail(fungibleCollectionId, newFungibleTokenId, Bob, Alice); + // reFungible + const reFungibleCollectionId = await createCollectionExpectSuccess({mode: 'ReFungible'}); + const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible'); + await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, Bob, Alice); - }); - }); - - it('Remove approval by using 0 amount', async () => { - await usingApi(async (api: ApiPromise) => { - + // garbage collection :-D + await destroyCollectionExpectSuccess(nftCollectionId); + await destroyCollectionExpectSuccess(fungibleCollectionId); + await destroyCollectionExpectSuccess(reFungibleCollectionId); }); }); }); --- a/tests/src/createCollection.test.ts +++ b/tests/src/createCollection.test.ts @@ -5,15 +5,15 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import { default as usingApi } from "./substrate/substrate-api"; -import { createCollectionExpectSuccess, createCollectionExpectFailure, CollectionMode } from "./util/helpers"; +import { default as usingApi } from './substrate/substrate-api'; +import { createCollectionExpectFailure, createCollectionExpectSuccess } from './util/helpers'; chai.use(chaiAsPromised); const expect = chai.expect; describe('integration test: ext. createCollection():', () => { it('Create new NFT collection', async () => { - await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: 'NFT'}); + await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}}); }); it('Create new NFT collection whith collection_name of maximum length (64 bytes)', async () => { await createCollectionExpectSuccess({name: 'A'.repeat(64)}); @@ -25,34 +25,33 @@ await createCollectionExpectSuccess({tokenPrefix: 'A'.repeat(16)}); }); it('Create new Fungible collection', async () => { - await createCollectionExpectSuccess({mode: 'Fungible'}); + await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}}); }); it('Create new ReFungible collection', async () => { - await createCollectionExpectSuccess({mode: 'ReFungible'}); + await createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}}); }); }); describe('(!negative test!) integration test: ext. createCollection():', () => { it('(!negative test!) create new NFT collection whith incorrect data (mode)', async () => { await usingApi(async (api) => { - const AcollectionCount = parseInt((await api.query.nft.collectionCount()).toString()); + const AcollectionCount = parseInt((await api.query.nft.collectionCount()).toString(), 10); - const badTransaction = async function () { - await createCollectionExpectSuccess({mode: 'BadMode' as CollectionMode}); - }; + const badTransaction = async () => await createCollectionExpectSuccess({mode: {type: 'Invalid'}}); + // tslint:disable-next-line:no-unused-expression expect(badTransaction()).to.be.rejected; - const BcollectionCount = parseInt((await api.query.nft.collectionCount()).toString()); + const BcollectionCount = parseInt((await api.query.nft.collectionCount()).toString(), 10); expect(BcollectionCount).to.be.equal(AcollectionCount, 'Error: Incorrect collection created.'); }); }); it('(!negative test!) create new NFT collection whith incorrect data (collection_name)', async () => { - await createCollectionExpectFailure({name: 'A'.repeat(65)}); + await createCollectionExpectFailure({ name: 'A'.repeat(65), mode: {type: 'NFT'}}); }); it('(!negative test!) create new NFT collection whith incorrect data (collection_description)', async () => { - await createCollectionExpectFailure({description: 'A'.repeat(257)}); + await createCollectionExpectFailure({ description: 'A'.repeat(257), mode: { type: 'NFT' }}); }); it('(!negative test!) create new NFT collection whith incorrect data (token_prefix)', async () => { - await createCollectionExpectFailure({tokenPrefix: 'A'.repeat(17)}); + await createCollectionExpectFailure({tokenPrefix: 'A'.repeat(17), mode: {type: 'NFT'}}); }); }); --- a/tests/src/substrate/substrate-api.ts +++ b/tests/src/substrate/substrate-api.ts @@ -90,7 +90,6 @@ res(rec); console.error = consoleError; console.log = consoleLog; - }); }; const reject = (errror: any) => { @@ -104,6 +103,8 @@ await transaction.signAndSend(sender, ({ events = [], status }) => { const transactionStatus = getTransactionStatus(events, status); + console.log('transactionStatus', transactionStatus, 'events', events); + if (transactionStatus == TransactionStatus.Success) { resolve(events); } else if (transactionStatus == TransactionStatus.Fail) { @@ -114,4 +115,4 @@ reject(e); } }); -} \ No newline at end of file +} --- a/tests/src/transferFrom.test.ts +++ b/tests/src/transferFrom.test.ts @@ -8,21 +8,47 @@ import chaiAsPromised from 'chai-as-promised'; import privateKey from './substrate/privateKey'; import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from './substrate/substrate-api'; -import {createCollectionExpectSuccess, destroyCollectionExpectSuccess} from './util/helpers'; +import { + approveExpectSuccess, + createCollectionExpectSuccess, + createItemExpectSuccess, + destroyCollectionExpectSuccess, + transferFromExpectSuccess, +} from './util/helpers'; +import {IKeyringPair} from "@polkadot/types/types"; chai.use(chaiAsPromised); const expect = chai.expect; -interface ITokenDataType { - Owner: number[]; - ConstData: number[]; - VariableData: number[]; -} - describe('Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => { - it('Execute the extrinsic and check nftItemList - owner of toren', async () => { + it('Execute the extrinsic and check nftItemList - owner of token', async () => { await usingApi(async (api: ApiPromise) => { + const Alice = privateKey('//Alice'); + const Bob = privateKey('//Bob'); + const Charlie = privateKey('//CHARLIE'); + const nftCollectionId = await createCollectionExpectSuccess(); + console.log('nftCollectionId', nftCollectionId); + const collectionInfo = await api.query.nft.collection(nftCollectionId); + console.log('collectionInfo', collectionInfo); + // nft + const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT'); + await approveExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob); + await transferFromExpectSuccess(nftCollectionId, newNftTokenId, Alice, Charlie, 1, 'NFT'); + + // fungible + /*const fungibleCollectionId = await createCollectionExpectSuccess({mode: 'Fungible'}); + const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible'); + await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob); + // reFungible + const reFungibleCollectionId = await createCollectionExpectSuccess({mode: 'ReFungible'}); + const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible'); + await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, Alice, Bob);*/ + + // garbage collection :-D + await destroyCollectionExpectSuccess(nftCollectionId); + // await destroyCollectionExpectSuccess(fungibleCollectionId); + // await destroyCollectionExpectSuccess(reFungibleCollectionId); }); }); }); --- a/tests/src/util/helpers.ts +++ b/tests/src/util/helpers.ts @@ -3,20 +3,20 @@ // file 'LICENSE', which is part of this source code package. // -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; +import { ApiPromise, Keyring } from '@polkadot/api'; +import { Enum, Struct } from '@polkadot/types/codec'; import type { AccountId, EventRecord } from '@polkadot/types/interfaces'; -import { ApiPromise, Keyring } from "@polkadot/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'; +import { u128 } from '@polkadot/types/primitive'; import { IKeyringPair } from '@polkadot/types/types'; import { BigNumber } from 'bignumber.js'; -import { Struct, Enum } from '@polkadot/types/codec'; -import { u128 } from '@polkadot/types/primitive'; +import BN from 'bn.js'; +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { alicesPublicKey, nullPublicKey } from '../accounts'; +import privateKey from '../substrate/privateKey'; +import { default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync } from '../substrate/substrate-api'; import { ICollectionInterface } from '../types'; -import BN from "bn.js"; +import { hexToStr, strToUTF16, utf16ToStr } from './util'; chai.use(chaiAsPromised); const expect = chai.expect; @@ -25,24 +25,30 @@ success: boolean, }; -type CreateCollectionResult = { - success: boolean, - collectionId: number -}; +interface CreateCollectionResult { + success: boolean; + collectionId: number; +} + +interface CreateItemResult { + success: boolean; + collectionId: number; + itemId: number; +} -type CreateItemResult = { - success: boolean, - collectionId: number, - itemId: number -}; +interface ITokenDataType { + Owner: number[]; + ConstData: number[]; + VariableData: number[]; +} export function getGenericResult(events: EventRecord[]): GenericResult { - let result: GenericResult = { - success: false - } + const result: GenericResult = { + success: false, + }; events.forEach(({ phase, event: { data, method, section } }) => { // console.log(` ${phase}: ${section}.${method}:: ${data}`); - if (method == 'ExtrinsicSuccess') { + if (method === 'ExtrinsicSuccess') { result.success = true; } }); @@ -60,10 +66,10 @@ collectionId = parseInt(data[0].toString()); } }); - let result: CreateCollectionResult = { + const result: CreateCollectionResult = { success, - collectionId - } + collectionId, + }; return result; } @@ -80,27 +86,46 @@ itemId = parseInt(data[1].toString()); } }); - let result: CreateItemResult = { + const result: CreateItemResult = { success, collectionId, - itemId - } + itemId, + }; return result; } -export type CollectionMode = 'NFT' | 'Fungible' | 'ReFungible'; +interface Invalid { + type: 'Invalid'; +} + +interface Nft { + type: 'NFT'; +} + +interface Fungible { + type: 'Fungible'; + decimalPoints: number; +} + +interface ReFungible { + type: 'ReFungible'; + decimalPoints: number; +} + +type CollectionMode = Nft | Fungible | ReFungible | Invalid; + export type CreateCollectionParams = { mode: CollectionMode, name: string, description: string, - tokenPrefix: string + tokenPrefix: string, }; const defaultCreateCollectionParams: CreateCollectionParams = { - name: 'name', description: 'description', - mode: 'NFT', - tokenPrefix: 'prefix' + mode: { type: 'NFT' }, + name: 'name', + tokenPrefix: 'prefix', } export async function createCollectionExpectSuccess(params: Partial = {}): Promise { @@ -109,25 +134,39 @@ let collectionId: number = 0; await usingApi(async (api) => { // Get number of collections before the transaction - const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString()); + const AcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString(), 10); // Run the CreateCollection transaction const alicePrivateKey = privateKey('//Alice'); - const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), mode); + + let modeprm = {}; + if (mode.type === 'NFT') { + modeprm = {nft: null}; + } else if (mode.type === 'Fungible') { + modeprm = {fungible: mode.decimalPoints}; + } else if (mode.type === 'ReFungible') { + modeprm = {refungible: mode.decimalPoints}; + } else if (mode.type === 'Invalid') { + modeprm = {invalid: null}; + } + + const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm); const events = await submitTransactionAsync(alicePrivateKey, tx); const result = getCreateCollectionResult(events); // Get number of collections after the transaction - const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString()); + const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString(), 10); - // Get the collection + // Get the collection const collection: any = (await api.query.nft.collection(result.collectionId)).toJSON(); // What to expect + // tslint:disable-next-line:no-unused-expression expect(result.success).to.be.true; expect(result.collectionId).to.be.equal(BcollectionCount); + // tslint:disable-next-line:no-unused-expression expect(collection).to.be.not.null; - expect(BcollectionCount).to.be.equal(AcollectionCount+1, 'Error: NFT collection NOT created.'); + expect(BcollectionCount).to.be.equal(AcollectionCount + 1, 'Error: NFT collection NOT created.'); expect(collection.Owner).to.be.equal(alicesPublicKey); expect(utf16ToStr(collection.Name)).to.be.equal(name); expect(utf16ToStr(collection.Description)).to.be.equal(description); @@ -138,17 +177,28 @@ return collectionId; } - + export async function createCollectionExpectFailure(params: Partial = {}) { const {name, description, mode, tokenPrefix } = {...defaultCreateCollectionParams, ...params}; + let modeprm = {}; + if (mode.type === 'NFT') { + modeprm = {nft: null}; + } else if (mode.type === 'Fungible') { + modeprm = {fungible: mode.decimalPoints}; + } else if (mode.type === 'ReFungible') { + modeprm = {refungible: mode.decimalPoints}; + } else if (mode.type === 'Invalid') { + modeprm = {invalid: null}; + } + 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(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), mode); + const tx = api.tx.nft.createCollection(strToUTF16(name), strToUTF16(description), strToUTF16(tokenPrefix), modeprm); const events = await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected; const result = getCreateCollectionResult(events); @@ -156,11 +206,12 @@ const BcollectionCount = parseInt((await api.query.nft.createdCollectionCount()).toString()); // What to expect + // tslint:disable-next-line:no-unused-expression expect(result.success).to.be.false; expect(BcollectionCount).to.be.equal(AcollectionCount, 'Error: Collection with incorrect data created.'); }); } - + export async function findUnusedAddress(api: ApiPromise): Promise { let bal = new BigNumber(0); let unused; @@ -170,7 +221,7 @@ unused = keyring.addFromUri(`//${randomSeed}`); bal = new BigNumber((await api.query.system.account(unused.address)).data.free.toString()); } while (bal.toFixed() != '0'); - return unused; + return unused; } function getDestroyResult(events: EventRecord[]): boolean { @@ -201,7 +252,7 @@ const events = await submitTransactionAsync(alicePrivateKey, tx); const result = getDestroyResult(events); - // Get the collection + // Get the collection const collection: any = (await api.query.nft.collection(collectionId)).toJSON(); // What to expect @@ -220,7 +271,7 @@ const events = await submitTransactionAsync(alicePrivateKey, tx); const result = getGenericResult(events); - // Get the collection + // Get the collection const collection: any = (await api.query.nft.collection(collectionId)).toJSON(); // What to expect @@ -239,7 +290,7 @@ const events = await submitTransactionAsync(alicePrivateKey, tx); const result = getGenericResult(events); - // Get the collection + // Get the collection const collection: any = (await api.query.nft.collection(collectionId)).toJSON(); // What to expect @@ -278,7 +329,7 @@ const events = await submitTransactionAsync(sender, tx); const result = getGenericResult(events); - // Get the collection + // Get the collection const collection: any = (await api.query.nft.collection(collectionId)).toJSON(); // What to expect @@ -300,48 +351,103 @@ export interface CreateFungibleData extends Struct { readonly value: u128; -}; +} -export interface CreateReFungibleData extends Struct {}; -export interface CreateNftData extends Struct {}; +export interface CreateReFungibleData extends Struct {} +export interface CreateNftData extends Struct {} export interface CreateItemData extends Enum { - NFT: CreateNftData, - Fungible: CreateFungibleData, - ReFungible: CreateReFungibleData -}; + NFT: CreateNftData; + Fungible: CreateFungibleData; + ReFungible: CreateReFungibleData; +} +export async function +approveExpectSuccess(collectionId: number, + tokenId: number, owner: IKeyringPair, approved: IKeyringPair, amount: number = 1) { + await usingApi(async (api: ApiPromise) => { + const allowanceBefore = + await api.query.nft.allowances(collectionId, [tokenId, owner.address, approved.address]) as unknown as BN; + const approveNftTx = await api.tx.nft.approve(approved.address, collectionId, tokenId, amount); + const events = await submitTransactionAsync(owner, approveNftTx); + const result = getCreateItemResult(events); + // tslint:disable-next-line:no-unused-expression + expect(result.success).to.be.true; + const allowanceAfter = + await api.query.nft.allowances(collectionId, [tokenId, owner.address, approved.address]) as unknown as BN; + expect(allowanceAfter.toNumber() - allowanceBefore.toNumber()).to.be.equal(amount); + }); +} + +export async function +transferFromExpectSuccess(collectionId: number, tokenId: number, accountFrom: IKeyringPair, + accountTo: IKeyringPair, value: number = 1, type: string = 'NFT') { + await usingApi(async (api: ApiPromise) => { + const transferFromTx = await api.tx.nft.transferFrom( + accountFrom.address, accountTo.address, collectionId, tokenId, value); + const events = await submitTransactionAsync(accountFrom, transferFromTx); + const result = getCreateItemResult(events); + // tslint:disable-next-line:no-unused-expression + expect(result.success).to.be.true; + if (type === 'NFT') { + const nftItemData = api.query.nft.nftItemList(collectionId, tokenId) as unknown as ITokenDataType; + console.log('NFT data', nftItemData); + } + if (type === 'Fungible') { + const nftItemData = api.query.nft.fungibleItemList(collectionId, tokenId) as unknown as ITokenDataType; + console.log('Fungible data', nftItemData); + } + if (type === 'ReFungible') { + const nftItemData = api.query.nft.reFungibleItemList(collectionId, tokenId) as unknown as ITokenDataType; + console.log('reFungibleItemList data', nftItemData); + } + }); +} + +export async function +approveExpectFail(collectionId: number, + tokenId: number, owner: IKeyringPair, approved: IKeyringPair, amount: number = 1) { + await usingApi(async (api: ApiPromise) => { + const approveNftTx = await api.tx.nft.approve(approved.address, collectionId, tokenId, amount); + const events = await expect(submitTransactionExpectFailAsync(owner, approveNftTx)).to.be.rejected; + const result = getCreateCollectionResult(events); + // tslint:disable-next-line:no-unused-expression + expect(result.success).to.be.false; + }); +} + export async function createItemExpectSuccess(sender: IKeyringPair, collectionId: number, createMode: string, owner: string = '') { let newItemId: number = 0; await usingApi(async (api) => { - const AItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString()); - const Aitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON(); + const AItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString(), 10); + const Aitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON(); const AItemBalance = new BigNumber(Aitem.Value); - if (owner === '') owner = sender.address; + if (owner === '') { + owner = sender.address; + } let tx; - if (createMode == 'Fungible') { - let createData = {fungible: {value: 10}}; + if (createMode === 'Fungible') { + const createData = {fungible: {value: 10}}; tx = api.tx.nft.createItem(collectionId, owner, createData); - } - else { + } else { tx = api.tx.nft.createItem(collectionId, owner, createMode); } const events = await submitTransactionAsync(sender, tx); const result = getCreateItemResult(events); - const BItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString()); - const Bitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON(); + const BItemCount = parseInt((await api.query.nft.itemListIndex(collectionId)).toString(), 10); + const Bitem: any = (await api.query.nft.fungibleItemList(collectionId, owner)).toJSON(); const BItemBalance = new BigNumber(Bitem.Value); // What to expect + // tslint:disable-next-line:no-unused-expression expect(result.success).to.be.true; - if (createMode == 'Fungible') { + if (createMode === 'Fungible') { expect(BItemBalance.minus(AItemBalance).toNumber()).to.be.equal(10); - } - else { - expect(BItemCount).to.be.equal(AItemCount+1); + } else { + expect(BItemCount).to.be.equal(AItemCount + 1); } expect(collectionId).to.be.equal(result.collectionId); expect(BItemCount).to.be.equal(result.itemId); @@ -358,7 +464,7 @@ const events = await submitTransactionAsync(sender, tx); const result = getGenericResult(events); - // Get the collection + // Get the collection const collection: any = (await api.query.nft.collection(collectionId)).toJSON(); // What to expect @@ -375,7 +481,7 @@ const events = await submitTransactionAsync(sender, tx); const result = getGenericResult(events); - // Get the collection + // Get the collection const collection: any = (await api.query.nft.collection(collectionId)).toJSON(); // What to expect @@ -392,7 +498,7 @@ const events = await submitTransactionAsync(sender, tx); const result = getGenericResult(events); - // Get the collection + // Get the collection const collection: any = (await api.query.nft.collection(collectionId)).toJSON(); // What to expect