difftreelog
Add tests for properties
in: master
6 files changed
tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -50,6 +50,7 @@
"testContracts": "mocha --timeout 9999999 -r ts-node/register ./**/contracts.test.ts",
"testCreateItem": "mocha --timeout 9999999 -r ts-node/register ./**/createItem.test.ts",
"testCreateMultipleItems": "mocha --timeout 9999999 -r ts-node/register ./**/createMultipleItems.test.ts",
+ "testCreateMultipleItemsEx": "mocha --timeout 9999999 -r ts-node/register ./**/createMultipleItemsEx.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",
tests/src/createCollection.test.tsdiffbeforeafterboth--- a/tests/src/createCollection.test.ts
+++ b/tests/src/createCollection.test.ts
@@ -17,7 +17,7 @@
import {expect} from 'chai';
import privateKey from './substrate/privateKey';
import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';
-import {createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo} from './util/helpers';
+import {createCollectionWithPropsExpectFailure, createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo, createCollectionWithPropsExpectSuccess} from './util/helpers';
describe('integration test: ext. createCollection():', () => {
it('Create new NFT collection', async () => {
@@ -38,6 +38,25 @@
it('Create new ReFungible collection', async () => {
await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
});
+
+ it('create new collection with properties #1', async () => {
+ await createCollectionWithPropsExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'},
+ properties: [{key: 'key1', value: 'val1'}],
+ propPerm: [{key: 'key1', tokenOwner: true, mutable: false, collectionAdmin: true}]});
+ });
+
+ it('create new collection with properties #2', async () => {
+ await createCollectionWithPropsExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'},
+ properties: [{key: 'key1', value: 'val1'}],
+ propPerm: [{key: 'key1', tokenOwner: false, mutable: true, collectionAdmin: false}]});
+ });
+
+ it('create new collection with properties #3', async () => {
+ await createCollectionWithPropsExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'},
+ properties: [{key: 'key1', value: 'val1'}],
+ propPerm: [{key: 'key1', tokenOwner: true, mutable: false, collectionAdmin: false}]});
+ });
+
it('Create new collection with extra fields', async () => {
await usingApi(async api => {
const alice = privateKey('//Alice');
@@ -96,4 +115,24 @@
await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/^common.CollectionTokenLimitExceeded$/);
});
});
+
+ it('(!negative test!) create collection with incorrect property limit (64 elements)', async () => {
+ const props = [];
+
+ for (let i = 0; i < 65; i++) {
+ props.push({key: `key${i}`, value: `value${i}`});
+ }
+
+ await createCollectionWithPropsExpectFailure({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}, properties: props});
+ });
+
+ it('(!negative test!) create collection with incorrect property limit (40 kb)', async () => {
+ const props = [];
+
+ for (let i = 0; i < 32; i++) {
+ props.push({key: `key${i}`.repeat(80), value: `value${i}`.repeat(80)});
+ }
+
+ await createCollectionWithPropsExpectFailure({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}, properties: props});
+ });
});
tests/src/createItem.test.tsdiffbeforeafterboth--- a/tests/src/createItem.test.ts
+++ b/tests/src/createItem.test.ts
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-import {default as usingApi} from './substrate/substrate-api';
+import {default as usingApi, executeTransaction} from './substrate/substrate-api';
import chai from 'chai';
import {Keyring} from '@polkadot/api';
import {IKeyringPair} from '@polkadot/types/types';
@@ -22,6 +22,7 @@
createCollectionExpectSuccess,
createItemExpectSuccess,
addCollectionAdminExpectSuccess,
+ createCollectionWithPropsExpectSuccess,
} from './util/helpers';
const expect = chai.expect;
@@ -70,6 +71,33 @@
await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
await createItemExpectSuccess(bob, newCollectionID, createMode);
});
+
+ it('Set property Admin', async () => {
+ const createMode = 'NFT';
+ const newCollectionID = await createCollectionWithPropsExpectSuccess({mode: {type: createMode},
+ properties: [{key: 'key1', value: 'val1'}],
+ propPerm: [{key: 'key1', mutable: true, collectionAdmin: true, tokenOwner: false}]});
+
+ await createItemExpectSuccess(alice, newCollectionID, createMode);
+ });
+
+ it('Set property AdminConst', async () => {
+ const createMode = 'NFT';
+ const newCollectionID = await createCollectionWithPropsExpectSuccess({mode: {type: createMode},
+ properties: [{key: 'key1', value: 'val1'}],
+ propPerm: [{key: 'key1', mutable: false, collectionAdmin: true, tokenOwner: false}]});
+
+ await createItemExpectSuccess(alice, newCollectionID, createMode);
+ });
+
+ it('Set property itemOwnerOrAdmin', async () => {
+ const createMode = 'NFT';
+ const newCollectionID = await createCollectionWithPropsExpectSuccess({mode: {type: createMode},
+ properties: [{key: 'key1', value: 'val1'}],
+ propPerm: [{key: 'key1', mutable: true, collectionAdmin: true, tokenOwner: true}]});
+
+ await createItemExpectSuccess(alice, newCollectionID, createMode);
+ });
});
describe('Negative integration test: ext. createItem():', () => {
@@ -96,4 +124,76 @@
const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
});
+
+ it('No editing rights', async () => {
+ await usingApi(async api => {
+ const createMode = 'NFT';
+ const newCollectionID = await createCollectionWithPropsExpectSuccess({mode: {type: createMode},
+ propPerm: [{key: 'key1', mutable: false, collectionAdmin: false, tokenOwner: false}]});
+
+ const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
+ await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
+
+ await expect(executeTransaction(
+ api,
+ alice,
+ api.tx.unique.setTokenProperties(newCollectionID, token, [{key: 'key1', value: 'v2'}]),
+ )).to.be.rejected;
+ });
+ });
+
+ it('User doesnt have editing rights', async () => {
+ await usingApi(async api => {
+ const createMode = 'NFT';
+ const newCollectionID = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});
+ const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
+
+ await expect(executeTransaction(
+ api,
+ bob,
+ api.tx.unique.setTokenProperties(newCollectionID, token, [{key: 'key1', value: 'v2'}]),
+ )).to.be.rejected;
+ });
+ });
+
+ it('Adding property without access rights', async () => {
+ await usingApi(async api => {
+ const createMode = 'NFT';
+ const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
+
+ const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
+ await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
+
+ await expect(executeTransaction(
+ api,
+ bob,
+ api.tx.unique.setTokenProperties(newCollectionID, token, [{key: 'key1', value: 'v2'}]),
+ )).to.be.rejected;
+ });
+ });
+
+ it('Adding more than 64 prps', async () => {
+ await usingApi(async api => {
+ const createMode = 'NFT';
+
+ const prps = [];
+
+ for (let i = 0; i < 65; i++) {
+ prps.push({key: `key${i}`, value: `value${i}`});
+ }
+
+ const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
+
+ await expect(executeTransaction(api, alice, api.tx.unique.setCollectionProperties(newCollectionID, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);
+ });
+ });
+
+ it('Trying to add bigger property than allowed', async () => {
+ await usingApi(async api => {
+ const createMode = 'NFT';
+ const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
+
+ await expect(executeTransaction(api, alice, api.tx.unique.setCollectionProperties(newCollectionID, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]))).to.be.rejectedWith(/common\.NoSpaceForProperty/);
+ });
+ });
});
tests/src/createMultipleItems.test.tsdiffbeforeafterboth--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -19,7 +19,7 @@
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 {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync, executeTransaction} from './substrate/substrate-api';
import {
createCollectionExpectSuccess,
destroyCollectionExpectSuccess,
@@ -33,6 +33,8 @@
getVariableMetadata,
getConstMetadata,
getCreatedCollectionCount,
+ createCollectionWithPropsExpectSuccess,
+ getCreateItemsResult,
} from './util/helpers';
chai.use(chaiAsPromised);
@@ -45,7 +47,9 @@
const itemsListIndexBefore = await getLastTokenId(api, collectionId);
expect(itemsListIndexBefore).to.be.equal(0);
const alice = privateKey('//Alice');
- const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
const createMultipleItemsTx = api.tx.unique
.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -135,6 +139,114 @@
expect(result.success).to.be.true;
});
});
+
+ it('Create 0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const collectionId = await createCollectionExpectSuccess();
+ const itemsListIndexBefore = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexBefore).to.be.equal(0);
+ const alice = privateKey('//Alice');
+ const bob = privateKey('//Bob');
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+ const createMultipleItemsTx = api.tx.unique
+ .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+ await submitTransactionAsync(alice, createMultipleItemsTx);
+ const itemsListIndexAfter = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexAfter).to.be.equal(3);
+
+ await expect(executeTransaction(
+ api,
+ alice,
+ api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]),
+ )).to.not.be.rejected;
+
+ expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
+ expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
+ expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
+
+ expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
+ expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
+ expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+
+ expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
+ expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
+ expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+ });
+ });
+
+ it('Create 0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const collectionId = await createCollectionExpectSuccess();
+ const itemsListIndexBefore = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexBefore).to.be.equal(0);
+ const alice = privateKey('//Alice');
+ const bob = privateKey('//Bob');
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+ const createMultipleItemsTx = api.tx.unique
+ .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+ await submitTransactionAsync(alice, createMultipleItemsTx);
+ const itemsListIndexAfter = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexAfter).to.be.equal(3);
+
+ await expect(executeTransaction(
+ api,
+ alice,
+ api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]),
+ )).to.not.be.rejected;
+
+ expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
+ expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
+ expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
+
+ expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
+ expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
+ expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+
+ expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
+ expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
+ expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+ });
+ });
+
+ it('Create 0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const collectionId = await createCollectionExpectSuccess();
+ const itemsListIndexBefore = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexBefore).to.be.equal(0);
+ const alice = privateKey('//Alice');
+ const bob = privateKey('//Bob');
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+ const createMultipleItemsTx = api.tx.unique
+ .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+ await submitTransactionAsync(alice, createMultipleItemsTx);
+ const itemsListIndexAfter = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexAfter).to.be.equal(3);
+
+ await expect(executeTransaction(
+ api,
+ alice,
+ api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]),
+ )).to.not.be.rejected;
+
+ expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
+ expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
+ expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
+
+ expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
+ expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
+ expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+
+ expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
+ expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
+ expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
+ });
+ });
});
describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {
@@ -155,7 +267,9 @@
const itemsListIndexBefore = await getLastTokenId(api, collectionId);
expect(itemsListIndexBefore).to.be.equal(0);
await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
- const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
const createMultipleItemsTx = api.tx.unique
.createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
await submitTransactionAsync(bob, createMultipleItemsTx);
@@ -245,7 +359,9 @@
const collectionId = await createCollectionExpectSuccess();
const itemsListIndexBefore = await getLastTokenId(api, collectionId);
expect(itemsListIndexBefore).to.be.equal(0);
- const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
const createMultipleItemsTx = api.tx.unique
.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
@@ -361,4 +477,146 @@
await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
});
});
+
+ it('No editing rights', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
+ propPerm: [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});
+ const itemsListIndexBefore = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexBefore).to.be.equal(0);
+ await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+
+ const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+
+ const events = await submitTransactionAsync(alice, createMultipleItemsTx);
+ const result = getCreateItemsResult(events);
+
+ for (const elem of result) {
+ await expect(executeTransaction(
+ api,
+ bob,
+ api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
+ )).to.be.rejected;
+ }
+
+ // await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
+ });
+ });
+
+ it('User doesnt have editing rights', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
+ propPerm: [{key: 'key1', mutable: false, collectionAdmin: false, tokenOwner: false}]});
+ const itemsListIndexBefore = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexBefore).to.be.equal(0);
+ await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+
+ const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+
+ const events = await submitTransactionAsync(alice, createMultipleItemsTx);
+ const result = getCreateItemsResult(events);
+
+ for (const elem of result) {
+ await expect(executeTransaction(
+ api,
+ bob,
+ api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
+ )).to.be.rejected;
+ }
+ });
+ });
+
+ it('Adding property without access rights', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}]});
+ const itemsListIndexBefore = await getLastTokenId(api, collectionId);
+ await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
+ expect(itemsListIndexBefore).to.be.equal(0);
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+
+ const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+
+ const events = await submitTransactionAsync(alice, createMultipleItemsTx);
+ const result = getCreateItemsResult(events);
+
+ for (const elem of result) {
+ await expect(executeTransaction(
+ api,
+ bob,
+ api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
+ )).to.be.rejected;
+ }
+ });
+ });
+
+ it('Adding more than 64 prps', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
+ propPerm: [{key: 'key1', mutable: true, collectionAdmin: true, tokenOwner: false}]});
+ const itemsListIndexBefore = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexBefore).to.be.equal(0);
+ await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
+
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+
+ const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+ const events = await submitTransactionAsync(alice, createMultipleItemsTx);
+
+ const result = getCreateItemsResult(events);
+
+ const prps = [];
+
+ for (let i = 0; i < 65; i++) {
+ prps.push({key: `key${i}`, value: `value${i}`});
+ }
+
+ await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collectionId, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);
+
+ for (const elem of result) {
+ await expect(executeTransaction(
+ api,
+ bob,
+ api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps),
+ )).to.be.rejected;
+ }
+ });
+ });
+
+ it('Trying to add bigger property than allowed', async () => {
+ await usingApi(async (api: ApiPromise) => {
+ const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
+ propPerm: [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});
+ const itemsListIndexBefore = await getLastTokenId(api, collectionId);
+ expect(itemsListIndexBefore).to.be.equal(0);
+ const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
+ {Nft: {const_data: '0x32', variable_data: '0x32'}},
+ {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+
+ const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
+
+ const events = await submitTransactionAsync(alice, createMultipleItemsTx);
+ const result = getCreateItemsResult(events);
+
+
+ await expect(executeTransaction(api, alice, api.tx.unique.setCollectionProperties(collectionId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]))).to.be.rejectedWith(/common\.NoSpaceForProperty/);
+
+ for (const elem of result) {
+ await expect(executeTransaction(
+ api,
+ bob,
+ api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]),
+ )).to.be.rejected;
+ }
+ });
+ });
});
tests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth161617import {expect} from 'chai';17import {expect} from 'chai';18import privateKey from './substrate/privateKey';18import privateKey from './substrate/privateKey';19import usingApi, {executeTransaction} from './substrate/substrate-api';19import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';20import {createCollectionExpectSuccess} from './util/helpers';20import {createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, addCollectionAdminExpectSuccess, getCreateItemsResult} from './util/helpers';212122describe('createMultipleItemsEx', () => {22describe('createMultipleItemsEx', () => {23 it('can initialize multiple NFT with different owners', async () => {24 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});25 const alice = privateKey('//Alice');26 const bob = privateKey('//Bob');27 const charlie = privateKey('//Charlie');28 await usingApi(async (api) => {29 const data = [30 {31 owner: {substrate: alice.address},32 constData: '0x0000',33 variableData: '0x1111',34 }, {35 owner: {substrate: bob.address},36 constData: '0x2222',37 variableData: '0x3333',38 }, {39 owner: {substrate: charlie.address},40 constData: '0x4444',41 variableData: '0x5555',42 },43 ];4445 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {46 NFT: data,47 }));48 const tokens = await api.query.nonfungible.tokenData.entries(collection);49 const json = tokens.map(([, token]) => token.toJSON());50 expect(json).to.be.deep.equal(data);51 });52 });5354 it('createMultipleItemsEx with property Admin', async () => {55 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});56 const alice = privateKey('//Alice');57 const bob = privateKey('//Bob');58 const charlie = privateKey('//Charlie');59 await usingApi(async (api) => {60 const data = [61 {62 owner: {substrate: alice.address},63 constData: '0x0000',64 variableData: '0x1111',65 }, {66 owner: {substrate: bob.address},67 constData: '0x2222',68 variableData: '0x3333',69 }, {70 owner: {substrate: charlie.address},71 constData: '0x4444',72 variableData: '0x5555',73 },74 ];7576 await expect(executeTransaction(77 api, 78 alice, 79 api.tx.unique.setPropertyPermissions(collection, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]), 80 )).to.not.be.rejected;8182 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {83 NFT: data,84 }));85 const tokens = await api.query.nonfungible.tokenData.entries(collection);86 const json = tokens.map(([, token]) => token.toJSON());87 expect(json).to.be.deep.equal(data);88 });89 });9091 it('createMultipleItemsEx with property AdminConst', async () => {92 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});93 const alice = privateKey('//Alice');94 const bob = privateKey('//Bob');95 const charlie = privateKey('//Charlie');96 await usingApi(async (api) => {97 const data = [98 {99 owner: {substrate: alice.address},100 constData: '0x0000',101 variableData: '0x1111',102 }, {103 owner: {substrate: bob.address},104 constData: '0x2222',105 variableData: '0x3333',106 }, {107 owner: {substrate: charlie.address},108 constData: '0x4444',109 variableData: '0x5555',110 },111 ];112 await expect(executeTransaction(113 api, 114 alice, 115 api.tx.unique.setPropertyPermissions(collection, [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]), 116 )).to.not.be.rejected;117118 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {119 NFT: data,120 }));121 122123 const tokens = await api.query.nonfungible.tokenData.entries(collection);124 const json = tokens.map(([, token]) => token.toJSON());125 expect(json).to.be.deep.equal(data);126 });127 });128129 it('createMultipleItemsEx with property itemOwnerOrAdmin', async () => {130 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});131 const alice = privateKey('//Alice');132 const bob = privateKey('//Bob');133 const charlie = privateKey('//Charlie');134 await usingApi(async (api) => {135 const data = [136 {137 owner: {substrate: alice.address},138 constData: '0x0000',139 variableData: '0x1111',140 }, {141 owner: {substrate: bob.address},142 constData: '0x2222',143 variableData: '0x3333',144 }, {145 owner: {substrate: charlie.address},146 constData: '0x4444',147 variableData: '0x5555',148 },149 ];150 await expect(executeTransaction(151 api, 152 alice, 153 api.tx.unique.setPropertyPermissions(collection, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]), 154 )).to.not.be.rejected;155156 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {157 NFT: data,158 }));159 160161 const tokens = await api.query.nonfungible.tokenData.entries(collection);162 const json = tokens.map(([, token]) => token.toJSON());163 expect(json).to.be.deep.equal(data);164 });165 });166167 it('No editing rights', async () => {168 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],169 propPerm: [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});170 const alice = privateKey('//Alice');171 const bob = privateKey('//Bob');172 const charlie = privateKey('//Charlie');173 await addCollectionAdminExpectSuccess(alice, collection, bob.address);174 await usingApi(async (api) => {175 const data = [176 {177 owner: {substrate: alice.address},178 }, {179 owner: {substrate: bob.address},180 }, {181 owner: {substrate: charlie.address},182 },183 ];184185 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});186 await executeTransaction(api, alice, tx);187 188 const events = await submitTransactionAsync(alice, tx);189 const result = getCreateItemsResult(events);190 191 for (const elem of result) {192 await expect(executeTransaction(193 api, 194 bob, 195 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 196 )).to.be.rejected;197 }198 });199 });200201 it('User doesnt have editing rights', async () => {202 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],203 propPerm: [{key: 'key1', mutable: false, collectionAdmin: false, tokenOwner: false}]});204 const alice = privateKey('//Alice');205 const bob = privateKey('//Bob');206 const charlie = privateKey('//Charlie');207 await addCollectionAdminExpectSuccess(alice, collection, bob.address);208 await usingApi(async (api) => {209 const data = [210 {211 owner: {substrate: alice.address},212 }, {213 owner: {substrate: bob.address},214 }, {215 owner: {substrate: charlie.address},216 },217 ];218219 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});220 await executeTransaction(api, alice, tx);221 222 const events = await submitTransactionAsync(alice, tx);223 const result = getCreateItemsResult(events);224 225 for (const elem of result) {226 await expect(executeTransaction(227 api, 228 bob, 229 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 230 )).to.be.rejected;231 }232 });233 });234235 it('Adding property without access rights', async () => {236 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}]});237 const alice = privateKey('//Alice');238 const bob = privateKey('//Bob');239 const charlie = privateKey('//Charlie');240 await addCollectionAdminExpectSuccess(alice, collection, bob.address);241 await usingApi(async (api) => {242 const data = [243 {244 owner: {substrate: alice.address},245 }, {246 owner: {substrate: bob.address},247 }, {248 owner: {substrate: charlie.address},249 },250 ];251252 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});253 await executeTransaction(api, alice, tx);254 255 const events = await submitTransactionAsync(alice, tx);256 const result = getCreateItemsResult(events);257 258 for (const elem of result) {259 await expect(executeTransaction(260 api, 261 bob, 262 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 263 )).to.be.rejected;264 }265 });266 });267268 it('Adding more than 64 prps', async () => {269 const collection = await createCollectionWithPropsExpectSuccess();270 const alice = privateKey('//Alice');271 const bob = privateKey('//Bob');272 const charlie = privateKey('//Charlie');273 await addCollectionAdminExpectSuccess(alice, collection, bob.address);274 await usingApi(async (api) => {275 const data = [276 {277 owner: {substrate: alice.address},278 }, {279 owner: {substrate: bob.address},280 }, {281 owner: {substrate: charlie.address},282 },283 ];284285 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});286 await executeTransaction(api, alice, tx);287 288 const events = await submitTransactionAsync(alice, tx);289 const result = getCreateItemsResult(events);290291 const prps = [];292 293 for (let i = 0; i < 65; i++) {294 prps.push({key: `key${i}`, value: `value${i}`});295 }296297 await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collection, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);298299 300 for (const elem of result) {301 await expect(executeTransaction(302 api, 303 bob, 304 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps), 305 )).to.be.rejected;306 }307 });308 });309310 it('Trying to add bigger property than allowed', async () => {311 const collection = await createCollectionWithPropsExpectSuccess();312 const alice = privateKey('//Alice');313 const bob = privateKey('//Bob');314 const charlie = privateKey('//Charlie');315 await addCollectionAdminExpectSuccess(alice, collection, bob.address);316 await usingApi(async (api) => {317 const data = [318 {319 owner: {substrate: alice.address},320 }, {321 owner: {substrate: bob.address},322 }, {323 owner: {substrate: charlie.address},324 },325 ];326327 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});328 await executeTransaction(api, alice, tx);329 330 const events = await submitTransactionAsync(alice, tx);331 const result = getCreateItemsResult(events);332333 const prps = [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}];334335 await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collection, prps))).to.be.rejectedWith(/common\.NoSpaceForProperty/);336337 338 for (const elem of result) {339 await expect(executeTransaction(340 api, 341 bob, 342 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps), 343 )).to.be.rejected;344 }345 });346 });347348 it('can initialize multiple NFT with different owners', async () => {349 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});350 const alice = privateKey('//Alice');351 const bob = privateKey('//Bob');352 const charlie = privateKey('//Charlie');353 await usingApi(async (api) => {354 const data = [355 {356 owner: {substrate: alice.address},357 constData: '0x0000',358 variableData: '0x1111',359 }, {360 owner: {substrate: bob.address},361 constData: '0x2222',362 variableData: '0x3333',363 }, {364 owner: {substrate: charlie.address},365 constData: '0x4444',366 variableData: '0x5555',367 },368 ];369370 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {371 NFT: data,372 }));373 const tokens = await api.query.nonfungible.tokenData.entries(collection);374 const json = tokens.map(([, token]) => token.toJSON());375 expect(json).to.be.deep.equal(data);376 });377 });37823 it('can initialize multiple NFT with different owners', async () => {379 it('can initialize multiple NFT with different owners', async () => {24 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});380 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});72 });428 });73 });429 });74});430});431'';75432tests/src/util/helpers.tsdiffbeforeafterboth--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -201,6 +201,37 @@
return result;
}
+export function getCreateItemsResult(events: EventRecord[]): CreateItemResult[] {
+ let success = false;
+ let collectionId = 0;
+ let itemId = 0;
+ let recipient;
+
+ const results : CreateItemResult[] = [];
+
+ events.forEach(({event: {data, method, section}}) => {
+ // console.log(` ${phase}: ${section}.${method}:: ${data}`);
+ if (method == 'ExtrinsicSuccess') {
+ success = true;
+ } else if ((section == 'common') && (method == 'ItemCreated')) {
+ collectionId = parseInt(data[0].toString(), 10);
+ itemId = parseInt(data[1].toString(), 10);
+ recipient = normalizeAccountId(data[2].toJSON() as any);
+
+ const itemRes: CreateItemResult = {
+ success,
+ collectionId,
+ itemId,
+ recipient,
+ };
+
+ results.push(itemRes);
+ }
+ });
+
+ return results;
+}
+
export function getCreateItemResult(events: EventRecord[]): CreateItemResult {
let success = false;
let collectionId = 0;
@@ -263,12 +294,26 @@
type CollectionMode = Nft | Fungible | ReFungible;
+export type Property = {
+ key: any,
+ value: any,
+};
+
+type PropertyPermission = {
+ key: any,
+ mutable: boolean;
+ collectionAdmin: boolean;
+ tokenOwner: boolean;
+}
+
export type CreateCollectionParams = {
mode: CollectionMode,
name: string,
description: string,
tokenPrefix: string,
schemaVersion: string,
+ properties?: Array<Property>,
+ propPerm?: Array<PropertyPermission>
};
const defaultCreateCollectionParams: CreateCollectionParams = {
@@ -333,6 +378,86 @@
return collectionId;
}
+export async function createCollectionWithPropsExpectSuccess(params: Partial<CreateCollectionParams> = {}): Promise<number> {
+ const {name, description, mode, tokenPrefix} = {...defaultCreateCollectionParams, ...params};
+
+ let collectionId = 0;
+ await usingApi(async (api) => {
+ // Get number of collections before the transaction
+ const collectionCountBefore = await getCreatedCollectionCount(api);
+
+ // Run the CreateCollection transaction
+ const alicePrivateKey = privateKey('//Alice');
+
+ 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: null};
+ }
+
+ const tx = api.tx.unique.createCollectionEx({name: strToUTF16(name), description: strToUTF16(description), tokenPrefix: strToUTF16(tokenPrefix), mode: modeprm as any, properties: params.properties, tokenPropertyPermissions: params.propPerm});
+ const events = await submitTransactionAsync(alicePrivateKey, tx);
+ const result = getCreateCollectionResult(events);
+
+ // Get number of collections after the transaction
+ const collectionCountAfter = await getCreatedCollectionCount(api);
+
+ // Get the collection
+ const collection = await queryCollectionExpectSuccess(api, result.collectionId);
+
+ // What to expect
+ // tslint:disable-next-line:no-unused-expression
+ expect(result.success).to.be.true;
+ expect(result.collectionId).to.be.equal(collectionCountAfter);
+ // tslint:disable-next-line:no-unused-expression
+ expect(collection).to.be.not.null;
+ expect(collectionCountAfter).to.be.equal(collectionCountBefore + 1, 'Error: NFT collection NOT created.');
+ expect(collection.owner.toString()).to.be.equal(toSubstrateAddress(alicesPublicKey));
+ expect(utf16ToStr(collection.name.toJSON() as any)).to.be.equal(name);
+ expect(utf16ToStr(collection.description.toJSON() as any)).to.be.equal(description);
+ expect(hexToStr(collection.tokenPrefix.toJSON())).to.be.equal(tokenPrefix);
+
+
+ collectionId = result.collectionId;
+ });
+
+ return collectionId;
+}
+
+export async function createCollectionWithPropsExpectFailure(params: Partial<CreateCollectionParams> = {}) {
+ const {name, description, mode, tokenPrefix} = {...defaultCreateCollectionParams, ...params};
+
+ const collectionId = 0;
+ await usingApi(async (api) => {
+ // Get number of collections before the transaction
+ const collectionCountBefore = await getCreatedCollectionCount(api);
+
+ // Run the CreateCollection transaction
+ const alicePrivateKey = privateKey('//Alice');
+
+ 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: null};
+ }
+
+ const tx = api.tx.unique.createCollectionEx({name: strToUTF16(name), description: strToUTF16(description), tokenPrefix: strToUTF16(tokenPrefix), mode: modeprm as any, properties: params.properties, tokenPropertyPermissions: params.propPerm});
+ await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected;
+
+
+ // Get number of collections after the transaction
+ const collectionCountAfter = await getCreatedCollectionCount(api);
+
+ expect(collectionCountAfter).to.be.equal(collectionCountBefore, 'Error: Collection with incorrect data created.');
+ });
+}
+
export async function createCollectionExpectFailure(params: Partial<CreateCollectionParams> = {}) {
const {name, description, mode, tokenPrefix} = {...defaultCreateCollectionParams, ...params};