difftreelog
Check collection properties for each collection mode
in: master
1 file changed
tests/src/eth/collectionProperties.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 {itEth, usingEthPlaygrounds, expect} from './util';18import {Pallets} from '../util';19import {IProperty, ITokenPropertyPermission} from '../util/playgrounds/types';20import {IKeyringPair} from '@polkadot/types/types';2122describe('EVM collection properties', () => {23 let donor: IKeyringPair;24 let alice: IKeyringPair;2526 before(async function() {27 await usingEthPlaygrounds(async (_helper, privateKey) => {28 donor = await privateKey({filename: __filename});29 [alice] = await _helper.arrange.createAccounts([20n], donor);30 });31 });3233 // Soft-deprecated: setCollectionProperty34 [35 {method: 'setCollectionProperties', methodParams: [[{key: 'testKey1', value: Buffer.from('testValue1')}, {key: 'testKey2', value: Buffer.from('testValue2')}]], expectedProps: [{key: 'testKey1', value: 'testValue1'}, {key: 'testKey2', value: 'testValue2'}]}, 36 {method: 'setCollectionProperty', methodParams: ['testKey', Buffer.from('testValue')], expectedProps: [{key: 'testKey', value: 'testValue'}]},37 ].map(testCase => 38 itEth(`Collection properties can be set: ${testCase.method}`, async({helper}) => {39 const caller = await helper.eth.createAccountWithBalance(donor);40 const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties: []});41 await collection.addAdmin(alice, {Ethereum: caller});4243 const address = helper.ethAddress.fromCollectionId(collection.collectionId);44 const contract = helper.ethNativeContract.collection(address, 'nft', caller, testCase.method === 'setCollectionProperty');4546 await contract.methods[testCase.method](...testCase.methodParams).send({from: caller});4748 const raw = (await collection.getData())?.raw;49 expect(raw.properties).to.deep.equal(testCase.expectedProps);50 }));5152 itEth('Cannot set invalid properties', async({helper}) => {53 const caller = await helper.eth.createAccountWithBalance(donor);54 const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties: []});55 await collection.addAdmin(alice, {Ethereum: caller});5657 const address = helper.ethAddress.fromCollectionId(collection.collectionId);58 const contract = helper.ethNativeContract.collection(address, 'nft', caller);5960 await expect(contract.methods.setCollectionProperties([{key: '', value: Buffer.from('val1')}]).send({from: caller})).to.be.rejected;61 await expect(contract.methods.setCollectionProperties([{key: 'déjà vu', value: Buffer.from('hmm...')}]).send({from: caller})).to.be.rejected;62 await expect(contract.methods.setCollectionProperties([{key: 'a'.repeat(257), value: Buffer.from('val3')}]).send({from: caller})).to.be.rejected;63 // TODO add more expects64 const raw = (await collection.getData())?.raw;65 expect(raw.properties).to.deep.equal([]);66 });676869 // Soft-deprecated: deleteCollectionProperty70 [71 {method: 'deleteCollectionProperties', methodParams: [['testKey1', 'testKey2']], expectedProps: [{key: 'testKey3', value: 'testValue3'}]},72 {method: 'deleteCollectionProperty', methodParams: ['testKey1'], expectedProps: [{key: 'testKey2', value: 'testValue2'}, {key: 'testKey3', value: 'testValue3'}]}, 73 ].map(testCase => 74 itEth(`Collection properties can be deleted: ${testCase.method}()`, async({helper}) => {75 const properties = [76 {key: 'testKey1', value: 'testValue1'},77 {key: 'testKey2', value: 'testValue2'},78 {key: 'testKey3', value: 'testValue3'}];79 const caller = await helper.eth.createAccountWithBalance(donor);80 const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties});81 82 await collection.addAdmin(alice, {Ethereum: caller});83 84 const address = helper.ethAddress.fromCollectionId(collection.collectionId);85 const contract = helper.ethNativeContract.collection(address, 'nft', caller, testCase.method === 'deleteCollectionProperty');86 87 await contract.methods[testCase.method](...testCase.methodParams).send({from: caller});88 89 const raw = (await collection.getData())?.raw;90 91 expect(raw.properties.length).to.equal(testCase.expectedProps.length);92 expect(raw.properties).to.deep.equal(testCase.expectedProps);93 }));9495 96 [97 {method: 'deleteCollectionProperties', methodParams: [['testKey2']]},98 {method: 'deleteCollectionProperty', methodParams: ['testKey2']},99 ].map(testCase => 100 itEth(`cannot ${testCase.method}() of non-owned collections`, async ({helper}) => {101 const properties = [102 {key: 'testKey1', value: 'testValue1'},103 {key: 'testKey2', value: 'testValue2'},104 ];105 const caller = await helper.eth.createAccountWithBalance(donor);106 const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties});107108 const address = helper.ethAddress.fromCollectionId(collection.collectionId);109 const collectionEvm = helper.ethNativeContract.collection(address, 'nft', caller, testCase.method === 'deleteCollectionProperty');110111 await expect(collectionEvm.methods[testCase.method](...testCase.methodParams).send({from: caller})).to.be.rejected;112 expect(await collection.getProperties()).to.deep.eq(properties);113 }));114115 itEth('Can be read', async({helper}) => {116 const caller = helper.eth.createAccount();117 const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties: [{key: 'testKey', value: 'testValue'}]});118119 const address = helper.ethAddress.fromCollectionId(collection.collectionId);120 const contract = helper.ethNativeContract.collection(address, 'nft', caller);121122 const value = await contract.methods.collectionProperty('testKey').call();123 expect(value).to.equal(helper.getWeb3().utils.toHex('testValue'));124 });125});126127describe('Supports ERC721Metadata', () => {128 let donor: IKeyringPair;129130 before(async function() {131 await usingEthPlaygrounds(async (_helper, privateKey) => {132 donor = await privateKey({filename: __filename});133 });134 });135136 [137 {case: 'nft' as const},138 {case: 'rft' as const, requiredPallets: [Pallets.ReFungible]},139 ].map(testCase => 140 itEth.ifWithPallets(`ERC721Metadata property can be set for ${testCase.case} collection`, testCase.requiredPallets || [], async ({helper}) => {141 const caller = await helper.eth.createAccountWithBalance(donor);142 const bruh = await helper.eth.createAccountWithBalance(donor);143 144 const BASE_URI = 'base/';145 const SUFFIX = 'suffix1';146 const URI = 'uri1';147 148 const collectionHelpers = helper.ethNativeContract.collectionHelpers(caller);149 const creatorMethod = testCase.case === 'rft' ? 'createRFTCollection' : 'createNFTCollection';150 151 const {collectionId, collectionAddress} = await helper.eth[creatorMethod](caller, 'n', 'd', 'p');152 const bruhCross = helper.ethCrossAccount.fromAddress(bruh);153 154 const contract = helper.ethNativeContract.collectionById(collectionId, testCase.case, caller);155 await contract.methods.addCollectionAdminCross(bruhCross).send(); // to check that admin will work too156 157 const collection1 = helper.nft.getCollectionObject(collectionId);158 const data1 = await collection1.getData();159 expect(data1?.raw.flags.erc721metadata).to.be.false;160 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.false;161 162 await collectionHelpers.methods.makeCollectionERC721MetadataCompatible(collectionAddress, BASE_URI)163 .send({from: bruh});164 165 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.true;166 167 const collection2 = helper.nft.getCollectionObject(collectionId);168 const data2 = await collection2.getData();169 expect(data2?.raw.flags.erc721metadata).to.be.true;170 171 const propertyPermissions = data2?.raw.tokenPropertyPermissions;172 expect(propertyPermissions?.length).to.equal(2);173 174 expect(propertyPermissions.find((tpp: ITokenPropertyPermission) => {175 return tpp.key === 'URI' && tpp.permission.mutable && tpp.permission.collectionAdmin && !tpp.permission.tokenOwner;176 })).to.be.not.null;177 178 expect(propertyPermissions.find((tpp: ITokenPropertyPermission) => {179 return tpp.key === 'URISuffix' && tpp.permission.mutable && tpp.permission.collectionAdmin && !tpp.permission.tokenOwner;180 })).to.be.not.null;181 182 expect(data2?.raw.properties?.find((property: IProperty) => {183 return property.key === 'baseURI' && property.value === BASE_URI;184 })).to.be.not.null;185 186 const token1Result = await contract.methods.mint(bruh).send();187 const tokenId1 = token1Result.events.Transfer.returnValues.tokenId;188 189 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI);190 191 await contract.methods.setProperties(tokenId1, [{key: 'URISuffix', value: Buffer.from(SUFFIX)}]).send();192 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI + SUFFIX);193 194 await contract.methods.setProperties(tokenId1, [{key: 'URI', value: Buffer.from(URI)}]).send();195 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(URI);196 197 await contract.methods.deleteProperties(tokenId1, ['URI']).send();198 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI + SUFFIX);199 200 const token2Result = await contract.methods.mintWithTokenURI(bruh, URI).send();201 const tokenId2 = token2Result.events.Transfer.returnValues.tokenId;202 203 expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(URI);204 205 await contract.methods.deleteProperties(tokenId2, ['URI']).send();206 expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(BASE_URI);207 208 await contract.methods.setProperties(tokenId2, [{key: 'URISuffix', value: Buffer.from(SUFFIX)}]).send();209 expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(BASE_URI + SUFFIX);210 }));211});212213describe('EVM collection property', () => {214 let donor: IKeyringPair;215216 before(async function() {217 await usingEthPlaygrounds(async (_helper, privateKey) => {218 donor = await privateKey({filename: __filename});219 });220 });221222 [223 {case: 'nft' as const},224 {case: 'rft' as const, requiredPallets: [Pallets.ReFungible]},225 {case: 'ft' as const},226 ].map(testCase => 227 itEth.ifWithPallets(`can set/read properties ${testCase.case}`, testCase.requiredPallets || [], async ({helper}) => {228 const collection = await helper[testCase.case].mintCollection(donor, {name: 'A', description: 'B', tokenPrefix: 'C'});229230 const sender = await helper.eth.createAccountWithBalance(donor, 100n);231 await collection.addAdmin(donor, {Ethereum: sender});232 233 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);234 const contract = helper.ethNativeContract.collection(collectionAddress, testCase.case, sender);235 236 const keys = ['key0', 'key1'];237 238 const writeProperties = [239 helper.ethProperty.property(keys[0], 'value0'),240 helper.ethProperty.property(keys[1], 'value1'),241 ];242 243 await contract.methods.setCollectionProperties(writeProperties).send();244 const readProperties = await contract.methods.collectionProperties([keys[0], keys[1]]).call();245 expect(readProperties).to.be.like(writeProperties);246 }));247248 [249 {case: 'nft' as const},250 {case: 'rft' as const, requiredPallets: [Pallets.ReFungible]},251 {case: 'ft' as const},252 ].map(testCase => 253 itEth.ifWithPallets(`can delete properties ${testCase.case}`, testCase.requiredPallets || [], async ({helper}) => {254 const collection = await helper[testCase.case].mintCollection(donor, {name: 'A', description: 'B', tokenPrefix: 'C'});255256 const sender = await helper.eth.createAccountWithBalance(donor, 100n);257 await collection.addAdmin(donor, {Ethereum: sender});258 259 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);260 const contract = helper.ethNativeContract.collection(collectionAddress, testCase.case, sender);261 262 const keys = ['key0', 'key1', 'key2', 'key3'];263 264 {265 const writeProperties = [266 helper.ethProperty.property(keys[0], 'value0'),267 helper.ethProperty.property(keys[1], 'value1'),268 helper.ethProperty.property(keys[2], 'value2'),269 helper.ethProperty.property(keys[3], 'value3'),270 ];271 272 await contract.methods.setCollectionProperties(writeProperties).send();273 const readProperties = await contract.methods.collectionProperties([keys[0], keys[1], keys[2], keys[3]]).call();274 expect(readProperties).to.be.like(writeProperties);275 }276 277 {278 const expectProperties = [279 helper.ethProperty.property(keys[0], 'value0'),280 helper.ethProperty.property(keys[1], 'value1'),281 ];282 283 await contract.methods.deleteCollectionProperties([keys[2], keys[3]]).send();284 const readProperties = await contract.methods.collectionProperties([]).call();285 expect(readProperties).to.be.like(expectProperties);286 }287 }));288});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 {itEth, usingEthPlaygrounds, expect} from './util';18import {Pallets} from '../util';19import {IProperty, ITokenPropertyPermission} from '../util/playgrounds/types';20import {IKeyringPair} from '@polkadot/types/types';2122describe('EVM collection properties', () => {23 let donor: IKeyringPair;24 let alice: IKeyringPair;2526 before(async function() {27 await usingEthPlaygrounds(async (_helper, privateKey) => {28 donor = await privateKey({filename: __filename});29 [alice] = await _helper.arrange.createAccounts([50n], donor);30 });31 });3233 // Soft-deprecated: setCollectionProperty34 [35 {method: 'setCollectionProperties', mode: 'nft' as const, methodParams: [[{key: 'testKey1', value: Buffer.from('testValue1')}, {key: 'testKey2', value: Buffer.from('testValue2')}]], expectedProps: [{key: 'testKey1', value: 'testValue1'}, {key: 'testKey2', value: 'testValue2'}]}, 36 {method: 'setCollectionProperties', mode: 'rft' as const, methodParams: [[{key: 'testKey1', value: Buffer.from('testValue1')}, {key: 'testKey2', value: Buffer.from('testValue2')}]], expectedProps: [{key: 'testKey1', value: 'testValue1'}, {key: 'testKey2', value: 'testValue2'}]}, 37 {method: 'setCollectionProperties', mode: 'ft' as const, methodParams: [[{key: 'testKey1', value: Buffer.from('testValue1')}, {key: 'testKey2', value: Buffer.from('testValue2')}]], expectedProps: [{key: 'testKey1', value: 'testValue1'}, {key: 'testKey2', value: 'testValue2'}]}, 38 {method: 'setCollectionProperty', mode: 'nft' as const, methodParams: ['testKey', Buffer.from('testValue')], expectedProps: [{key: 'testKey', value: 'testValue'}]},39 ].map(testCase => 40 itEth.ifWithPallets(`Collection properties can be set: ${testCase.method}() for ${testCase.mode}`, testCase.mode === 'rft' ? [Pallets.ReFungible] : [], async({helper}) => {41 const caller = await helper.eth.createAccountWithBalance(donor);42 const collection = await helper[testCase.mode].mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties: []});43 await collection.addAdmin(alice, {Ethereum: caller});44 45 const address = helper.ethAddress.fromCollectionId(collection.collectionId);46 const collectionEvm = helper.ethNativeContract.collection(address, 'nft', caller, testCase.method === 'setCollectionProperty');4748 // collectionProperties returns an empty array if no properties: 49 expect(await collectionEvm.methods.collectionProperties([]).call()).to.be.like([]);50 expect(await collectionEvm.methods.collectionProperties(['NonExistingKey']).call()).to.be.like([]);5152 await collectionEvm.methods[testCase.method](...testCase.methodParams).send({from: caller});5354 const raw = (await collection.getData())?.raw;55 expect(raw.properties).to.deep.equal(testCase.expectedProps);5657 // collectionProperties returns properties: 58 expect(await collectionEvm.methods.collectionProperties([]).call()).to.be.like(testCase.expectedProps.map(prop => helper.ethProperty.property(prop.key, prop.value)));59 }));6061 itEth('Cannot set invalid properties', async({helper}) => {62 const caller = await helper.eth.createAccountWithBalance(donor);63 const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties: []});64 await collection.addAdmin(alice, {Ethereum: caller});6566 const address = helper.ethAddress.fromCollectionId(collection.collectionId);67 const contract = helper.ethNativeContract.collection(address, 'nft', caller);6869 await expect(contract.methods.setCollectionProperties([{key: '', value: Buffer.from('val1')}]).send({from: caller})).to.be.rejected;70 await expect(contract.methods.setCollectionProperties([{key: 'déjà vu', value: Buffer.from('hmm...')}]).send({from: caller})).to.be.rejected;71 await expect(contract.methods.setCollectionProperties([{key: 'a'.repeat(257), value: Buffer.from('val3')}]).send({from: caller})).to.be.rejected;72 // TODO add more expects73 const raw = (await collection.getData())?.raw;74 expect(raw.properties).to.deep.equal([]);75 });767778 // Soft-deprecated: deleteCollectionProperty79 [80 {method: 'deleteCollectionProperties', mode: 'nft' as const, methodParams: [['testKey1', 'testKey2']], expectedProps: [{key: 'testKey3', value: 'testValue3'}]},81 {method: 'deleteCollectionProperties', mode: 'rft' as const, methodParams: [['testKey1', 'testKey2']], expectedProps: [{key: 'testKey3', value: 'testValue3'}]},82 {method: 'deleteCollectionProperties', mode: 'ft' as const, methodParams: [['testKey1', 'testKey2']], expectedProps: [{key: 'testKey3', value: 'testValue3'}]},83 {method: 'deleteCollectionProperty', mode: 'nft' as const, methodParams: ['testKey1'], expectedProps: [{key: 'testKey2', value: 'testValue2'}, {key: 'testKey3', value: 'testValue3'}]}, 84 ].map(testCase => 85 itEth(`Collection properties can be deleted: ${testCase.method}() for ${testCase.mode}`, async({helper}) => {86 const properties = [87 {key: 'testKey1', value: 'testValue1'},88 {key: 'testKey2', value: 'testValue2'},89 {key: 'testKey3', value: 'testValue3'}];90 const caller = await helper.eth.createAccountWithBalance(donor);91 const collection = await helper[testCase.mode].mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties});92 93 await collection.addAdmin(alice, {Ethereum: caller});94 95 const address = helper.ethAddress.fromCollectionId(collection.collectionId);96 const contract = helper.ethNativeContract.collection(address, 'nft', caller, testCase.method === 'deleteCollectionProperty');97 98 await contract.methods[testCase.method](...testCase.methodParams).send({from: caller});99 100 const raw = (await collection.getData())?.raw;101 102 expect(raw.properties.length).to.equal(testCase.expectedProps.length);103 expect(raw.properties).to.deep.equal(testCase.expectedProps);104 }));105106 107 [108 {method: 'deleteCollectionProperties', methodParams: [['testKey2']]},109 {method: 'deleteCollectionProperty', methodParams: ['testKey2']},110 ].map(testCase => 111 itEth(`cannot ${testCase.method}() of non-owned collections`, async ({helper}) => {112 const properties = [113 {key: 'testKey1', value: 'testValue1'},114 {key: 'testKey2', value: 'testValue2'},115 ];116 const caller = await helper.eth.createAccountWithBalance(donor);117 const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties});118119 const address = helper.ethAddress.fromCollectionId(collection.collectionId);120 const collectionEvm = helper.ethNativeContract.collection(address, 'nft', caller, testCase.method === 'deleteCollectionProperty');121122 await expect(collectionEvm.methods[testCase.method](...testCase.methodParams).send({from: caller})).to.be.rejected;123 expect(await collection.getProperties()).to.deep.eq(properties);124 }));125126 itEth('Can be read', async({helper}) => {127 const caller = helper.eth.createAccount();128 const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties: [{key: 'testKey', value: 'testValue'}]});129130 const address = helper.ethAddress.fromCollectionId(collection.collectionId);131 const contract = helper.ethNativeContract.collection(address, 'nft', caller);132133 const value = await contract.methods.collectionProperty('testKey').call();134 expect(value).to.equal(helper.getWeb3().utils.toHex('testValue'));135 });136});137138describe('Supports ERC721Metadata', () => {139 let donor: IKeyringPair;140141 before(async function() {142 await usingEthPlaygrounds(async (_helper, privateKey) => {143 donor = await privateKey({filename: __filename});144 });145 });146147 [148 {case: 'nft' as const},149 {case: 'rft' as const, requiredPallets: [Pallets.ReFungible]},150 ].map(testCase => 151 itEth.ifWithPallets(`ERC721Metadata property can be set for ${testCase.case} collection`, testCase.requiredPallets || [], async ({helper}) => {152 const caller = await helper.eth.createAccountWithBalance(donor);153 const bruh = await helper.eth.createAccountWithBalance(donor);154 155 const BASE_URI = 'base/';156 const SUFFIX = 'suffix1';157 const URI = 'uri1';158 159 const collectionHelpers = helper.ethNativeContract.collectionHelpers(caller);160 const creatorMethod = testCase.case === 'rft' ? 'createRFTCollection' : 'createNFTCollection';161 162 const {collectionId, collectionAddress} = await helper.eth[creatorMethod](caller, 'n', 'd', 'p');163 const bruhCross = helper.ethCrossAccount.fromAddress(bruh);164 165 const contract = helper.ethNativeContract.collectionById(collectionId, testCase.case, caller);166 await contract.methods.addCollectionAdminCross(bruhCross).send(); // to check that admin will work too167 168 const collection1 = helper.nft.getCollectionObject(collectionId);169 const data1 = await collection1.getData();170 expect(data1?.raw.flags.erc721metadata).to.be.false;171 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.false;172 173 await collectionHelpers.methods.makeCollectionERC721MetadataCompatible(collectionAddress, BASE_URI)174 .send({from: bruh});175 176 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.true;177 178 const collection2 = helper.nft.getCollectionObject(collectionId);179 const data2 = await collection2.getData();180 expect(data2?.raw.flags.erc721metadata).to.be.true;181 182 const propertyPermissions = data2?.raw.tokenPropertyPermissions;183 expect(propertyPermissions?.length).to.equal(2);184 185 expect(propertyPermissions.find((tpp: ITokenPropertyPermission) => {186 return tpp.key === 'URI' && tpp.permission.mutable && tpp.permission.collectionAdmin && !tpp.permission.tokenOwner;187 })).to.be.not.null;188 189 expect(propertyPermissions.find((tpp: ITokenPropertyPermission) => {190 return tpp.key === 'URISuffix' && tpp.permission.mutable && tpp.permission.collectionAdmin && !tpp.permission.tokenOwner;191 })).to.be.not.null;192 193 expect(data2?.raw.properties?.find((property: IProperty) => {194 return property.key === 'baseURI' && property.value === BASE_URI;195 })).to.be.not.null;196 197 const token1Result = await contract.methods.mint(bruh).send();198 const tokenId1 = token1Result.events.Transfer.returnValues.tokenId;199 200 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI);201 202 await contract.methods.setProperties(tokenId1, [{key: 'URISuffix', value: Buffer.from(SUFFIX)}]).send();203 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI + SUFFIX);204 205 await contract.methods.setProperties(tokenId1, [{key: 'URI', value: Buffer.from(URI)}]).send();206 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(URI);207 208 await contract.methods.deleteProperties(tokenId1, ['URI']).send();209 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI + SUFFIX);210 211 const token2Result = await contract.methods.mintWithTokenURI(bruh, URI).send();212 const tokenId2 = token2Result.events.Transfer.returnValues.tokenId;213 214 expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(URI);215 216 await contract.methods.deleteProperties(tokenId2, ['URI']).send();217 expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(BASE_URI);218 219 await contract.methods.setProperties(tokenId2, [{key: 'URISuffix', value: Buffer.from(SUFFIX)}]).send();220 expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(BASE_URI + SUFFIX);221 }));222});223224describe('EVM collection property', () => {225 let donor: IKeyringPair;226227 before(async function() {228 await usingEthPlaygrounds(async (_helper, privateKey) => {229 donor = await privateKey({filename: __filename});230 });231 });232233 [234 {case: 'nft' as const},235 {case: 'rft' as const, requiredPallets: [Pallets.ReFungible]},236 {case: 'ft' as const},237 ].map(testCase => 238 itEth.ifWithPallets(`can set/read properties ${testCase.case}`, testCase.requiredPallets || [], async ({helper}) => {239 const collection = await helper[testCase.case].mintCollection(donor, {name: 'A', description: 'B', tokenPrefix: 'C'});240241 const sender = await helper.eth.createAccountWithBalance(donor, 100n);242 await collection.addAdmin(donor, {Ethereum: sender});243 244 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);245 const contract = helper.ethNativeContract.collection(collectionAddress, testCase.case, sender);246 247 const keys = ['key0', 'key1'];248 249 const writeProperties = [250 helper.ethProperty.property(keys[0], 'value0'),251 helper.ethProperty.property(keys[1], 'value1'),252 ];253 254 await contract.methods.setCollectionProperties(writeProperties).send();255 const readProperties = await contract.methods.collectionProperties([keys[0], keys[1]]).call();256 expect(readProperties).to.be.like(writeProperties);257 }));258259 [260 {case: 'nft' as const},261 {case: 'rft' as const, requiredPallets: [Pallets.ReFungible]},262 {case: 'ft' as const},263 ].map(testCase => 264 itEth.ifWithPallets(`can delete properties ${testCase.case}`, testCase.requiredPallets || [], async ({helper}) => {265 const collection = await helper[testCase.case].mintCollection(donor, {name: 'A', description: 'B', tokenPrefix: 'C'});266267 const sender = await helper.eth.createAccountWithBalance(donor, 100n);268 await collection.addAdmin(donor, {Ethereum: sender});269 270 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);271 const contract = helper.ethNativeContract.collection(collectionAddress, testCase.case, sender);272 273 const keys = ['key0', 'key1', 'key2', 'key3'];274 275 {276 const writeProperties = [277 helper.ethProperty.property(keys[0], 'value0'),278 helper.ethProperty.property(keys[1], 'value1'),279 helper.ethProperty.property(keys[2], 'value2'),280 helper.ethProperty.property(keys[3], 'value3'),281 ];282 283 await contract.methods.setCollectionProperties(writeProperties).send();284 const readProperties = await contract.methods.collectionProperties([keys[0], keys[1], keys[2], keys[3]]).call();285 expect(readProperties).to.be.like(writeProperties);286 }287 288 {289 const expectedProperties = [290 helper.ethProperty.property(keys[0], 'value0'),291 helper.ethProperty.property(keys[1], 'value1'),292 ];293 294 await contract.methods.deleteCollectionProperties([keys[2], keys[3]]).send();295 const readProperties = await contract.methods.collectionProperties([]).call();296 expect(readProperties).to.be.like(expectedProperties);297 }298 }));299});