You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.7 KiB
TypeScript

// frontend/tests/ThemeToggle.test.tsx
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { describe, it, expect, beforeEach } from "vitest";
import { ThemeProvider } from "@/components/ThemeProvider";
import { ThemeToggle } from "@/components/ThemeToggle";
function setup() {
return render(
<ThemeProvider>
<ThemeToggle />
</ThemeProvider>,
);
}
describe("ThemeToggle", () => {
beforeEach(() => {
localStorage.clear();
document.documentElement.removeAttribute("data-theme");
});
it("클릭 시 data-theme가 light↔dark로 토글", async () => {
setup();
const btn = screen.getByLabelText("테마 전환");
fireEvent.click(btn);
await waitFor(() =>
expect(document.documentElement.getAttribute("data-theme")).toBe("dark"),
);
fireEvent.click(btn);
await waitFor(() =>
expect(document.documentElement.getAttribute("data-theme")).toBe("light"),
);
});
it("선택이 localStorage(ari-theme)에 영속", async () => {
setup();
fireEvent.click(screen.getByLabelText("테마 전환"));
await waitFor(() => expect(localStorage.getItem("ari-theme")).toBe("dark"));
});
it("다크에서 sun, 라이트에서 moon 아이콘", async () => {
const { container } = setup();
await waitFor(() => expect(container.querySelector("svg")).toBeTruthy());
fireEvent.click(screen.getByLabelText("테마 전환"));
await waitFor(() =>
expect(document.documentElement.getAttribute("data-theme")).toBe("dark"),
);
// sun은 다중 path(8개), moon은 단일 path → path 수로 구분
expect(container.querySelectorAll("path").length).toBeGreaterThan(1);
});
});