1import {expect} from 'chai';2import privateKey from '../substrate/privateKey';3import usingApi, {executeTransaction} from '../substrate/substrate-api';4import {5 addCollectionAdminExpectSuccess,6 createCollectionExpectSuccess,7 createItemExpectSuccess,8 getCreateCollectionResult,9 transferExpectSuccess,10} from '../util/helpers';11import {IKeyringPair} from '@polkadot/types/types';1213let alice: IKeyringPair;14let bob: IKeyringPair;15let charlie: IKeyringPair;16171819describe('Integration Test: Collection Properties', () => {20 before(async () => {21 alice = privateKey('//Alice');22 bob = privateKey('//Bob');23 });2425 it('Reads properties from a collection', async () => {26 await usingApi(async api => {27 const collection = await createCollectionExpectSuccess();28 const properties = (await api.query.common.collectionProperties(collection)).toJSON();29 expect(properties.map).to.be.empty;30 expect(properties.consumedSpace).to.equal(0);31 });32 });3334 it('Sets properties for a collection', async () => {35 await usingApi(async api => {36 const events = await executeTransaction(api, bob, api.tx.unique.createCollectionEx({mode: 'NFT'}));37 const {collectionId} = getCreateCollectionResult(events);3839 40 await expect(executeTransaction(41 api, 42 bob, 43 api.tx.unique.setCollectionProperties(collectionId, [{key: 'electron', value: 'come bond'}]), 44 )).to.not.be.rejected;4546 await addCollectionAdminExpectSuccess(bob, collectionId, alice.address);4748 49 await expect(executeTransaction(50 api, 51 alice, 52 api.tx.unique.setCollectionProperties(collectionId, [{key: 'black hole'}]), 53 )).to.not.be.rejected;5455 const properties = (await api.rpc.unique.collectionProperties(collectionId, ['electron', 'black hole'])).toJSON();56 expect(properties).to.be.deep.equal([57 {key: `0x${Buffer.from('electron').toString('hex')}`, value: `0x${Buffer.from('come bond').toString('hex')}`},58 {key: `0x${Buffer.from('black hole').toString('hex')}`, value: `0x${Buffer.from('').toString('hex')}`},59 ]);60 });61 });6263 it('Changes properties of a collection', async () => {64 await usingApi(async api => {65 const collection = await createCollectionExpectSuccess();6667 await expect(executeTransaction(68 api, 69 alice, 70 api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'come bond'}, {key: 'black hole'}]), 71 )).to.not.be.rejected;7273 74 await expect(executeTransaction(75 api, 76 alice, 77 api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'bonded'}, {key: 'black hole', value: 'LIGO'}]), 78 )).to.not.be.rejected;7980 const properties = (await api.rpc.unique.collectionProperties(collection, ['electron', 'black hole'])).toJSON();81 expect(properties).to.be.deep.equal([82 {key: `0x${Buffer.from('electron').toString('hex')}`, value: `0x${Buffer.from('bonded').toString('hex')}`},83 {key: `0x${Buffer.from('black hole').toString('hex')}`, value: `0x${Buffer.from('LIGO').toString('hex')}`},84 ]);85 });86 });8788 it('Deletes properties of a collection', async () => {89 await usingApi(async api => {90 const collection = await createCollectionExpectSuccess();9192 await expect(executeTransaction(93 api, 94 alice, 95 api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'come bond'}, {key: 'black hole', value: 'LIGO'}]), 96 )).to.not.be.rejected;9798 await expect(executeTransaction(99 api, 100 alice, 101 api.tx.unique.deleteCollectionProperties(collection, ['electron']), 102 )).to.not.be.rejected;103104 const properties = (await api.rpc.unique.collectionProperties(collection, ['electron', 'black hole'])).toJSON();105 expect(properties).to.be.deep.equal([106 {key: `0x${Buffer.from('black hole').toString('hex')}`, value: `0x${Buffer.from('LIGO').toString('hex')}`},107 ]);108 });109 });110});111112describe('Negative Integration Test: Collection Properties', () => {113 before(async () => {114 alice = privateKey('//Alice');115 bob = privateKey('//Bob');116 });117 118 it('Fails to set properties in a collection if not its onwer/administrator', async () => {119 await usingApi(async api => {120 const collection = await createCollectionExpectSuccess();121122 await expect(executeTransaction(123 api, 124 bob, 125 api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'come bond'}, {key: 'black hole', value: 'LIGO'}]), 126 )).to.be.rejectedWith(/common\.NoPermission/);127 128 const properties = (await api.query.common.collectionProperties(collection)).toJSON();129 expect(properties.map).to.be.empty;130 expect(properties.consumedSpace).to.equal(0);131 });132 });133 134 it('Fails to set properties that exceed the limits', async () => {135 await usingApi(async api => {136 const collection = await createCollectionExpectSuccess();137 const spaceLimit = (await api.query.common.collectionProperties(collection)).toJSON().spaceLimit as number; 138139 140 {141 console.error = () => {};142 await expect(executeTransaction(143 api, 144 alice, 145 api.tx.unique.setCollectionProperties(collection, [{key: 'electron', value: 'low high '.repeat(Math.ceil(spaceLimit! / 9))}]), 146 )).to.be.rejected;147 }148149 let properties = (await api.rpc.unique.collectionProperties(collection, ['electron'])).toJSON();150 expect(properties).to.be.empty;151152 await expect(executeTransaction(153 api, 154 alice, 155 api.tx.unique.setCollectionProperties(collection, [156 {key: 'electron', value: 'low high '.repeat(Math.ceil(spaceLimit! / 18))}, 157 {key: 'black hole', value: '0'.repeat(Math.ceil(spaceLimit! / 2))}, 158 ]), 159 )).to.be.rejectedWith(/common\.NoSpaceForProperty/);160161 properties = (await api.rpc.unique.collectionProperties(collection, ['electron', 'black hole'])).toJSON();162 expect(properties).to.be.empty;163 });164 });165 166 it('Fails to set more properties than it is allowed', async () => {167 await usingApi(async api => {168 const collection = await createCollectionExpectSuccess();169170 const propertiesToBeSet = [];171 for (let i = 0; i < 65; i++) {172 propertiesToBeSet.push({173 key: 'electron ' + i,174 value: Math.random() > 0.5 ? 'high' : 'low',175 });176 }177178 await expect(executeTransaction(179 api, 180 alice, 181 api.tx.unique.setCollectionProperties(collection, propertiesToBeSet), 182 )).to.be.rejectedWith(/common\.PropertyLimitReached/);183184 const properties = (await api.query.common.collectionProperties(collection)).toJSON();185 expect(properties.map).to.be.empty;186 expect(properties.consumedSpace).to.equal(0);187 });188 });189});190191192193describe('Integration Test: Access Rights to Token Properties', () => {194 before(async () => {195 alice = privateKey('//Alice');196 bob = privateKey('//Bob');197 });198 199 it('Reads access rights to properties of a collection', async () => {200 await usingApi(async api => {201 const collection = await createCollectionExpectSuccess();202 const propertyRights = (await api.query.common.collectionPropertyPermissions(collection)).toJSON();203 expect(propertyRights).to.be.empty;204 });205 });206 207 it('Sets access rights to properties of a collection', async () => {208 await usingApi(async api => {209 const collection = await createCollectionExpectSuccess();210211 await expect(executeTransaction(212 api, 213 alice, 214 api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: true}}]), 215 )).to.not.be.rejected;216217 await addCollectionAdminExpectSuccess(alice, collection, bob.address);218219 await expect(executeTransaction(220 api, 221 alice, 222 api.tx.unique.setPropertyPermissions(collection, [{key: 'mindgame', permission: {collectionAdmin: true, tokenOwner: false}}]), 223 )).to.not.be.rejected;224225 const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery', 'mindgame'])).toJSON();226 expect(propertyRights).to.be.deep.equal([227 {key: `0x${Buffer.from('skullduggery').toString('hex')}`, permission: {'mutable': true, 'collectionAdmin': false, 'tokenOwner': false}},228 {key: `0x${Buffer.from('mindgame').toString('hex')}`, permission: {'mutable': false, 'collectionAdmin': true, 'tokenOwner': false}},229 ]);230 });231 });232 233 it('Changes access rights to properties of a collection', async () => {234 await usingApi(async api => {235 const collection = await createCollectionExpectSuccess();236237 await expect(executeTransaction(238 api, 239 alice, 240 api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: true, collectionAdmin: true}}]), 241 )).to.not.be.rejected;242243 await expect(executeTransaction(244 api, 245 alice, 246 api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]), 247 )).to.not.be.rejected;248249 const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery'])).toJSON();250 expect(propertyRights).to.be.deep.equal([251 {key: `0x${Buffer.from('skullduggery').toString('hex')}`, permission: {'mutable': false, 'collectionAdmin': false, 'tokenOwner': true}},252 ]);253 });254 });255});256257describe('Negative Integration Test: Access Rights to Token Properties', () => {258 before(async () => {259 alice = privateKey('//Alice');260 bob = privateKey('//Bob');261 });262263 it('Prevents from setting access rights to properties of a collection if not an onwer/admin', async () => {264 await usingApi(async api => {265 const collection = await createCollectionExpectSuccess();266267 await expect(executeTransaction(268 api, 269 bob, 270 api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: true, tokenOwner: true}}]), 271 )).to.be.rejectedWith(/common\.NoPermission/);272273 const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery'])).toJSON();274 expect(propertyRights).to.be.empty;275 });276 });277278 it('Prevents from adding too many possible properties', async () => {279 await usingApi(async api => {280 const collection = await createCollectionExpectSuccess();281282 const constitution = [];283 for (let i = 0; i < 65; i++) {284 constitution.push({285 key: 'property ' + i,286 permission: Math.random() > 0.5 ? {mutable: true, collectionAdmin: true, tokenOwner: true} : {},287 });288 }289290 await expect(executeTransaction(291 api, 292 alice, 293 api.tx.unique.setPropertyPermissions(collection, constitution), 294 )).to.be.rejectedWith(/common\.PropertyLimitReached/);295296 const propertyRights = (await api.query.common.collectionPropertyPermissions(collection)).toJSON();297 expect(propertyRights).to.be.empty;298 });299 });300301 it('Prevents access rights to be modified if constant', async () => {302 await usingApi(async api => {303 const collection = await createCollectionExpectSuccess();304305 await expect(executeTransaction(306 api, 307 alice, 308 api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {mutable: false, tokenOwner: true}}]), 309 )).to.not.be.rejected;310311 await expect(executeTransaction(312 api, 313 alice, 314 api.tx.unique.setPropertyPermissions(collection, [{key: 'skullduggery', permission: {}}]), 315 )).to.be.rejectedWith(/common\.NoPermission/);316317 const propertyRights = (await api.rpc.unique.propertyPermissions(collection, ['skullduggery'])).toJSON();318 expect(propertyRights).to.deep.equal([319 {key: `0x${Buffer.from('skullduggery').toString('hex')}`, permission: {'mutable': false, 'collectionAdmin': false, 'tokenOwner': true}},320 ]);321 });322 });323});324325326327describe('Integration Test: Token Properties', () => {328 let collection: number;329 let token: number;330 let permissions: {permission: any, signers: IKeyringPair[]}[];331332 before(async () => {333 alice = privateKey('//Alice');334 bob = privateKey('//Bob');335 charlie = privateKey('//Charlie');336337 permissions = [338 {permission: {mutable: true, collectionAdmin: true}, signers: [alice, bob]},339 {permission: {mutable: false, collectionAdmin: true}, signers: [alice, bob]},340 {permission: {mutable: true, tokenOwner: true}, signers: [charlie]},341 {permission: {mutable: false, tokenOwner: true}, signers: [charlie]},342 {permission: {mutable: true, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie]},343 {permission: {mutable: false, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie]},344 ];345 });346347 beforeEach(async () => {348 collection = await createCollectionExpectSuccess();349 token = await createItemExpectSuccess(alice, collection, 'NFT');350 await addCollectionAdminExpectSuccess(alice, collection, bob.address);351 await transferExpectSuccess(collection, token, alice, charlie);352 });353 354 it('Reads properties of a token', async () => {355 await usingApi(async api => {356 const collection = await createCollectionExpectSuccess();357 const token = await createItemExpectSuccess(alice, collection, 'NFT');358 359 const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();360 expect(properties.map).to.be.empty;361 expect(properties.consumedSpace).to.be.equal(0);362363 const tokenData = (await api.rpc.unique.tokenData(collection, token, ['anything'])).toJSON().properties;364 expect(tokenData).to.be.empty;365 });366 });367368 it('Assigns properties to a token according to permissions', async () => {369 await usingApi(async api => {370 const propertyKeys: string[] = [];371 let i = 0;372 for (const permission of permissions) {373 for (const signer of permission.signers) {374 const key = i + ' ' + signer.address;375 propertyKeys.push(key);376377 await expect(executeTransaction(378 api, 379 alice, 380 api.tx.unique.setPropertyPermissions(collection, [{key: key, permission: permission.permission}]), 381 ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;382383 await expect(executeTransaction(384 api, 385 signer, 386 api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin increase'}]), 387 ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;388 }389390 i++;391 }392393 const properties = (await api.rpc.unique.tokenProperties(collection, token, propertyKeys)).toJSON() as any[];394 const tokensData = (await api.rpc.unique.tokenData(collection, token, propertyKeys)).toJSON().properties as any[];395 for (let i = 0; i < properties.length; i++) {396 expect(properties[i].value).to.be.equal(`0x${Buffer.from('Serotonin increase').toString('hex')}`);397 expect(tokensData[i].value).to.be.equal(`0x${Buffer.from('Serotonin increase').toString('hex')}`);398 }399 });400 });401402 it('Changes properties of a token according to permissions', async () => {403 await usingApi(async api => {404 const propertyKeys: string[] = [];405 let i = 0;406 for (const permission of permissions) {407 if (!permission.permission.mutable) continue;408 409 for (const signer of permission.signers) {410 const key = i + ' ' + signer.address;411 propertyKeys.push(key);412413 await expect(executeTransaction(414 api, 415 alice, 416 api.tx.unique.setPropertyPermissions(collection, [{key: key, permission: permission.permission}]), 417 ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;418419 await expect(executeTransaction(420 api, 421 signer, 422 api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin increase'}]), 423 ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;424425 await expect(executeTransaction(426 api, 427 signer, 428 api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin stable'}]), 429 ), `on changing property ${i} by ${signer.address}`).to.not.be.rejected;430 }431432 i++;433 }434435 const properties = (await api.rpc.unique.tokenProperties(collection, token, propertyKeys)).toJSON() as any[];436 const tokensData = (await api.rpc.unique.tokenData(collection, token, propertyKeys)).toJSON().properties as any[];437 for (let i = 0; i < properties.length; i++) {438 expect(properties[i].value).to.be.equal(`0x${Buffer.from('Serotonin stable').toString('hex')}`);439 expect(tokensData[i].value).to.be.equal(`0x${Buffer.from('Serotonin stable').toString('hex')}`);440 }441 });442 });443444 it('Deletes properties of a token according to permissions', async () => {445 await usingApi(async api => {446 const propertyKeys: string[] = [];447 let i = 0;448449 for (const permission of permissions) {450 if (!permission.permission.mutable) continue;451 452 for (const signer of permission.signers) {453 const key = i + ' ' + signer.address;454 propertyKeys.push(key);455456 await expect(executeTransaction(457 api, 458 alice, 459 api.tx.unique.setPropertyPermissions(collection, [{key: key, permission: permission.permission}]), 460 ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;461462 await expect(executeTransaction(463 api, 464 signer, 465 api.tx.unique.setTokenProperties(collection, token, [{key: key, value: 'Serotonin increase'}]), 466 ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;467468 await expect(executeTransaction(469 api, 470 signer, 471 api.tx.unique.deleteTokenProperties(collection, token, [key]), 472 ), `on deleting property ${i} by ${signer.address}`).to.not.be.rejected;473 }474 475 i++;476 }477478 const properties = (await api.rpc.unique.tokenProperties(collection, token, propertyKeys)).toJSON() as any[];479 expect(properties).to.be.empty;480 const tokensData = (await api.rpc.unique.tokenData(collection, token, propertyKeys)).toJSON().properties as any[];481 expect(tokensData).to.be.empty;482 expect((await api.query.nonfungible.tokenProperties(collection, token)).toJSON().consumedSpace).to.be.equal(0);483 });484 });485});486487describe('Negative Integration Test: Token Properties', () => {488 let collection: number;489 let token: number;490 let originalSpace: number;491 let constitution: {permission: any, signers: IKeyringPair[], sinner: IKeyringPair}[];492493 before(async () => {494 alice = privateKey('//Alice');495 bob = privateKey('//Bob');496 charlie = privateKey('//Charlie');497 const dave = privateKey('//Dave');498499 constitution = [500 {permission: {mutable: true, collectionAdmin: true}, signers: [alice, bob], sinner: charlie},501 {permission: {mutable: false, collectionAdmin: true}, signers: [alice, bob], sinner: charlie},502 {permission: {mutable: true, tokenOwner: true}, signers: [charlie], sinner: alice},503 {permission: {mutable: false, tokenOwner: true}, signers: [charlie], sinner: alice},504 {permission: {mutable: true, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie], sinner: dave},505 {permission: {mutable: false, collectionAdmin: true, tokenOwner: true}, signers: [alice, bob, charlie], sinner: dave},506 ];507 });508509 beforeEach(async () => {510 collection = await createCollectionExpectSuccess();511 token = await createItemExpectSuccess(alice, collection, 'NFT');512 await addCollectionAdminExpectSuccess(alice, collection, bob.address);513 await transferExpectSuccess(collection, token, alice, charlie);514 515 await usingApi(async api => {516 let i = 0;517 for (const passage of constitution) {518 const signer = passage.signers[0];519 520 await expect(executeTransaction(521 api, 522 alice, 523 api.tx.unique.setPropertyPermissions(collection, [{key: i, permission: passage.permission}]), 524 ), `on setting permission ${i} by ${signer.address}`).to.not.be.rejected;525526 await expect(executeTransaction(527 api, 528 signer, 529 api.tx.unique.setTokenProperties(collection, token, [{key: i, value: 'Serotonin increase'}]), 530 ), `on adding property ${i} by ${signer.address}`).to.not.be.rejected;531532 i++;533 }534535 originalSpace = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON().consumedSpace as number;536 });537 });538539 it('Forbids changing/deleting properties of a token if the user is outside of permissions', async () => {540 await usingApi(async api => {541 let i = -1;542 for (const forbiddance of constitution) {543 i++;544 if (!forbiddance.permission.mutable) continue;545546 await expect(executeTransaction(547 api, 548 forbiddance.sinner, 549 api.tx.unique.setTokenProperties(collection, token, [{key: i, value: 'Serotonin down'}]), 550 ), `on failing to change property ${i} by ${forbiddance.sinner.address}`).to.be.rejectedWith(/common\.NoPermission/);551552 await expect(executeTransaction(553 api, 554 forbiddance.sinner, 555 api.tx.unique.deleteTokenProperties(collection, token, [forbiddance.permission]), 556 ), `on failing to delete property ${i} by ${forbiddance.sinner.address}`).to.be.rejectedWith(/common\.NoPermission/);557 }558559 560 const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();561 expect(properties.consumedSpace).to.be.equal(originalSpace);562 });563 });564565 it('Forbids changing/deleting properties of a token if the property is permanent (constant)', async () => {566 await usingApi(async api => {567 let i = -1;568 for (const permission of constitution) {569 i++;570 if (permission.permission.mutable) continue;571572 await expect(executeTransaction(573 api, 574 permission.signers[0], 575 api.tx.unique.setTokenProperties(collection, token, [{key: i, value: 'Serotonin down'}]), 576 ), `on failing to change property ${i} by ${permission.signers[0].address}`).to.be.rejectedWith(/common\.NoPermission/);577578 await expect(executeTransaction(579 api, 580 permission.signers[0], 581 api.tx.unique.deleteTokenProperties(collection, token, [i.toString()]), 582 ), `on failing to delete property ${i} by ${permission.signers[0].address}`).to.be.rejectedWith(/common\.NoPermission/);583 }584585 586 const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();587 expect(properties.consumedSpace).to.be.equal(originalSpace);588 });589 });590591 it('Forbids adding properties to a token if the property is not declared / forbidden with the \'None\' permission', async () => {592 await usingApi(async api => {593 await expect(executeTransaction(594 api, 595 alice, 596 api.tx.unique.setTokenProperties(collection, token, [{key: 'non-existent', value: 'I exist!'}]), 597 ), 'on failing to add a previously non-existent property').to.be.rejectedWith(/common\.NoPermission/);598 599 await expect(executeTransaction(600 api, 601 alice, 602 api.tx.unique.setPropertyPermissions(collection, [{key: 'now-existent', permission: {}}]), 603 ), 'on setting a new non-permitted property').to.not.be.rejected;604605 await expect(executeTransaction(606 api, 607 alice, 608 api.tx.unique.setTokenProperties(collection, token, [{key: 'now-existent', value: 'I exist!'}]), 609 ), 'on failing to add a property forbidden by the \'None\' permission').to.be.rejectedWith(/common\.NoPermission/);610611 expect((await api.rpc.unique.tokenProperties(collection, token, ['non-existent', 'now-existent'])).toJSON()).to.be.empty;612 const properties = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();613 expect(properties.consumedSpace).to.be.equal(originalSpace);614 });615 });616617 it('Forbids adding too many properties to a token', async () => {618 await usingApi(async api => {619 await expect(executeTransaction(620 api, 621 alice, 622 api.tx.unique.setPropertyPermissions(collection, [623 {key: 'a holy book', permission: {collectionAdmin: true, tokenOwner: true}}, 624 {key: 'young years', permission: {collectionAdmin: true, tokenOwner: true}},625 ]), 626 ), 'on setting a new non-permitted property').to.not.be.rejected;627628 629 {630 console.error = () => {};631 await expect(executeTransaction(632 api, 633 alice, 634 api.tx.unique.setCollectionProperties(collection, [{key: 'a holy book', value: 'word '.repeat(6554)}]), 635 )).to.be.rejected;636 }637638 await expect(executeTransaction(639 api, 640 alice, 641 api.tx.unique.setTokenProperties(collection, token, [642 {key: 'a holy book', value: 'word '.repeat(3277)}, 643 {key: 'young years', value: 'neverending'.repeat(1490)},644 ]), 645 )).to.be.rejectedWith(/common\.NoSpaceForProperty/);646647 expect((await api.rpc.unique.tokenProperties(collection, token, ['a holy book', 'young years'])).toJSON()).to.be.empty;648 const propertiesMap = (await api.query.nonfungible.tokenProperties(collection, token)).toJSON();649 expect(propertiesMap.consumedSpace).to.be.equal(originalSpace);650 });651 });652});