1- import { Component , Provider , Injectable , ErrorHandler } from '@angular/core' ;
1+ import { Injectable , ErrorHandler } from '@angular/core' ;
22import { TestBed } from '@angular/core/testing' ;
33import {
44 NavigationEnd ,
77 NavigationCancel ,
88 NavigationError ,
99} 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' ;
1211import { filter , first , mapTo , take } from 'rxjs/operators' ;
1312
1413import {
@@ -22,9 +21,9 @@ import {
2221 routerReducer ,
2322 RouterReducerState ,
2423 RouterStateSerializer ,
25- StoreRouterConfig ,
26- StoreRouterConnectingModule ,
24+ StateKeyOrSelector ,
2725} from '../src' ;
26+ import { createTestModule } from './utils' ;
2827
2928describe ( 'integration spec' , ( ) => {
3029 it ( 'should work' , ( done : any ) => {
@@ -677,12 +676,76 @@ describe('integration spec', () => {
677676 } ;
678677
679678 createTestModule ( {
680- reducers : { reducer } ,
679+ reducers : { 'router-reducer' : reducer } ,
681680 config : { stateKey : 'router-reducer' } ,
682681 } ) ;
683682
684683 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+ } ) ;
686749
687750 router
688751 . navigateByUrl ( '/' )
@@ -825,62 +888,6 @@ describe('integration spec', () => {
825888 } ) ;
826889} ) ;
827890
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-
884891function waitForNavigation ( router : Router , event : any = NavigationEnd ) {
885892 return router . events
886893 . pipe (
@@ -897,7 +904,11 @@ function waitForNavigation(router: Router, event: any = NavigationEnd) {
897904 * Example: router event is fired -> store is updated -> store log appears before router log
898905 * Also, actions$ always fires the next action AFTER the store is updated
899906 */
900- function logOfRouterAndActionsAndStore ( ) : any [ ] {
907+ function logOfRouterAndActionsAndStore (
908+ options : { stateKey : StateKeyOrSelector } = {
909+ stateKey : 'reducer' ,
910+ }
911+ ) : any [ ] {
901912 const router : Router = TestBed . get ( Router ) ;
902913 const store : Store < any > = TestBed . get ( Store ) ;
903914 // Not using effects' Actions to avoid @ngrx/effects dependency
@@ -915,6 +926,12 @@ function logOfRouterAndActionsAndStore(): any[] {
915926 actions$ . subscribe ( action =>
916927 log . push ( { type : 'action' , action : action . type } )
917928 ) ;
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+ } ) ;
919936 return log ;
920937}
0 commit comments