@@ -14,6 +14,7 @@ import {
14
14
addListenerAction ,
15
15
removeListenerAction ,
16
16
TaskAbortError ,
17
+ clearListenerMiddlewareAction ,
17
18
} from '../index'
18
19
19
20
import type {
@@ -492,6 +493,109 @@ describe('createActionListenerMiddleware', () => {
492
493
} )
493
494
} )
494
495
496
+ describe ( 'clear listeners' , ( ) => {
497
+ test ( 'dispatch(clearListenerAction()) cancels running listeners and removes all subscriptions' , async ( ) => {
498
+ const listener1Test = deferred ( )
499
+ let listener1Calls = 0
500
+ let listener2Calls = 0
501
+ let listener3Calls = 0
502
+
503
+ middleware . addListener ( {
504
+ actionCreator : testAction1 ,
505
+ async listener ( _ , listenerApi ) {
506
+ listener1Calls ++
507
+ listenerApi . signal . addEventListener (
508
+ 'abort' ,
509
+ ( ) => listener1Test . resolve ( listener1Calls ) ,
510
+ { once : true }
511
+ )
512
+ await listenerApi . condition ( ( ) => true )
513
+ listener1Test . reject ( new Error ( 'unreachable: listener1Test' ) )
514
+ } ,
515
+ } )
516
+
517
+ middleware . addListener ( {
518
+ actionCreator : clearListenerMiddlewareAction ,
519
+ listener ( ) {
520
+ listener2Calls ++
521
+ } ,
522
+ } )
523
+
524
+ middleware . addListener ( {
525
+ predicate : ( ) => true ,
526
+ listener ( ) {
527
+ listener3Calls ++
528
+ } ,
529
+ } )
530
+
531
+ store . dispatch ( testAction1 ( 'a' ) )
532
+ store . dispatch ( clearListenerMiddlewareAction ( ) )
533
+ store . dispatch ( testAction1 ( 'b' ) )
534
+ expect ( await listener1Test ) . toBe ( 1 )
535
+ expect ( listener1Calls ) . toBe ( 1 )
536
+ expect ( listener3Calls ) . toBe ( 1 )
537
+ expect ( listener2Calls ) . toBe ( 0 )
538
+ } )
539
+
540
+ test ( 'clear() cancels running listeners and removes all subscriptions' , async ( ) => {
541
+ const listener1Test = deferred ( )
542
+
543
+ let listener1Calls = 0
544
+ let listener2Calls = 0
545
+
546
+ middleware . addListener ( {
547
+ actionCreator : testAction1 ,
548
+ async listener ( _ , listenerApi ) {
549
+ listener1Calls ++
550
+ listenerApi . signal . addEventListener (
551
+ 'abort' ,
552
+ ( ) => listener1Test . resolve ( listener1Calls ) ,
553
+ { once : true }
554
+ )
555
+ await listenerApi . condition ( ( ) => true )
556
+ listener1Test . reject ( new Error ( 'unreachable: listener1Test' ) )
557
+ } ,
558
+ } )
559
+
560
+ middleware . addListener ( {
561
+ actionCreator : testAction2 ,
562
+ listener ( ) {
563
+ listener2Calls ++
564
+ } ,
565
+ } )
566
+
567
+ store . dispatch ( testAction1 ( 'a' ) )
568
+
569
+ middleware . clear ( )
570
+ store . dispatch ( testAction1 ( 'b' ) )
571
+ store . dispatch ( testAction2 ( 'c' ) )
572
+
573
+ expect ( listener2Calls ) . toBe ( 0 )
574
+ expect ( await listener1Test ) . toBe ( 1 )
575
+ } )
576
+
577
+ test ( 'clear() cancels all running forked tasks' , async ( ) => {
578
+ const fork1Test = deferred ( )
579
+
580
+ middleware . addListener ( {
581
+ actionCreator : testAction1 ,
582
+ async listener ( _ , { fork } ) {
583
+ const taskResult = await fork ( ( ) => {
584
+ return 3
585
+ } ) . result
586
+ fork1Test . resolve ( taskResult )
587
+ } ,
588
+ } )
589
+
590
+ store . dispatch ( testAction1 ( 'a' ) )
591
+
592
+ middleware . clear ( )
593
+ store . dispatch ( testAction1 ( 'b' ) )
594
+
595
+ expect ( await fork1Test ) . toHaveProperty ( 'status' , 'cancelled' )
596
+ } )
597
+ } )
598
+
495
599
describe ( 'Listener API' , ( ) => {
496
600
test ( 'Passes both getState and getOriginalState in the API' , ( ) => {
497
601
const store = configureStore ( {
0 commit comments