difftreelog
Merge pull request #67 from usetech-llc/feature/NFTPAR-257
in: master
Feature/nftpar 257
6 files changed
tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -28,7 +28,8 @@
"testTransferFrom": "mocha --timeout 9999999 -r ts-node/register ./**/transferFrom.test.ts",
"testCreateCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts",
"testToggleContractWhiteList": "mocha --timeout 9999999 -r ts-node/register ./**/toggleContractWhiteList.test.ts",
- "testAddToContractWhiteList": "mocha --timeout 9999999 -r ts-node/register ./**/addToContractWhiteList.test.ts"
+ "testAddToContractWhiteList": "mocha --timeout 9999999 -r ts-node/register ./**/addToContractWhiteList.test.ts",
+ "testTransfer": "mocha --timeout 9999999 -r ts-node/register ./**/transfer.test.ts"
},
"author": "",
"license": "Apache 2.0",
tests/src/burnItem.test.tsdiffbeforeafterboth--- a/tests/src/burnItem.test.ts
+++ b/tests/src/burnItem.test.ts
@@ -35,16 +35,16 @@
const tx = api.tx.nft.burnItem(collectionId, tokenId, 0);
const events = await submitTransactionAsync(alice, tx);
const result = getGenericResult(events);
-
- // Get the item
+ // Get the item
const item: any = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON();
-
// What to expect
+ // tslint:disable-next-line:no-unused-expression
expect(result.success).to.be.true;
+ // tslint:disable-next-line:no-unused-expression
expect(item).to.be.not.null;
expect(item.Owner).to.be.equal(nullPublicKey);
});
-
+
});
it('Burn item in Fungible collection', async () => {
const createMode = 'Fungible';
tests/src/substrate/get-balance.tsdiffbeforeafterboth--- a/tests/src/substrate/get-balance.ts
+++ b/tests/src/substrate/get-balance.ts
@@ -3,12 +3,12 @@
// file 'LICENSE', which is part of this source code package.
//
-import { ApiPromise } from "@polkadot/api";
-import promisifySubstrate from "./promisify-substrate";
-import {AccountInfo} from "@polkadot/types/interfaces/system";
+import { ApiPromise } from '@polkadot/api';
+import {AccountInfo} from '@polkadot/types/interfaces/system';
+import promisifySubstrate from './promisify-substrate';
-export default async function getBalance(api: ApiPromise, accounts: string[]): Promise<bigint[]> {
- const balance = promisifySubstrate(api, (accounts: string[]) => api.query.system.account.multi(accounts));
+export default async function getBalance(api: ApiPromise, accounts: string[]): Promise<Array<bigint>> {
+ const balance = promisifySubstrate(api, (acc: string[]) => api.query.system.account.multi(acc));
const responce = await balance(accounts) as unknown as AccountInfo[];
- return responce.map(r => r.data.free.toBigInt().valueOf());
+ return responce.map((r) => r.data.free.toBigInt().valueOf());
}
tests/src/substrate/substrate-api.tsdiffbeforeafterboth--- a/tests/src/substrate/substrate-api.ts
+++ b/tests/src/substrate/substrate-api.ts
@@ -58,21 +58,22 @@
return TransactionStatus.Fail;
}
-export function submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {
- return new Promise(async function(resolve, reject) {
+export function
+submitTransactionAsync(sender: IKeyringPair, transaction: SubmittableExtrinsic<ApiTypes>): Promise<EventRecord[]> {
+ return new Promise(async (resolve, reject) => {
try {
await transaction.signAndSend(sender, ({ events = [], status }) => {
const transactionStatus = getTransactionStatus(events, status);
- if (transactionStatus == TransactionStatus.Success) {
+ if (transactionStatus === TransactionStatus.Success) {
resolve(events);
- } else if (transactionStatus == TransactionStatus.Fail) {
+ } else if (transactionStatus === TransactionStatus.Fail) {
console.log(`Something went wrong with transaction. Status: ${status}`);
reject(events);
}
});
} catch (e) {
- console.log("Error: ", e);
+ console.log('Error: ', e);
reject(e);
}
});
tests/src/transfer.test.tsdiffbeforeafterboth--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -3,49 +3,174 @@
// file 'LICENSE', which is part of this source code package.
//
-import { expect, assert } from "chai";
-import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api";
-import { alicesPublicKey, bobsPublicKey, ferdiesPublicKey } from "./accounts";
-import privateKey from "./substrate/privateKey";
-import getBalance from "./substrate/get-balance";
-import { BigNumber } from 'bignumber.js';
-import { findUnusedAddress } from './util/helpers'
+import { ApiPromise } from '@polkadot/api';
+import { IKeyringPair } from '@polkadot/types/types';
+import { expect } from 'chai';
+import { alicesPublicKey, bobsPublicKey } from './accounts';
+import getBalance from './substrate/get-balance';
+import privateKey from './substrate/privateKey';
+import { default as usingApi, submitTransactionAsync } from './substrate/substrate-api';
+import {
+ burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess,
+ destroyCollectionExpectSuccess,
+ findUnusedAddress,
+ getCreateCollectionResult,
+ getCreateItemResult,
+ transferExpectFail,
+ transferExpectSuccess,
+} from './util/helpers';
-describe('Transfer', () => {
- it('Balance transfers', async () => {
- await usingApi(async api => {
+let Alice: IKeyringPair;
+let Bob: IKeyringPair;
+let Charlie: IKeyringPair;
+
+describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
+ it('Balance transfers and check balance', async () => {
+ await usingApi(async (api: ApiPromise) => {
const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
const alicePrivateKey = privateKey('//Alice');
-
+
const transfer = api.tx.balances.transfer(bobsPublicKey, 1n);
- const result = await submitTransactionAsync(alicePrivateKey, transfer);
+ const events = await submitTransactionAsync(alicePrivateKey, transfer);
+ const result = getCreateItemResult(events);
+ // tslint:disable-next-line:no-unused-expression
+ expect(result.success).to.be.true;
const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alicesPublicKey, bobsPublicKey]);
+ // tslint:disable-next-line:no-unused-expression
expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
+ // tslint:disable-next-line:no-unused-expression
expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
});
});
it('Inability to pay fees error message is correct', async () => {
- await usingApi(async api => {
+ await usingApi(async (api) => {
// Find unused address
const pk = await findUnusedAddress(api);
- const error = console.error;
- const log = console.log;
- console.log = function () {};
- console.error = function () {};
-
const badTransfer = api.tx.balances.transfer(bobsPublicKey, 1n);
- const badTransaction = async function () {
- const result = await submitTransactionAsync(pk, badTransfer);
+ // const events = await submitTransactionAsync(pk, badTransfer);
+ const badTransaction = async () => {
+ const events = await submitTransactionAsync(pk, badTransfer);
+ const result = getCreateCollectionResult(events);
+ // tslint:disable-next-line:no-unused-expression
+ expect(result.success).to.be.false;
};
- await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees");
+ expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');
+ });
+ });
- console.log = log;
- console.error = error;
+ it('Create collection, balance transfers and check balance', async () => {
+ await usingApi(async (api) => {
+ const Alice = privateKey('//Alice');
+ const Bob = privateKey('//Bob');
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ await transferExpectSuccess(nftCollectionId, newNftTokenId, Alice, Bob, 1, 'NFT');
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1, 'Fungible');
+ // reFungible
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await transferExpectSuccess(reFungibleCollectionId,
+ newReFungibleTokenId, Alice, Bob, 1, 'ReFungible');
});
});
});
+
+describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
+ before(async () => {
+ await usingApi(async (api: ApiPromise) => {
+ Alice = privateKey('//Alice');
+ Bob = privateKey('//Bob');
+ Charlie = privateKey('//Charlie');
+ });
+ });
+ it('Transfer with not existed collection_id', async () => {
+ await usingApi(async (api) => {
+ // nft
+ const nftCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
+ await transferExpectFail(nftCollectionCount + 1, 1, Alice, Bob, 1);
+ // fungible
+ const fungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
+ await transferExpectFail(fungibleCollectionCount + 1, 1, Alice, Bob, 1);
+ // reFungible
+ const reFungibleCollectionCount = await api.query.nft.createdCollectionCount() as unknown as number;
+ await transferExpectFail(reFungibleCollectionCount + 1, 1, Alice, Bob, 1);
+ });
+ });
+ it('Transfer with deleted collection_id', async () => {
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ await destroyCollectionExpectSuccess(nftCollectionId);
+ await transferExpectFail(nftCollectionId, newNftTokenId, Alice, Bob, 1, 'NFT');
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await destroyCollectionExpectSuccess(fungibleCollectionId);
+ await transferExpectFail(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1, 'Fungible');
+ // reFungible
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await destroyCollectionExpectSuccess(reFungibleCollectionId);
+ await transferExpectFail(reFungibleCollectionId,
+ newReFungibleTokenId, Alice, Bob, 1, 'ReFungible');
+ });
+ it('Transfer with not existed item_id', async () => {
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ await transferExpectFail(nftCollectionId, 2, Alice, Bob, 1, 'NFT');
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ await transferExpectFail(fungibleCollectionId, 2, Alice, Bob, 1, 'Fungible');
+ // reFungible
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ await transferExpectFail(reFungibleCollectionId,
+ 2, Alice, Bob, 1, 'ReFungible');
+ });
+ it('Transfer with deleted item_id', async () => {
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ await burnItemExpectSuccess(Alice, nftCollectionId, newNftTokenId, 1);
+ await transferExpectFail(nftCollectionId, newNftTokenId, Alice, Bob, 1, 'NFT');
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await burnItemExpectSuccess(Alice, fungibleCollectionId, newFungibleTokenId, 10);
+ await transferExpectFail(fungibleCollectionId, newFungibleTokenId, Alice, Bob, 1, 'Fungible');
+ // reFungible
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await burnItemExpectSuccess(Alice, reFungibleCollectionId, newReFungibleTokenId, 1);
+ await transferExpectFail(reFungibleCollectionId,
+ newReFungibleTokenId, Alice, Bob, 1, 'ReFungible');
+ });
+ it('Transfer with recipient that is not owner', async () => {
+ // nft
+ const nftCollectionId = await createCollectionExpectSuccess();
+ const newNftTokenId = await createItemExpectSuccess(Alice, nftCollectionId, 'NFT');
+ await transferExpectFail(nftCollectionId, newNftTokenId, Charlie, Bob, 1, 'NFT');
+ // fungible
+ const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
+ const newFungibleTokenId = await createItemExpectSuccess(Alice, fungibleCollectionId, 'Fungible');
+ await transferExpectFail(fungibleCollectionId, newFungibleTokenId, Charlie, Bob, 1, 'Fungible');
+ // reFungible
+ const reFungibleCollectionId = await
+ createCollectionExpectSuccess({mode: {type: 'ReFungible', decimalPoints: 0}});
+ const newReFungibleTokenId = await createItemExpectSuccess(Alice, reFungibleCollectionId, 'ReFungible');
+ await transferExpectFail(reFungibleCollectionId,
+ newReFungibleTokenId, Charlie, Bob, 1, 'ReFungible');
+ });
+});
tests/src/util/helpers.tsdiffbeforeafterboth391 ReFungible: CreateReFungibleData;391 ReFungible: CreateReFungibleData;392}392}393394export async function burnItemExpectSuccess(owner: IKeyringPair, collectionId: number, tokenId: number, value = 0) {395 await usingApi(async (api) => {396 const tx = api.tx.nft.burnItem(collectionId, tokenId, value);397 const events = await submitTransactionAsync(owner, tx);398 const result = getGenericResult(events);399 // Get the item400 const item: any = (await api.query.nft.nftItemList(collectionId, tokenId)).toJSON();401 // What to expect402 // tslint:disable-next-line:no-unused-expression403 expect(result.success).to.be.true;404 // tslint:disable-next-line:no-unused-expression405 expect(item).to.be.not.null;406 expect(item.Owner).to.be.equal(nullPublicKey);407 });408}393409394export async function410export async function395approveExpectSuccess(collectionId: number,411approveExpectSuccess(collectionId: number,461 });477 });462}478}479480export async function481transferExpectSuccess(collectionId: number,482 tokenId: number,483 sender: IKeyringPair,484 recipient: IKeyringPair,485 value: number = 1,486 type: string = 'NFT') {487 await usingApi(async (api: ApiPromise) => {488 let balanceBefore = new BN(0);489 if (type === 'Fungible') {490 balanceBefore = await api.query.nft.balance(collectionId, recipient.address) as unknown as BN;491 }492 const transferTx = await api.tx.nft.transfer(recipient.address, collectionId, tokenId, value);493 const events = await submitTransactionAsync(sender, transferTx);494 const result = getCreateItemResult(events);495 // tslint:disable-next-line:no-unused-expression496 expect(result.success).to.be.true;497 if (type === 'NFT') {498 const nftItemData = await api.query.nft.nftItemList(collectionId, tokenId) as unknown as ITokenDataType;499 expect(nftItemData.Owner.toString()).to.be.equal(recipient.address);500 }501 if (type === 'Fungible') {502 const balanceAfter = await api.query.nft.balance(collectionId, recipient.address) as unknown as BN;503 expect(balanceAfter.sub(balanceBefore).toNumber()).to.be.equal(value);504 }505 if (type === 'ReFungible') {506 const nftItemData =507 await api.query.nft.reFungibleItemList(collectionId, tokenId) as unknown as IReFungibleTokenDataType;508 expect(nftItemData.Owner[0].Owner.toString()).to.be.equal(recipient.address);509 expect(nftItemData.Owner[0].Fraction.toNumber()).to.be.equal(value);510 }511 });512}513514export async function515transferExpectFail(collectionId: number,516 tokenId: number,517 sender: IKeyringPair,518 recipient: IKeyringPair,519 value: number = 1,520 type: string = 'NFT') {521 await usingApi(async (api: ApiPromise) => {522 const transferTx = await api.tx.nft.transfer(recipient.address, collectionId, tokenId, value);523 const events = await expect(submitTransactionExpectFailAsync(sender, transferTx)).to.be.rejected;524 if (events && Array.isArray(events)) {525 const result = getCreateCollectionResult(events);526 // tslint:disable-next-line:no-unused-expression527 expect(result.success).to.be.false;528 }529 });530}463531464export async function532export async function465approveExpectFail(collectionId: number,533approveExpectFail(collectionId: number,525 const collection: any = (await api.query.nft.collection(collectionId)).toJSON();594 const collection: any = (await api.query.nft.collection(collectionId)).toJSON();526595527 // What to expect596 // What to expect597 // tslint:disable-next-line:no-unused-expression528 expect(result.success).to.be.true;598 expect(result.success).to.be.true;529 expect(collection.Access).to.be.equal('WhiteList');599 expect(collection.Access).to.be.equal('WhiteList');530 });600 });559 const collection: any = (await api.query.nft.collection(collectionId)).toJSON();629 const collection: any = (await api.query.nft.collection(collectionId)).toJSON();560630561 // What to expect631 // What to expect632 // tslint:disable-next-line:no-unused-expression562 expect(result.success).to.be.true;633 expect(result.success).to.be.true;563 expect(collection.MintMode).to.be.equal(true);634 expect(collection.MintMode).to.be.equal(true);564 });635 });