Files
fusion/packages/dashboard/app/hooks/__tests__/usePoppedOutTasks.test.ts
gsxdsm f6f9e822f5 refactor(dashboard): extract task-detail, board-scroll, popped-out hooks
Extract three AppInner state clusters into hooks:
- useMainPanelTaskDetail: the main-panel task-detail snapshot + initial tab;
  setTask accepts the SetStateAction updater form so the embedded detail can
  patch the snapshot on task updates.
- useBoardScrollRestore: the board scroll snapshot refs, capture, and the
  double-requestAnimationFrame restore effect keyed on taskView; exposes
  requestRestore for App to schedule a restore on detail close.
- usePoppedOutTasks: the popped-out task-detail windows (dedupe-by-id popOut,
  close-by-id).

App keeps the navigation-history composition (openTaskDetailInMainPanel /
closeTaskDetailMainPanel) and now consumes the hooks' primitives.
Behavior-preserving; App.test.tsx identical (5 pre-existing failures, none
introduced). Verified by typecheck, eslint, and 5 renderHook tests.

Completes U6 (App.tsx module-breakup plan).
2026-06-23 21:09:36 -07:00

32 lines
945 B
TypeScript

import { describe, expect, it } from "vitest";
import { renderHook, act } from "@testing-library/react";
import { usePoppedOutTasks } from "../usePoppedOutTasks";
const task = (id: string) => ({ id, title: id, status: "todo" } as never);
describe("usePoppedOutTasks", () => {
it("popOut adds a task and dedupes by id", () => {
const { result } = renderHook(() => usePoppedOutTasks());
act(() => {
result.current.popOut(task("1"));
result.current.popOut(task("1"));
result.current.popOut(task("2"));
});
expect(result.current.tasks.map((t) => t.id)).toEqual(["1", "2"]);
});
it("close removes only the matching id", () => {
const { result } = renderHook(() => usePoppedOutTasks());
act(() => {
result.current.popOut(task("1"));
result.current.popOut(task("2"));
result.current.close("1");
});
expect(result.current.tasks.map((t) => t.id)).toEqual(["2"]);
});
});