git.delta.rocks / unique-network / refs/commits / 36ef0466a311

difftreelog

Add tests for properties

kryadinskii2022-05-10parent: #2976d69.patch.diff
in: master

6 files changed

modifiedtests/package.jsondiffbeforeafterboth
50 "testContracts": "mocha --timeout 9999999 -r ts-node/register ./**/contracts.test.ts",50 "testContracts": "mocha --timeout 9999999 -r ts-node/register ./**/contracts.test.ts",
51 "testCreateItem": "mocha --timeout 9999999 -r ts-node/register ./**/createItem.test.ts",51 "testCreateItem": "mocha --timeout 9999999 -r ts-node/register ./**/createItem.test.ts",
52 "testCreateMultipleItems": "mocha --timeout 9999999 -r ts-node/register ./**/createMultipleItems.test.ts",52 "testCreateMultipleItems": "mocha --timeout 9999999 -r ts-node/register ./**/createMultipleItems.test.ts",
53 "testCreateMultipleItemsEx": "mocha --timeout 9999999 -r ts-node/register ./**/createMultipleItemsEx.test.ts",
53 "testApprove": "mocha --timeout 9999999 -r ts-node/register ./**/approve.test.ts",54 "testApprove": "mocha --timeout 9999999 -r ts-node/register ./**/approve.test.ts",
54 "testTransferFrom": "mocha --timeout 9999999 -r ts-node/register ./**/transferFrom.test.ts",55 "testTransferFrom": "mocha --timeout 9999999 -r ts-node/register ./**/transferFrom.test.ts",
55 "testCreateCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts",56 "testCreateCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts",
modifiedtests/src/createCollection.test.tsdiffbeforeafterboth
17import {expect} from 'chai';17import {expect} from 'chai';
18import privateKey from './substrate/privateKey';18import privateKey from './substrate/privateKey';
19import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';19import usingApi, {executeTransaction, submitTransactionAsync} from './substrate/substrate-api';
20import {createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo} from './util/helpers';20import {createCollectionWithPropsExpectFailure, createCollectionExpectFailure, createCollectionExpectSuccess, getCreateCollectionResult, getDetailedCollectionInfo, createCollectionWithPropsExpectSuccess} from './util/helpers';
2121
22describe('integration test: ext. createCollection():', () => {22describe('integration test: ext. createCollection():', () => {
23 it('Create new NFT collection', async () => {23 it('Create new NFT collection', async () => {
39 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});39 await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
40 });40 });
41
42 it('create new collection with properties #1', async () => {
43 await createCollectionWithPropsExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'},
44 properties: [{key: 'key1', value: 'val1'}],
45 propPerm: [{key: 'key1', tokenOwner: true, mutable: false, collectionAdmin: true}]});
46 });
47
48 it('create new collection with properties #2', async () => {
49 await createCollectionWithPropsExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'},
50 properties: [{key: 'key1', value: 'val1'}],
51 propPerm: [{key: 'key1', tokenOwner: false, mutable: true, collectionAdmin: false}]});
52 });
53
54 it('create new collection with properties #3', async () => {
55 await createCollectionWithPropsExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'},
56 properties: [{key: 'key1', value: 'val1'}],
57 propPerm: [{key: 'key1', tokenOwner: true, mutable: false, collectionAdmin: false}]});
58 });
59
41 it('Create new collection with extra fields', async () => {60 it('Create new collection with extra fields', async () => {
42 await usingApi(async api => {61 await usingApi(async api => {
97 });116 });
98 });117 });
118
119 it('(!negative test!) create collection with incorrect property limit (64 elements)', async () => {
120 const props = [];
121
122 for (let i = 0; i < 65; i++) {
123 props.push({key: `key${i}`, value: `value${i}`});
124 }
125
126 await createCollectionWithPropsExpectFailure({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}, properties: props});
127 });
128
129 it('(!negative test!) create collection with incorrect property limit (40 kb)', async () => {
130 const props = [];
131
132 for (let i = 0; i < 32; i++) {
133 props.push({key: `key${i}`.repeat(80), value: `value${i}`.repeat(80)});
134 }
135
136 await createCollectionWithPropsExpectFailure({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}, properties: props});
137 });
99});138});
100139
modifiedtests/src/createItem.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {default as usingApi} from './substrate/substrate-api';17import {default as usingApi, executeTransaction} from './substrate/substrate-api';
18import chai from 'chai';18import chai from 'chai';
19import {Keyring} from '@polkadot/api';19import {Keyring} from '@polkadot/api';
20import {IKeyringPair} from '@polkadot/types/types';20import {IKeyringPair} from '@polkadot/types/types';
21import {21import {
22 createCollectionExpectSuccess,22 createCollectionExpectSuccess,
23 createItemExpectSuccess,23 createItemExpectSuccess,
24 addCollectionAdminExpectSuccess,24 addCollectionAdminExpectSuccess,
25 createCollectionWithPropsExpectSuccess,
25} from './util/helpers';26} from './util/helpers';
2627
27const expect = chai.expect;28const expect = chai.expect;
71 await createItemExpectSuccess(bob, newCollectionID, createMode);72 await createItemExpectSuccess(bob, newCollectionID, createMode);
72 });73 });
74
75 it('Set property Admin', async () => {
76 const createMode = 'NFT';
77 const newCollectionID = await createCollectionWithPropsExpectSuccess({mode: {type: createMode},
78 properties: [{key: 'key1', value: 'val1'}],
79 propPerm: [{key: 'key1', mutable: true, collectionAdmin: true, tokenOwner: false}]});
80
81 await createItemExpectSuccess(alice, newCollectionID, createMode);
82 });
83
84 it('Set property AdminConst', async () => {
85 const createMode = 'NFT';
86 const newCollectionID = await createCollectionWithPropsExpectSuccess({mode: {type: createMode},
87 properties: [{key: 'key1', value: 'val1'}],
88 propPerm: [{key: 'key1', mutable: false, collectionAdmin: true, tokenOwner: false}]});
89
90 await createItemExpectSuccess(alice, newCollectionID, createMode);
91 });
92
93 it('Set property itemOwnerOrAdmin', async () => {
94 const createMode = 'NFT';
95 const newCollectionID = await createCollectionWithPropsExpectSuccess({mode: {type: createMode},
96 properties: [{key: 'key1', value: 'val1'}],
97 propPerm: [{key: 'key1', mutable: true, collectionAdmin: true, tokenOwner: true}]});
98
99 await createItemExpectSuccess(alice, newCollectionID, createMode);
100 });
73});101});
74102
75describe('Negative integration test: ext. createItem():', () => {103describe('Negative integration test: ext. createItem():', () => {
97 await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;125 await expect(createItemExpectSuccess(bob, newCollectionID, createMode)).to.be.rejected;
98 });126 });
127
128 it('No editing rights', async () => {
129 await usingApi(async api => {
130 const createMode = 'NFT';
131 const newCollectionID = await createCollectionWithPropsExpectSuccess({mode: {type: createMode},
132 propPerm: [{key: 'key1', mutable: false, collectionAdmin: false, tokenOwner: false}]});
133
134 const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
135 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
136
137 await expect(executeTransaction(
138 api,
139 alice,
140 api.tx.unique.setTokenProperties(newCollectionID, token, [{key: 'key1', value: 'v2'}]),
141 )).to.be.rejected;
142 });
143 });
144
145 it('User doesnt have editing rights', async () => {
146 await usingApi(async api => {
147 const createMode = 'NFT';
148 const newCollectionID = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});
149 const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
150
151 await expect(executeTransaction(
152 api,
153 bob,
154 api.tx.unique.setTokenProperties(newCollectionID, token, [{key: 'key1', value: 'v2'}]),
155 )).to.be.rejected;
156 });
157 });
158
159 it('Adding property without access rights', async () => {
160 await usingApi(async api => {
161 const createMode = 'NFT';
162 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
163
164 const token = await createItemExpectSuccess(alice, newCollectionID, 'NFT');
165 await addCollectionAdminExpectSuccess(alice, newCollectionID, bob.address);
166
167 await expect(executeTransaction(
168 api,
169 bob,
170 api.tx.unique.setTokenProperties(newCollectionID, token, [{key: 'key1', value: 'v2'}]),
171 )).to.be.rejected;
172 });
173 });
174
175 it('Adding more than 64 prps', async () => {
176 await usingApi(async api => {
177 const createMode = 'NFT';
178
179 const prps = [];
180
181 for (let i = 0; i < 65; i++) {
182 prps.push({key: `key${i}`, value: `value${i}`});
183 }
184
185 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
186
187 await expect(executeTransaction(api, alice, api.tx.unique.setCollectionProperties(newCollectionID, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);
188 });
189 });
190
191 it('Trying to add bigger property than allowed', async () => {
192 await usingApi(async api => {
193 const createMode = 'NFT';
194 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
195
196 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/);
197 });
198 });
99});199});
100200
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
19import chai from 'chai';19import chai from 'chai';
20import chaiAsPromised from 'chai-as-promised';20import chaiAsPromised from 'chai-as-promised';
21import privateKey from './substrate/privateKey';21import privateKey from './substrate/privateKey';
22import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';22import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync, executeTransaction} from './substrate/substrate-api';
23import {23import {
24 createCollectionExpectSuccess,24 createCollectionExpectSuccess,
25 destroyCollectionExpectSuccess,25 destroyCollectionExpectSuccess,
33 getVariableMetadata,33 getVariableMetadata,
34 getConstMetadata,34 getConstMetadata,
35 getCreatedCollectionCount,35 getCreatedCollectionCount,
36 createCollectionWithPropsExpectSuccess,
37 getCreateItemsResult,
36} from './util/helpers';38} from './util/helpers';
3739
38chai.use(chaiAsPromised);40chai.use(chaiAsPromised);
45 const itemsListIndexBefore = await getLastTokenId(api, collectionId);47 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
46 expect(itemsListIndexBefore).to.be.equal(0);48 expect(itemsListIndexBefore).to.be.equal(0);
47 const alice = privateKey('//Alice');49 const alice = privateKey('//Alice');
48 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];50 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
51 {Nft: {const_data: '0x32', variable_data: '0x32'}},
52 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
49 const createMultipleItemsTx = api.tx.unique53 const createMultipleItemsTx = api.tx.unique
50 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);54 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
51 await submitTransactionAsync(alice, createMultipleItemsTx);55 await submitTransactionAsync(alice, createMultipleItemsTx);
136 });140 });
137 });141 });
142
143 it('Create 0x31, 0x32, 0x33 items in active NFT with property Admin', async () => {
144 await usingApi(async (api: ApiPromise) => {
145 const collectionId = await createCollectionExpectSuccess();
146 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
147 expect(itemsListIndexBefore).to.be.equal(0);
148 const alice = privateKey('//Alice');
149 const bob = privateKey('//Bob');
150 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
151 {Nft: {const_data: '0x32', variable_data: '0x32'}},
152 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
153 const createMultipleItemsTx = api.tx.unique
154 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
155 await submitTransactionAsync(alice, createMultipleItemsTx);
156 const itemsListIndexAfter = await getLastTokenId(api, collectionId);
157 expect(itemsListIndexAfter).to.be.equal(3);
158
159 await expect(executeTransaction(
160 api,
161 alice,
162 api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]),
163 )).to.not.be.rejected;
164
165 expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
166 expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
167 expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
168
169 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
170 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
171 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
172
173 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
174 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
175 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
176 });
177 });
178
179 it('Create 0x31, 0x32, 0x33 items in active NFT with property AdminConst', async () => {
180 await usingApi(async (api: ApiPromise) => {
181 const collectionId = await createCollectionExpectSuccess();
182 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
183 expect(itemsListIndexBefore).to.be.equal(0);
184 const alice = privateKey('//Alice');
185 const bob = privateKey('//Bob');
186 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
187 {Nft: {const_data: '0x32', variable_data: '0x32'}},
188 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
189 const createMultipleItemsTx = api.tx.unique
190 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
191 await submitTransactionAsync(alice, createMultipleItemsTx);
192 const itemsListIndexAfter = await getLastTokenId(api, collectionId);
193 expect(itemsListIndexAfter).to.be.equal(3);
194
195 await expect(executeTransaction(
196 api,
197 alice,
198 api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]),
199 )).to.not.be.rejected;
200
201 expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
202 expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
203 expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
204
205 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
206 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
207 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
208
209 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
210 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
211 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
212 });
213 });
214
215 it('Create 0x31, 0x32, 0x33 items in active NFT with property itemOwnerOrAdmin', async () => {
216 await usingApi(async (api: ApiPromise) => {
217 const collectionId = await createCollectionExpectSuccess();
218 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
219 expect(itemsListIndexBefore).to.be.equal(0);
220 const alice = privateKey('//Alice');
221 const bob = privateKey('//Bob');
222 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
223 {Nft: {const_data: '0x32', variable_data: '0x32'}},
224 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
225 const createMultipleItemsTx = api.tx.unique
226 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
227 await submitTransactionAsync(alice, createMultipleItemsTx);
228 const itemsListIndexAfter = await getLastTokenId(api, collectionId);
229 expect(itemsListIndexAfter).to.be.equal(3);
230
231 await expect(executeTransaction(
232 api,
233 alice,
234 api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]),
235 )).to.not.be.rejected;
236
237 expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
238 expect(await getTokenOwner(api, collectionId, 2)).to.be.deep.equal(normalizeAccountId(alice.address));
239 expect(await getTokenOwner(api, collectionId, 3)).to.be.deep.equal(normalizeAccountId(alice.address));
240
241 expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
242 expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
243 expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
244
245 expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
246 expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
247 expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
248 });
249 });
138});250});
139251
140describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {252describe('Integration Test createMultipleItems(collection_id, owner, items_data) with collection admin permissions:', () => {
155 const itemsListIndexBefore = await getLastTokenId(api, collectionId);267 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
156 expect(itemsListIndexBefore).to.be.equal(0);268 expect(itemsListIndexBefore).to.be.equal(0);
157 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);269 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
158 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];270 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
271 {Nft: {const_data: '0x32', variable_data: '0x32'}},
272 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
159 const createMultipleItemsTx = api.tx.unique273 const createMultipleItemsTx = api.tx.unique
160 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);274 .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
161 await submitTransactionAsync(bob, createMultipleItemsTx);275 await submitTransactionAsync(bob, createMultipleItemsTx);
245 const collectionId = await createCollectionExpectSuccess();359 const collectionId = await createCollectionExpectSuccess();
246 const itemsListIndexBefore = await getLastTokenId(api, collectionId);360 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
247 expect(itemsListIndexBefore).to.be.equal(0);361 expect(itemsListIndexBefore).to.be.equal(0);
248 const args = [{NFT: ['0x31', '0x31']}, {NFT: ['0x32', '0x32']}, {NFT: ['0x33', '0x33']}];362 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
363 {Nft: {const_data: '0x32', variable_data: '0x32'}},
364 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
249 const createMultipleItemsTx = api.tx.unique365 const createMultipleItemsTx = api.tx.unique
250 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);366 .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
251 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;367 await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
362 });478 });
363 });479 });
480
481 it('No editing rights', async () => {
482 await usingApi(async (api: ApiPromise) => {
483 const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
484 propPerm: [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});
485 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
486 expect(itemsListIndexBefore).to.be.equal(0);
487 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
488 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
489 {Nft: {const_data: '0x32', variable_data: '0x32'}},
490 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
491
492 const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
493
494 const events = await submitTransactionAsync(alice, createMultipleItemsTx);
495 const result = getCreateItemsResult(events);
496
497 for (const elem of result) {
498 await expect(executeTransaction(
499 api,
500 bob,
501 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
502 )).to.be.rejected;
503 }
504
505 // await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
506 });
507 });
508
509 it('User doesnt have editing rights', async () => {
510 await usingApi(async (api: ApiPromise) => {
511 const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
512 propPerm: [{key: 'key1', mutable: false, collectionAdmin: false, tokenOwner: false}]});
513 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
514 expect(itemsListIndexBefore).to.be.equal(0);
515 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
516 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
517 {Nft: {const_data: '0x32', variable_data: '0x32'}},
518 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
519
520 const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
521
522 const events = await submitTransactionAsync(alice, createMultipleItemsTx);
523 const result = getCreateItemsResult(events);
524
525 for (const elem of result) {
526 await expect(executeTransaction(
527 api,
528 bob,
529 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
530 )).to.be.rejected;
531 }
532 });
533 });
534
535 it('Adding property without access rights', async () => {
536 await usingApi(async (api: ApiPromise) => {
537 const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}]});
538 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
539 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
540 expect(itemsListIndexBefore).to.be.equal(0);
541 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
542 {Nft: {const_data: '0x32', variable_data: '0x32'}},
543 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
544
545 const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
546
547 const events = await submitTransactionAsync(alice, createMultipleItemsTx);
548 const result = getCreateItemsResult(events);
549
550 for (const elem of result) {
551 await expect(executeTransaction(
552 api,
553 bob,
554 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
555 )).to.be.rejected;
556 }
557 });
558 });
559
560 it('Adding more than 64 prps', async () => {
561 await usingApi(async (api: ApiPromise) => {
562 const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
563 propPerm: [{key: 'key1', mutable: true, collectionAdmin: true, tokenOwner: false}]});
564 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
565 expect(itemsListIndexBefore).to.be.equal(0);
566 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
567
568 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
569 {Nft: {const_data: '0x32', variable_data: '0x32'}},
570 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
571
572 const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
573 const events = await submitTransactionAsync(alice, createMultipleItemsTx);
574
575 const result = getCreateItemsResult(events);
576
577 const prps = [];
578
579 for (let i = 0; i < 65; i++) {
580 prps.push({key: `key${i}`, value: `value${i}`});
581 }
582
583 await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collectionId, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);
584
585 for (const elem of result) {
586 await expect(executeTransaction(
587 api,
588 bob,
589 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps),
590 )).to.be.rejected;
591 }
592 });
593 });
594
595 it('Trying to add bigger property than allowed', async () => {
596 await usingApi(async (api: ApiPromise) => {
597 const collectionId = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],
598 propPerm: [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});
599 const itemsListIndexBefore = await getLastTokenId(api, collectionId);
600 expect(itemsListIndexBefore).to.be.equal(0);
601 const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
602 {Nft: {const_data: '0x32', variable_data: '0x32'}},
603 {Nft: {const_data: '0x33', variable_data: '0x33'}}];
604
605 const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
606
607 const events = await submitTransactionAsync(alice, createMultipleItemsTx);
608 const result = getCreateItemsResult(events);
609
610
611 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/);
612
613 for (const elem of result) {
614 await expect(executeTransaction(
615 api,
616 bob,
617 api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]),
618 )).to.be.rejected;
619 }
620 });
621 });
364});622});
365623
modifiedtests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth
1616
17import {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';
2121
22describe('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 ];
44
45 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 });
53
54 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 ];
75
76 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;
81
82 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 });
90
91 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;
117
118 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {
119 NFT: data,
120 }));
121
122
123 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 });
128
129 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;
155
156 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {
157 NFT: data,
158 }));
159
160
161 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 });
166
167 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 ];
184
185 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 });
200
201 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 ];
218
219 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 });
234
235 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 ];
251
252 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 });
267
268 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 ];
284
285 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);
290
291 const prps = [];
292
293 for (let i = 0; i < 65; i++) {
294 prps.push({key: `key${i}`, value: `value${i}`});
295 }
296
297 await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collection, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);
298
299
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 });
309
310 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 ];
326
327 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);
332
333 const prps = [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}];
334
335 await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collection, prps))).to.be.rejectedWith(/common\.NoSpaceForProperty/);
336
337
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 });
347
348 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 ];
369
370 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 });
378
23 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'';
75432
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
201 return result;201 return result;
202}202}
203
204export function getCreateItemsResult(events: EventRecord[]): CreateItemResult[] {
205 let success = false;
206 let collectionId = 0;
207 let itemId = 0;
208 let recipient;
209
210 const results : CreateItemResult[] = [];
211
212 events.forEach(({event: {data, method, section}}) => {
213 // console.log(` ${phase}: ${section}.${method}:: ${data}`);
214 if (method == 'ExtrinsicSuccess') {
215 success = true;
216 } else if ((section == 'common') && (method == 'ItemCreated')) {
217 collectionId = parseInt(data[0].toString(), 10);
218 itemId = parseInt(data[1].toString(), 10);
219 recipient = normalizeAccountId(data[2].toJSON() as any);
220
221 const itemRes: CreateItemResult = {
222 success,
223 collectionId,
224 itemId,
225 recipient,
226 };
227
228 results.push(itemRes);
229 }
230 });
231
232 return results;
233}
203234
204export function getCreateItemResult(events: EventRecord[]): CreateItemResult {235export function getCreateItemResult(events: EventRecord[]): CreateItemResult {
205 let success = false;236 let success = false;
263294
264type CollectionMode = Nft | Fungible | ReFungible;295type CollectionMode = Nft | Fungible | ReFungible;
296
297export type Property = {
298 key: any,
299 value: any,
300};
301
302type PropertyPermission = {
303 key: any,
304 mutable: boolean;
305 collectionAdmin: boolean;
306 tokenOwner: boolean;
307}
265308
266export type CreateCollectionParams = {309export type CreateCollectionParams = {
267 mode: CollectionMode,310 mode: CollectionMode,
268 name: string,311 name: string,
269 description: string,312 description: string,
270 tokenPrefix: string,313 tokenPrefix: string,
271 schemaVersion: string,314 schemaVersion: string,
315 properties?: Array<Property>,
316 propPerm?: Array<PropertyPermission>
272};317};
273318
274const defaultCreateCollectionParams: CreateCollectionParams = {319const defaultCreateCollectionParams: CreateCollectionParams = {
333 return collectionId;378 return collectionId;
334}379}
380
381export async function createCollectionWithPropsExpectSuccess(params: Partial<CreateCollectionParams> = {}): Promise<number> {
382 const {name, description, mode, tokenPrefix} = {...defaultCreateCollectionParams, ...params};
383
384 let collectionId = 0;
385 await usingApi(async (api) => {
386 // Get number of collections before the transaction
387 const collectionCountBefore = await getCreatedCollectionCount(api);
388
389 // Run the CreateCollection transaction
390 const alicePrivateKey = privateKey('//Alice');
391
392 let modeprm = {};
393 if (mode.type === 'NFT') {
394 modeprm = {nft: null};
395 } else if (mode.type === 'Fungible') {
396 modeprm = {fungible: mode.decimalPoints};
397 } else if (mode.type === 'ReFungible') {
398 modeprm = {refungible: null};
399 }
400
401 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});
402 const events = await submitTransactionAsync(alicePrivateKey, tx);
403 const result = getCreateCollectionResult(events);
404
405 // Get number of collections after the transaction
406 const collectionCountAfter = await getCreatedCollectionCount(api);
407
408 // Get the collection
409 const collection = await queryCollectionExpectSuccess(api, result.collectionId);
410
411 // What to expect
412 // tslint:disable-next-line:no-unused-expression
413 expect(result.success).to.be.true;
414 expect(result.collectionId).to.be.equal(collectionCountAfter);
415 // tslint:disable-next-line:no-unused-expression
416 expect(collection).to.be.not.null;
417 expect(collectionCountAfter).to.be.equal(collectionCountBefore + 1, 'Error: NFT collection NOT created.');
418 expect(collection.owner.toString()).to.be.equal(toSubstrateAddress(alicesPublicKey));
419 expect(utf16ToStr(collection.name.toJSON() as any)).to.be.equal(name);
420 expect(utf16ToStr(collection.description.toJSON() as any)).to.be.equal(description);
421 expect(hexToStr(collection.tokenPrefix.toJSON())).to.be.equal(tokenPrefix);
422
423
424 collectionId = result.collectionId;
425 });
426
427 return collectionId;
428}
429
430export async function createCollectionWithPropsExpectFailure(params: Partial<CreateCollectionParams> = {}) {
431 const {name, description, mode, tokenPrefix} = {...defaultCreateCollectionParams, ...params};
432
433 const collectionId = 0;
434 await usingApi(async (api) => {
435 // Get number of collections before the transaction
436 const collectionCountBefore = await getCreatedCollectionCount(api);
437
438 // Run the CreateCollection transaction
439 const alicePrivateKey = privateKey('//Alice');
440
441 let modeprm = {};
442 if (mode.type === 'NFT') {
443 modeprm = {nft: null};
444 } else if (mode.type === 'Fungible') {
445 modeprm = {fungible: mode.decimalPoints};
446 } else if (mode.type === 'ReFungible') {
447 modeprm = {refungible: null};
448 }
449
450 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});
451 await expect(submitTransactionExpectFailAsync(alicePrivateKey, tx)).to.be.rejected;
452
453
454 // Get number of collections after the transaction
455 const collectionCountAfter = await getCreatedCollectionCount(api);
456
457 expect(collectionCountAfter).to.be.equal(collectionCountBefore, 'Error: Collection with incorrect data created.');
458 });
459}
335460
336export async function createCollectionExpectFailure(params: Partial<CreateCollectionParams> = {}) {461export async function createCollectionExpectFailure(params: Partial<CreateCollectionParams> = {}) {
337 const {name, description, mode, tokenPrefix} = {...defaultCreateCollectionParams, ...params};462 const {name, description, mode, tokenPrefix} = {...defaultCreateCollectionParams, ...params};