From 5c4b102cf165291bdda50a82b52dde78ab635799 Mon Sep 17 00:00:00 2001
From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com>
Date: Fri, 25 Feb 2022 21:01:21 +0100
Subject: [PATCH 1/3] test: refactor router test (#287)

---
 .../example-app/src/app/app-routing.module.ts |  4 +-
 apps/example-app/src/app/app.module.ts        |  4 +-
 .../src/app/examples/09-router.spec.ts        | 48 +++++++++++++++++--
 .../example-app/src/app/examples/09-router.ts |  2 +-
 4 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/apps/example-app/src/app/app-routing.module.ts b/apps/example-app/src/app/app-routing.module.ts
index 1cfa2f59..a553ba61 100644
--- a/apps/example-app/src/app/app-routing.module.ts
+++ b/apps/example-app/src/app/app-routing.module.ts
@@ -9,7 +9,7 @@ import { MaterialFormsComponent } from './examples/04-forms-with-material';
 import { ComponentWithProviderComponent } from './examples/05-component-provider';
 import { WithNgRxStoreComponent } from './examples/06-with-ngrx-store';
 import { WithNgRxMockStoreComponent } from './examples/07-with-ngrx-mock-store';
-import { MasterComponent, DetailComponent, HiddenDetailComponent } from './examples/09-router';
+import { RootComponent, DetailComponent, HiddenDetailComponent } from './examples/09-router';
 
 export const examples = [
   {
@@ -70,7 +70,7 @@ export const examples = [
   },
   {
     path: 'with-router',
-    component: MasterComponent,
+    component: RootComponent,
     data: {
       name: 'Router',
     },
diff --git a/apps/example-app/src/app/app.module.ts b/apps/example-app/src/app/app.module.ts
index fb4ccaf7..cb95434f 100644
--- a/apps/example-app/src/app/app.module.ts
+++ b/apps/example-app/src/app/app.module.ts
@@ -20,7 +20,7 @@ import { MaterialFormsComponent } from './examples/04-forms-with-material';
 import { ComponentWithProviderComponent } from './examples/05-component-provider';
 import { WithNgRxStoreComponent, reducer } from './examples/06-with-ngrx-store';
 import { WithNgRxMockStoreComponent } from './examples/07-with-ngrx-mock-store';
-import { MasterComponent, DetailComponent, HiddenDetailComponent } from './examples/09-router';
+import { RootComponent, DetailComponent, HiddenDetailComponent } from './examples/09-router';
 import { ScrollingModule } from '@angular/cdk/scrolling';
 
 function reducerItems() {
@@ -40,7 +40,7 @@ function reducerItems() {
     ComponentWithProviderComponent,
     WithNgRxStoreComponent,
     WithNgRxMockStoreComponent,
-    MasterComponent,
+    RootComponent,
     DetailComponent,
     HiddenDetailComponent,
   ],
diff --git a/apps/example-app/src/app/examples/09-router.spec.ts b/apps/example-app/src/app/examples/09-router.spec.ts
index 16f037fc..1e2be51b 100644
--- a/apps/example-app/src/app/examples/09-router.spec.ts
+++ b/apps/example-app/src/app/examples/09-router.spec.ts
@@ -1,9 +1,49 @@
-import { render, screen } from '@testing-library/angular';
+import { render, screen, waitForElementToBeRemoved } from '@testing-library/angular';
+import userEvent from '@testing-library/user-event';
 
-import { DetailComponent, MasterComponent, HiddenDetailComponent } from './09-router';
+import { DetailComponent, RootComponent, HiddenDetailComponent } from './09-router';
 
 test('it can navigate to routes', async () => {
-  const { navigate } = await render(MasterComponent, {
+  await render(RootComponent, {
+    declarations: [DetailComponent, HiddenDetailComponent],
+    routes: [
+      {
+        path: '',
+        children: [
+          {
+            path: 'detail/:id',
+            component: DetailComponent,
+          },
+          {
+            path: 'hidden-detail',
+            component: HiddenDetailComponent,
+          },
+        ],
+      },
+    ],
+  });
+
+  expect(screen.queryByText(/Detail one/i)).not.toBeInTheDocument();
+
+  userEvent.click(screen.getByRole('link', { name: /load one/i }));
+  expect(await screen.findByRole('heading', { name: /Detail one/i })).toBeInTheDocument();
+
+  userEvent.click(screen.getByRole('link', { name: /load three/i }));
+  await waitForElementToBeRemoved(() => screen.queryByRole('heading', { name: /Detail one/i }));
+  expect(await screen.findByRole('heading', { name: /Detail three/i })).toBeInTheDocument();
+
+  userEvent.click(screen.getByRole('link', { name: /back to parent/i }));
+  await waitForElementToBeRemoved(() => screen.queryByRole('heading', { name: /Detail three/i }));
+
+  userEvent.click(screen.getByRole('link', { name: /load two/i }));
+  expect(await screen.findByRole('heading', { name: /Detail two/i })).toBeInTheDocument();
+
+  userEvent.click(screen.getByRole('link', { name: /hidden x/i }));
+  expect(await screen.findByText(/You found the treasure!/i)).toBeInTheDocument();
+});
+
+test('it can navigate to routes - workaround', async () => {
+  const { navigate } = await render(RootComponent, {
     declarations: [DetailComponent, HiddenDetailComponent],
     routes: [
       {
@@ -42,7 +82,7 @@ test('it can navigate to routes', async () => {
 
 test('it can navigate to routes with a base path', async () => {
   const basePath = 'base';
-  const { navigate } = await render(MasterComponent, {
+  const { navigate } = await render(RootComponent, {
     declarations: [DetailComponent, HiddenDetailComponent],
     routes: [
       {
diff --git a/apps/example-app/src/app/examples/09-router.ts b/apps/example-app/src/app/examples/09-router.ts
index 7d4e300d..6ea0df73 100644
--- a/apps/example-app/src/app/examples/09-router.ts
+++ b/apps/example-app/src/app/examples/09-router.ts
@@ -13,7 +13,7 @@ import { map } from 'rxjs/operators';
     <router-outlet></router-outlet>
   `,
 })
-export class MasterComponent {}
+export class RootComponent {}
 
 @Component({
   selector: 'app-detail',

From 8dba35bb310dd3ebed05696ca43c3cfc8f79eada Mon Sep 17 00:00:00 2001
From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com>
Date: Thu, 17 Mar 2022 14:11:27 +0100
Subject: [PATCH 2/3] ci: update actions v3 (#289)

---
 .github/workflows/ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 80741a41..6ecfd98d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,9 +20,9 @@ jobs:
     runs-on: ${{ matrix.os }}
 
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: use Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
-        uses: actions/setup-node@v2
+        uses: actions/setup-node@v3
         with:
           node-version: ${{ matrix.node-version }}
       - name: install

From 6e4723b8dca2f7cb704e3d29198dfe809dd8beff Mon Sep 17 00:00:00 2001
From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com>
Date: Tue, 22 Mar 2022 08:45:11 +0100
Subject: [PATCH 3/3] fix: invoke initialNavigation if it's a method

In some tests we might mock the router instance, and don't provide the initial navigation
---
 projects/testing-library/src/lib/testing-library.ts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts
index 8a6ad6a7..baa2dce9 100644
--- a/projects/testing-library/src/lib/testing-library.ts
+++ b/projects/testing-library/src/lib/testing-library.ts
@@ -119,7 +119,9 @@ export async function render<SutType, WrapperType = SutType>(
   const zone = inject(NgZone);
 
   const router = inject(Router);
-  router?.initialNavigation();
+  if (typeof router?.initialNavigation === 'function') {
+    router?.initialNavigation();
+  }
 
   const navigate = async (elementOrPath: Element | string, basePath = ''): Promise<boolean> => {
     const href = typeof elementOrPath === 'string' ? elementOrPath : elementOrPath.getAttribute('href');