test(router): Add tests for initialNavigation: enabledBlocking (#45733)

Adds additional tests to verify `enabledBlocking` functionality. The
initial attempt to fix #44355 would have broken the scenario where a new
navigation cancels the initial navigation. We also cannot rely on
`NavigationError` like the example workaround in that issue report is
doing because there won't be one if a guard simply rejects
the initial nav (#16211).

PR Close #45733
This commit is contained in:
Andrew Scott
2022-04-22 16:07:20 -07:00
committed by Jessica Janiuk
parent 1e07a112b0
commit e92799c97e
+113 -2
View File
@@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {APP_BASE_HREF, DOCUMENT, Location, ɵgetDOM as getDOM} from '@angular/common';
import {ApplicationRef, Component, CUSTOM_ELEMENTS_SCHEMA, destroyPlatform, NgModule} from '@angular/core';
import {APP_BASE_HREF, DOCUMENT, ɵgetDOM as getDOM} from '@angular/common';
import {ApplicationRef, Component, CUSTOM_ELEMENTS_SCHEMA, destroyPlatform, Injectable, NgModule} from '@angular/core';
import {inject} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
@@ -48,6 +48,7 @@ describe('bootstrap', () => {
class SecondRootCmp {
}
@Injectable({providedIn: 'root'})
class TestResolver implements Resolve<any> {
resolve() {
let resolve: any = null;
@@ -76,6 +77,116 @@ describe('bootstrap', () => {
}
}));
// TODO(#44355): bootstrapping fails when the initial navigation fails
xit('should complete resolvers when initial navigation fails and initialNavigation = enabledBlocking',
async () => {
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(
[{
matcher: () => {
throw new Error('error in matcher');
},
children: []
}],
{useHash: true, initialNavigation: 'enabledBlocking'})
],
declarations: [RootCmp],
bootstrap: [RootCmp],
providers: [...testProviders],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
class TestModule {
constructor() {
log.push('TestModule');
}
}
await platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
const router = res.injector.get(Router);
expect(router.navigated).toEqual(false);
expect(router.getCurrentNavigation()).toBeNull();
expect(log).toContain('TestModule');
expect(log).toContain('NavigationError');
});
});
it('should wait for redirect when initialNavigation = enabledBlocking', async () => {
@Injectable({providedIn: 'root'})
class Redirect {
constructor(private router: Router) {}
canActivate() {
this.router.navigateByUrl('redirectToMe');
return false;
}
}
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(
[
{path: 'redirectToMe', children: [], resolve: {test: TestResolver}},
{path: '**', canActivate: [Redirect], children: []}
],
{useHash: true, initialNavigation: 'enabledBlocking'})
],
declarations: [RootCmp],
bootstrap: [RootCmp],
providers: [...testProviders],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
class TestModule {
constructor(router: Router) {
log.push('TestModule');
}
}
await platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
const router = res.injector.get(Router);
expect(router.navigated).toEqual(true);
expect(router.url).toContain('redirectToMe');
expect(log).toContain('TestModule');
});
});
it('should wait for redirect with UrlTree when initialNavigation = enabledBlocking', async () => {
@Injectable({providedIn: 'root'})
class Redirect {
constructor(private router: Router) {}
canActivate() {
return this.router.createUrlTree(['/redirectToMe']);
}
}
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(
[
{path: 'redirectToMe', children: [], resolve: {test: TestResolver}},
{path: '**', canActivate: [Redirect], children: []}
],
{useHash: true, initialNavigation: 'enabledBlocking'})
],
declarations: [RootCmp],
bootstrap: [RootCmp],
providers: [...testProviders],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
class TestModule {
constructor(router: Router) {
log.push('TestModule');
}
}
await platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
const router = res.injector.get(Router);
expect(router.navigated).toEqual(true);
expect(router.url).toContain('redirectToMe');
expect(log).toContain('TestModule');
});
});
it('should wait for resolvers to complete when initialNavigation = enabledBlocking', (done) => {
@Component({selector: 'test', template: 'test'})
class TestCmpEnabled {