@@ -16,6 +16,7 @@ import {
16
16
const middlewareApi = {
17
17
getState : expect . any ( Function ) ,
18
18
getOriginalState : expect . any ( Function ) ,
19
+ condition : expect . any ( Function ) ,
19
20
extra : undefined ,
20
21
dispatch : expect . any ( Function ) ,
21
22
currentPhase : expect . stringMatching ( / b e f o r e R e d u c e r | a f t e r R e d u c e r / ) ,
@@ -45,6 +46,10 @@ describe('createActionListenerMiddleware', () => {
45
46
} )
46
47
const { increment } = counterSlice . actions
47
48
49
+ function delay ( ms : number ) {
50
+ return new Promise ( ( resolve ) => setTimeout ( resolve , ms ) )
51
+ }
52
+
48
53
let reducer : jest . Mock
49
54
let middleware : ReturnType < typeof createActionListenerMiddleware >
50
55
@@ -469,4 +474,87 @@ describe('createActionListenerMiddleware', () => {
469
474
store . dispatch ( testAction1 ( 'a' ) )
470
475
expect ( listener . mock . calls ) . toEqual ( [ [ testAction1 ( 'a' ) , middlewareApi ] ] )
471
476
} )
477
+
478
+ test ( 'condition method resolves promise when the predicate succeeds' , async ( ) => {
479
+ const store = configureStore ( {
480
+ reducer : counterSlice . reducer ,
481
+ middleware : ( gDM ) => gDM ( ) . prepend ( middleware ) ,
482
+ } )
483
+
484
+ let finalCount = 0
485
+ let listenerStarted = false
486
+
487
+ middleware . addListener (
488
+ // @ts -expect-error
489
+ ( action , currentState : CounterState ) => {
490
+ return increment . match ( action ) && currentState . value === 0
491
+ } ,
492
+ async ( action , listenerApi ) => {
493
+ listenerStarted = true
494
+ const result = await listenerApi . condition (
495
+ // @ts -expect-error
496
+ ( action , currentState : CounterState ) => {
497
+ return currentState . value === 3
498
+ }
499
+ )
500
+
501
+ expect ( result ) . toBe ( true )
502
+ const latestState = listenerApi . getState ( ) as CounterState
503
+ finalCount = latestState . value
504
+ } ,
505
+ { when : 'beforeReducer' }
506
+ )
507
+
508
+ store . dispatch ( increment ( ) )
509
+ expect ( listenerStarted ) . toBe ( true )
510
+ await delay ( 50 )
511
+ store . dispatch ( increment ( ) )
512
+ store . dispatch ( increment ( ) )
513
+
514
+ await delay ( 50 )
515
+
516
+ expect ( finalCount ) . toBe ( 3 )
517
+ } )
518
+
519
+ test ( 'condition method resolves promise when there is a timeout' , async ( ) => {
520
+ const store = configureStore ( {
521
+ reducer : counterSlice . reducer ,
522
+ middleware : ( gDM ) => gDM ( ) . prepend ( middleware ) ,
523
+ } )
524
+
525
+ let finalCount = 0
526
+ let listenerStarted = false
527
+
528
+ middleware . addListener (
529
+ // @ts -expect-error
530
+ ( action , currentState : CounterState ) => {
531
+ return increment . match ( action ) && currentState . value === 0
532
+ } ,
533
+ async ( action , listenerApi ) => {
534
+ listenerStarted = true
535
+ const result = await listenerApi . condition (
536
+ // @ts -expect-error
537
+ ( action , currentState : CounterState ) => {
538
+ return currentState . value === 3
539
+ } ,
540
+ 50
541
+ )
542
+
543
+ expect ( result ) . toBe ( false )
544
+ const latestState = listenerApi . getState ( ) as CounterState
545
+ finalCount = latestState . value
546
+ } ,
547
+ { when : 'beforeReducer' }
548
+ )
549
+
550
+ store . dispatch ( increment ( ) )
551
+ expect ( listenerStarted ) . toBe ( true )
552
+
553
+ store . dispatch ( increment ( ) )
554
+
555
+ await delay ( 150 )
556
+ store . dispatch ( increment ( ) )
557
+
558
+ expect ( finalCount ) . toBe ( 2 )
559
+ } )
472
560
} )
0 commit comments