refactor(web): extract allocation drag finalize helpers

This commit is contained in:
2026-04-01 09:57:29 +02:00
parent 54c6cf2e2d
commit 6dac993521
3 changed files with 237 additions and 23 deletions
@@ -0,0 +1,148 @@
import { describe, expect, it } from "vitest";
import {
buildAllocationMovedSnapshot,
hasAllocationDateChange,
requiresAllocationFragmentExtraction,
shouldTreatAllocationDragAsClick,
} from "./timelineAllocationFinalize.js";
const baseDates = {
allocationStartDate: new Date("2025-01-01T00:00:00.000Z"),
allocationEndDate: new Date("2025-01-05T00:00:00.000Z"),
originalStartDate: new Date("2025-01-01T00:00:00.000Z"),
originalEndDate: new Date("2025-01-05T00:00:00.000Z"),
currentStartDate: new Date("2025-01-01T00:00:00.000Z"),
currentEndDate: new Date("2025-01-05T00:00:00.000Z"),
} as const;
describe("timelineAllocationFinalize", () => {
it("treats missing dates as no change", () => {
expect(
hasAllocationDateChange({
mode: "move",
scope: "allocation",
allocationId: "alloc-1",
mutationAllocationId: null,
projectName: "Alpha",
allocationStartDate: null,
allocationEndDate: null,
originalStartDate: null,
originalEndDate: baseDates.originalEndDate,
currentStartDate: baseDates.currentStartDate,
currentEndDate: baseDates.currentEndDate,
pointerDeltaX: 0,
daysDelta: 0,
}),
).toBe(false);
});
it("detects start or end date changes", () => {
expect(
hasAllocationDateChange({
mode: "move",
scope: "allocation",
allocationId: "alloc-1",
mutationAllocationId: null,
projectName: "Alpha",
...baseDates,
currentEndDate: new Date("2025-01-06T00:00:00.000Z"),
pointerDeltaX: 0,
daysDelta: 1,
}),
).toBe(true);
});
it("treats only small move drags without day changes as clicks", () => {
expect(
shouldTreatAllocationDragAsClick(
{ mode: "move", daysDelta: 0, pointerDeltaX: -5 },
5,
),
).toBe(true);
expect(
shouldTreatAllocationDragAsClick(
{ mode: "resize-end", daysDelta: 0, pointerDeltaX: 0 },
5,
),
).toBe(false);
expect(
shouldTreatAllocationDragAsClick(
{ mode: "move", daysDelta: 1, pointerDeltaX: 2 },
5,
),
).toBe(false);
});
it("requires extraction only for segment drags that no longer match allocation boundaries", () => {
expect(
requiresAllocationFragmentExtraction({
mode: "move",
scope: "segment",
allocationId: "alloc-1",
mutationAllocationId: null,
projectName: "Alpha",
...baseDates,
allocationStartDate: new Date("2024-12-31T00:00:00.000Z"),
pointerDeltaX: 0,
daysDelta: 1,
}),
).toBe(true);
expect(
requiresAllocationFragmentExtraction({
mode: "move",
scope: "allocation",
allocationId: "alloc-1",
mutationAllocationId: null,
projectName: "Alpha",
...baseDates,
pointerDeltaX: 0,
daysDelta: 1,
}),
).toBe(false);
});
it("returns null snapshots when required dates or ids are missing", () => {
expect(
buildAllocationMovedSnapshot({
mode: "move",
scope: "allocation",
allocationId: null,
mutationAllocationId: null,
projectName: "Alpha",
...baseDates,
pointerDeltaX: 0,
daysDelta: 1,
}),
).toBeNull();
});
it("builds a mutation snapshot with fallback mutation allocation ids", () => {
expect(
buildAllocationMovedSnapshot({
mode: "move",
scope: "allocation",
allocationId: "alloc-1",
mutationAllocationId: null,
projectName: null,
...baseDates,
currentStartDate: new Date("2025-01-02T00:00:00.000Z"),
currentEndDate: new Date("2025-01-06T00:00:00.000Z"),
pointerDeltaX: 32,
daysDelta: 1,
}),
).toEqual({
allocationId: "alloc-1",
mutationAllocationId: "alloc-1",
projectName: "",
before: {
startDate: new Date("2025-01-01T00:00:00.000Z"),
endDate: new Date("2025-01-05T00:00:00.000Z"),
},
after: {
startDate: new Date("2025-01-02T00:00:00.000Z"),
endDate: new Date("2025-01-06T00:00:00.000Z"),
},
});
});
});