refactor(router): polishing

This commit is contained in:
Dzmitry Shylovich 2017-03-24 01:19:35 +03:00 committed by Victor Berchet
parent ea848f74af
commit fb1be83a1b
2 changed files with 99 additions and 102 deletions

View File

@ -293,7 +293,7 @@ class ApplyRedirects {
} }
if (route.loadChildren) { if (route.loadChildren) {
return mergeMap.call(runGuards(ngModule.injector, route), (shouldLoad: any) => { return mergeMap.call(runCanLoadGuard(ngModule.injector, route), (shouldLoad: boolean) => {
if (shouldLoad) { if (shouldLoad) {
return (<any>route)._loadedConfig ? return (<any>route)._loadedConfig ?
@ -396,12 +396,12 @@ class ApplyRedirects {
} }
} }
function runGuards(moduleInjector: Injector, route: Route): Observable<boolean> { function runCanLoadGuard(moduleInjector: Injector, route: Route): Observable<boolean> {
const canLoad = route.canLoad; const canLoad = route.canLoad;
if (!canLoad || canLoad.length === 0) return of (true); if (!canLoad || canLoad.length === 0) return of (true);
const obs = map.call(from(canLoad), (c: any) => { const obs = map.call(from(canLoad), (injectionToken: any) => {
const guard = moduleInjector.get(c); const guard = moduleInjector.get(injectionToken);
return wrapIntoObservable(guard.canLoad ? guard.canLoad(route) : guard(route)); return wrapIntoObservable(guard.canLoad ? guard.canLoad(route) : guard(route));
}); });

View File

@ -2075,107 +2075,104 @@ describe('Integration', () => {
}); });
describe('CanLoad', () => { describe('CanLoad', () => {
describe('should not load children when CanLoad returns false', () => { beforeEach(() => {
beforeEach(() => { TestBed.configureTestingModule({
TestBed.configureTestingModule({ providers: [
providers: [ {provide: 'alwaysFalse', useValue: (a: any) => false},
{provide: 'alwaysFalse', useValue: (a: any) => false}, {
{ provide: 'returnFalseAndNavigate',
provide: 'returnFalseAndNavigate', useFactory: (router: any) => (a: any) => {
useFactory: (router: any) => (a: any) => { router.navigate(['blank']);
router.navigate(['blank']); return false;
return false;
},
deps: [Router],
}, },
{provide: 'alwaysTrue', useValue: (a: any) => true}, deps: [Router],
] },
}); {provide: 'alwaysTrue', useValue: (a: any) => true},
]
}); });
it('works',
fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader],
(router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => {
@Component({selector: 'lazy', template: 'lazy-loaded'})
class LazyLoadedComponent {
}
@NgModule({
declarations: [LazyLoadedComponent],
imports:
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])]
})
class LoadedModule {
}
loader.stubbedModules = {lazyFalse: LoadedModule, lazyTrue: LoadedModule};
const fixture = createRoot(router, RootCmp);
router.resetConfig([
{path: 'lazyFalse', canLoad: ['alwaysFalse'], loadChildren: 'lazyFalse'},
{path: 'lazyTrue', canLoad: ['alwaysTrue'], loadChildren: 'lazyTrue'}
]);
const recordedEvents: any[] = [];
router.events.forEach(e => recordedEvents.push(e));
// failed navigation
router.navigateByUrl('/lazyFalse/loaded');
advance(fixture);
expect(location.path()).toEqual('/');
expectEvents(recordedEvents, [
[NavigationStart, '/lazyFalse/loaded'],
[NavigationCancel, '/lazyFalse/loaded'],
]);
recordedEvents.splice(0);
// successful navigation
router.navigateByUrl('/lazyTrue/loaded');
advance(fixture);
expect(location.path()).toEqual('/lazyTrue/loaded');
expectEvents(recordedEvents, [
[NavigationStart, '/lazyTrue/loaded'],
[RouteConfigLoadStart],
[RouteConfigLoadEnd],
[RoutesRecognized, '/lazyTrue/loaded'],
[NavigationEnd, '/lazyTrue/loaded'],
]);
})));
it('should support navigating from within the guard',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp);
router.resetConfig([
{path: 'lazyFalse', canLoad: ['returnFalseAndNavigate'], loadChildren: 'lazyFalse'},
{path: 'blank', component: BlankCmp}
]);
const recordedEvents: any[] = [];
router.events.forEach(e => recordedEvents.push(e));
router.navigateByUrl('/lazyFalse/loaded');
advance(fixture);
expect(location.path()).toEqual('/blank');
expectEvents(recordedEvents, [
[NavigationStart, '/lazyFalse/loaded'], [NavigationCancel, '/lazyFalse/loaded'],
[NavigationStart, '/blank'], [RoutesRecognized, '/blank'],
[NavigationEnd, '/blank']
]);
})));
}); });
it('should not load children when CanLoad returns false',
fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader],
(router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => {
@Component({selector: 'lazy', template: 'lazy-loaded'})
class LazyLoadedComponent {
}
@NgModule({
declarations: [LazyLoadedComponent],
imports:
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])]
})
class LoadedModule {
}
loader.stubbedModules = {lazyFalse: LoadedModule, lazyTrue: LoadedModule};
const fixture = createRoot(router, RootCmp);
router.resetConfig([
{path: 'lazyFalse', canLoad: ['alwaysFalse'], loadChildren: 'lazyFalse'},
{path: 'lazyTrue', canLoad: ['alwaysTrue'], loadChildren: 'lazyTrue'}
]);
const recordedEvents: any[] = [];
router.events.forEach(e => recordedEvents.push(e));
// failed navigation
router.navigateByUrl('/lazyFalse/loaded');
advance(fixture);
expect(location.path()).toEqual('/');
expectEvents(recordedEvents, [
[NavigationStart, '/lazyFalse/loaded'],
[NavigationCancel, '/lazyFalse/loaded'],
]);
recordedEvents.splice(0);
// successful navigation
router.navigateByUrl('/lazyTrue/loaded');
advance(fixture);
expect(location.path()).toEqual('/lazyTrue/loaded');
expectEvents(recordedEvents, [
[NavigationStart, '/lazyTrue/loaded'],
[RouteConfigLoadStart],
[RouteConfigLoadEnd],
[RoutesRecognized, '/lazyTrue/loaded'],
[NavigationEnd, '/lazyTrue/loaded'],
]);
})));
it('should support navigating from within the guard',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
const fixture = createRoot(router, RootCmp);
router.resetConfig([
{path: 'lazyFalse', canLoad: ['returnFalseAndNavigate'], loadChildren: 'lazyFalse'},
{path: 'blank', component: BlankCmp}
]);
const recordedEvents: any[] = [];
router.events.forEach(e => recordedEvents.push(e));
router.navigateByUrl('/lazyFalse/loaded');
advance(fixture);
expect(location.path()).toEqual('/blank');
expectEvents(recordedEvents, [
[NavigationStart, '/lazyFalse/loaded'], [NavigationCancel, '/lazyFalse/loaded'],
[NavigationStart, '/blank'], [RoutesRecognized, '/blank'], [NavigationEnd, '/blank']
]);
})));
}); });
describe('order', () => { describe('order', () => {