1234567891011121314151617import {expect} from 'chai';18import usingApi, {executeTransaction} from './substrate/substrate-api';19import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, getBalance, getLastTokenId} from './util/helpers';2021describe('Integration Test: createMultipleItemsEx', () => {22 it('can initialize multiple NFT with different owners', async () => {23 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});24 await usingApi(async (api, privateKeyWrapper) => {25 const alice = privateKeyWrapper('//Alice');26 const bob = privateKeyWrapper('//Bob');27 const charlie = privateKeyWrapper('//Charlie');28 const data = [29 {30 owner: {substrate: alice.address},31 }, {32 owner: {substrate: bob.address},33 }, {34 owner: {substrate: charlie.address},35 },36 ];3738 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {39 NFT: data,40 }));41 const tokens = await api.query.nonfungible.tokenData.entries(collection);42 const json = tokens.map(([, token]) => token.toJSON());43 expect(json).to.be.deep.equal(data);44 });45 });4647 it('createMultipleItemsEx with property Admin', async () => {48 const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});49 await usingApi(async (api, privateKeyWrapper) => {50 const alice = privateKeyWrapper('//Alice');51 const bob = privateKeyWrapper('//Bob');52 const charlie = privateKeyWrapper('//Charlie');53 const data = [54 {55 owner: {substrate: alice.address},56 properties: [{key: 'k', value: 'v1'}],57 }, {58 owner: {substrate: bob.address},59 properties: [{key: 'k', value: 'v2'}],60 }, {61 owner: {substrate: charlie.address},62 properties: [{key: 'k', value: 'v3'}],63 },64 ];6566 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {67 NFT: data,68 }));69 for (let i = 1; i < 4; i++) {70 expect(await api.rpc.unique.tokenProperties(collection, i)).not.to.be.empty;71 }72 });73 });7475 it('createMultipleItemsEx with property AdminConst', async () => {76 const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]});77 await usingApi(async (api, privateKeyWrapper) => {78 const alice = privateKeyWrapper('//Alice');79 const bob = privateKeyWrapper('//Bob');80 const charlie = privateKeyWrapper('//Charlie');81 const data = [82 {83 owner: {substrate: alice.address},84 properties: [{key: 'k', value: 'v1'}],85 }, {86 owner: {substrate: bob.address},87 properties: [{key: 'k', value: 'v2'}],88 }, {89 owner: {substrate: charlie.address},90 properties: [{key: 'k', value: 'v3'}],91 },92 ];9394 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {95 NFT: data,96 }));97 for (let i = 1; i < 4; i++) {98 expect(await api.rpc.unique.tokenProperties(collection, i)).not.to.be.empty;99 }100 });101 });102103 it('createMultipleItemsEx with property itemOwnerOrAdmin', async () => {104 const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: true}}]});105 await usingApi(async (api, privateKeyWrapper) => {106 const alice = privateKeyWrapper('//Alice');107 const bob = privateKeyWrapper('//Bob');108 const charlie = privateKeyWrapper('//Charlie');109 const data = [110 {111 owner: {substrate: alice.address},112 properties: [{key: 'k', value: 'v1'}],113 }, {114 owner: {substrate: bob.address},115 properties: [{key: 'k', value: 'v2'}],116 }, {117 owner: {substrate: charlie.address},118 properties: [{key: 'k', value: 'v3'}],119 },120 ];121122 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {123 NFT: data,124 }));125 for (let i = 1; i < 4; i++) {126 expect(await api.rpc.unique.tokenProperties(collection, i)).not.to.be.empty;127 }128 });129 });130131 it('can initialize fungible with multiple owners', async () => {132 const collection = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});133 await usingApi(async (api, privateKeyWrapper) => {134 const alice = privateKeyWrapper('//Alice');135 const bob = privateKeyWrapper('//Bob');136137 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {138 Fungible: new Map([139 [JSON.stringify({Substrate: alice.address}), 50],140 [JSON.stringify({Substrate: bob.address}), 100],141 ]),142 }));143144 expect(await getBalance(api, collection, alice.address, 0)).to.equal(50n);145 expect(await getBalance(api, collection, bob.address, 0)).to.equal(100n);146 });147 });148149 it('can initialize an RFT with multiple owners', async () => {150 const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});151 await usingApi(async (api, privateKeyWrapper) => {152 const alice = privateKeyWrapper('//Alice');153 const bob = privateKeyWrapper('//Bob');154155 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {156 RefungibleMultipleOwners: {157 users: new Map([158 [JSON.stringify({Substrate: alice.address}), 1],159 [JSON.stringify({Substrate: bob.address}), 2],160 ]),161 },162 }));163164 const itemsListIndexAfter = await getLastTokenId(api, collection);165 expect(itemsListIndexAfter).to.be.equal(1);166167 expect(await getBalance(api, collection, alice.address, 1)).to.be.equal(1n);168 expect(await getBalance(api, collection, bob.address, 1)).to.be.equal(2n);169 });170 });171172 it('can initialize multiple RFTs with the same owner', async () => {173 const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});174 await usingApi(async (api, privateKeyWrapper) => {175 const alice = privateKeyWrapper('//Alice');176177 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {178 RefungibleMultipleItems: [179 {user: {Substrate: alice.address}, pieces: 1},180 {user: {Substrate: alice.address}, pieces: 3},181 ],182 }));183184 const itemsListIndexAfter = await getLastTokenId(api, collection);185 expect(itemsListIndexAfter).to.be.equal(2);186187 expect(await getBalance(api, collection, alice.address, 1)).to.be.equal(1n);188 expect(await getBalance(api, collection, alice.address, 2)).to.be.equal(3n);189 });190 });191});192193describe('Negative test: createMultipleItemsEx', () => {194 it('No editing rights', async () => {195 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],196 propPerm: [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}]});197 await usingApi(async (api, privateKeyWrapper) => {198 const alice = privateKeyWrapper('//Alice');199 const bob = privateKeyWrapper('//Bob');200 const charlie = privateKeyWrapper('//Charlie');201 await addCollectionAdminExpectSuccess(alice, collection, bob.address);202 const data = [203 {204 owner: {substrate: alice.address},205 properties: [{key: 'key1', value: 'v2'}],206 }, {207 owner: {substrate: bob.address},208 properties: [{key: 'key1', value: 'v2'}],209 }, {210 owner: {substrate: charlie.address},211 properties: [{key: 'key1', value: 'v2'}],212 },213 ];214215 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});216 217218 219 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);220 });221 });222223 it('User doesnt have editing rights', async () => {224 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],225 propPerm: [{key: 'key1', permission: {mutable: false, collectionAdmin: false, tokenOwner: false}}]});226 await usingApi(async (api, privateKeyWrapper) => {227 const alice = privateKeyWrapper('//Alice');228 const bob = privateKeyWrapper('//Bob');229 await addCollectionAdminExpectSuccess(alice, collection, bob.address);230 const data = [231 {232 owner: {substrate: alice.address},233 properties: [{key: 'key1', value: 'v2'}],234 }, {235 owner: {substrate: alice.address},236 properties: [{key: 'key1', value: 'v2'}],237 }, {238 owner: {substrate: alice.address},239 properties: [{key: 'key1', value: 'v2'}],240 },241 ];242243 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});244 245246 247 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);248 });249 });250251 it('Adding property without access rights', async () => {252 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}]});253 await usingApi(async (api, privateKeyWrapper) => {254 const alice = privateKeyWrapper('//Alice');255 const bob = privateKeyWrapper('//Bob');256 const charlie = privateKeyWrapper('//Charlie');257 await addCollectionAdminExpectSuccess(alice, collection, bob.address);258 const data = [259 {260 owner: {substrate: alice.address},261 properties: [{key: 'key1', value: 'v2'}],262 }, {263 owner: {substrate: bob.address},264 properties: [{key: 'key1', value: 'v2'}],265 }, {266 owner: {substrate: charlie.address},267 properties: [{key: 'key1', value: 'v2'}],268 },269 ];270271 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});272273 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);274 275 });276 });277278 it('Adding more than 64 properties', async () => {279 const propPerms = [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}];280281 for (let i = 0; i < 65; i++) {282 propPerms.push({key: `key${i}`, permission: {mutable: true, collectionAdmin: true, tokenOwner: true}});283 }284285 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});286 await usingApi(async (api, privateKeyWrapper) => {287 const alice = privateKeyWrapper('//Alice');288 await expect(executeTransaction(api, alice, api.tx.unique.setTokenPropertyPermissions(collection, propPerms))).to.be.rejectedWith(/common\.PropertyLimitReached/);289 });290 });291292 it('Trying to add bigger property than allowed', async () => {293 const collection = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});294 await usingApi(async (api, privateKeyWrapper) => {295 const alice = privateKeyWrapper('//Alice');296 const bob = privateKeyWrapper('//Bob');297 const charlie = privateKeyWrapper('//Charlie');298 await addCollectionAdminExpectSuccess(alice, collection, bob.address);299 const data = [300 {301 owner: {substrate: alice.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],302 }, {303 owner: {substrate: bob.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],304 }, {305 owner: {substrate: charlie.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],306 },307 ];308309 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});310311 312 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);313 });314 });315316 it('can initialize multiple NFT with different owners', async () => {317 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});318 await usingApi(async (api, privateKeyWrapper) => {319 const alice = privateKeyWrapper('//Alice');320 const bob = privateKeyWrapper('//Bob');321 const charlie = privateKeyWrapper('//Charlie');322 const data = [323 {324 owner: {substrate: alice.address},325 }, {326 owner: {substrate: bob.address},327 }, {328 owner: {substrate: charlie.address},329 },330 ];331332 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {333 NFT: data,334 }));335 const tokens = await api.query.nonfungible.tokenData.entries(collection);336 const json = tokens.map(([, token]) => token.toJSON());337 expect(json).to.be.deep.equal(data);338 });339 });340341 it('can initialize multiple NFT with different owners', async () => {342 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});343 await usingApi(async (api, privateKeyWrapper) => {344 const alice = privateKeyWrapper('//Alice');345 const bob = privateKeyWrapper('//Bob');346 const charlie = privateKeyWrapper('//Charlie');347 const data = [348 {349 owner: {substrate: alice.address},350 }, {351 owner: {substrate: bob.address},352 }, {353 owner: {substrate: charlie.address},354 },355 ];356357 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {358 NFT: data,359 }));360 const tokens = await api.query.nonfungible.tokenData.entries(collection);361 const json = tokens.map(([, token]) => token.toJSON());362 expect(json).to.be.deep.equal(data);363 });364 });365366 it('fails when trying to set multiple owners when creating multiple refungibles', async () => {367 const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});368369 await usingApi(async (api, privateKeyWrapper) => {370 const alice = privateKeyWrapper('//Alice');371 const bob = privateKeyWrapper('//Bob');372 373 const users = new Map();374 users.set(JSON.stringify({substrate: alice.address}), 1);375 users.set(JSON.stringify({substrate: bob.address}), 1);376377 378 await expect(executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {379 RefungibleMultipleItems: [380 {users},381 {users},382 ],383 }))).to.be.rejectedWith(/^refungible\.NotRefungibleDataUsedToMintFungibleCollectionToken$/);384 });385 });386});