// 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( , ); } 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); }); });