From 8a3577d2e7c871e58307fa014c7f5e1446cdd3e3 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Wed, 15 Apr 2026 05:52:33 +0200 Subject: review: fixes --- .../group-move/__tests__/group-move.test.ts | 104 +++++++++++++++++++++ 1 file changed, 104 insertions(+) (limited to 'apps/web/src/lib/timeline/group-move/__tests__') diff --git a/apps/web/src/lib/timeline/group-move/__tests__/group-move.test.ts b/apps/web/src/lib/timeline/group-move/__tests__/group-move.test.ts index e6c86e41..9e89c48a 100644 --- a/apps/web/src/lib/timeline/group-move/__tests__/group-move.test.ts +++ b/apps/web/src/lib/timeline/group-move/__tests__/group-move.test.ts @@ -11,6 +11,7 @@ import type { import type { Transform } from "@/lib/rendering"; import { buildMoveGroup } from "@/lib/timeline/group-move/build-group"; import { resolveGroupMove } from "@/lib/timeline/group-move/resolve-move"; +import { snapGroupEdges } from "@/lib/timeline/group-move/snap"; function buildTransform(): Transform { return { @@ -284,4 +285,107 @@ describe("group move", () => { }, ]); }); + + test("snapGroupEdges snaps the closest group edge and preserves offsets", () => { + const tracks = buildTracks({ + overlay: [ + buildVideoTrack({ + id: "overlay-video", + elements: [ + buildVideoElement({ id: "video-1", startTime: 5, duration: 2 }), + ], + }), + buildTextTrack({ + id: "overlay-text", + elements: [ + buildTextElement({ id: "text-1", startTime: 8, duration: 3 }), + ], + }), + ], + main: buildVideoTrack({ + id: "main", + elements: [ + buildVideoElement({ id: "video-snap", startTime: 10, duration: 4 }), + ], + }), + }); + const group = buildMoveGroup({ + anchorRef: { trackId: "overlay-video", elementId: "video-1" }, + selectedElements: [ + { trackId: "overlay-video", elementId: "video-1" }, + { trackId: "overlay-text", elementId: "text-1" }, + ], + tracks, + }); + if (!group) { + throw new Error("Expected group"); + } + + const result = snapGroupEdges({ + group, + anchorStartTime: 6, + tracks, + playheadTime: 100, + zoomLevel: 1, + }); + + expect(result).toEqual({ + snappedAnchorStartTime: 7, + snapPoint: { + time: 10, + type: "element-start", + elementId: "video-snap", + trackId: "main", + }, + }); + }); + + test("snapGroupEdges returns the raw anchor time when nothing is within threshold", () => { + const tracks = buildTracks({ + overlay: [ + buildVideoTrack({ + id: "overlay-video", + elements: [ + buildVideoElement({ id: "video-1", startTime: 5, duration: 2 }), + ], + }), + buildTextTrack({ + id: "overlay-text", + elements: [ + buildTextElement({ id: "text-1", startTime: 8, duration: 3 }), + ], + }), + ], + main: buildVideoTrack({ + id: "main", + elements: [ + buildVideoElement({ id: "video-snap", startTime: 100, duration: 4 }), + ], + }), + }); + const group = buildMoveGroup({ + anchorRef: { trackId: "overlay-video", elementId: "video-1" }, + selectedElements: [ + { trackId: "overlay-video", elementId: "video-1" }, + { trackId: "overlay-text", elementId: "text-1" }, + ], + tracks, + }); + if (!group) { + throw new Error("Expected group"); + } + + const result = snapGroupEdges({ + group, + anchorStartTime: 6, + tracks, + playheadTime: 200, + zoomLevel: 1000, + }); + + expect(result).toEqual({ + snappedAnchorStartTime: 6, + snapPoint: null, + }); + }); }); -- cgit v1.3.1