Skip to content

Commit

Permalink
Add unit test for providers
Browse files Browse the repository at this point in the history
- Added a test to ensure the `ThemeProvider` correctly applies the selected `theme`
  to the document's `root` element.
- Mocked `localStorage` to return a predefined `theme` value for testing.
- Verified that the appropriate `class` is applied to `document.documentElement`
  based on the `theme`.
  • Loading branch information
Fingertips18 committed Sep 27, 2024
1 parent 9250bc9 commit 046a032
Show file tree
Hide file tree
Showing 5 changed files with 378 additions and 2 deletions.
113 changes: 111 additions & 2 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"devDependencies": {
"@eslint/js": "^9.9.0",
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.0.1",
"@types/node": "^22.5.4",
"@types/react": "^18.3.3",
Expand Down
95 changes: 95 additions & 0 deletions client/src/lib/providers/query-provider.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { fireEvent, render, act } from "@testing-library/react";
import { useMutation, useQuery } from "@tanstack/react-query";
import { describe, it, expect, vi } from "vitest";
import "@testing-library/jest-dom";

import QueryProvider from "./query-provider";

const DefaultMockComponent = () => {
const { data } = useQuery({
queryKey: ["testQuery"],
queryFn: async () => await Promise.resolve("Fetched data"),
});

return <p>{data}</p>;
};

const SuccessMockComponent = () => {
const { mutate } = useMutation({
mutationKey: ["testQuery"],
mutationFn: async () => await Promise.resolve("Success"),
onSuccess: (data) => console.log(data),
});

return <button onClick={() => mutate()} />;
};

const ErrorMockComponent = () => {
const { mutate } = useMutation({
mutationKey: ["testQuery"],
mutationFn: async () => await Promise.reject(new Error("Error")),
onError: ({ message }) => console.log(message),
});

return <button onClick={() => mutate()} />;
};

describe("Query Provider", () => {
it("renders without crashing", () => {
const label = "Hello world!";

const { getByText } = render(
<QueryProvider>
<p>{label}</p>
</QueryProvider>
);

expect(getByText(label)).toBeInTheDocument();
});

it("should render fetched data", async () => {
const { findByText } = render(
<QueryProvider>
<DefaultMockComponent />
</QueryProvider>
);

expect(await findByText("Fetched data")).toBeInTheDocument();
});

it("should logs 'Success' on mutation call", async () => {
const consoleLogSpy = vi.spyOn(console, "log");

const { getByRole } = render(
<QueryProvider>
<SuccessMockComponent />
</QueryProvider>
);

const button = getByRole("button");

await act(async () => {
fireEvent.click(button);
});

expect(consoleLogSpy).toHaveBeenCalledWith("Success");
});

it("should logs 'Error' on mutation call", async () => {
const consoleLogSpy = vi.spyOn(console, "log");

const { getByRole } = render(
<QueryProvider>
<ErrorMockComponent />
</QueryProvider>
);

const button = getByRole("button");

await act(async () => {
fireEvent.click(button);
});

expect(consoleLogSpy).toHaveBeenCalledWith("Error");
});
});
71 changes: 71 additions & 0 deletions client/src/lib/providers/theme-provider.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { describe, it, expect, vi, beforeAll } from "vitest";
import { render } from "@testing-library/react";
import "@testing-library/jest-dom";

import { ThemeProvider, ThemeProviderContext } from "./theme-provider";

describe("Theme Provider", () => {
beforeAll(() => {
Object.defineProperty(window, "matchMedia", {
writable: true,
value: (query: string) => ({
matches: false,
media: query,
onchange: null,
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => {},
}),
});
});

it("should render without any issues", () => {
const label = "Hello world!";

const { getByText } = render(
<ThemeProvider>
<p>{label}</p>
</ThemeProvider>
);

expect(getByText(label)).toBeInTheDocument();
});

it("sets the initial theme from localStorage", () => {
const localStorageMock = {
getItem: vi.fn().mockReturnValue("light"),
setItem: vi.fn(),
};

Object.defineProperty(window, "localStorage", { value: localStorageMock });

const { getByTestId } = render(
<ThemeProvider>
<ThemeProviderContext.Consumer>
{({ theme }) => <p data-testid="theme">{theme}</p>}
</ThemeProviderContext.Consumer>
</ThemeProvider>
);

expect(getByTestId("theme")).toHaveTextContent("light");
});

it("applies the theme to the document root", () => {
const localStorageMock = {
getItem: vi.fn().mockReturnValue("dark"),
setItem: vi.fn(),
};

Object.defineProperty(window, "localStorage", { value: localStorageMock });

render(
<ThemeProvider>
<p>Test</p>
</ThemeProvider>
);

const root = window.document.documentElement;

expect(root.classList.contains("dark")).toBeTruthy();
});
});
Loading

0 comments on commit 046a032

Please sign in to comment.