difftreelog
test transfer already nested token + destroy a non-empty collection + additional refactoring
in: master
7 files changed
tests/package.jsondiffbeforeafterboth--- a/tests/package.json
+++ b/tests/package.json
@@ -54,6 +54,7 @@
"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",
+ "testDestroyCollection": "mocha --timeout 9999999 -r ts-node/register ./**/destroyCollection.test.ts",
"testToggleContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/toggleContractAllowList.test.ts",
"testAddToContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/addToContractAllowList.test.ts",
"testTransfer": "mocha --timeout 9999999 -r ts-node/register ./**/transfer.test.ts",
tests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {expect} from 'chai';18import privateKey from './substrate/privateKey';19import usingApi, {executeTransaction} from './substrate/substrate-api';20import {createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, addCollectionAdminExpectSuccess} from './util/helpers';2122describe('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 }, {34 owner: {substrate: bob.address},35 // constData: '0x2222',36 }, {37 owner: {substrate: charlie.address},38 // constData: '0x4444',39 },40 ];4142 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {43 NFT: data,44 }));45 const tokens = await api.query.nonfungible.tokenData.entries(collection);46 const json = tokens.map(([, token]) => token.toJSON());47 expect(json).to.be.deep.equal(data);48 });49 });5051 it('createMultipleItemsEx with property Admin', async () => {52 const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});53 const alice = privateKey('//Alice');54 const bob = privateKey('//Bob');55 const charlie = privateKey('//Charlie');56 await usingApi(async (api) => {57 const data = [58 {59 owner: {substrate: alice.address},60 // constData: '0x1111',61 properties: [{key: 'k', value: 'v1'}],62 }, {63 owner: {substrate: bob.address},64 // constData: '0x2222',65 properties: [{key: 'k', value: 'v2'}],66 }, {67 owner: {substrate: charlie.address},68 // constData: '0x4444',69 properties: [{key: 'k', value: 'v3'}],70 },71 ];7273 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {74 NFT: data,75 }));76 for (let i = 1; i < 4; i++) {77 expect(await api.rpc.unique.tokenProperties(collection, i)).not.to.be.empty;78 }79 });80 });8182 it('createMultipleItemsEx with property AdminConst', async () => {83 const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]});84 const alice = privateKey('//Alice');85 const bob = privateKey('//Bob');86 const charlie = privateKey('//Charlie');87 await usingApi(async (api) => {88 const data = [89 {90 owner: {substrate: alice.address},91 // constData: '0x0000',92 properties: [{key: 'k', value: 'v1'}],93 }, {94 owner: {substrate: bob.address},95 // constData: '0x2222',96 properties: [{key: 'k', value: 'v2'}],97 }, {98 owner: {substrate: charlie.address},99 // constData: '0x4444',100 properties: [{key: 'k', value: 'v3'}],101 },102 ];103104 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {105 NFT: data,106 }));107 for (let i = 1; i < 4; i++) {108 expect(await api.rpc.unique.tokenProperties(collection, i)).not.to.be.empty;109 }110 });111 });112113 it('createMultipleItemsEx with property itemOwnerOrAdmin', async () => {114 const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: true}}]});115 const alice = privateKey('//Alice');116 const bob = privateKey('//Bob');117 const charlie = privateKey('//Charlie');118 await usingApi(async (api) => {119 const data = [120 {121 owner: {substrate: alice.address},122 // constData: '0x0000',123 properties: [{key: 'k', value: 'v1'}],124 }, {125 owner: {substrate: bob.address},126 // constData: '0x2222',127 properties: [{key: 'k', value: 'v2'}],128 }, {129 owner: {substrate: charlie.address},130 // constData: '0x4444',131 properties: [{key: 'k', value: 'v3'}],132 },133 ];134135 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {136 NFT: data,137 }));138 for (let i = 1; i < 4; i++) {139 expect(await api.rpc.unique.tokenProperties(collection, i)).not.to.be.empty;140 }141 });142 });143144 it('No editing rights', async () => {145 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],146 propPerm: [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}]});147 const alice = privateKey('//Alice');148 const bob = privateKey('//Bob');149 const charlie = privateKey('//Charlie');150 await addCollectionAdminExpectSuccess(alice, collection, bob.address);151 await usingApi(async (api) => {152 const data = [153 {154 owner: {substrate: alice.address},155 properties: [{key: 'key1', value: 'v2'}],156 }, {157 owner: {substrate: bob.address},158 properties: [{key: 'key1', value: 'v2'}],159 }, {160 owner: {substrate: charlie.address},161 properties: [{key: 'key1', value: 'v2'}],162 },163 ];164165 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});166 // await executeTransaction(api, alice, tx);167168 //await submitTransactionExpectFailAsync(alice, tx);169 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);170 });171 });172173 it('User doesnt have editing rights', async () => {174 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],175 propPerm: [{key: 'key1', permission: {mutable: false, collectionAdmin: false, tokenOwner: false}}]});176 const alice = privateKey('//Alice');177 const bob = privateKey('//Bob');178 await addCollectionAdminExpectSuccess(alice, collection, bob.address);179 await usingApi(async (api) => {180 const data = [181 {182 owner: {substrate: alice.address},183 properties: [{key: 'key1', value: 'v2'}],184 }, {185 owner: {substrate: alice.address},186 properties: [{key: 'key1', value: 'v2'}],187 }, {188 owner: {substrate: alice.address},189 properties: [{key: 'key1', value: 'v2'}],190 },191 ];192193 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});194 // await executeTransaction(api, alice, tx);195196 //await submitTransactionExpectFailAsync(alice, tx);197 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);198 });199 });200201 it('Adding property without access rights', async () => {202 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}]});203 const alice = privateKey('//Alice');204 const bob = privateKey('//Bob');205 const charlie = privateKey('//Charlie');206 await addCollectionAdminExpectSuccess(alice, collection, bob.address);207 await usingApi(async (api) => {208 const data = [209 {210 owner: {substrate: alice.address},211 properties: [{key: 'key1', value: 'v2'}],212 }, {213 owner: {substrate: bob.address},214 properties: [{key: 'key1', value: 'v2'}],215 }, {216 owner: {substrate: charlie.address},217 properties: [{key: 'key1', value: 'v2'}],218 },219 ];220221 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});222223 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);224 //await submitTransactionExpectFailAsync(alice, tx);225 });226 });227228 it('Adding more than 64 properties', async () => {229 const propPerms = [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}];230231 for (let i = 0; i < 65; i++) {232 propPerms.push({key: `key${i}`, permission: {mutable: true, collectionAdmin: true, tokenOwner: true}});233 }234235 const alice = privateKey('//Alice');236 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});237 await usingApi(async (api) => {238 await expect(executeTransaction(api, alice, api.tx.unique.setPropertyPermissions(collection, propPerms))).to.be.rejectedWith(/common\.PropertyLimitReached/);239 });240 });241242 it('Trying to add bigger property than allowed', async () => {243 const collection = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});244 const alice = privateKey('//Alice');245 const bob = privateKey('//Bob');246 const charlie = privateKey('//Charlie');247 await addCollectionAdminExpectSuccess(alice, collection, bob.address);248 await usingApi(async (api) => {249 const data = [250 {251 owner: {substrate: alice.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],252 }, {253 owner: {substrate: bob.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],254 }, {255 owner: {substrate: charlie.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],256 },257 ];258259 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});260261 //await submitTransactionExpectFailAsync(alice, tx);262 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);263 });264 });265266 it('can initialize multiple NFT with different owners', async () => {267 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});268 const alice = privateKey('//Alice');269 const bob = privateKey('//Bob');270 const charlie = privateKey('//Charlie');271 await usingApi(async (api) => {272 const data = [273 {274 owner: {substrate: alice.address},275 // constData: '0x0000',276 }, {277 owner: {substrate: bob.address},278 // constData: '0x2222',279 }, {280 owner: {substrate: charlie.address},281 // constData: '0x4444',282 },283 ];284285 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {286 NFT: data,287 }));288 const tokens = await api.query.nonfungible.tokenData.entries(collection);289 const json = tokens.map(([, token]) => token.toJSON());290 expect(json).to.be.deep.equal(data);291 });292 });293294 it('can initialize multiple NFT with different owners', async () => {295 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});296 const alice = privateKey('//Alice');297 const bob = privateKey('//Bob');298 const charlie = privateKey('//Charlie');299 await usingApi(async (api) => {300 const data = [301 {302 owner: {substrate: alice.address},303 // constData: '0x0000',304 }, {305 owner: {substrate: bob.address},306 // constData: '0x2222',307 }, {308 owner: {substrate: charlie.address},309 // constData: '0x4444',310 },311 ];312313 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {314 NFT: data,315 }));316 const tokens = await api.query.nonfungible.tokenData.entries(collection);317 const json = tokens.map(([, token]) => token.toJSON());318 expect(json).to.be.deep.equal(data);319 });320 });321322 it('fails when trying to set multiple owners when creating multiple refungibles', async () => {323 const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});324 const alice = privateKey('//Alice');325 const bob = privateKey('//Bob');326327 await usingApi(async (api) => {328 // Polkadot requires map, and yet requires keys to be JSON encoded329 const users = new Map();330 users.set(JSON.stringify({substrate: alice.address}), 1);331 users.set(JSON.stringify({substrate: bob.address}), 1);332333 // TODO: better error message?334 await expect(executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {335 RefungibleMultipleItems: [336 {users},337 {users},338 ],339 }))).to.be.rejectedWith(/^refungible\.NotRefungibleDataUsedToMintFungibleCollectionToken$/);340 });341 });342});343'';1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {expect} from 'chai';18import privateKey from './substrate/privateKey';19import usingApi, {executeTransaction} from './substrate/substrate-api';20import {createCollectionExpectSuccess, createCollectionWithPropsExpectSuccess, addCollectionAdminExpectSuccess} from './util/helpers';2122describe('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 }, {33 owner: {substrate: bob.address},34 }, {35 owner: {substrate: charlie.address},36 },37 ];3839 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {40 NFT: data,41 }));42 const tokens = await api.query.nonfungible.tokenData.entries(collection);43 const json = tokens.map(([, token]) => token.toJSON());44 expect(json).to.be.deep.equal(data);45 });46 });4748 it('createMultipleItemsEx with property Admin', async () => {49 const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]});50 const alice = privateKey('//Alice');51 const bob = privateKey('//Bob');52 const charlie = privateKey('//Charlie');53 await usingApi(async (api) => {54 const data = [55 {56 owner: {substrate: alice.address},57 properties: [{key: 'k', value: 'v1'}],58 }, {59 owner: {substrate: bob.address},60 properties: [{key: 'k', value: 'v2'}],61 }, {62 owner: {substrate: charlie.address},63 properties: [{key: 'k', value: 'v3'}],64 },65 ];6667 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {68 NFT: data,69 }));70 for (let i = 1; i < 4; i++) {71 expect(await api.rpc.unique.tokenProperties(collection, i)).not.to.be.empty;72 }73 });74 });7576 it('createMultipleItemsEx with property AdminConst', async () => {77 const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]});78 const alice = privateKey('//Alice');79 const bob = privateKey('//Bob');80 const charlie = privateKey('//Charlie');81 await usingApi(async (api) => {82 const data = [83 {84 owner: {substrate: alice.address},85 properties: [{key: 'k', value: 'v1'}],86 }, {87 owner: {substrate: bob.address},88 properties: [{key: 'k', value: 'v2'}],89 }, {90 owner: {substrate: charlie.address},91 properties: [{key: 'k', value: 'v3'}],92 },93 ];9495 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {96 NFT: data,97 }));98 for (let i = 1; i < 4; i++) {99 expect(await api.rpc.unique.tokenProperties(collection, i)).not.to.be.empty;100 }101 });102 });103104 it('createMultipleItemsEx with property itemOwnerOrAdmin', async () => {105 const collection = await createCollectionWithPropsExpectSuccess({mode: {type: 'NFT'}, propPerm: [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: true}}]});106 const alice = privateKey('//Alice');107 const bob = privateKey('//Bob');108 const charlie = privateKey('//Charlie');109 await usingApi(async (api) => {110 const data = [111 {112 owner: {substrate: alice.address},113 properties: [{key: 'k', value: 'v1'}],114 }, {115 owner: {substrate: bob.address},116 properties: [{key: 'k', value: 'v2'}],117 }, {118 owner: {substrate: charlie.address},119 properties: [{key: 'k', value: 'v3'}],120 },121 ];122123 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {124 NFT: data,125 }));126 for (let i = 1; i < 4; i++) {127 expect(await api.rpc.unique.tokenProperties(collection, i)).not.to.be.empty;128 }129 });130 });131132 it('No editing rights', async () => {133 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],134 propPerm: [{key: 'key1', permission: {mutable: true, collectionAdmin: false, tokenOwner: false}}]});135 const alice = privateKey('//Alice');136 const bob = privateKey('//Bob');137 const charlie = privateKey('//Charlie');138 await addCollectionAdminExpectSuccess(alice, collection, bob.address);139 await usingApi(async (api) => {140 const data = [141 {142 owner: {substrate: alice.address},143 properties: [{key: 'key1', value: 'v2'}],144 }, {145 owner: {substrate: bob.address},146 properties: [{key: 'key1', value: 'v2'}],147 }, {148 owner: {substrate: charlie.address},149 properties: [{key: 'key1', value: 'v2'}],150 },151 ];152153 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});154 // await executeTransaction(api, alice, tx);155156 //await submitTransactionExpectFailAsync(alice, tx);157 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);158 });159 });160161 it('User doesnt have editing rights', async () => {162 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}],163 propPerm: [{key: 'key1', permission: {mutable: false, collectionAdmin: false, tokenOwner: false}}]});164 const alice = privateKey('//Alice');165 const bob = privateKey('//Bob');166 await addCollectionAdminExpectSuccess(alice, collection, bob.address);167 await usingApi(async (api) => {168 const data = [169 {170 owner: {substrate: alice.address},171 properties: [{key: 'key1', value: 'v2'}],172 }, {173 owner: {substrate: alice.address},174 properties: [{key: 'key1', value: 'v2'}],175 }, {176 owner: {substrate: alice.address},177 properties: [{key: 'key1', value: 'v2'}],178 },179 ];180181 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});182 // await executeTransaction(api, alice, tx);183184 //await submitTransactionExpectFailAsync(alice, tx);185 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);186 });187 });188189 it('Adding property without access rights', async () => {190 const collection = await createCollectionWithPropsExpectSuccess({properties: [{key: 'key1', value: 'v'}]});191 const alice = privateKey('//Alice');192 const bob = privateKey('//Bob');193 const charlie = privateKey('//Charlie');194 await addCollectionAdminExpectSuccess(alice, collection, bob.address);195 await usingApi(async (api) => {196 const data = [197 {198 owner: {substrate: alice.address},199 properties: [{key: 'key1', value: 'v2'}],200 }, {201 owner: {substrate: bob.address},202 properties: [{key: 'key1', value: 'v2'}],203 }, {204 owner: {substrate: charlie.address},205 properties: [{key: 'key1', value: 'v2'}],206 },207 ];208209 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});210211 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);212 //await submitTransactionExpectFailAsync(alice, tx);213 });214 });215216 it('Adding more than 64 properties', async () => {217 const propPerms = [{key: 'key', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}];218219 for (let i = 0; i < 65; i++) {220 propPerms.push({key: `key${i}`, permission: {mutable: true, collectionAdmin: true, tokenOwner: true}});221 }222223 const alice = privateKey('//Alice');224 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});225 await usingApi(async (api) => {226 await expect(executeTransaction(api, alice, api.tx.unique.setPropertyPermissions(collection, propPerms))).to.be.rejectedWith(/common\.PropertyLimitReached/);227 });228 });229230 it('Trying to add bigger property than allowed', async () => {231 const collection = await createCollectionWithPropsExpectSuccess({propPerm: [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]});232 const alice = privateKey('//Alice');233 const bob = privateKey('//Bob');234 const charlie = privateKey('//Charlie');235 await addCollectionAdminExpectSuccess(alice, collection, bob.address);236 await usingApi(async (api) => {237 const data = [238 {239 owner: {substrate: alice.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],240 }, {241 owner: {substrate: bob.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],242 }, {243 owner: {substrate: charlie.address}, properties: [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}],244 },245 ];246247 const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});248249 //await submitTransactionExpectFailAsync(alice, tx);250 await expect(executeTransaction(api, alice, tx)).to.be.rejectedWith(/common\.NoPermission/);251 });252 });253254 it('can initialize multiple NFT with different owners', async () => {255 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});256 const alice = privateKey('//Alice');257 const bob = privateKey('//Bob');258 const charlie = privateKey('//Charlie');259 await usingApi(async (api) => {260 const data = [261 {262 owner: {substrate: alice.address},263 }, {264 owner: {substrate: bob.address},265 }, {266 owner: {substrate: charlie.address},267 },268 ];269270 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {271 NFT: data,272 }));273 const tokens = await api.query.nonfungible.tokenData.entries(collection);274 const json = tokens.map(([, token]) => token.toJSON());275 expect(json).to.be.deep.equal(data);276 });277 });278279 it('can initialize multiple NFT with different owners', async () => {280 const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});281 const alice = privateKey('//Alice');282 const bob = privateKey('//Bob');283 const charlie = privateKey('//Charlie');284 await usingApi(async (api) => {285 const data = [286 {287 owner: {substrate: alice.address},288 }, {289 owner: {substrate: bob.address},290 }, {291 owner: {substrate: charlie.address},292 },293 ];294295 await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {296 NFT: data,297 }));298 const tokens = await api.query.nonfungible.tokenData.entries(collection);299 const json = tokens.map(([, token]) => token.toJSON());300 expect(json).to.be.deep.equal(data);301 });302 });303304 it('fails when trying to set multiple owners when creating multiple refungibles', async () => {305 const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});306 const alice = privateKey('//Alice');307 const bob = privateKey('//Bob');308309 await usingApi(async (api) => {310 // Polkadot requires map, and yet requires keys to be JSON encoded311 const users = new Map();312 users.set(JSON.stringify({substrate: alice.address}), 1);313 users.set(JSON.stringify({substrate: bob.address}), 1);314315 // TODO: better error message?316 await expect(executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {317 RefungibleMultipleItems: [318 {users},319 {users},320 ],321 }))).to.be.rejectedWith(/^refungible\.NotRefungibleDataUsedToMintFungibleCollectionToken$/);322 });323 });324});325'';tests/src/destroyCollection.test.tsdiffbeforeafterboth--- a/tests/src/destroyCollection.test.ts
+++ b/tests/src/destroyCollection.test.ts
@@ -25,6 +25,7 @@
setCollectionLimitsExpectSuccess,
addCollectionAdminExpectSuccess,
getCreatedCollectionCount,
+ createItemExpectSuccess,
} from './util/helpers';
chai.use(chaiAsPromised);
@@ -83,4 +84,10 @@
await destroyCollectionExpectFailure(collectionId, '//Alice');
});
+ it('fails when a collection still has a token', async () => {
+ const collectionId = await createCollectionExpectSuccess();
+ await createItemExpectSuccess(alice, collectionId, 'NFT');
+
+ await destroyCollectionExpectFailure(collectionId, '//Alice');
+ });
});
tests/src/nesting/migration-check.test.tsdiffbeforeafterboth--- a/tests/src/nesting/migration-check.test.ts
+++ b/tests/src/nesting/migration-check.test.ts
@@ -31,12 +31,12 @@
name: strToUTF16('Mojave Pictures'),
description: strToUTF16('$2.2 billion power plant!'),
tokenPrefix: '0x0002030',
- offchainSchema: '0x111111',
- schemaVersion: 'Unique',
+ //offchainSchema: '0x111111',
+ //schemaVersion: 'Unique',
limits: {
accountTokenOwnershipLimit: 3,
},
- constOnChainSchema: '0x333333',
+ //constOnChainSchema: '0x333333',
});
const events = await submitTransactionAsync(alice, tx);
const result = getCreateCollectionResult(events);
@@ -96,17 +96,17 @@
const collectionNew = (await api.query.common.collectionById(collectionId)).toJSON() as any;
// Make sure the extra fields are what they should be
- const constOnChainSchema = await api.query.common.collectionData(collectionId, 'ConstOnChainSchema');
- const offchainSchema = await api.query.common.collectionData(collectionId, 'OffchainSchema');
+ //const constOnChainSchema = await api.query.common.collectionData(collectionId, 'ConstOnChainSchema');
+ //const offchainSchema = await api.query.common.collectionData(collectionId, 'OffchainSchema');
- expect(constOnChainSchema.toHex()).to.be.deep.equal(collectionOld.constOnChainSchema);
- expect(offchainSchema.toHex()).to.be.deep.equal(collectionOld.offchainSchema);
+ //expect(constOnChainSchema.toHex()).to.be.deep.equal(collectionOld.constOnChainSchema);
+ //expect(offchainSchema.toHex()).to.be.deep.equal(collectionOld.offchainSchema);
expect(collectionNew).to.have.nested.property('limits.nestingRule');
// Get rid of extra fields to perform comparison on the rest of the collection
delete collectionNew.limits.nestingRule;
- delete collectionOld.constOnChainSchema;
- delete collectionOld.offchainSchema;
+ //delete collectionOld.constOnChainSchema;
+ //delete collectionOld.offchainSchema;
expect(collectionNew).to.be.deep.equal(collectionOld);
});
tests/src/nesting/nest.test.tsdiffbeforeafterboth--- a/tests/src/nesting/nest.test.ts
+++ b/tests/src/nesting/nest.test.ts
@@ -10,6 +10,7 @@
enablePublicMintingExpectSuccess,
getTokenOwner,
getTopmostTokenOwner,
+ normalizeAccountId,
setCollectionPermissionsExpectSuccess,
transferExpectFailure,
transferExpectSuccess,
@@ -28,7 +29,7 @@
});
});
- it('Performs the full suite: bundles a token, transfers, and allows to unnest', async () => {
+ it('Performs the full suite: bundles a token, transfers, and unnests', async () => {
await usingApi(async api => {
const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: 'Owner'});
@@ -58,6 +59,33 @@
});
});
+ it('Transfers an already bundled token', async () => {
+ await usingApi(async api => {
+ const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+ await setCollectionPermissionsExpectSuccess(alice, collection, {nesting: 'Owner'});
+
+ const tokenA = await createItemExpectSuccess(alice, collection, 'NFT');
+ const tokenB = await createItemExpectSuccess(alice, collection, 'NFT');
+
+ // Create a nested token
+ const tokenC = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, tokenA)});
+ expect(await getTopmostTokenOwner(api, collection, tokenC)).to.be.deep.equal({Substrate: alice.address});
+ expect(await getTokenOwner(api, collection, tokenC)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, tokenA).toLowerCase()});
+
+ // Transfer the nested token to another token
+ await expect(executeTransaction(
+ api,
+ alice,
+ api.tx.unique.transferFrom(
+ normalizeAccountId({Ethereum: tokenIdToAddress(collection, tokenA)}),
+ normalizeAccountId({Ethereum: tokenIdToAddress(collection, tokenB)}),
+ collection, tokenC, 1),
+ )).to.not.be.rejected;
+ expect(await getTopmostTokenOwner(api, collection, tokenC)).to.be.deep.equal({Substrate: alice.address});
+ expect(await getTokenOwner(api, collection, tokenC)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, tokenB).toLowerCase()});
+ });
+ });
+
// ---------- Non-Fungible ----------
it('NFT: allows an Owner to nest/unnest their token', async () => {
tests/src/setChainLimits.test.tsdiffbeforeafterboth--- a/tests/src/setChainLimits.test.ts
+++ b/tests/src/setChainLimits.test.ts
@@ -43,8 +43,6 @@
nftSponsorTransferTimeout: 1,
fungibleSponsorTransferTimeout: 1,
refungibleSponsorTransferTimeout: 1,
- offchainSchemaLimit: 1,
- constOnChainSchemaLimit: 1,
};
});
});
tests/src/util/helpers.tsdiffbeforeafterboth--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -135,8 +135,8 @@
nftSponsorTransferTimeout: number;
fungibleSponsorTransferTimeout: number;
refungibleSponsorTransferTimeout: number;
- offchainSchemaLimit: number;
- constOnChainSchemaLimit: number;
+ //offchainSchemaLimit: number;
+ //constOnChainSchemaLimit: number;
}
export interface IReFungibleTokenDataType {
@@ -310,7 +310,6 @@
name: string,
description: string,
tokenPrefix: string,
- schemaVersion: string,
properties?: Array<Property>,
propPerm?: Array<PropertyPermission>
};
@@ -320,7 +319,6 @@
mode: {type: 'NFT'},
name: 'name',
tokenPrefix: 'prefix',
- schemaVersion: 'ImageURL',
};
export async function createCollectionExpectSuccess(params: Partial<CreateCollectionParams> = {}): Promise<number> {
@@ -780,25 +778,8 @@
const result = getGenericResult(events);
expect(result.success).to.be.false;
- });
-}
-
-/*export async function setOffchainSchemaExpectSuccess(sender: IKeyringPair, collectionId: number, data: number[]) {
- await usingApi(async (api) => {
- const tx = api.tx.unique.setOffchainSchema(collectionId, '0x' + Buffer.from(data).toString('hex'));
- const events = await submitTransactionAsync(sender, tx);
- const result = getGenericResult(events);
-
- expect(result.success).to.be.true;
});
}
-
-export async function setOffchainSchemaExpectFailure(sender: IKeyringPair, collectionId: number, data: number[]) {
- await usingApi(async (api) => {
- const tx = api.tx.unique.setOffchainSchema(collectionId, '0x' + Buffer.from(data).toString('hex'));
- await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
- });
-}*/
export interface CreateFungibleData {
readonly Value: bigint;
@@ -1110,13 +1091,6 @@
): Promise<string[]> {
return (await api.rpc.unique.adminlist(collectionId)).toHuman() as any;
}
-/*export async function getConstMetadata(
- api: ApiPromise,
- collectionId: number,
- tokenId: number,
-): Promise<number[]> {
- return [...(await api.rpc.unique.constMetadata(collectionId, tokenId))];
-}*/
export async function getTokenProperties(
api: ApiPromise,
collectionId: number,