Add quick-win tests for components and hooks
Adds tests for DifficultyIndicator, Toast, RollModeMenu, OverflowMenu, useTheme, and useRulesEdition. Covers rendering, user interactions, auto-dismiss timers, external store sync, and localStorage persistence. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
45
apps/web/src/hooks/__tests__/use-rules-edition.test.ts
Normal file
45
apps/web/src/hooks/__tests__/use-rules-edition.test.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
// @vitest-environment jsdom
|
||||
import { act, renderHook } from "@testing-library/react";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { useRulesEdition } from "../use-rules-edition.js";
|
||||
|
||||
const STORAGE_KEY = "initiative:rules-edition";
|
||||
|
||||
describe("useRulesEdition", () => {
|
||||
afterEach(() => {
|
||||
// Reset to default
|
||||
const { result } = renderHook(() => useRulesEdition());
|
||||
act(() => result.current.setEdition("5.5e"));
|
||||
localStorage.removeItem(STORAGE_KEY);
|
||||
});
|
||||
|
||||
it("defaults to 5.5e", () => {
|
||||
const { result } = renderHook(() => useRulesEdition());
|
||||
expect(result.current.edition).toBe("5.5e");
|
||||
});
|
||||
|
||||
it("setEdition updates value", () => {
|
||||
const { result } = renderHook(() => useRulesEdition());
|
||||
|
||||
act(() => result.current.setEdition("5e"));
|
||||
|
||||
expect(result.current.edition).toBe("5e");
|
||||
});
|
||||
|
||||
it("setEdition persists to localStorage", () => {
|
||||
const { result } = renderHook(() => useRulesEdition());
|
||||
|
||||
act(() => result.current.setEdition("5e"));
|
||||
|
||||
expect(localStorage.getItem(STORAGE_KEY)).toBe("5e");
|
||||
});
|
||||
|
||||
it("multiple hooks stay in sync", () => {
|
||||
const { result: r1 } = renderHook(() => useRulesEdition());
|
||||
const { result: r2 } = renderHook(() => useRulesEdition());
|
||||
|
||||
act(() => r1.current.setEdition("5e"));
|
||||
|
||||
expect(r2.current.edition).toBe("5e");
|
||||
});
|
||||
});
|
||||
63
apps/web/src/hooks/__tests__/use-theme.test.ts
Normal file
63
apps/web/src/hooks/__tests__/use-theme.test.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
// @vitest-environment jsdom
|
||||
import { act, renderHook } from "@testing-library/react";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { useTheme } from "../use-theme.js";
|
||||
|
||||
const STORAGE_KEY = "initiative:theme";
|
||||
|
||||
describe("useTheme", () => {
|
||||
afterEach(() => {
|
||||
// Reset to default
|
||||
const { result } = renderHook(() => useTheme());
|
||||
act(() => result.current.setPreference("system"));
|
||||
localStorage.removeItem(STORAGE_KEY);
|
||||
});
|
||||
|
||||
it("defaults to system preference", () => {
|
||||
const { result } = renderHook(() => useTheme());
|
||||
expect(result.current.preference).toBe("system");
|
||||
});
|
||||
|
||||
it("setPreference updates to light", () => {
|
||||
const { result } = renderHook(() => useTheme());
|
||||
|
||||
act(() => result.current.setPreference("light"));
|
||||
|
||||
expect(result.current.preference).toBe("light");
|
||||
expect(result.current.resolved).toBe("light");
|
||||
});
|
||||
|
||||
it("setPreference updates to dark", () => {
|
||||
const { result } = renderHook(() => useTheme());
|
||||
|
||||
act(() => result.current.setPreference("dark"));
|
||||
|
||||
expect(result.current.preference).toBe("dark");
|
||||
expect(result.current.resolved).toBe("dark");
|
||||
});
|
||||
|
||||
it("persists preference to localStorage", () => {
|
||||
const { result } = renderHook(() => useTheme());
|
||||
|
||||
act(() => result.current.setPreference("light"));
|
||||
|
||||
expect(localStorage.getItem(STORAGE_KEY)).toBe("light");
|
||||
});
|
||||
|
||||
it("applies theme to document element", () => {
|
||||
const { result } = renderHook(() => useTheme());
|
||||
|
||||
act(() => result.current.setPreference("light"));
|
||||
|
||||
expect(document.documentElement.dataset.theme).toBe("light");
|
||||
});
|
||||
|
||||
it("multiple hooks stay in sync", () => {
|
||||
const { result: r1 } = renderHook(() => useTheme());
|
||||
const { result: r2 } = renderHook(() => useTheme());
|
||||
|
||||
act(() => r1.current.setPreference("dark"));
|
||||
|
||||
expect(r2.current.preference).toBe("dark");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user