git.delta.rocks / unique-network / refs/commits / c7b709a1e360

difftreelog

test(eth-nesting) fix and refactor

Fahrrader2022-06-09parent: #5a779df.patch.diff
in: master

1 file changed

modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
3import {expect} from 'chai';3import {expect} from 'chai';
4import { collectionIdToAddress, createEthAccountWithBalance, GAS_ARGS, itWeb3, tokenIdToAddress} from '../../eth/util/helpers';4import {collectionIdToAddress, createEthAccountWithBalance, GAS_ARGS, itWeb3, tokenIdToAddress} from '../../eth/util/helpers';
5import usingApi, {submitTransactionAsync} from '../../substrate/substrate-api';5import usingApi, {submitTransactionAsync} from '../../substrate/substrate-api';
6import {createCollectionExpectSuccess, setCollectionLimitsExpectSuccess} from '../../util/helpers';6import {createCollectionExpectSuccess, setCollectionPermissionsExpectSuccess} from '../../util/helpers';
7import nonFungibleAbi from '../nonFungibleAbi.json';7import nonFungibleAbi from '../nonFungibleAbi.json';
88
9let alice: IKeyringPair;9let alice: IKeyringPair;
1010
11const getCollectionFromSubstrate = async (api: ApiPromise, ethAddress: string): Promise<{ collectionId: number, address: string }> => {11const getCollectionFromSubstrate = async (
12 api: ApiPromise,
13 ethAddress: string,
14): Promise<{ collectionId: number, address: string }> => {
12 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});15 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
13 await setCollectionLimitsExpectSuccess(alice, collectionId, {nestingRule: 'Owner'});16 await setCollectionPermissionsExpectSuccess(alice, collectionId, {nesting: 'Owner'});
14 await submitTransactionAsync(alice, api.tx.unique.addCollectionAdmin(collectionId, {Ethereum: ethAddress}));17 await submitTransactionAsync(alice, api.tx.unique.addCollectionAdmin(collectionId, {Ethereum: ethAddress}));
15 return {collectionId, address: collectionIdToAddress(collectionId)};18 return {collectionId, address: collectionIdToAddress(collectionId)};
16};19};
1720
18describe('Integration Test: Nesting', () => {21describe('Integration Test: EVM Nesting', () => {
19 before(async () => {22 before(async () => {
20 await usingApi(async (api, privateKeyWrapper) => {23 await usingApi(async (_api, privateKeyWrapper) => {
21 alice = privateKeyWrapper('//Alice');24 alice = privateKeyWrapper('//Alice');
22 });25 });
23 });26 });
39
40 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});42 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
4143
44 // Create a token to be nested
42 const nftTokenId = await contract.methods.nextTokenId().call();45 const nftTokenId = await contract.methods.nextTokenId().call();
43 await contract.methods.mint(46 await contract.methods.mint(
44 owner,47 owner,
45 nftTokenId,48 nftTokenId,
46 ).send({from: owner});49 ).send({from: owner});
4750
51 // Nest into a token
48 const firstTargetNftTokenId = await contract.methods.nextTokenId().call();52 const firstTargetNftTokenId = await contract.methods.nextTokenId().call();
49 await contract.methods.mint(53 await contract.methods.mint(
50 owner,54 owner,
56 await contract.methods.transfer(targetNftTokenAddress, nftTokenId).send({from: owner});60 await contract.methods.transfer(targetNftTokenAddress, nftTokenId).send({from: owner});
57 expect(await contract.methods.ownerOf(nftTokenId).call()).to.be.equal(targetNftTokenAddress);61 expect(await contract.methods.ownerOf(nftTokenId).call()).to.be.equal(targetNftTokenAddress);
58 62
63 // Re-nest into another
59 const secondTargetNftTokenId = await contract.methods.nextTokenId().call();64 const secondTargetNftTokenId = await contract.methods.nextTokenId().call();
60 await contract.methods.mint(65 await contract.methods.mint(
61 owner,66 owner,
7277
73 const {collectionId: collectionIdA, address: addressCollectionA} = await getCollectionFromSubstrate(api, owner);78 const {collectionId: collectionIdA, address: addressCollectionA} = await getCollectionFromSubstrate(api, owner);
74 const {collectionId: collectionIdB, address: addressCollectionB} = await getCollectionFromSubstrate(api, owner);79 const {collectionId: collectionIdB, address: addressCollectionB} = await getCollectionFromSubstrate(api, owner);
7580 await setCollectionPermissionsExpectSuccess(alice, collectionIdA, {nesting: {OwnerRestricted:[collectionIdA, collectionIdB]}});
7681
77 const contractA = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionA, {from: owner, ...GAS_ARGS});82 const contractA = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionA, {from: owner, ...GAS_ARGS});
78 const contractB = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionB, {from: owner, ...GAS_ARGS});83 const contractB = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionB, {from: owner, ...GAS_ARGS});
7984
85 // Create a token to nest into
80 const nftTokenIdA1 = await contractA.methods.nextTokenId().call();86 const targetNftTokenId = await contractA.methods.nextTokenId().call();
81 await contractA.methods.mint(87 await contractA.methods.mint(
82 owner,88 owner,
83 nftTokenIdA1,89 targetNftTokenId,
84 ).send({from: owner});90 ).send({from: owner});
85 const nftTokenAddressA1 = tokenIdToAddress(collectionIdA, nftTokenIdA1);91 const nftTokenAddressA1 = tokenIdToAddress(collectionIdA, targetNftTokenId);
8692
93 // Create a token for nesting in the same collection as the target
87 const nftTokenIdA2 = await contractA.methods.nextTokenId().call();94 const nftTokenIdA = await contractA.methods.nextTokenId().call();
88 await contractA.methods.mint(95 await contractA.methods.mint(
89 owner,96 owner,
90 nftTokenIdA2,97 nftTokenIdA,
91 ).send({from: owner});98 ).send({from: owner});
9299
100 // Create a token for nesting in a different collection
93 const nftTokenIdB1 = await contractB.methods.nextTokenId().call();101 const nftTokenIdB = await contractB.methods.nextTokenId().call();
94 await contractB.methods.mint(102 await contractB.methods.mint(
95 owner,103 owner,
96 nftTokenIdB1,104 nftTokenIdB,
97 ).send({from: owner});105 ).send({from: owner});
98106
99 await setCollectionLimitsExpectSuccess(alice, collectionIdA, {nestingRule: {OwnerRestricted:[collectionIdA, collectionIdB]}});107 // Nest
100
101 await contractA.methods.transfer(nftTokenAddressA1, nftTokenIdA2).send({from: owner});108 await contractA.methods.transfer(nftTokenAddressA1, nftTokenIdA).send({from: owner});
102 expect(await contractA.methods.ownerOf(nftTokenIdA2).call()).to.be.equal(nftTokenAddressA1);109 expect(await contractA.methods.ownerOf(nftTokenIdA).call()).to.be.equal(nftTokenAddressA1);
103110
104 await contractB.methods.transfer(nftTokenAddressA1, nftTokenIdB1).send({from: owner});111 await contractB.methods.transfer(nftTokenAddressA1, nftTokenIdB).send({from: owner});
105 expect(await contractB.methods.ownerOf(nftTokenIdB1).call()).to.be.equal(nftTokenAddressA1);112 expect(await contractB.methods.ownerOf(nftTokenIdB).call()).to.be.equal(nftTokenAddressA1);
106 });113 });
107});114});
108115
109describe('Negative Test: Nesting', async() => {116describe('Negative Test: EVM Nesting', async() => {
110 before(async () => {117 before(async () => {
111 await usingApi(async (api, privateKeyWrapper) => {118 await usingApi(async (api, privateKeyWrapper) => {
112 alice = privateKeyWrapper('//Alice');119 alice = privateKeyWrapper('//Alice');
117 const owner = await createEthAccountWithBalance(api, web3);124 const owner = await createEthAccountWithBalance(api, web3);
118125
119 const {collectionId, address} = await getCollectionFromSubstrate(api, owner);126 const {collectionId, address} = await getCollectionFromSubstrate(api, owner);
120 await setCollectionLimitsExpectSuccess(alice, collectionId, {nestingRule: 'Disabled'});127 await setCollectionPermissionsExpectSuccess(alice, collectionId, {nesting: 'Disabled'});
121128
122 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});129 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
123130
131 // Create a token to nest into
124 const nftTokenId = await contract.methods.nextTokenId().call();132 const targetNftTokenId = await contract.methods.nextTokenId().call();
125 await contract.methods.mint(133 await contract.methods.mint(
126 owner,134 owner,
127 nftTokenId,135 targetNftTokenId,
128 ).send({from: owner});136 ).send({from: owner});
129137
138 const targetNftTokenAddress = tokenIdToAddress(collectionId, targetNftTokenId);
139
140 // Create a token to nest
130 const targetNftTokenId = await contract.methods.nextTokenId().call();141 const nftTokenId = await contract.methods.nextTokenId().call();
131 await contract.methods.mint(142 await contract.methods.mint(
132 owner,143 owner,
133 targetNftTokenId,144 nftTokenId,
134 ).send({from: owner});145 ).send({from: owner});
135146
136 const targetNftTokenAddress = tokenIdToAddress(collectionId, targetNftTokenId);147 // Try to nest
137
138 await expect(contract.methods148 await expect(contract.methods
139 .transfer(targetNftTokenAddress, nftTokenId)149 .transfer(targetNftTokenAddress, nftTokenId)
140 .call()).to.be.rejectedWith('NestingIsDisabled');150 .call()).to.be.rejectedWith('NestingIsDisabled');
141 });151 });
142 152
143 itWeb3('NFT: disallows a non-Owner to nest someone else\'s token', async ({api, web3}) => {153 itWeb3('NFT: disallows a non-Owner to nest someone else\'s token', async ({api, web3}) => {
144 const owner = await createEthAccountWithBalance(api, web3);154 const owner = await createEthAccountWithBalance(api, web3);
145 const receiver = await createEthAccountWithBalance(api, web3);155 const malignant = await createEthAccountWithBalance(api, web3);
146156
147 const {collectionId: collectionIdA, address: addressCollectionA} = await getCollectionFromSubstrate(api, owner);157 const {collectionId, address: collectionAdress} = await getCollectionFromSubstrate(api, owner);
148 const {collectionId: collectionIdB, address: addressCollectionB} = await getCollectionFromSubstrate(api, receiver);
149158
150 const contractA = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionA, {from: owner, ...GAS_ARGS});159 const contract = new web3.eth.Contract(nonFungibleAbi as any, collectionAdress, {from: owner, ...GAS_ARGS});
151 const contractB = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionB, {from: receiver, ...GAS_ARGS});160
152161 // Mint a token
153 const nftTokenIdA = await contractA.methods.nextTokenId().call();162 const targetTokenId = await contract.methods.nextTokenId().call();
154 await contractA.methods.mint(163 await contract.methods.mint(
155 owner,164 owner,
156 nftTokenIdA,165 targetTokenId,
157 ).send({from: owner});166 ).send({from: owner});
158 167 const targetTokenAddress = tokenIdToAddress(collectionId, targetTokenId);
168
169 // Mint a token belonging to a different account
159 const nftTokenIdB = await contractB.methods.nextTokenId().call();170 const tokenId = await contract.methods.nextTokenId().call();
160 await contractB.methods.mint(171 await contract.methods.mint(
161 receiver,172 malignant,
162 nftTokenIdB,173 tokenId,
163 ).send({from: receiver});174 ).send({from: owner});
164 175
165 const nftTokenAddressB = tokenIdToAddress(collectionIdB, nftTokenIdB);176 // Try to nest one token in another as a non-owner account
166
167 await expect(contractA.methods177 await expect(contract.methods
168 .transfer(nftTokenAddressB, nftTokenIdA)178 .transfer(targetTokenAddress, tokenId)
169 .call()).to.be.rejectedWith('OnlyOwnerAllowedToNest');179 .call({from: malignant})).to.be.rejectedWith('OnlyOwnerAllowedToNest');
170 });180 });
171 181
172 itWeb3('NFT: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async ({api, web3}) => {182 itWeb3('NFT: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async ({api, web3}) => {
173 const owner = await createEthAccountWithBalance(api, web3);183 const owner = await createEthAccountWithBalance(api, web3);
184 const malignant = await createEthAccountWithBalance(api, web3);
174185
175 const {collectionId: collectionIdA, address: addressCollectionA} = await getCollectionFromSubstrate(api, owner);186 const {collectionId: collectionIdA, address: addressCollectionA} = await getCollectionFromSubstrate(api, owner);
176 const {collectionId: collectionIdB, address: addressCollectionB} = await getCollectionFromSubstrate(api, owner);187 const {collectionId: collectionIdB, address: addressCollectionB} = await getCollectionFromSubstrate(api, owner);
177188
178 const contractA = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionA, {from: owner, ...GAS_ARGS});189 const contractA = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionA, {from: owner, ...GAS_ARGS});
179 const contractB = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionB, {from: owner, ...GAS_ARGS});190 const contractB = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionB, {from: owner, ...GAS_ARGS});
180191
181 await setCollectionLimitsExpectSuccess(alice, collectionIdA, {nestingRule: {OwnerRestricted:[collectionIdA]}});192 await setCollectionPermissionsExpectSuccess(alice, collectionIdA, {nesting: {OwnerRestricted:[collectionIdA, collectionIdB]}});
182193
194 // Create a token in one collection
183 const nftTokenIdA = await contractA.methods.nextTokenId().call();195 const nftTokenIdA = await contractA.methods.nextTokenId().call();
184 await contractA.methods.mint(196 await contractA.methods.mint(
185 owner,197 owner,
186 nftTokenIdA,198 nftTokenIdA,
187 ).send({from: owner});199 ).send({from: owner});
188 200 const nftTokenAddressA = tokenIdToAddress(collectionIdA, nftTokenIdA);
201
202 // Create a token in another collection belonging to someone else
189 const nftTokenIdB = await contractB.methods.nextTokenId().call();203 const nftTokenIdB = await contractB.methods.nextTokenId().call();
190 await contractB.methods.mint(204 await contractB.methods.mint(
191 owner,205 malignant,
192 nftTokenIdB,206 nftTokenIdB,
193 ).send({from: owner});207 ).send({from: owner});
194 208
195 const nftTokenAddressA = tokenIdToAddress(collectionIdA, nftTokenIdA);209 // Try to drag someone else's token into the other collection and nest
196
197 await expect(contractB.methods210 await expect(contractB.methods
198 .transfer(nftTokenAddressA, nftTokenIdB)211 .transfer(nftTokenAddressA, nftTokenIdB)
199 .call()).to.be.rejectedWith('SourceCollectionIsNotAllowedToNest');212 .call({from: malignant})).to.be.rejectedWith('OnlyOwnerAllowedToNest');
200 });213 });
201 214
202 itWeb3('NFT: disallows to nest token in an unlisted collection', async ({api, web3}) => {215 itWeb3('NFT: disallows to nest token in an unlisted collection', async ({api, web3}) => {
203 const owner = await createEthAccountWithBalance(api, web3);216 const owner = await createEthAccountWithBalance(api, web3);
204217
205 const {collectionId: collectionIdA, address: addressCollectionA} = await getCollectionFromSubstrate(api, owner);218 const {collectionId: collectionIdA, address: addressCollectionA} = await getCollectionFromSubstrate(api, owner);
219 const {address: addressCollectionB} = await getCollectionFromSubstrate(api, owner);
206220
207 const contractA = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionA, {from: owner, ...GAS_ARGS});221 const contractA = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionA, {from: owner, ...GAS_ARGS});
222 const contractB = new web3.eth.Contract(nonFungibleAbi as any, addressCollectionB, {from: owner, ...GAS_ARGS});
208223
209 await setCollectionLimitsExpectSuccess(alice, collectionIdA, {nestingRule: {OwnerRestricted:[]}});224 await setCollectionPermissionsExpectSuccess(alice, collectionIdA, {nesting: {OwnerRestricted:[collectionIdA]}});
210225
226 // Create a token in one collection
211 const nftTokenIdA = await contractA.methods.nextTokenId().call();227 const nftTokenIdA = await contractA.methods.nextTokenId().call();
212 await contractA.methods.mint(228 await contractA.methods.mint(
213 owner,229 owner,
214 nftTokenIdA,230 nftTokenIdA,
215 ).send({from: owner});231 ).send({from: owner});
216
217 const nftTokenAddressA = tokenIdToAddress(collectionIdA, nftTokenIdA);232 const nftTokenAddressA = tokenIdToAddress(collectionIdA, nftTokenIdA);
218233
234 // Create a token in another collection
235 const nftTokenIdB = await contractB.methods.nextTokenId().call();
236 await contractB.methods.mint(
237 owner,
238 nftTokenIdB,
239 ).send({from: owner});
240
241 // Try to nest into a token in the other collection, disallowed in the first
219 await expect(contractA.methods242 await expect(contractB.methods
220 .transfer(nftTokenAddressA, nftTokenIdA)243 .transfer(nftTokenAddressA, nftTokenIdB)
221 .call()).to.be.rejectedWith('SourceCollectionIsNotAllowedToNest');244 .call()).to.be.rejectedWith('SourceCollectionIsNotAllowedToNest');
222 });245 });
223});246});