1
- import { Component , Provider , Injectable , ErrorHandler } from '@angular/core' ;
1
+ import { Injectable , ErrorHandler } from '@angular/core' ;
2
2
import { TestBed } from '@angular/core/testing' ;
3
3
import {
4
4
NavigationEnd ,
7
7
NavigationCancel ,
8
8
NavigationError ,
9
9
} from '@angular/router' ;
10
- import { RouterTestingModule } from '@angular/router/testing' ;
11
- import { Store , StoreModule , ScannedActionsSubject } from '@ngrx/store' ;
10
+ import { Store , ScannedActionsSubject } from '@ngrx/store' ;
12
11
import { filter , first , mapTo , take } from 'rxjs/operators' ;
13
12
14
13
import {
@@ -22,9 +21,9 @@ import {
22
21
routerReducer ,
23
22
RouterReducerState ,
24
23
RouterStateSerializer ,
25
- StoreRouterConfig ,
26
- StoreRouterConnectingModule ,
24
+ StateKeyOrSelector ,
27
25
} from '../src' ;
26
+ import { createTestModule } from './utils' ;
28
27
29
28
describe ( 'integration spec' , ( ) => {
30
29
it ( 'should work' , ( done : any ) => {
@@ -677,12 +676,76 @@ describe('integration spec', () => {
677
676
} ;
678
677
679
678
createTestModule ( {
680
- reducers : { reducer } ,
679
+ reducers : { 'router-reducer' : reducer } ,
681
680
config : { stateKey : 'router-reducer' } ,
682
681
} ) ;
683
682
684
683
const router : Router = TestBed . get ( Router ) ;
685
- const log = logOfRouterAndActionsAndStore ( ) ;
684
+ const log = logOfRouterAndActionsAndStore ( { stateKey : 'router-reducer' } ) ;
685
+
686
+ router
687
+ . navigateByUrl ( '/' )
688
+ . then ( ( ) => {
689
+ expect ( log ) . toEqual ( [
690
+ { type : 'store' , state : '' } , // init event. has nothing to do with the router
691
+ { type : 'store' , state : '' } , // ROUTER_REQUEST event in the store
692
+ { type : 'action' , action : ROUTER_REQUEST } ,
693
+ { type : 'router' , event : 'NavigationStart' , url : '/' } ,
694
+ { type : 'store' , state : '/' } , // ROUTER_NAVIGATION event in the store
695
+ { type : 'action' , action : ROUTER_NAVIGATION } ,
696
+ { type : 'router' , event : 'RoutesRecognized' , url : '/' } ,
697
+ { type : 'router' , event : 'GuardsCheckStart' , url : '/' } ,
698
+ { type : 'router' , event : 'GuardsCheckEnd' , url : '/' } ,
699
+ { type : 'router' , event : 'ResolveStart' , url : '/' } ,
700
+ { type : 'router' , event : 'ResolveEnd' , url : '/' } ,
701
+ { type : 'store' , state : '/' } , // ROUTER_NAVIGATED event in the store
702
+ { type : 'action' , action : ROUTER_NAVIGATED } ,
703
+ { type : 'router' , event : 'NavigationEnd' , url : '/' } ,
704
+ ] ) ;
705
+ } )
706
+ . then ( ( ) => {
707
+ log . splice ( 0 ) ;
708
+ return router . navigateByUrl ( 'next' ) ;
709
+ } )
710
+ . then ( ( ) => {
711
+ expect ( log ) . toEqual ( [
712
+ { type : 'store' , state : '/' } ,
713
+ { type : 'action' , action : ROUTER_REQUEST } ,
714
+ { type : 'router' , event : 'NavigationStart' , url : '/next' } ,
715
+ { type : 'store' , state : '/next' } ,
716
+ { type : 'action' , action : ROUTER_NAVIGATION } ,
717
+ { type : 'router' , event : 'RoutesRecognized' , url : '/next' } ,
718
+ { type : 'router' , event : 'GuardsCheckStart' , url : '/next' } ,
719
+ { type : 'router' , event : 'GuardsCheckEnd' , url : '/next' } ,
720
+ { type : 'router' , event : 'ResolveStart' , url : '/next' } ,
721
+ { type : 'router' , event : 'ResolveEnd' , url : '/next' } ,
722
+ { type : 'store' , state : '/next' } ,
723
+ { type : 'action' , action : ROUTER_NAVIGATED } ,
724
+ { type : 'router' , event : 'NavigationEnd' , url : '/next' } ,
725
+ ] ) ;
726
+
727
+ done ( ) ;
728
+ } ) ;
729
+ } ) ;
730
+
731
+ it ( 'should work when defining state selector' , ( done : any ) => {
732
+ const reducer = ( state : string = '' , action : RouterAction < any > ) => {
733
+ if ( action . type === ROUTER_NAVIGATION ) {
734
+ return action . payload . routerState . url . toString ( ) ;
735
+ } else {
736
+ return state ;
737
+ }
738
+ } ;
739
+
740
+ createTestModule ( {
741
+ reducers : { routerReducer : reducer } ,
742
+ config : { stateKey : ( state : any ) => state . routerReducer } ,
743
+ } ) ;
744
+
745
+ const router : Router = TestBed . get ( Router ) ;
746
+ const log = logOfRouterAndActionsAndStore ( {
747
+ stateKey : ( state : any ) => state . routerReducer ,
748
+ } ) ;
686
749
687
750
router
688
751
. navigateByUrl ( '/' )
@@ -825,62 +888,6 @@ describe('integration spec', () => {
825
888
} ) ;
826
889
} ) ;
827
890
828
- function createTestModule (
829
- opts : {
830
- reducers ?: any ;
831
- canActivate ?: Function ;
832
- canLoad ?: Function ;
833
- providers ?: Provider [ ] ;
834
- config ?: StoreRouterConfig ;
835
- } = { }
836
- ) {
837
- @Component ( {
838
- selector : 'test-app' ,
839
- template : '<router-outlet></router-outlet>' ,
840
- } )
841
- class AppCmp { }
842
-
843
- @Component ( {
844
- selector : 'pagea-cmp' ,
845
- template : 'pagea-cmp' ,
846
- } )
847
- class SimpleCmp { }
848
-
849
- TestBed . configureTestingModule ( {
850
- declarations : [ AppCmp , SimpleCmp ] ,
851
- imports : [
852
- StoreModule . forRoot ( opts . reducers ) ,
853
- RouterTestingModule . withRoutes ( [
854
- { path : '' , component : SimpleCmp } ,
855
- {
856
- path : 'next' ,
857
- component : SimpleCmp ,
858
- canActivate : [ 'CanActivateNext' ] ,
859
- } ,
860
- {
861
- path : 'load' ,
862
- loadChildren : 'test' ,
863
- canLoad : [ 'CanLoadNext' ] ,
864
- } ,
865
- ] ) ,
866
- StoreRouterConnectingModule . forRoot ( opts . config ) ,
867
- ] ,
868
- providers : [
869
- {
870
- provide : 'CanActivateNext' ,
871
- useValue : opts . canActivate || ( ( ) => true ) ,
872
- } ,
873
- {
874
- provide : 'CanLoadNext' ,
875
- useValue : opts . canLoad || ( ( ) => true ) ,
876
- } ,
877
- opts . providers || [ ] ,
878
- ] ,
879
- } ) ;
880
-
881
- TestBed . createComponent ( AppCmp ) ;
882
- }
883
-
884
891
function waitForNavigation ( router : Router , event : any = NavigationEnd ) {
885
892
return router . events
886
893
. pipe (
@@ -897,7 +904,11 @@ function waitForNavigation(router: Router, event: any = NavigationEnd) {
897
904
* Example: router event is fired -> store is updated -> store log appears before router log
898
905
* Also, actions$ always fires the next action AFTER the store is updated
899
906
*/
900
- function logOfRouterAndActionsAndStore ( ) : any [ ] {
907
+ function logOfRouterAndActionsAndStore (
908
+ options : { stateKey : StateKeyOrSelector } = {
909
+ stateKey : 'reducer' ,
910
+ }
911
+ ) : any [ ] {
901
912
const router : Router = TestBed . get ( Router ) ;
902
913
const store : Store < any > = TestBed . get ( Store ) ;
903
914
// Not using effects' Actions to avoid @ngrx/effects dependency
@@ -915,6 +926,12 @@ function logOfRouterAndActionsAndStore(): any[] {
915
926
actions$ . subscribe ( action =>
916
927
log . push ( { type : 'action' , action : action . type } )
917
928
) ;
918
- store . subscribe ( store => log . push ( { type : 'store' , state : store . reducer } ) ) ;
929
+ store . subscribe ( store => {
930
+ if ( typeof options . stateKey === 'function' ) {
931
+ log . push ( { type : 'store' , state : options . stateKey ( store ) } ) ;
932
+ } else {
933
+ log . push ( { type : 'store' , state : store [ options . stateKey ] } ) ;
934
+ }
935
+ } ) ;
919
936
return log ;
920
937
}
0 commit comments