Skip to content

Commit d3407ca

Browse files
authored
feat: add initialRoute parameter to avoid resolver issues with using a default route (#367)
1 parent 701dc5e commit d3407ca

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

projects/testing-library/src/lib/models.ts

+15
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,21 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
328328
*/
329329
routes?: Routes;
330330

331+
/**
332+
* @description
333+
* Specifies which route should be initially navigated to
334+
*
335+
* @example
336+
* const component = await render(AppComponent, {
337+
* initialRoute: 'myroute',
338+
* routes: [
339+
* { path: '', component: HomeComponent },
340+
* { path: 'myroute', component: SecondaryComponent }
341+
* ]
342+
* })
343+
*/
344+
initialRoute?: string;
345+
331346
/**
332347
* @description
333348
* Removes the Angular attributes (ng-version, and root-id) from the fixture.

projects/testing-library/src/lib/testing-library.ts

+3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export async function render<SutType, WrapperType = SutType>(
6464
routes = [],
6565
removeAngularAttributes = false,
6666
defaultImports = [],
67+
initialRoute = '',
6768
} = { ...globalConfig, ...renderOptions };
6869

6970
dtlConfigure({
@@ -107,6 +108,8 @@ export async function render<SutType, WrapperType = SutType>(
107108
const zone = safeInject(NgZone);
108109
const router = safeInject(Router);
109110

111+
if (initialRoute) await router.navigate([initialRoute]);
112+
110113
if (typeof router?.initialNavigation === 'function') {
111114
if (zone) {
112115
zone.run(() => router.initialNavigation());

projects/testing-library/tests/render.spec.ts

+46
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
import { NoopAnimationsModule, BrowserAnimationsModule } from '@angular/platform-browser/animations';
1313
import { TestBed } from '@angular/core/testing';
1414
import { render, fireEvent, screen } from '../src/public_api';
15+
import { Resolve, RouterModule } from '@angular/router';
1516

1617
@Component({
1718
selector: 'atl-fixture',
@@ -296,3 +297,48 @@ describe('DebugElement', () => {
296297
expect(view.debugElement.componentInstance).toBeInstanceOf(FixtureComponent);
297298
});
298299
});
300+
301+
describe('initialRoute', () => {
302+
@Component({
303+
standalone: true,
304+
selector: 'atl-fixture2',
305+
template: `<button>Secondary Component</button>`,
306+
})
307+
class SecondaryFixtureComponent {}
308+
309+
@Component({
310+
standalone: true,
311+
selector: 'atl-router-fixture',
312+
template: `<router-outlet></router-outlet>`,
313+
imports: [RouterModule],
314+
})
315+
class RouterFixtureComponent {}
316+
317+
@Injectable()
318+
class FixtureResolver implements Resolve<void> {
319+
public isResolved = false;
320+
321+
public resolve() {
322+
this.isResolved = true;
323+
}
324+
}
325+
326+
it('allows initially rendering a specific route to avoid triggering a resolver for the default route', async () => {
327+
const initialRoute = 'initial-route';
328+
const routes = [
329+
{ path: initialRoute, component: FixtureComponent },
330+
{ path: '**', resolve: { data: FixtureResolver }, component: SecondaryFixtureComponent },
331+
];
332+
333+
await render(RouterFixtureComponent, {
334+
initialRoute,
335+
routes,
336+
providers: [FixtureResolver],
337+
});
338+
const resolver = TestBed.inject(FixtureResolver);
339+
340+
expect(resolver.isResolved).toBe(false);
341+
expect(screen.queryByText('Secondary Component')).not.toBeInTheDocument();
342+
expect(screen.getByText('button')).toBeInTheDocument();
343+
});
344+
});

0 commit comments

Comments
 (0)