diff --git a/components/theme-toggle.test.tsx b/components/theme-toggle.test.tsx index 9f4f096..1995ab4 100644 --- a/components/theme-toggle.test.tsx +++ b/components/theme-toggle.test.tsx @@ -1,16 +1,43 @@ -import { describe, it, expect, vi } from "vitest"; +import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, fireEvent } from "@testing-library/react"; import { ThemeToggle } from "./theme-toggle"; -// Mock next-themes -vi.mock("next-themes", () => ({ - useTheme: () => ({ - theme: "light", - setTheme: vi.fn(), - }), -})); +// Mock next-themes at the top level +vi.mock("next-themes", () => { + const mockSetTheme = vi.fn(); + return { + useTheme: vi.fn(() => ({ + theme: "light", + setTheme: mockSetTheme, + resolvedTheme: "light", + systemTheme: "light", + themes: ["light", "dark"], + forcedTheme: undefined, + })), + }; +}); describe("ThemeToggle", () => { + let mockSetTheme: ReturnType; + + beforeEach(async () => { + vi.clearAllMocks(); + // Get the mocked module + const nextThemes = await import("next-themes"); + const useThemeMock = vi.mocked(nextThemes.useTheme); + + // Create fresh mock for each test + mockSetTheme = vi.fn(); + useThemeMock.mockReturnValue({ + theme: "light", + setTheme: mockSetTheme, + resolvedTheme: "light", + systemTheme: "light", + themes: ["light", "dark"], + forcedTheme: undefined, + }); + }); + it("should render the theme toggle button", () => { render(); const button = screen.getByRole("button", { name: /toggle theme/i }); @@ -24,19 +51,32 @@ describe("ThemeToggle", () => { expect(sunIcon).toHaveClass("scale-100"); }); - it("should call setTheme when clicked", () => { - const mockSetTheme = vi.fn(); - vi.mocked(vi.importActual("next-themes")).useTheme = () => ({ - theme: "light", + it("should call setTheme when clicked", async () => { + render(); + const button = screen.getByRole("button"); + fireEvent.click(button); + + expect(mockSetTheme).toHaveBeenCalledWith("dark"); + }); + + it("should toggle to light theme when in dark mode", async () => { + // Update mock for dark mode + const nextThemes = await import("next-themes"); + const useThemeMock = vi.mocked(nextThemes.useTheme); + + useThemeMock.mockReturnValue({ + theme: "dark", setTheme: mockSetTheme, + resolvedTheme: "dark", + systemTheme: "light", + themes: ["light", "dark"], + forcedTheme: undefined, }); render(); const button = screen.getByRole("button"); fireEvent.click(button); - // Note: In a real test, we'd verify mockSetTheme was called - // but this is just an example to show the setup works - expect(button).toBeInTheDocument(); + expect(mockSetTheme).toHaveBeenCalledWith("light"); }); }); diff --git a/lib/errors.test.ts b/lib/errors.test.ts index 6fa61ba..48aee70 100644 --- a/lib/errors.test.ts +++ b/lib/errors.test.ts @@ -138,7 +138,8 @@ describe("handleError", () => { }); it("should log errors with context", async () => { - const loggerModule = await vi.importMock("./logger"); + const loggerModule = + await vi.importMock("./logger"); const error = new BadRequestError("Test error"); handleError(error, "TestContext"); @@ -156,7 +157,7 @@ describe("handleError", () => { describe("withErrorHandling", () => { it("should wrap async handler and catch errors", async () => { - const handler = async () => { + const handler = async (): Promise => { throw new BadRequestError("Test error"); }; diff --git a/lib/logger.test.ts b/lib/logger.test.ts index 1f80211..8ce1634 100644 --- a/lib/logger.test.ts +++ b/lib/logger.test.ts @@ -64,13 +64,15 @@ describe("Logger", () => { describe("log levels in production", () => { beforeEach(async () => { // Change mock to return production - const env = await vi.importMock("./environment"); + const env = + await vi.importMock("./environment"); vi.mocked(env.getCurrentEnvironment).mockReturnValue("production"); }); afterEach(async () => { // Reset to development - const env = await vi.importMock("./environment"); + const env = + await vi.importMock("./environment"); vi.mocked(env.getCurrentEnvironment).mockReturnValue("development"); });