refactor(web): extract project drag session

This commit is contained in:
2026-04-01 11:16:15 +02:00
parent 0181f2b304
commit 3fe3a5fb2a
5 changed files with 164 additions and 17 deletions
@@ -0,0 +1,80 @@
import { describe, expect, it, vi } from "vitest";
import { beginProjectDragSession } from "./timelineProjectDragSession.js";
describe("timelineProjectDragSession", () => {
it("starts the session, forwards movement, and finalizes on mouseup", () => {
const previousCleanup = vi.fn();
const setState = vi.fn();
const updatePosition = vi.fn();
const finalize = vi.fn();
const state = { projectId: "project-1", isDragging: true };
const cleanupRef = { current: previousCleanup as (() => void) | null };
const stateRef = { current: { projectId: null, isDragging: false } };
const handlers: {
move?: (event: MouseEvent) => void;
up?: (event: MouseEvent) => void;
} = {};
const attachDrag = vi.fn((_: Document, onMove: (event: MouseEvent) => void, onUp: (event: MouseEvent) => void) => {
handlers.move = onMove;
handlers.up = onUp;
return vi.fn();
});
beginProjectDragSession({
state,
cleanupRef,
stateRef,
setState,
documentTarget: {} as Document,
attachDrag,
updatePosition,
finalize,
});
expect(previousCleanup).toHaveBeenCalledOnce();
expect(stateRef.current).toBe(state);
expect(setState).toHaveBeenCalledWith(state);
handlers.move?.({ clientX: 42 } as MouseEvent);
expect(updatePosition).toHaveBeenCalledWith(42);
const preventDefault = vi.fn();
const attachedCleanup = cleanupRef.current;
handlers.up?.({ clientX: 54, preventDefault } as unknown as MouseEvent);
expect(attachedCleanup).toHaveBeenCalledOnce();
expect(cleanupRef.current).toBeNull();
expect(finalize).toHaveBeenCalledWith(54);
expect(preventDefault).toHaveBeenCalledOnce();
});
it("works when no prior cleanup is registered", () => {
const setState = vi.fn();
const updatePosition = vi.fn();
const finalize = vi.fn().mockResolvedValue(undefined);
const cleanupRef = { current: null as (() => void) | null };
const stateRef = { current: { projectId: null, isDragging: false } };
let upHandler: ((event: MouseEvent) => void) | undefined;
beginProjectDragSession({
state: { projectId: "project-2", isDragging: true },
cleanupRef,
stateRef,
setState,
documentTarget: {} as Document,
attachDrag: (_documentTarget, _onMove, onUp) => {
upHandler = onUp;
return vi.fn();
},
updatePosition,
finalize,
});
upHandler?.({ clientX: 12, preventDefault() {} } as MouseEvent);
expect(updatePosition).not.toHaveBeenCalled();
expect(finalize).toHaveBeenCalledWith(12);
expect(cleanupRef.current).toBeNull();
});
});