diff --git a/web/src/App.test.jsx b/web/src/App.test.jsx
index 113113ba3d..9adae67c95 100644
--- a/web/src/App.test.jsx
+++ b/web/src/App.test.jsx
@@ -1,5 +1,5 @@
/*
- * Copyright (c) [2022] SUSE LLC
+ * Copyright (c) [2022-2023] SUSE LLC
*
* All Rights Reserved.
*
@@ -28,11 +28,6 @@ import { STARTUP, CONFIG, INSTALL } from "~/client/phase";
import { IDLE, BUSY } from "~/client/status";
jest.mock("~/client");
-
-jest.mock('react-router-dom', () => ({
- Outlet: mockComponent("Content"),
-}));
-
jest.mock("~/components/layout/Layout", () => mockLayout());
// Mock some components,
@@ -147,7 +142,7 @@ describe("App", () => {
it("renders the application content", async () => {
installerRender();
- await screen.findByText("Content");
+ await screen.findByText(/Outlet Content/);
});
});
@@ -169,7 +164,7 @@ describe("App", () => {
it("renders the Installation component on the INSTALL phase", async () => {
installerRender();
- await screen.findByText("Content");
+ await screen.findByText(/Outlet Content/);
changePhaseTo(INSTALL);
await screen.findByText("Installation Mock");
});
@@ -183,7 +178,7 @@ describe("App", () => {
it("renders the application's content", async () => {
installerRender();
- await screen.findByText("Content");
+ await screen.findByText(/Outlet Content/);
});
});
});
diff --git a/web/src/Main.test.jsx b/web/src/Main.test.jsx
index fe874a3783..eb8e337a5a 100644
--- a/web/src/Main.test.jsx
+++ b/web/src/Main.test.jsx
@@ -1,5 +1,5 @@
/*
- * Copyright (c) [2022] SUSE LLC
+ * Copyright (c) [2022-2023] SUSE LLC
*
* All Rights Reserved.
*
@@ -21,18 +21,16 @@
import React from "react";
import { screen } from "@testing-library/react";
-import { installerRender, mockComponent } from "~/test-utils";
+import { plainRender, mockComponent } from "~/test-utils";
import Main from "~/Main";
jest.mock("~/components/questions/Questions", () => mockComponent("Questions Mock"));
-jest.mock('react-router-dom', () => ({
- Outlet: mockComponent("Content"),
-}));
it("renders the Questions component and the content", async () => {
- installerRender();
+ plainRender();
await screen.findByText("Questions Mock");
- await screen.findByText("Content");
+ // react-router-dom Outlet is mocked. See test-utils for more details
+ await screen.findByText("Outlet Content");
});
diff --git a/web/src/components/core/ChangeProductButton.test.jsx b/web/src/components/core/ChangeProductButton.test.jsx
index b83471ad51..384e5d1331 100644
--- a/web/src/components/core/ChangeProductButton.test.jsx
+++ b/web/src/components/core/ChangeProductButton.test.jsx
@@ -21,12 +21,11 @@
import React from "react";
import { screen, waitFor } from "@testing-library/react";
-import { plainRender } from "~/test-utils";
+import { plainRender, mockNavigateFn } from "~/test-utils";
import { createClient } from "~/client";
import { ChangeProductButton } from "~/components/core";
let mockProducts;
-const mockNavigateFn = jest.fn();
jest.mock("~/client");
jest.mock("~/context/software", () => ({
@@ -37,9 +36,6 @@ jest.mock("~/context/software", () => ({
};
}
}));
-jest.mock('react-router-dom', () => ({
- useNavigate: () => mockNavigateFn,
-}));
beforeEach(() => {
createClient.mockImplementation(() => {
diff --git a/web/src/components/core/Page.test.jsx b/web/src/components/core/Page.test.jsx
index 75ef659e76..e9199bbc3b 100644
--- a/web/src/components/core/Page.test.jsx
+++ b/web/src/components/core/Page.test.jsx
@@ -24,11 +24,6 @@ import { screen } from "@testing-library/react";
import { installerRender, mockLayout } from "~/test-utils";
import { Page } from "~/components/core";
-const mockNavigateFn = jest.fn();
-
-jest.mock('react-router-dom', () => ({
- useNavigate: () => mockNavigateFn,
-}));
jest.mock("~/components/layout/Layout", () => mockLayout());
describe("Page", () => {
diff --git a/web/src/components/core/Section.test.jsx b/web/src/components/core/Section.test.jsx
index 56af194095..3f3410316d 100644
--- a/web/src/components/core/Section.test.jsx
+++ b/web/src/components/core/Section.test.jsx
@@ -21,13 +21,9 @@
import React from "react";
import { screen, within } from "@testing-library/react";
-import { plainRender } from "~/test-utils";
+import { plainRender, installerRender } from "~/test-utils";
import { Section } from "~/components/core";
-jest.mock('react-router-dom', () => ({
- Link: ({ to, children }) => {children}
-}));
-
describe("Section", () => {
it("renders given title", () => {
plainRender();
@@ -74,10 +70,9 @@ describe("Section", () => {
describe("when path is given", () => {
it("renders a link for navigating to it", async () => {
- plainRender();
+ installerRender();
const heading = screen.getByRole("heading", { name: "Settings" });
const link = within(heading).getByRole("link", { name: "Settings" });
- // NOTE: ReactRouter#Link is mocked at the top of file.
expect(link).toHaveAttribute("href", "/settings");
});
});
@@ -86,7 +81,7 @@ describe("Section", () => {
describe("and path is not present", () => {
it("triggers it when the user click on the section title", async () => {
const openDialog = jest.fn();
- const { user } = plainRender(
+ const { user } = installerRender(
);
const button = screen.getByRole("button", { name: "Settings" });
@@ -96,15 +91,9 @@ describe("Section", () => {
});
describe("but path is present too", () => {
- // Silence "Error: Not Implemented: navigation..." from jsdom when clicking a link
- // https://github.com/jsdom/jsdom/issues/2112
- const eventListener = (e) => e.preventDefault();
- beforeEach(() => window.addEventListener("click", eventListener));
- afterEach(() => window.removeEventListener("click", eventListener, true));
-
it("does not triggers it when the user click on the section title", async () => {
const openDialog = jest.fn();
- const { user } = plainRender(
+ const { user } = installerRender(
);
const link = screen.getByRole("link", { name: "Settings" });
diff --git a/web/src/components/l10n/L10nPage.test.jsx b/web/src/components/l10n/L10nPage.test.jsx
index d046a88ad5..19617c5c46 100644
--- a/web/src/components/l10n/L10nPage.test.jsx
+++ b/web/src/components/l10n/L10nPage.test.jsx
@@ -21,24 +21,18 @@
import React from "react";
import { screen } from "@testing-library/react";
-import { installerRender, mockLayout } from "~/test-utils";
+import { installerRender, mockLayout, mockNavigateFn } from "~/test-utils";
import { L10nPage } from "~/components/l10n";
import { createClient } from "~/client";
-const mockNavigateFn = jest.fn();
-
-jest.mock("~/client");
-jest.mock('react-router-dom', () => ({
- useNavigate: () => mockNavigateFn,
-}));
-jest.mock("~/components/layout/Layout", () => mockLayout());
-
+const setLanguagesFn = jest.fn();
const languages = [
{ id: "en_US", name: "English" },
{ id: "de_DE", name: "German" }
];
-const setLanguagesFn = jest.fn();
+jest.mock("~/client");
+jest.mock("~/components/layout/Layout", () => mockLayout());
beforeEach(() => {
// if defined outside, the mock is cleared automatically
diff --git a/web/src/components/network/NetworkPage.test.jsx b/web/src/components/network/NetworkPage.test.jsx
index 37fa8fbd89..e982c1c2dc 100644
--- a/web/src/components/network/NetworkPage.test.jsx
+++ b/web/src/components/network/NetworkPage.test.jsx
@@ -26,11 +26,6 @@ import NetworkPage from "~/components/network/NetworkPage";
import { ConnectionTypes } from "~/client/network";
import { createClient } from "~/client";
-const mockNavigateFn = jest.fn();
-
-jest.mock('react-router-dom', () => ({
- useNavigate: () => mockNavigateFn,
-}));
jest.mock("~/client");
const wiredConnection = {
diff --git a/web/src/components/overview/L10nSection.test.jsx b/web/src/components/overview/L10nSection.test.jsx
index 8a1c86a73c..ec282d6fc2 100644
--- a/web/src/components/overview/L10nSection.test.jsx
+++ b/web/src/components/overview/L10nSection.test.jsx
@@ -21,17 +21,11 @@
import React from "react";
import { act, screen } from "@testing-library/react";
-import { installerRender, createCallbackMock, mockComponent } from "~/test-utils";
+import { installerRender, createCallbackMock } from "~/test-utils";
import { L10nSection } from "~/components/overview";
import { createClient } from "~/client";
-const mockNavigateFn = jest.fn();
-
jest.mock("~/client");
-jest.mock('react-router-dom', () => ({
- useNavigate: () => mockNavigateFn,
- Link: mockComponent("Link")
-}));
const languages = [
{ id: "en_US", name: "English" },
diff --git a/web/src/components/overview/NetworkSection.test.jsx b/web/src/components/overview/NetworkSection.test.jsx
index dd6ecf8087..6885db3dff 100644
--- a/web/src/components/overview/NetworkSection.test.jsx
+++ b/web/src/components/overview/NetworkSection.test.jsx
@@ -26,13 +26,7 @@ import { NetworkSection } from "~/components/overview";
import { ConnectionTypes, NetworkEventTypes } from "~/client/network";
import { createClient } from "~/client";
-const mockNavigateFn = jest.fn();
-
jest.mock("~/client");
-jest.mock('react-router-dom', () => ({
- useNavigate: () => mockNavigateFn,
- Link: mockComponent("Link")
-}));
jest.mock('~/components/core/SectionSkeleton', () => mockComponent("Section Skeleton"));
diff --git a/web/src/components/overview/Overview.test.jsx b/web/src/components/overview/Overview.test.jsx
index 8c0a6a9fd3..fb4da63b92 100644
--- a/web/src/components/overview/Overview.test.jsx
+++ b/web/src/components/overview/Overview.test.jsx
@@ -44,11 +44,6 @@ jest.mock("~/context/software", () => ({
}
}));
-jest.mock('react-router-dom', () => ({
- Navigate: mockComponent("Navigate"),
- useNavigate: () => jest.fn()
-}));
-
jest.mock("~/components/layout/Layout", () => mockLayout());
jest.mock("~/components/overview/L10nSection", () => mockComponent("Localization Section"));
jest.mock("~/components/overview/StorageSection", () => mockComponent("Storage Section"));
@@ -92,7 +87,8 @@ describe("when no product is selected", () => {
it("redirects to the product selection page", async () => {
installerRender();
- await screen.findByText("Navigate");
+ // react-router-dom Navigate is mocked. See test-utils for more details.
+ await screen.findByText("Navigating to /products");
});
});
diff --git a/web/src/components/overview/StorageSection.test.jsx b/web/src/components/overview/StorageSection.test.jsx
index de8d9ec7e6..b66d7c738b 100644
--- a/web/src/components/overview/StorageSection.test.jsx
+++ b/web/src/components/overview/StorageSection.test.jsx
@@ -26,14 +26,8 @@ import { createClient } from "~/client";
import { BUSY, IDLE } from "~/client/status";
import { StorageSection } from "~/components/overview";
-const mockUseNavigate = jest.fn();
jest.mock("~/client");
jest.mock("~/components/core/SectionSkeleton", () => mockComponent("Loading storage"));
-jest.mock("react-router-dom", () => ({
- ...jest.requireActual("react-router-dom"),
- useNavigate: () => mockUseNavigate,
- Link: mockComponent("Link")
-}));
let status = IDLE;
let proposal = {
diff --git a/web/src/components/overview/UsersSection.test.jsx b/web/src/components/overview/UsersSection.test.jsx
index 3144d6c624..e9da0f525d 100644
--- a/web/src/components/overview/UsersSection.test.jsx
+++ b/web/src/components/overview/UsersSection.test.jsx
@@ -21,17 +21,11 @@
import React from "react";
import { screen } from "@testing-library/react";
-import { installerRender, mockComponent } from "~/test-utils";
+import { installerRender } from "~/test-utils";
import { UsersSection } from "~/components/overview";
import { createClient } from "~/client";
-const mockNavigateFn = jest.fn();
-
jest.mock("~/client");
-jest.mock('react-router-dom', () => ({
- useNavigate: () => mockNavigateFn,
- Link: mockComponent("Link")
-}));
const user = {
fullName: "Jane Doe",
diff --git a/web/src/components/software/ProductSelectionPage.test.jsx b/web/src/components/software/ProductSelectionPage.test.jsx
index b018cc792f..b726a37b45 100644
--- a/web/src/components/software/ProductSelectionPage.test.jsx
+++ b/web/src/components/software/ProductSelectionPage.test.jsx
@@ -1,5 +1,5 @@
/*
- * Copyright (c) [2022] SUSE LLC
+ * Copyright (c) [2022-2023] SUSE LLC
*
* All Rights Reserved.
*
@@ -21,7 +21,7 @@
import React from "react";
import { screen } from "@testing-library/react";
-import { installerRender, mockLayout } from "~/test-utils";
+import { installerRender, mockLayout, mockNavigateFn } from "~/test-utils";
import { ProductSelectionPage } from "~/components/software";
import { createClient } from "~/client";
@@ -39,12 +39,6 @@ const products = [
];
jest.mock("~/client");
-const mockUseNavigate = jest.fn();
-jest.mock("react-router-dom", () => ({
- ...jest.requireActual("react-router-dom"),
- useNavigate: () => mockUseNavigate
-}));
-
jest.mock("~/context/software", () => ({
...jest.requireActual("~/context/software"),
useSoftware: () => {
@@ -78,7 +72,7 @@ describe("when the user chooses a product", () => {
const button = await screen.findByRole("button", { name: "Select" });
await user.click(button);
expect(softwareMock.selectProduct).toHaveBeenCalledWith("MicroOS");
- expect(mockUseNavigate).toHaveBeenCalledWith("/");
+ expect(mockNavigateFn).toHaveBeenCalledWith("/");
});
});
@@ -89,6 +83,6 @@ describe("when the user chooses does not change the product", () => {
const button = await screen.findByRole("button", { name: "Select" });
await user.click(button);
expect(softwareMock.selectProduct).not.toHaveBeenCalled();
- expect(mockUseNavigate).toHaveBeenCalledWith("/");
+ expect(mockNavigateFn).toHaveBeenCalledWith("/");
});
});
diff --git a/web/src/components/storage/ProposalPage.test.jsx b/web/src/components/storage/ProposalPage.test.jsx
index 5e9162bbd5..bfef1a791e 100644
--- a/web/src/components/storage/ProposalPage.test.jsx
+++ b/web/src/components/storage/ProposalPage.test.jsx
@@ -35,14 +35,8 @@ const FakeProposalTargetSection = ({ calculateProposal }) => {
};
jest.mock("~/client");
-jest.mock("react-router-dom", () => ({
- ...jest.requireActual("react-router-dom"),
- useNavigate: () => jest.fn()
-}));
-
jest.mock("~/components/core/SectionSkeleton", () => mockComponent("Loading proposal"));
jest.mock("~/components/storage/ProposalTargetSection", () => FakeProposalTargetSection);
-
jest.mock("~/components/storage/ProposalSettingsSection", () => mockComponent("Settings section"));
jest.mock("~/components/storage/ProposalActionsSection", () => mockComponent("Actions section"));
diff --git a/web/src/test-utils.js b/web/src/test-utils.js
index 66561a3a83..253e90dc19 100644
--- a/web/src/test-utils.js
+++ b/web/src/test-utils.js
@@ -26,17 +26,38 @@
*/
import React from "react";
+import { MemoryRouter } from "react-router-dom";
import userEvent from "@testing-library/user-event";
import { render } from "@testing-library/react";
import { createClient } from "~/client/index";
import { InstallerClientProvider } from "~/context/installer";
-const InstallerProvider = ({ children }) => {
+/**
+ * Allows checking when react-router-dom navigate function was
+ * called with certain path
+ *
+ * @example
+ * expect(mockNavigateFn).toHaveBeenCalledWith("/")
+ */
+const mockNavigateFn = jest.fn();
+
+// Centralize the react-router-dom mock here
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual("react-router-dom"),
+ useNavigate: () => mockNavigateFn,
+ Navigate: ({ to: route }) => <>Navigating to {route}>,
+ Outlet: () => <>Outlet Content>
+}));
+
+const Providers = ({ children }) => {
const client = createClient();
+
return (
- {children}
+
+ {children}
+
);
};
@@ -45,7 +66,7 @@ const installerRender = (ui, options = {}) => {
return (
{
user: userEvent.setup(),
- ...render(ui, { wrapper: InstallerProvider, ...options })
+ ...render(ui, { wrapper: Providers, ...options })
}
);
};
@@ -111,4 +132,11 @@ const mockLayout = () => ({
AdditionalInfo: ({ children }) => children,
});
-export { installerRender, plainRender, createCallbackMock, mockComponent, mockLayout };
+export {
+ plainRender,
+ installerRender,
+ createCallbackMock,
+ mockComponent,
+ mockLayout,
+ mockNavigateFn
+};