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

difftreelog

feat make scheduler tests to use playgrounds

Daniel Shiposha2022-09-13parent: #3329598.patch.diff
in: master

1 file changed

modifiedtests/src/.outdated/scheduler.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import chai, {expect} from 'chai';
18import chaiAsPromised from 'chai-as-promised';
19import {17import {
20 default as usingApi,18 default as usingApi,
21 executeTransaction,
22 submitTransactionAsync,19 submitTransactionAsync,
23 submitTransactionExpectFailAsync,20 submitTransactionExpectFailAsync,
24} from '../substrate/substrate-api';21} from '../substrate/substrate-api';
25import {22import {
26 createItemExpectSuccess,23 createItemExpectSuccess,
27 createCollectionExpectSuccess,24 createCollectionExpectSuccess,
28 scheduleTransferExpectSuccess,25 scheduleTransferExpectSuccess,
29 scheduleTransferAndWaitExpectSuccess,
30 setCollectionSponsorExpectSuccess,26 setCollectionSponsorExpectSuccess,
31 confirmSponsorshipExpectSuccess,27 confirmSponsorshipExpectSuccess,
32 findUnusedAddress,28 findUnusedAddress,
38 normalizeAccountId,34 normalizeAccountId,
39 getTokenOwner,35 getTokenOwner,
40 getGenericResult,36 getGenericResult,
41 scheduleTransferFundsExpectSuccess,
42 getFreeBalance,37 getFreeBalance,
43 confirmSponsorshipByKeyExpectSuccess,38 confirmSponsorshipByKeyExpectSuccess,
44 scheduleExpectFailure,39 scheduleExpectFailure,
45 scheduleAfter,40 scheduleAfter,
46 cancelScheduled,
47 requirePallets,
48 Pallets,
49 getBlockNumber,
50 scheduleAt,
51} from '../deprecated-helpers/helpers';41} from './util/helpers';
52import {IKeyringPair, SignatureOptions} from '@polkadot/types/types';42import {expect, itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
53import {RuntimeDispatchInfo} from '@polkadot/types/interfaces';
54import {ApiPromise} from '@polkadot/api';43import {IKeyringPair} from '@polkadot/types/types';
55import {objectSpread} from '@polkadot/util';
5644
57chai.use(chaiAsPromised);
58
59// Check that there are no failing Dispatched events in the block
60function checkForFailedSchedulerEvents(api: ApiPromise, events: any[]) {
61 return new Promise((res, rej) => {
62 let schedulerEventPresent = false;
63
64 for (const {event} of events) {
65 if (api.events.scheduler.Dispatched.is(event)) {
66 schedulerEventPresent = true;
67 const result = event.data.result;
68 if (result.isErr) {
69 const decoded = api.registry.findMetaError(result.asErr.asModule);
70 const {method, section} = decoded;
71 rej(new Error(`${section}.${method}`));
72 }
73 }
74 }
75 res(schedulerEventPresent);
76 });
77}
78
79describe('Scheduling token and balance transfers', () => {45describe('Scheduling token and balance transfers', () => {
80 let alice: IKeyringPair;46 let alice: IKeyringPair;
81 let bob: IKeyringPair;47 let bob: IKeyringPair;
8248
83 before(async function() {49 before(async () => {
84 await requirePallets(this, [Pallets.Scheduler]);
85
86 await usingApi(async (_, privateKeyWrapper) => {50 await usingPlaygrounds(async (_, privateKeyWrapper) => {
87 alice = privateKeyWrapper('//Alice');51 alice = privateKeyWrapper('//Alice');
88 bob = privateKeyWrapper('//Bob');52 bob = privateKeyWrapper('//Bob');
89 });53 });
90 });54 });
9155
56 itSub.ifWithPallets('Can delay a transfer of an owned token', [Pallets.Scheduler], async ({helper}) => {
57 const collection = await helper.nft.mintDefaultCollection(alice);
58 const token = await collection.mintToken(alice);
59 const schedulerId = await helper.scheduler.makeScheduledId();
60 const blocksBeforeExecution = 4;
9261
93 it('Can delay a transfer of an owned token', async () => {62 await token.scheduleAfter(schedulerId, blocksBeforeExecution)
94 await usingApi(async api => {63 .transfer(alice, {Substrate: bob.address});
95 const collectionId = await createCollectionExpectSuccess();
96 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
97 const scheduledId = await makeScheduledId();
9864
99 await scheduleTransferAndWaitExpectSuccess(api, collectionId, tokenId, alice, bob, 1, 4, scheduledId);65 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});
100 });
101 });
10266
103 it('Can transfer funds periodically', async () => {67 await helper.wait.newBlocks(blocksBeforeExecution + 1);
104 await usingApi(async api => {
105 const scheduledId = await makeScheduledId();
106 const waitForBlocks = 1;
107 const period = 2;
108 const repetitions = 2;
10968
110 const amount = 1n * UNIQUE;69 expect(await token.getOwner()).to.be.deep.equal({Substrate: bob.address});
70 });
11171
112 await scheduleTransferFundsExpectSuccess(api, amount, alice, bob, waitForBlocks, scheduledId, period, repetitions);72 itSub.ifWithPallets('Can transfer funds periodically', [Pallets.Scheduler], async ({helper}) => {
73 const scheduledId = await helper.scheduler.makeScheduledId();
113 const bobsBalanceBefore = await getFreeBalance(bob);74 const waitForBlocks = 1;
11475
115 await waitNewBlocks(waitForBlocks + 1);76 const amount = 1n * UNIQUE;
116 const bobsBalanceAfterFirst = await getFreeBalance(bob);77 const periodic = {
117 expect(bobsBalanceAfterFirst)78 period: 2,
118 .to.be.equal(
119 bobsBalanceBefore + 1n * amount,
120 '#1 Balance of the recipient should be increased by 1 * amount',79 repetitions: 2,
121 );80 };
12281
123 await waitNewBlocks(period);82 const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);
124 const bobsBalanceAfterSecond = await getFreeBalance(bob);
125 expect(bobsBalanceAfterSecond)
126 .to.be.equal(
127 bobsBalanceBefore + 2n * amount,
128 '#2 Balance of the recipient should be increased by 2 * amount',
129 );
130 });
131 });
13283
133 it('Can cancel a scheduled operation which has not yet taken effect', async () => {84 await helper.scheduler.scheduleAfter(scheduledId, waitForBlocks, {periodic})
134 await usingApi(async api => {
135 const collectionId = await createCollectionExpectSuccess();
136 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');85 .balance.transferToSubstrate(alice, bob.address, amount);
137 const scheduledId = await makeScheduledId();
138 const waitForBlocks = 4;
13986
140 const amount = 1;87 await helper.wait.newBlocks(waitForBlocks + 1);
14188
142 await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, amount, waitForBlocks, scheduledId);89 const bobsBalanceAfterFirst = await helper.balance.getSubstrate(bob.address);
90 expect(bobsBalanceAfterFirst)
91 .to.be.equal(
143 await expect(cancelScheduled(api, alice, scheduledId)).to.not.be.rejected;92 bobsBalanceBefore + 1n * amount,
93 '#1 Balance of the recipient should be increased by 1 * amount',
94 );
14495
145 await waitNewBlocks(waitForBlocks);96 await helper.wait.newBlocks(periodic.period);
14697
147 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(alice.address));98 const bobsBalanceAfterSecond = await helper.balance.getSubstrate(bob.address);
99 expect(bobsBalanceAfterSecond)
100 .to.be.equal(
101 bobsBalanceBefore + 2n * amount,
102 '#2 Balance of the recipient should be increased by 2 * amount',
148 });103 );
149 });104 });
150105
151 it('Can cancel a periodic operation (transfer of funds)', async () => {106 itSub.ifWithPallets('Can cancel a scheduled operation which has not yet taken effect', [Pallets.Scheduler], async ({helper}) => {
152 await usingApi(async api => {107 const collection = await helper.nft.mintDefaultCollection(alice);
153 const waitForBlocks = 1;
154 const period = 3;
155 const repetitions = 2;108 const token = await collection.mintToken(alice);
156109
157 const scheduledId = await makeScheduledId();110 const scheduledId = await helper.scheduler.makeScheduledId();
158 const amount = 1n * UNIQUE;111 const waitForBlocks = 4;
159112
160 const bobsBalanceBefore = await getFreeBalance(bob);113 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});
161 await scheduleTransferFundsExpectSuccess(api, amount, alice, bob, waitForBlocks, scheduledId, period, repetitions);
162114
163 await waitNewBlocks(waitForBlocks + 1);115 await token.scheduleAfter(scheduledId, waitForBlocks)
164 const bobsBalanceAfterFirst = await getFreeBalance(bob);116 .transfer(alice, {Substrate: bob.address});
165 expect(bobsBalanceAfterFirst)
166 .to.be.equal(
167 bobsBalanceBefore + 1n * amount,
168 '#1 Balance of the recipient should be increased by 1 * amount',
169 );
170117
171 await expect(cancelScheduled(api, alice, scheduledId)).to.not.be.rejected;118 await helper.scheduler.cancelScheduled(alice, scheduledId);
172119
173 await waitNewBlocks(period);120 await waitNewBlocks(waitForBlocks + 1);
174 const bobsBalanceAfterSecond = await getFreeBalance(bob);121
175 expect(bobsBalanceAfterSecond)122 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});
176 .to.be.equal(
177 bobsBalanceAfterFirst,
178 '#2 Balance of the recipient should not be changed',
179 );
180 });
181 });123 });
182124
183 it('Scheduled tasks are transactional', async function() {125 itSub.ifWithPallets('Can cancel a periodic operation (transfer of funds)', [Pallets.Scheduler], async ({helper}) => {
184 await requirePallets(this, [Pallets.TestUtils]);126 const waitForBlocks = 1;
127 const periodic = {
128 period: 3,
129 repetitions: 2,
130 };
185131
186 await usingApi(async api => {132 const scheduledId = await helper.scheduler.makeScheduledId();
187 const scheduledId = await makeScheduledId();
188 const waitForBlocks = 4;
189133
190 const initTestVal = 42;134 const amount = 1n * UNIQUE;
191 const changedTestVal = 111;
192135
193 const initTx = api.tx.testUtils.setTestValue(initTestVal);136 const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);
194 await submitTransactionAsync(alice, initTx);
195137
196 const changeErrTx = api.tx.testUtils.setTestValueAndRollback(changedTestVal);138 await helper.scheduler.scheduleAfter(scheduledId, waitForBlocks, {periodic})
139 .balance.transferToSubstrate(alice, bob.address, amount);
197140
198 await expect(scheduleAfter(141 await helper.wait.newBlocks(waitForBlocks + 1);
199 api,
200 changeErrTx,
201 alice,
202 waitForBlocks,
203 scheduledId,
204 )).to.not.be.rejected;
205142
206 await waitNewBlocks(waitForBlocks + 1);143 const bobsBalanceAfterFirst = await helper.balance.getSubstrate(bob.address);
207144
208 const testVal = (await api.query.testUtils.testValue()).toNumber();145 expect(bobsBalanceAfterFirst)
146 .to.be.equal(
209 expect(testVal, 'The test value should NOT be commited')147 bobsBalanceBefore + 1n * amount,
210 .not.to.be.equal(changedTestVal)148 '#1 Balance of the recipient should be increased by 1 * amount',
211 .and.to.be.equal(initTx);
212 });149 );
213 });
214150
215 it('Scheduled tasks should take correct fees', async function() {151 await helper.scheduler.cancelScheduled(alice, scheduledId);
216 await requirePallets(this, [Pallets.TestUtils]);152 await helper.wait.newBlocks(periodic.period);
217153
218 await usingApi(async api => {154 const bobsBalanceAfterSecond = await helper.balance.getSubstrate(bob.address);
219 const scheduledId = await makeScheduledId();155 expect(bobsBalanceAfterSecond)
156 .to.be.equal(
220 const waitForBlocks = 8;157 bobsBalanceAfterFirst,
221 const period = 2;158 '#2 Balance of the recipient should not be changed',
222 const repetitions = 2;159 );
160 });
223161
224 const dummyTx = api.tx.testUtils.justTakeFee();162 itSub.ifWithPallets('Scheduled tasks are transactional', [Pallets.Scheduler, Pallets.TestUtils], async ({helper}) => {
225
226 const signingInfo = await api.derive.tx.signingInfo(alice.address);163 const scheduledId = await helper.scheduler.makeScheduledId();
164 const waitForBlocks = 4;
227165
228 // We need to sign the tx because166 const initTestVal = 42;
229 // unsigned transactions does not have an inclusion fee167 const changedTestVal = 111;
230 dummyTx.sign(alice, {
231 blockHash: api.genesisHash,
232 genesisHash: api.genesisHash,
233 runtimeVersion: api.runtimeVersion,
234 nonce: signingInfo.nonce,
235 });
236168
237 const scheduledLen = dummyTx.callIndex.length;169 await helper.executeExtrinsic(
170 alice,
171 'api.tx.testUtils.setTestValue',
172 [initTestVal],
173 true,
174 );
238175
239 const queryInfo = await api.call.transactionPaymentApi.queryInfo(176 await helper.scheduler.scheduleAfter(scheduledId, waitForBlocks)
177 .executeExtrinsic(
178 alice,
179 'api.tx.testUtils.setTestValueAndRollback',
240 dummyTx.toHex(),180 [changedTestVal],
241 scheduledLen,181 true,
242 );182 );
243183
244 const expectedScheduledFee = (await queryInfo as RuntimeDispatchInfo)184 await helper.wait.newBlocks(waitForBlocks + 1);
245 .partialFee.toBigInt();
246185
247 await expect(scheduleAfter(186 const testVal = (await helper.api!.query.testUtils.testValue()).toNumber();
248 api,187 expect(testVal, 'The test value should NOT be commited')
249 dummyTx,
250 alice,188 .to.be.equal(initTestVal);
251 waitForBlocks,
252 scheduledId,
253 period,
254 repetitions,
255 )).to.not.be.rejected;189 });
256190
257 await waitNewBlocks(1);191 itSub.ifWithPallets('Scheduled tasks should take correct fees', [Pallets.Scheduler, Pallets.TestUtils], async function({helper}) {
192 const scheduledId = await helper.scheduler.makeScheduledId();
193 const waitForBlocks = 8;
194 const periodic = {
195 period: 2,
196 repetitions: 2,
197 };
258198
259 const aliceInitBalance = await getFreeBalance(alice);199 const dummyTx = helper.constructApiCall('api.tx.testUtils.justTakeFee', []);
260 let diff;200 const scheduledLen = dummyTx.callIndex.length;
261201
262 await waitNewBlocks(waitForBlocks);202 const expectedScheduledFee = (await helper.getPaymentInfo(alice, dummyTx, scheduledLen))
203 .partialFee.toBigInt();
263204
264 const aliceBalanceAfterFirst = await getFreeBalance(alice);205 await helper.scheduler.scheduleAfter(scheduledId, waitForBlocks, {periodic})
265 expect(
266 aliceBalanceAfterFirst < aliceInitBalance,206 .executeExtrinsic(alice, 'api.tx.testUtils.justTakeFee', [], true);
267 '[after execution #1] Scheduled task should take a fee',
268 ).to.be.true;
269207
270 diff = aliceInitBalance - aliceBalanceAfterFirst;208 await helper.wait.newBlocks(1);
271 expect(diff).to.be.equal(
272 expectedScheduledFee,
273 'Scheduled task should take the right amount of fees',
274 );
275209
276 await waitNewBlocks(period);210 const aliceInitBalance = await helper.balance.getSubstrate(alice.address);
211 let diff;
277212
278 const aliceBalanceAfterSecond = await getFreeBalance(alice);213 await helper.wait.newBlocks(waitForBlocks);
279 expect(
280 aliceBalanceAfterSecond < aliceBalanceAfterFirst,
281 '[after execution #2] Scheduled task should take a fee',
282 ).to.be.true;
283214
284 diff = aliceBalanceAfterFirst - aliceBalanceAfterSecond;215 const aliceBalanceAfterFirst = await helper.balance.getSubstrate(alice.address);
216 expect(
217 aliceBalanceAfterFirst < aliceInitBalance,
218 '[after execution #1] Scheduled task should take a fee',
219 ).to.be.true;
220
221 diff = aliceInitBalance - aliceBalanceAfterFirst;
285 expect(diff).to.be.equal(222 expect(diff).to.be.equal(
286 expectedScheduledFee,223 expectedScheduledFee,
287 'Scheduled task should take the right amount of fees',224 'Scheduled task should take the right amount of fees',
288 );225 );
226
227 await helper.wait.newBlocks(periodic.period);
228
229 const aliceBalanceAfterSecond = await helper.balance.getSubstrate(alice.address);
230 expect(
231 aliceBalanceAfterSecond < aliceBalanceAfterFirst,
232 '[after execution #2] Scheduled task should take a fee',
233 ).to.be.true;
234
235 diff = aliceBalanceAfterFirst - aliceBalanceAfterSecond;
236 expect(diff).to.be.equal(
237 expectedScheduledFee,
238 'Scheduled task should take the right amount of fees',
289 });239 );
290 });240 });
291241
292 // Check if we can cancel a scheduled periodic operation242 // Check if we can cancel a scheduled periodic operation
293 // in the same block in which it is running243 // in the same block in which it is running
294 it('Can cancel the periodic sheduled tx when the tx is running', async () => {244 itSub.ifWithPallets('Can cancel the periodic sheduled tx when the tx is running', [Pallets.Scheduler, Pallets.TestUtils], async ({helper}) => {
295 await usingApi(async api => {245 const currentBlockNumber = await helper.chain.getLatestBlockNumber();
296 const currentBlockNumber = await getBlockNumber(api);
297 const blocksBeforeExecution = 10;246 const blocksBeforeExecution = 10;
298 const firstExecutionBlockNumber = currentBlockNumber + blocksBeforeExecution;247 const firstExecutionBlockNumber = currentBlockNumber + blocksBeforeExecution;
299
300 const scheduledId = await makeScheduledId();
301 const scheduledCancelId = await makeScheduledId();
302248
303 const period = 5;249 const [
250 scheduledId,
304 const repetitions = 5;251 scheduledCancelId,
252 ] = await helper.scheduler.makeScheduledIds(2);
305253
306 const initTestVal = 0;254 const periodic = {
307 const incTestVal = initTestVal + 1;255 period: 5,
308 const finalTestVal = initTestVal + 2;
309 await executeTransaction(
310 api,
311 alice,256 repetitions: 5,
312 api.tx.testUtils.setTestValue(initTestVal),
313 );257 };
314258
315 const incTx = api.tx.testUtils.incTestValue();259 const initTestVal = 0;
260 const incTestVal = initTestVal + 1;
316 const cancelTx = api.tx.scheduler.cancelNamed(scheduledId);261 const finalTestVal = initTestVal + 2;
317262
318 await expect(scheduleAt(263 await helper.executeExtrinsic(
319 api, 264 alice,
320 incTx,
321 alice,
322 firstExecutionBlockNumber, 265 'api.tx.testUtils.setTestValue',
323 scheduledId, 266 [initTestVal],
324 period, 267 true,
325 repetitions,268 );
326 )).to.not.be.rejected;
327269
328 // Cancel the inc tx after 2 executions270 await helper.scheduler.scheduleAt(scheduledId, firstExecutionBlockNumber, {periodic})
329 // *in the same block* in which the second execution is scheduled
330 await expect(scheduleAt(
331 api,
332 cancelTx,271 .executeExtrinsic(
333 alice,272 alice,
334 firstExecutionBlockNumber + period,273 'api.tx.testUtils.incTestValue',
274 [],
335 scheduledCancelId,275 true,
336 )).to.not.be.rejected;276 );
337277
338 await waitNewBlocks(blocksBeforeExecution);278 // Cancel the inc tx after 2 executions
279 // *in the same block* in which the second execution is scheduled
280 await helper.scheduler.scheduleAt(scheduledCancelId, firstExecutionBlockNumber + periodic.period)
281 .scheduler.cancelScheduled(alice, scheduledId);
339282
340 // execution #0283 await helper.wait.newBlocks(blocksBeforeExecution);
341 expect((await api.query.testUtils.testValue()).toNumber())
342 .to.be.equal(incTestVal);
343284
344 await waitNewBlocks(period);285 // execution #0
286 expect((await helper.api!.query.testUtils.testValue()).toNumber())
287 .to.be.equal(incTestVal);
345288
346 // execution #1289 await helper.wait.newBlocks(periodic.period);
347 expect((await api.query.testUtils.testValue()).toNumber())
348 .to.be.equal(finalTestVal);
349290
350 for (let i = 1; i < repetitions; i++) {291 // execution #1
292 expect((await helper.api!.query.testUtils.testValue()).toNumber())
293 .to.be.equal(finalTestVal);
294
295 for (let i = 1; i < periodic.repetitions; i++) {
351 await waitNewBlocks(period);296 await waitNewBlocks(periodic.period);
352 expect((await api.query.testUtils.testValue()).toNumber())297 expect((await helper.api!.query.testUtils.testValue()).toNumber())
353 .to.be.equal(finalTestVal);298 .to.be.equal(finalTestVal);
354 }299 }
355 });
356 });300 });
357301
358 it('A scheduled operation can cancel itself', async () => {302 itSub.ifWithPallets('A scheduled operation can cancel itself', [Pallets.Scheduler, Pallets.TestUtils], async ({helper}) => {
359 await usingApi(async api => {303 const scheduledId = await helper.scheduler.makeScheduledId();
360 const scheduledId = await makeScheduledId();
361 const waitForBlocks = 8;304 const waitForBlocks = 8;
362 const period = 2;305 const periodic = {
363 const repetitions = 5;306 period: 2,
307 repetitions: 5,
308 };
364309
365 const initTestVal = 0;310 const initTestVal = 0;
366 const maxTestVal = 2;311 const maxTestVal = 2;
367312
368 await executeTransaction(313 await helper.executeExtrinsic(
369 api,314 alice,
315 'api.tx.testUtils.setTestValue',
316 [initTestVal],
317 true,
318 );
319
320 await helper.scheduler.scheduleAfter(scheduledId, waitForBlocks, {periodic})
321 .executeExtrinsic(
370 alice,322 alice,
371 api.tx.testUtils.setTestValue(initTestVal),323 'api.tx.testUtils.selfCancelingInc',
324 [scheduledId, maxTestVal],
325 true,
372 );326 );
373327
374 const selfCancelingTx = api.tx.testUtils.selfCancelingInc(scheduledId, maxTestVal);328 await helper.wait.newBlocks(waitForBlocks + 1);
375329
376 await expect(scheduleAfter(330 // execution #0
377 api,331 expect((await helper.api!.query.testUtils.testValue()).toNumber())
378 selfCancelingTx,332 .to.be.equal(initTestVal + 1);
379 alice,
380 waitForBlocks,
381 scheduledId,
382 period,
383 repetitions,
384 )).to.not.be.rejected;
385333
386 await waitNewBlocks(waitForBlocks + 1);334 await helper.wait.newBlocks(periodic.period);
387335
388 // execution #0336 // execution #1
389 expect((await api.query.testUtils.testValue()).toNumber())337 expect((await helper.api!.query.testUtils.testValue()).toNumber())
390 .to.be.equal(initTestVal + 1);338 .to.be.equal(initTestVal + 2);
391339
392 await waitNewBlocks(period);340 await helper.wait.newBlocks(periodic.period);
393341
394 // execution #1342 // <canceled>
395 expect((await api.query.testUtils.testValue()).toNumber())
396 .to.be.equal(initTestVal + 2);
397
398 await waitNewBlocks(period);
399
400 // <canceled>
401 expect((await api.query.testUtils.testValue()).toNumber())343 expect((await helper.api!.query.testUtils.testValue()).toNumber())
402 .to.be.equal(initTestVal + 2);344 .to.be.equal(initTestVal + 2);
403 });
404 });345 });
405});346});
406347
407describe('Negative Test: Scheduling', () => {348describe('Negative Test: Scheduling', () => {
408 let alice: IKeyringPair;349 let alice: IKeyringPair;
409 let bob: IKeyringPair;350 let bob: IKeyringPair;
410351
411 before(async function() {352 before(async () => {
412 await requirePallets(this, [Pallets.Scheduler]);
413
414 await usingApi(async (_, privateKeyWrapper) => {353 await usingPlaygrounds(async (_, privateKeyWrapper) => {
415 alice = privateKeyWrapper('//Alice');354 alice = privateKeyWrapper('//Alice');
416 bob = privateKeyWrapper('//Bob');355 bob = privateKeyWrapper('//Bob');
417 });356 });
418 });357 });
419358
420 it("Can't overwrite a scheduled ID", async () => {359 itSub.ifWithPallets("Can't overwrite a scheduled ID", [Pallets.Scheduler, Pallets.TestUtils], async ({helper}) => {
421 await usingApi(async api => {360 const collection = await helper.nft.mintDefaultCollection(alice);
422 const collectionId = await createCollectionExpectSuccess();
423 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');361 const token = await collection.mintToken(alice);
424 const scheduledId = await makeScheduledId();
425 const waitForBlocks = 4;
426 const amount = 1;
427362
428 await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, amount, waitForBlocks, scheduledId);363 const scheduledId = await helper.scheduler.makeScheduledId();
429 await expect(scheduleAfter(
430 api,
431 api.tx.balances.transfer(alice.address, 1n * UNIQUE),
432 bob, 364 const waitForBlocks = 4;
433 /* period = */ 2,
434 scheduledId,
435 )).to.be.rejectedWith(/scheduler\.FailedToSchedule/);
436365
437 const bobsBalanceBefore = await getFreeBalance(bob);366 await token.scheduleAfter(scheduledId, waitForBlocks)
367 .transfer(alice, {Substrate: bob.address});
438368
439 await waitNewBlocks(waitForBlocks + 1);369 await expect(helper.scheduler.scheduleAfter(scheduledId, waitForBlocks)
370 .balance.transferToSubstrate(alice, bob.address, 1n * UNIQUE))
371 .to.be.rejectedWith(/scheduler\.FailedToSchedule/);
440372
441 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(bob.address));373 const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);
374
375 await helper.wait.newBlocks(waitForBlocks + 1);
376
377 const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);
378
442 expect(bobsBalanceBefore).to.be.equal(await getFreeBalance(bob));379 expect(await token.getOwner()).to.be.deep.equal({Substrate: bob.address});
443 });380 expect(bobsBalanceBefore).to.be.equal(bobsBalanceAfter);
444 });381 });
445382
446 it("Can't cancel an operation which is not scheduled", async () => {383 itSub.ifWithPallets("Can't cancel an operation which is not scheduled", [Pallets.Scheduler, Pallets.TestUtils], async ({helper}) => {
447 await usingApi(async api => {384 const scheduledId = await helper.scheduler.makeScheduledId();
448 const scheduledId = await makeScheduledId();
449 await expect(cancelScheduled(api, alice, scheduledId)).to.be.rejectedWith(/scheduler\.NotFound/);385 await expect(helper.scheduler.cancelScheduled(alice, scheduledId))
450 });386 .to.be.rejectedWith(/scheduler\.NotFound/);
451 });387 });
452388
453 it("Can't cancel a non-owned scheduled operation", async () => {389 itSub.ifWithPallets("Can't cancel a non-owned scheduled operation", [Pallets.Scheduler, Pallets.TestUtils], async ({helper}) => {
454 await usingApi(async api => {390 const collection = await helper.nft.mintDefaultCollection(alice);
455 const collectionId = await createCollectionExpectSuccess();
456 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');391 const token = await collection.mintToken(alice);
457 const scheduledId = await makeScheduledId();
458 const waitForBlocks = 8;
459392
460 const amount = 1;393 const scheduledId = await helper.scheduler.makeScheduledId();
394 const waitForBlocks = 8;
461395
462 await scheduleTransferExpectSuccess(api, collectionId, tokenId, alice, bob, amount, waitForBlocks, scheduledId);396 await token.scheduleAfter(scheduledId, waitForBlocks)
463 await expect(cancelScheduled(api, bob, scheduledId)).to.be.rejectedWith(/BadOrigin/);397 .transfer(alice, {Substrate: bob.address});
464398
465 await waitNewBlocks(waitForBlocks + 1);399 await expect(helper.scheduler.cancelScheduled(bob, scheduledId))
400 .to.be.rejectedWith(/badOrigin/);
466401
467 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal(normalizeAccountId(bob.address));402 await helper.wait.newBlocks(waitForBlocks + 1);
403
468 });404 expect(await token.getOwner()).to.be.deep.equal({Substrate: bob.address});
469 });405 });
470});406});
471407