diff --git a/modules/@angular/router/src/router.ts b/modules/@angular/router/src/router.ts index bf9465d273..ef8ea7c28f 100644 --- a/modules/@angular/router/src/router.ts +++ b/modules/@angular/router/src/router.ts @@ -572,7 +572,7 @@ export class PreActivation { .map(s => { if (s instanceof CanActivate) { return andObservables( - from([this.runCanActivate(s.route), this.runCanActivateChild(s.path)])); + from([this.runCanActivateChild(s.path), this.runCanActivate(s.route)])); } else if (s instanceof CanDeactivate) { // workaround https://github.com/Microsoft/TypeScript/issues/7271 const s2 = s as CanDeactivate; diff --git a/modules/@angular/router/test/integration.spec.ts b/modules/@angular/router/test/integration.spec.ts index 99c5d821d0..978a077e50 100644 --- a/modules/@angular/router/test/integration.spec.ts +++ b/modules/@angular/router/test/integration.spec.ts @@ -19,6 +19,7 @@ import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, Even import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing'; + describe('Integration', () => { beforeEach(() => { TestBed.configureTestingModule({ @@ -1271,6 +1272,65 @@ describe('Integration', () => { }))); }); }); + + describe('order', () => { + + class Logger { + logs: string[] = []; + add(thing: string) { this.logs.push(thing); } + } + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + Logger, { + provide: 'canActivateChild_parent', + useFactory: (logger: Logger) => () => (logger.add('canActivateChild_parent'), true), + deps: [Logger] + }, + { + provide: 'canActivate_team', + useFactory: (logger: Logger) => () => (logger.add('canActivate_team'), true), + deps: [Logger] + }, + { + provide: 'canDeactivate_team', + useFactory: (logger: Logger) => () => (logger.add('canDeactivate_team'), true), + deps: [Logger] + } + ] + }); + }); + + it('should call guards in the right order', + fakeAsync(inject( + [Router, Location, Logger], (router: Router, location: Location, logger: Logger) => { + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{ + path: '', + canActivateChild: ['canActivateChild_parent'], + children: [{ + path: 'team/:id', + canActivate: ['canActivate_team'], + canDeactivate: ['canDeactivate_team'], + component: TeamCmp + }] + }]); + + router.navigateByUrl('/team/22'); + advance(fixture); + + router.navigateByUrl('/team/33'); + advance(fixture); + + expect(logger.logs).toEqual([ + 'canActivateChild_parent', 'canActivate_team', + + 'canDeactivate_team', 'canActivateChild_parent', 'canActivate_team' + ]); + }))); + }); }); describe('routerActiveLink', () => {