Skip to content

Commit 74ff3b5

Browse files
atscottthePunderWoman
authored andcommitted
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
1 parent 35f20af commit 74ff3b5

1 file changed

Lines changed: 113 additions & 2 deletions

File tree

‎packages/router/test/bootstrap.spec.ts‎

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {APP_BASE_HREF, DOCUMENT, Location, ɵgetDOM as getDOM} from '@angular/common';
10-
import {ApplicationRef, Component, CUSTOM_ELEMENTS_SCHEMA, destroyPlatform, NgModule} from '@angular/core';
9+
import {APP_BASE_HREF, DOCUMENT, ɵgetDOM as getDOM} from '@angular/common';
10+
import {ApplicationRef, Component, CUSTOM_ELEMENTS_SCHEMA, destroyPlatform, Injectable, NgModule} from '@angular/core';
1111
import {inject} from '@angular/core/testing';
1212
import {BrowserModule} from '@angular/platform-browser';
1313
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
@@ -48,6 +48,7 @@ describe('bootstrap', () => {
4848
class SecondRootCmp {
4949
}
5050

51+
@Injectable({providedIn: 'root'})
5152
class TestResolver implements Resolve<any> {
5253
resolve() {
5354
let resolve: any = null;
@@ -76,6 +77,116 @@ describe('bootstrap', () => {
7677
}
7778
}));
7879

80+
// TODO(#44355): bootstrapping fails when the initial navigation fails
81+
xit('should complete resolvers when initial navigation fails and initialNavigation = enabledBlocking',
82+
async () => {
83+
@NgModule({
84+
imports: [
85+
BrowserModule,
86+
RouterModule.forRoot(
87+
[{
88+
matcher: () => {
89+
throw new Error('error in matcher');
90+
},
91+
children: []
92+
}],
93+
{useHash: true, initialNavigation: 'enabledBlocking'})
94+
],
95+
declarations: [RootCmp],
96+
bootstrap: [RootCmp],
97+
providers: [...testProviders],
98+
schemas: [CUSTOM_ELEMENTS_SCHEMA]
99+
})
100+
class TestModule {
101+
constructor() {
102+
log.push('TestModule');
103+
}
104+
}
105+
106+
await platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
107+
const router = res.injector.get(Router);
108+
expect(router.navigated).toEqual(false);
109+
expect(router.getCurrentNavigation()).toBeNull();
110+
expect(log).toContain('TestModule');
111+
expect(log).toContain('NavigationError');
112+
});
113+
});
114+
115+
it('should wait for redirect when initialNavigation = enabledBlocking', async () => {
116+
@Injectable({providedIn: 'root'})
117+
class Redirect {
118+
constructor(private router: Router) {}
119+
canActivate() {
120+
this.router.navigateByUrl('redirectToMe');
121+
return false;
122+
}
123+
}
124+
@NgModule({
125+
imports: [
126+
BrowserModule,
127+
RouterModule.forRoot(
128+
[
129+
{path: 'redirectToMe', children: [], resolve: {test: TestResolver}},
130+
{path: '**', canActivate: [Redirect], children: []}
131+
],
132+
{useHash: true, initialNavigation: 'enabledBlocking'})
133+
],
134+
declarations: [RootCmp],
135+
bootstrap: [RootCmp],
136+
providers: [...testProviders],
137+
schemas: [CUSTOM_ELEMENTS_SCHEMA]
138+
})
139+
class TestModule {
140+
constructor(router: Router) {
141+
log.push('TestModule');
142+
}
143+
}
144+
145+
await platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
146+
const router = res.injector.get(Router);
147+
expect(router.navigated).toEqual(true);
148+
expect(router.url).toContain('redirectToMe');
149+
expect(log).toContain('TestModule');
150+
});
151+
});
152+
153+
it('should wait for redirect with UrlTree when initialNavigation = enabledBlocking', async () => {
154+
@Injectable({providedIn: 'root'})
155+
class Redirect {
156+
constructor(private router: Router) {}
157+
canActivate() {
158+
return this.router.createUrlTree(['/redirectToMe']);
159+
}
160+
}
161+
@NgModule({
162+
imports: [
163+
BrowserModule,
164+
RouterModule.forRoot(
165+
[
166+
{path: 'redirectToMe', children: [], resolve: {test: TestResolver}},
167+
{path: '**', canActivate: [Redirect], children: []}
168+
],
169+
{useHash: true, initialNavigation: 'enabledBlocking'})
170+
],
171+
declarations: [RootCmp],
172+
bootstrap: [RootCmp],
173+
providers: [...testProviders],
174+
schemas: [CUSTOM_ELEMENTS_SCHEMA]
175+
})
176+
class TestModule {
177+
constructor(router: Router) {
178+
log.push('TestModule');
179+
}
180+
}
181+
182+
await platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => {
183+
const router = res.injector.get(Router);
184+
expect(router.navigated).toEqual(true);
185+
expect(router.url).toContain('redirectToMe');
186+
expect(log).toContain('TestModule');
187+
});
188+
});
189+
79190
it('should wait for resolvers to complete when initialNavigation = enabledBlocking', (done) => {
80191
@Component({selector: 'test', template: 'test'})
81192
class TestCmpEnabled {

0 commit comments

Comments
 (0)