summaryrefslogtreecommitdiff
path: root/apps/web/src/services/storage/migrations/__tests__
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-07 01:09:13 +0200
committerMaze Winther <mazewinther@gmail.com>2026-04-07 01:09:13 +0200
commite4b67094e757917588fb624a30aa046667403add (patch)
tree55452692eac69a5a63b58f2a5cdb701dd7023d68 /apps/web/src/services/storage/migrations/__tests__
parent79df73643185c02493364a077402726d1fa7b9ec (diff)
downloadopencut-e4b67094e757917588fb624a30aa046667403add.tar.gz
refactor: split effects and masks into dedicated rust crates, introduce MediaTime and FrameRate
Diffstat (limited to 'apps/web/src/services/storage/migrations/__tests__')
-rw-r--r--apps/web/src/services/storage/migrations/__tests__/v1-to-v2.test.ts2
-rw-r--r--apps/web/src/services/storage/migrations/__tests__/v22-to-v23.test.ts192
2 files changed, 193 insertions, 1 deletions
diff --git a/apps/web/src/services/storage/migrations/__tests__/v1-to-v2.test.ts b/apps/web/src/services/storage/migrations/__tests__/v1-to-v2.test.ts
index 7a4dd641..7a0617a7 100644
--- a/apps/web/src/services/storage/migrations/__tests__/v1-to-v2.test.ts
+++ b/apps/web/src/services/storage/migrations/__tests__/v1-to-v2.test.ts
@@ -4,7 +4,7 @@ import {
DEFAULT_BACKGROUND_COLOR,
} from "@/lib/background/constants";
import { DEFAULT_CANVAS_SIZE } from "@/lib/canvas/constants";
-import { DEFAULT_FPS } from "@/lib/fps/constants";
+const DEFAULT_FPS = 30;
import type { MediaAssetData } from "@/services/storage/types";
import { getProjectId, transformProjectV1ToV2 } from "../transformers/v1-to-v2";
import {
diff --git a/apps/web/src/services/storage/migrations/__tests__/v22-to-v23.test.ts b/apps/web/src/services/storage/migrations/__tests__/v22-to-v23.test.ts
new file mode 100644
index 00000000..5b764b48
--- /dev/null
+++ b/apps/web/src/services/storage/migrations/__tests__/v22-to-v23.test.ts
@@ -0,0 +1,192 @@
+import { describe, expect, test } from "bun:test";
+import { transformProjectV22ToV23 } from "../transformers/v22-to-v23";
+
+describe("V22 to V23 Migration", () => {
+ test("converts project time values from seconds to ticks and fps to a frame-rate object", () => {
+ const result = transformProjectV22ToV23({
+ project: {
+ id: "project-v22-time",
+ version: 22,
+ metadata: {
+ id: "project-v22-time",
+ name: "Project",
+ duration: 15.5,
+ createdAt: "2026-01-01T00:00:00.000Z",
+ updatedAt: "2026-01-01T00:00:00.000Z",
+ },
+ settings: {
+ fps: 29.97,
+ canvasSize: { width: 1920, height: 1080 },
+ background: { type: "color", color: "#000000" },
+ },
+ timelineViewState: {
+ zoomLevel: 1,
+ scrollLeft: 120,
+ playheadTime: 1.25,
+ },
+ scenes: [
+ {
+ id: "scene-1",
+ bookmarks: [
+ { time: 2.5, duration: 0.75, note: "Marker", color: "#ff0000" },
+ { time: 4.5 },
+ ],
+ tracks: [
+ {
+ id: "track-1",
+ type: "video",
+ elements: [
+ {
+ id: "element-1",
+ type: "video",
+ startTime: 1.25,
+ duration: 5.5,
+ trimStart: 0.25,
+ trimEnd: 0.5,
+ sourceDuration: 6.25,
+ animations: {
+ bindings: {
+ opacity: {
+ path: "opacity",
+ kind: "number",
+ components: [
+ {
+ key: "value",
+ channelId: "opacity:value",
+ },
+ ],
+ },
+ },
+ channels: {
+ "opacity:value": {
+ kind: "scalar",
+ keys: [
+ {
+ id: "key-1",
+ time: 0.5,
+ value: 1,
+ segmentToNext: "bezier",
+ tangentMode: "flat",
+ rightHandle: {
+ dt: 0.25,
+ dv: 0.2,
+ },
+ },
+ {
+ id: "key-2",
+ time: 1.0,
+ value: 0.4,
+ segmentToNext: "linear",
+ tangentMode: "flat",
+ leftHandle: {
+ dt: -0.125,
+ dv: -0.1,
+ },
+ },
+ ],
+ },
+ },
+ },
+ },
+ ],
+ },
+ ],
+ createdAt: "2026-01-01T00:00:00.000Z",
+ updatedAt: "2026-01-01T00:00:00.000Z",
+ },
+ ],
+ },
+ });
+
+ expect(result.skipped).toBe(false);
+ expect(result.project.version).toBe(23);
+
+ const metadata = result.project.metadata as Record<string, unknown>;
+ expect(metadata.duration).toBe(1_860_000);
+
+ const settings = result.project.settings as Record<string, unknown>;
+ expect(settings.fps).toEqual({ numerator: 30_000, denominator: 1_001 });
+
+ const timelineViewState = result.project.timelineViewState as Record<
+ string,
+ unknown
+ >;
+ expect(timelineViewState.playheadTime).toBe(150_000);
+ expect(timelineViewState.scrollLeft).toBe(120);
+
+ const scenes = result.project.scenes as Array<Record<string, unknown>>;
+ const scene = scenes[0];
+ expect(scene.bookmarks).toEqual([
+ {
+ time: 300_000,
+ duration: 90_000,
+ note: "Marker",
+ color: "#ff0000",
+ },
+ { time: 540_000 },
+ ]);
+
+ const tracks = scene.tracks as Array<Record<string, unknown>>;
+ const elements = tracks[0].elements as Array<Record<string, unknown>>;
+ const element = elements[0];
+ expect(element.startTime).toBe(150_000);
+ expect(element.duration).toBe(660_000);
+ expect(element.trimStart).toBe(30_000);
+ expect(element.trimEnd).toBe(60_000);
+ expect(element.sourceDuration).toBe(750_000);
+
+ const animations = element.animations as Record<string, unknown>;
+ const channels = animations.channels as Record<string, Record<string, unknown>>;
+ expect(channels["opacity:value"]).toEqual({
+ kind: "scalar",
+ keys: [
+ {
+ id: "key-1",
+ time: 60_000,
+ value: 1,
+ segmentToNext: "bezier",
+ tangentMode: "flat",
+ rightHandle: {
+ dt: 30_000,
+ dv: 0.2,
+ },
+ },
+ {
+ id: "key-2",
+ time: 120_000,
+ value: 0.4,
+ segmentToNext: "linear",
+ tangentMode: "flat",
+ leftHandle: {
+ dt: -15_000,
+ dv: -0.1,
+ },
+ },
+ ],
+ });
+ });
+
+ test("skips projects already on v23", () => {
+ const result = transformProjectV22ToV23({
+ project: {
+ id: "project-v23",
+ version: 23,
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("already v23");
+ });
+
+ test("skips projects not on v22", () => {
+ const result = transformProjectV22ToV23({
+ project: {
+ id: "project-v21",
+ version: 21,
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("not v22");
+ });
+});