import { describe, expect, it, vi } from "vitest"; import { finalizeProjectDrag } from "./timelineProjectDragFinalize.js"; const BASE_DRAG = { isDragging: true, projectId: "project-1", currentStartDate: new Date("2025-01-12T00:00:00.000Z"), currentEndDate: new Date("2025-01-22T00:00:00.000Z"), daysDelta: 2, }; describe("timelineProjectDragFinalize", () => { it("returns null without clearing when the drag is already inactive", () => { const updatePosition = vi.fn(); const clearSession = vi.fn(); expect( finalizeProjectDrag({ clientX: 20, dragRef: { current: { ...BASE_DRAG, isDragging: false } }, previewRef: { current: null }, updatePosition, clearSession, mutate: vi.fn(), mutateAsync: vi.fn(), }), ).toBeNull(); expect(updatePosition).toHaveBeenCalledWith(20); expect(clearSession).not.toHaveBeenCalled(); }); it("preserves preview, clears the session, and fires mutate for real drags", () => { const clearSession = vi.fn(); const mutate = vi.fn(); const cancelAnimationFrameSpy = vi.fn(); vi.stubGlobal("cancelAnimationFrame", cancelAnimationFrameSpy); const previewRef = { current: { mode: "move" as const, cellWidth: 48, targets: [], pointerDeltaX: 0, daysDelta: 0, frame: 7, }, }; try { expect( finalizeProjectDrag({ clientX: 24, dragRef: { current: BASE_DRAG }, previewRef, updatePosition: vi.fn(), clearSession, mutate, mutateAsync: vi.fn(), }), ).toBeNull(); expect(cancelAnimationFrameSpy).toHaveBeenCalledWith(7); expect(previewRef.current.frame).toBeNull(); expect(clearSession).toHaveBeenCalledOnce(); expect(mutate).toHaveBeenCalledWith({ projectId: "project-1", newStartDate: new Date("2025-01-12T00:00:00.000Z"), newEndDate: new Date("2025-01-22T00:00:00.000Z"), }); } finally { vi.unstubAllGlobals(); } }); it("clears but suppresses mutation for no-op drags", () => { const clearSession = vi.fn(); const mutate = vi.fn(); const mutateAsync = vi.fn(); expect( finalizeProjectDrag({ clientX: 30, dragRef: { current: { ...BASE_DRAG, daysDelta: 0 } }, previewRef: { current: null }, updatePosition: vi.fn(), clearSession, mutate, mutateAsync, }), ).toBeNull(); expect(clearSession).toHaveBeenCalledOnce(); expect(mutate).not.toHaveBeenCalled(); expect(mutateAsync).not.toHaveBeenCalled(); }); it("returns the async mutation promise when requested", async () => { const result = { ok: true }; const mutateAsync = vi.fn().mockResolvedValue(result); await expect( finalizeProjectDrag({ clientX: 36, mode: "mutateAsync", dragRef: { current: BASE_DRAG }, previewRef: { current: null }, updatePosition: vi.fn(), clearSession: vi.fn(), mutate: vi.fn(), mutateAsync, }), ).resolves.toEqual(result); expect(mutateAsync).toHaveBeenCalledWith({ projectId: "project-1", newStartDate: new Date("2025-01-12T00:00:00.000Z"), newEndDate: new Date("2025-01-22T00:00:00.000Z"), }); }); });