@@ -4,7 +4,7 @@ import SmartTransactionsController, {
4
4
DEFAULT_INTERVAL ,
5
5
} from './SmartTransactionsController' ;
6
6
import { API_BASE_URL , CHAIN_IDS , CHAIN_IDS_HEX_TO_DEC } from './constants' ;
7
- import { SmartTransaction } from './types' ;
7
+ import { SmartTransaction , SmartTransactionStatuses } from './types' ;
8
8
9
9
const confirmExternalMock = jest . fn ( ) ;
10
10
@@ -31,9 +31,11 @@ jest.mock('ethers', () => ({
31
31
} ,
32
32
} ) ) ;
33
33
34
+ const addressFrom = '0x268392a24B6b093127E8581eAfbD1DA228bAdAe3' ;
35
+
34
36
const createUnsignedTransaction = ( ) => {
35
37
return {
36
- from : '0x268392a24B6b093127E8581eAfbD1DA228bAdAe3' ,
38
+ from : addressFrom ,
37
39
to : '0x0000000000000000000000000000000000000000' ,
38
40
value : 0 ,
39
41
data : '0x' ,
@@ -195,6 +197,8 @@ const testHistory = [
195
197
196
198
const ethereumChainIdDec = CHAIN_IDS_HEX_TO_DEC [ CHAIN_IDS . ETHEREUM ] ;
197
199
200
+ const trackMetaMetricsEventSpy = jest . fn ( ) ;
201
+
198
202
describe ( 'SmartTransactionsController' , ( ) => {
199
203
let smartTransactionsController : SmartTransactionsController ;
200
204
let networkListener : ( networkState : NetworkState ) => void ;
@@ -217,12 +221,10 @@ describe('SmartTransactionsController', () => {
217
221
txController : {
218
222
confirmExternalTransaction : confirmExternalMock ,
219
223
} ,
220
- trackMetaMetricsEvent : jest . fn ( ) ,
224
+ trackMetaMetricsEvent : trackMetaMetricsEventSpy ,
221
225
} ) ;
222
-
223
- jest
224
- . spyOn ( smartTransactionsController , 'checkPoll' )
225
- . mockImplementation ( ( ) => ( { } ) ) ;
226
+ // eslint-disable-next-line jest/prefer-spy-on
227
+ smartTransactionsController . subscribe = jest . fn ( ) ;
226
228
} ) ;
227
229
228
230
afterEach ( async ( ) => {
@@ -264,6 +266,35 @@ describe('SmartTransactionsController', () => {
264
266
} ) ;
265
267
} ) ;
266
268
269
+ describe ( 'checkPoll' , ( ) => {
270
+ it ( 'calls poll if there is no pending transaction and pending transactions' , ( ) => {
271
+ const pollSpy = jest
272
+ . spyOn ( smartTransactionsController , 'poll' )
273
+ . mockImplementation ( ( ) => {
274
+ return new Promise ( ( ) => ( { } ) ) ;
275
+ } ) ;
276
+ const { smartTransactionsState } = smartTransactionsController . state ;
277
+ const pendingStx = createStateAfterPending ( ) ;
278
+ smartTransactionsController . update ( {
279
+ smartTransactionsState : {
280
+ ...smartTransactionsState ,
281
+ smartTransactions : {
282
+ [ CHAIN_IDS . ETHEREUM ] : pendingStx as SmartTransaction [ ] ,
283
+ } ,
284
+ } ,
285
+ } ) ;
286
+ expect ( pollSpy ) . toHaveBeenCalled ( ) ;
287
+ } ) ;
288
+
289
+ it ( 'calls stop if there is a timeoutHandle and no pending transactions' , ( ) => {
290
+ const stopSpy = jest . spyOn ( smartTransactionsController , 'stop' ) ;
291
+ smartTransactionsController . timeoutHandle = setInterval ( ( ) => ( { } ) ) ;
292
+ smartTransactionsController . checkPoll ( smartTransactionsController . state ) ;
293
+ expect ( stopSpy ) . toHaveBeenCalled ( ) ;
294
+ clearInterval ( smartTransactionsController . timeoutHandle ) ;
295
+ } ) ;
296
+ } ) ;
297
+
267
298
describe ( 'poll' , ( ) => {
268
299
it ( 'does not call updateSmartTransactions on unsupported networks' , async ( ) => {
269
300
const updateSmartTransactionsSpy = jest . spyOn (
@@ -276,6 +307,59 @@ describe('SmartTransactionsController', () => {
276
307
} ) ;
277
308
} ) ;
278
309
310
+ describe ( 'updateSmartTransactions' , ( ) => {
311
+ it ( 'calls fetchSmartTransactionsStatus if there are pending transactions' , ( ) => {
312
+ const fetchSmartTransactionsStatusSpy = jest
313
+ . spyOn ( smartTransactionsController , 'fetchSmartTransactionsStatus' )
314
+ . mockImplementation ( ( ) => {
315
+ return new Promise ( ( ) => ( { } ) ) ;
316
+ } ) ;
317
+ const { smartTransactionsState } = smartTransactionsController . state ;
318
+ const pendingStx = createStateAfterPending ( ) ;
319
+ smartTransactionsController . update ( {
320
+ smartTransactionsState : {
321
+ ...smartTransactionsState ,
322
+ smartTransactions : {
323
+ [ CHAIN_IDS . ETHEREUM ] : pendingStx as SmartTransaction [ ] ,
324
+ } ,
325
+ } ,
326
+ } ) ;
327
+ expect ( fetchSmartTransactionsStatusSpy ) . toHaveBeenCalled ( ) ;
328
+ } ) ;
329
+ } ) ;
330
+
331
+ describe ( 'trackStxStatusChange' , ( ) => {
332
+ it ( 'does not track if no prevSmartTransactions' , ( ) => {
333
+ const smartTransaction = createStateAfterPending ( ) [ 0 ] ;
334
+ smartTransactionsController . trackStxStatusChange (
335
+ smartTransaction as SmartTransaction ,
336
+ ) ;
337
+ expect ( trackMetaMetricsEventSpy ) . not . toHaveBeenCalled ( ) ;
338
+ } ) ;
339
+
340
+ it ( 'does not track if smartTransaction and prevSmartTransaction have the same status' , ( ) => {
341
+ const smartTransaction = createStateAfterPending ( ) [ 0 ] ;
342
+ smartTransactionsController . trackStxStatusChange (
343
+ smartTransaction as SmartTransaction ,
344
+ smartTransaction as SmartTransaction ,
345
+ ) ;
346
+ expect ( trackMetaMetricsEventSpy ) . not . toHaveBeenCalled ( ) ;
347
+ } ) ;
348
+
349
+ it ( 'tracks status change if smartTransaction and prevSmartTransaction have different statuses' , ( ) => {
350
+ const smartTransaction = {
351
+ ...createStateAfterPending ( ) [ 0 ] ,
352
+ swapMetaData : { } ,
353
+ } ;
354
+ const prevSmartTransaction = { ...smartTransaction , status : '' } ;
355
+ smartTransactionsController . trackStxStatusChange (
356
+ smartTransaction as SmartTransaction ,
357
+ prevSmartTransaction as SmartTransaction ,
358
+ ) ;
359
+ expect ( trackMetaMetricsEventSpy ) . toHaveBeenCalled ( ) ;
360
+ } ) ;
361
+ } ) ;
362
+
279
363
describe ( 'setOptInState' , ( ) => {
280
364
it ( 'sets optIn state' , ( ) => {
281
365
smartTransactionsController . setOptInState ( true ) ;
@@ -310,6 +394,11 @@ describe('SmartTransactionsController', () => {
310
394
} ) ;
311
395
312
396
describe ( 'submitSignedTransactions' , ( ) => {
397
+ beforeEach ( ( ) => {
398
+ // eslint-disable-next-line jest/prefer-spy-on
399
+ smartTransactionsController . checkPoll = jest . fn ( ( ) => ( { } ) ) ;
400
+ } ) ;
401
+
313
402
it ( 'submits a smart transaction with signed transactions' , async ( ) => {
314
403
const signedTransaction = createSignedTransaction ( ) ;
315
404
const signedCanceledTransaction = createSignedCanceledTransaction ( ) ;
@@ -332,6 +421,11 @@ describe('SmartTransactionsController', () => {
332
421
} ) ;
333
422
334
423
describe ( 'fetchSmartTransactionsStatus' , ( ) => {
424
+ beforeEach ( ( ) => {
425
+ // eslint-disable-next-line jest/prefer-spy-on
426
+ smartTransactionsController . checkPoll = jest . fn ( ( ) => ( { } ) ) ;
427
+ } ) ;
428
+
335
429
it ( 'fetches a pending status for a single smart transaction via batchStatus API' , async ( ) => {
336
430
const uuids = [ 'uuid1' ] ;
337
431
const pendingBatchStatusApiResponse = createPendingBatchStatusApiResponse ( ) ;
@@ -395,6 +489,11 @@ describe('SmartTransactionsController', () => {
395
489
} ) ;
396
490
397
491
describe ( 'updateSmartTransaction' , ( ) => {
492
+ beforeEach ( ( ) => {
493
+ // eslint-disable-next-line jest/prefer-spy-on
494
+ smartTransactionsController . checkPoll = jest . fn ( ( ) => ( { } ) ) ;
495
+ } ) ;
496
+
398
497
it ( 'updates smart transaction based on uuid' , ( ) => {
399
498
const pendingStx = {
400
499
...createStateAfterPending ( ) [ 0 ] ,
@@ -453,6 +552,11 @@ describe('SmartTransactionsController', () => {
453
552
} ) ;
454
553
455
554
describe ( 'confirmSmartTransaction' , ( ) => {
555
+ beforeEach ( ( ) => {
556
+ // eslint-disable-next-line jest/prefer-spy-on
557
+ smartTransactionsController . checkPoll = jest . fn ( ( ) => ( { } ) ) ;
558
+ } ) ;
559
+
456
560
it ( 'calls confirm external transaction' , async ( ) => {
457
561
const successfulStx = {
458
562
...createStateAfterSuccess ( ) [ 0 ] ,
@@ -463,6 +567,20 @@ describe('SmartTransactionsController', () => {
463
567
) ;
464
568
expect ( confirmExternalMock ) . toHaveBeenCalled ( ) ;
465
569
} ) ;
570
+
571
+ it ( 'throws an error if ethersProvider fails' , async ( ) => {
572
+ smartTransactionsController . ethersProvider . getTransactionReceipt . mockRejectedValueOnce (
573
+ 'random error' as never ,
574
+ ) ;
575
+ const successfulStx = {
576
+ ...createStateAfterSuccess ( ) [ 0 ] ,
577
+ history : testHistory ,
578
+ } ;
579
+ await smartTransactionsController . confirmSmartTransaction (
580
+ successfulStx as SmartTransaction ,
581
+ ) ;
582
+ expect ( trackMetaMetricsEventSpy ) . toHaveBeenCalled ( ) ;
583
+ } ) ;
466
584
} ) ;
467
585
468
586
describe ( 'cancelSmartTransaction' , ( ) => {
@@ -487,4 +605,43 @@ describe('SmartTransactionsController', () => {
487
605
expect ( configureSpy ) . toHaveBeenCalledTimes ( 0 ) ;
488
606
} ) ;
489
607
} ) ;
608
+
609
+ describe ( 'getTransactions' , ( ) => {
610
+ beforeEach ( ( ) => {
611
+ // eslint-disable-next-line jest/prefer-spy-on
612
+ smartTransactionsController . checkPoll = jest . fn ( ( ) => ( { } ) ) ;
613
+ } ) ;
614
+
615
+ it ( 'retrieves smart transactions by addressFrom and status' , ( ) => {
616
+ const { smartTransactionsState } = smartTransactionsController . state ;
617
+ const pendingStx = {
618
+ ...createStateAfterPending ( ) [ 0 ] ,
619
+ history : testHistory ,
620
+ txParams : {
621
+ from : addressFrom ,
622
+ } ,
623
+ } ;
624
+ smartTransactionsController . update ( {
625
+ smartTransactionsState : {
626
+ ...smartTransactionsState ,
627
+ smartTransactions : {
628
+ [ CHAIN_IDS . ETHEREUM ] : [ pendingStx ] as SmartTransaction [ ] ,
629
+ } ,
630
+ } ,
631
+ } ) ;
632
+ const pendingStxs = smartTransactionsController . getTransactions ( {
633
+ addressFrom,
634
+ status : SmartTransactionStatuses . PENDING ,
635
+ } ) ;
636
+ expect ( pendingStxs ) . toStrictEqual ( [ pendingStx ] ) ;
637
+ } ) ;
638
+
639
+ it ( 'returns empty array if there are no smart transactions' , ( ) => {
640
+ const transactions = smartTransactionsController . getTransactions ( {
641
+ addressFrom,
642
+ status : SmartTransactionStatuses . PENDING ,
643
+ } ) ;
644
+ expect ( transactions ) . toStrictEqual ( [ ] ) ;
645
+ } ) ;
646
+ } ) ;
490
647
} ) ;
0 commit comments