Files
kandev/apps/web/hooks/use-task-listing-view.test.tsx
T
2026-07-25 19:30:52 +01:00

73 lines
2.5 KiB
TypeScript

import { act, renderHook, waitFor } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { defaultState } from "@/lib/state/default-state";
import type { AppState } from "@/lib/state/store";
import {
TASK_LISTING_VIEW_CHANGE_EVENT,
TASK_LISTING_VIEW_STORAGE_KEY,
} from "@/lib/task-listing/view-preference";
const mocks = vi.hoisted(() => ({
isMobile: false,
state: null as AppState | null,
setUserSettings: vi.fn(),
}));
vi.mock("@/components/state-provider", () => ({
useAppStore: <T,>(selector: (state: AppState) => T) => selector(mocks.state!),
}));
vi.mock("@/hooks/use-responsive-breakpoint", () => ({
useResponsiveBreakpoint: () => ({ isMobile: mocks.isMobile }),
}));
import { useTaskListingView } from "./use-task-listing-view";
function resetMocks() {
mocks.isMobile = false;
mocks.state = structuredClone(defaultState) as AppState;
mocks.state.setUserSettings = mocks.setUserSettings;
mocks.setUserSettings.mockReset();
window.localStorage.clear();
}
afterEach(resetMocks);
beforeEach(resetMocks);
describe("useTaskListingView", () => {
it("updates from local custom and storage events", () => {
const { result } = renderHook(() => useTaskListingView());
expect(result.current.preferredView).toBe("kanban");
act(() => {
window.localStorage.setItem(TASK_LISTING_VIEW_STORAGE_KEY, '"pipeline"');
window.dispatchEvent(new CustomEvent(TASK_LISTING_VIEW_CHANGE_EVENT));
});
expect(result.current.preferredView).toBe("pipeline");
act(() => {
window.localStorage.setItem(TASK_LISTING_VIEW_STORAGE_KEY, '"list"');
const storageEvent = new Event("storage");
Object.defineProperty(storageEvent, "key", { value: TASK_LISTING_VIEW_STORAGE_KEY });
window.dispatchEvent(storageEvent);
});
expect(result.current.preferredView).toBe("list");
});
it("syncs mobile Pipeline fallback as Kanban without overwriting the saved preference", async () => {
mocks.isMobile = true;
mocks.state!.userSettings.kanbanViewMode = "graph2";
window.localStorage.setItem(TASK_LISTING_VIEW_STORAGE_KEY, '"pipeline"');
const { result } = renderHook(() => useTaskListingView());
expect(result.current.preferredView).toBe("pipeline");
expect(result.current.effectiveView).toBe("kanban");
await waitFor(() => {
expect(mocks.setUserSettings).toHaveBeenCalledWith(
expect.objectContaining({ kanbanViewMode: null, loaded: true }),
);
});
});
});