From 30aa3ee0a43c6ff673d5a321dac8a667ee4e7ed2 Mon Sep 17 00:00:00 2001 From: Marc Cataford Date: Mon, 19 Feb 2024 12:28:34 -0500 Subject: [PATCH] test: add NavigationBar coverage --- src/components/NavigationBar.test.tsx | 89 +++++++++++++++++++++++++++ src/components/NavigationBar.tsx | 2 +- 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/components/NavigationBar.test.tsx diff --git a/src/components/NavigationBar.test.tsx b/src/components/NavigationBar.test.tsx new file mode 100644 index 0000000..eac5b57 --- /dev/null +++ b/src/components/NavigationBar.test.tsx @@ -0,0 +1,89 @@ +import { describe, it, expect, vi, afterEach } from "vitest"; +import { screen, render } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; + +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { NavigationProvider } from "@/hooks/useNavigation"; +import * as NavigationHook from "@/hooks/useNavigation"; + +import NavigationBar from "./NavigationBar"; + +function Wrappers({ children }) { + return ( + + + {children} + + + ); +} + +function renderComponent() { + return { + ...render(, { wrapper: Wrappers }), + user: userEvent.setup(), + }; +} + +describe("NavigationBar", () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + it("renders navigation buttons", async () => { + renderComponent(); + + const buttons = await screen.findAllByRole("button"); + + expect(buttons.length).toEqual(2); + expect( + screen.getByText(/Your feeds/, { selector: "button" }), + ).toBeInTheDocument(); + expect( + screen.getByText(/Settings/, { selector: "button" }), + ).toBeInTheDocument(); + }); + + it.each` + destination | buttonTextPattern | expectedUrl + ${"feeds"} | ${/Your feeds/} | ${"/feeds/"} + ${"settings"} | ${/Settings/} | ${"/settings/"} + `( + "clicking navigation buttons triggers navigation ($destination)", + async ({ buttonTextPattern, expectedUrl }) => { + const mockPushHistory = vi.spyOn(window.history, "pushState"); + + const { user } = renderComponent(); + + const feedsButton = await screen.getByText(buttonTextPattern, { + selector: "button", + }); + + await user.click(feedsButton); + + // The history and location are updated. + expect(mockPushHistory).toHaveBeenCalledTimes(1); + expect(mockPushHistory).toHaveBeenCalledWith({}, "", expectedUrl); + expect(window.location.pathname).toEqual(expectedUrl); + }, + ); + + it.each` + url | expectedText + ${"/settings/"} | ${"Settings"} + ${"/feeds/"} | ${"Your feeds"} + `( + "displays the name of the current location", + async ({ url, expectedText }) => { + const mockCurrentLocation = vi + .spyOn(NavigationHook, "default") + .mockReturnValue({ location: url, navigate: () => {} }); + + renderComponent(); + + const locationTitle = await screen.getByLabelText("current location"); + + expect(locationTitle).toBeInTheDocument(); + expect(locationTitle.textContent).toEqual(expectedText); + }, + ); +}); diff --git a/src/components/NavigationBar.tsx b/src/components/NavigationBar.tsx index 098cb70..16bbf38 100644 --- a/src/components/NavigationBar.tsx +++ b/src/components/NavigationBar.tsx @@ -21,7 +21,7 @@ export default function NavigationBar() { <> - + {routePrettyNames[location]}