diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-03-27 00:55:15 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-03-29 15:56:48 +0200 |
| commit | 4d127a038bf768eded68aae3cfa5c1b12241bdac (patch) | |
| tree | 16bbb801caf6770546cff4fdb37b6408ec9ead98 /apps/web/src/services/storage/migrations/__tests__ | |
| parent | 82817cb50cb0487350573d6129130aec705f924b (diff) | |
| download | opencut-4d127a038bf768eded68aae3cfa5c1b12241bdac.tar.gz | |
chore: normalize line endings
Diffstat (limited to 'apps/web/src/services/storage/migrations/__tests__')
9 files changed, 896 insertions, 896 deletions
diff --git a/apps/web/src/services/storage/migrations/__tests__/fixtures/index.ts b/apps/web/src/services/storage/migrations/__tests__/fixtures/index.ts index 5f82e14a..a97e42d7 100644 --- a/apps/web/src/services/storage/migrations/__tests__/fixtures/index.ts +++ b/apps/web/src/services/storage/migrations/__tests__/fixtures/index.ts @@ -1,10 +1,10 @@ -/** - * Test fixtures for storage migrations. - * These represent real project data shapes from each version. - */ - -export * from "./v0"; -export * from "./v1"; -export * from "./v2"; -export * from "./v3"; -export * from "./v5"; +/**
+ * Test fixtures for storage migrations.
+ * These represent real project data shapes from each version.
+ */
+
+export * from "./v0";
+export * from "./v1";
+export * from "./v2";
+export * from "./v3";
+export * from "./v5";
diff --git a/apps/web/src/services/storage/migrations/__tests__/fixtures/v5.ts b/apps/web/src/services/storage/migrations/__tests__/fixtures/v5.ts index 5e181c76..89bb83c3 100644 --- a/apps/web/src/services/storage/migrations/__tests__/fixtures/v5.ts +++ b/apps/web/src/services/storage/migrations/__tests__/fixtures/v5.ts @@ -1,54 +1,54 @@ -export const v5Project = { - id: "project-v5-456", - version: 5, - metadata: { - id: "project-v5-456", - name: "My V5 Project", - thumbnail: "data:image/png;base64,abc123", - duration: 30, - createdAt: "2024-06-01T10:00:00.000Z", - updatedAt: "2024-06-01T14:00:00.000Z", - }, - settings: { - fps: 30, - canvasSize: { width: 1920, height: 1080 }, - background: { type: "color", color: "#000000" }, - }, - currentSceneId: "scene-main", - scenes: [ - { - id: "scene-main", - name: "Main scene", - isMain: true, - tracks: [ - { - id: "track-1", - type: "video", - name: "Video Track", - isMain: true, - elements: [], - }, - ], - bookmarks: [2.0, 5.5, 12.0], - createdAt: "2024-06-01T10:00:00.000Z", - updatedAt: "2024-06-01T14:00:00.000Z", - }, - { - id: "scene-intro", - name: "Intro", - isMain: false, - tracks: [ - { - id: "track-2", - type: "video", - name: "Video Track", - isMain: true, - elements: [], - }, - ], - bookmarks: [], - createdAt: "2024-06-01T10:00:00.000Z", - updatedAt: "2024-06-01T14:00:00.000Z", - }, - ], -}; +export const v5Project = {
+ id: "project-v5-456",
+ version: 5,
+ metadata: {
+ id: "project-v5-456",
+ name: "My V5 Project",
+ thumbnail: "data:image/png;base64,abc123",
+ duration: 30,
+ createdAt: "2024-06-01T10:00:00.000Z",
+ updatedAt: "2024-06-01T14:00:00.000Z",
+ },
+ settings: {
+ fps: 30,
+ canvasSize: { width: 1920, height: 1080 },
+ background: { type: "color", color: "#000000" },
+ },
+ currentSceneId: "scene-main",
+ scenes: [
+ {
+ id: "scene-main",
+ name: "Main scene",
+ isMain: true,
+ tracks: [
+ {
+ id: "track-1",
+ type: "video",
+ name: "Video Track",
+ isMain: true,
+ elements: [],
+ },
+ ],
+ bookmarks: [2.0, 5.5, 12.0],
+ createdAt: "2024-06-01T10:00:00.000Z",
+ updatedAt: "2024-06-01T14:00:00.000Z",
+ },
+ {
+ id: "scene-intro",
+ name: "Intro",
+ isMain: false,
+ tracks: [
+ {
+ id: "track-2",
+ type: "video",
+ name: "Video Track",
+ isMain: true,
+ elements: [],
+ },
+ ],
+ bookmarks: [],
+ createdAt: "2024-06-01T10:00:00.000Z",
+ updatedAt: "2024-06-01T14:00:00.000Z",
+ },
+ ],
+};
diff --git a/apps/web/src/services/storage/migrations/__tests__/v15-to-v16.test.ts b/apps/web/src/services/storage/migrations/__tests__/v15-to-v16.test.ts index f2a4908f..122af2cb 100644 --- a/apps/web/src/services/storage/migrations/__tests__/v15-to-v16.test.ts +++ b/apps/web/src/services/storage/migrations/__tests__/v15-to-v16.test.ts @@ -1,93 +1,93 @@ -import { describe, expect, test } from "bun:test"; -import { transformProjectV15ToV16 } from "../transformers/v15-to-v16"; - -describe("V15 to V16 Migration", () => { - test("renames sticker tracks to graphic tracks", () => { - const result = transformProjectV15ToV16({ - project: { - id: "project-v15", - version: 15, - metadata: { - id: "project-v15", - name: "Project", - createdAt: "2024-01-01T00:00:00.000Z", - updatedAt: "2024-01-01T00:00:00.000Z", - }, - settings: { - fps: 30, - canvasSize: { width: 1920, height: 1080 }, - background: { type: "color", color: "#000000" }, - }, - currentSceneId: "scene-main", - scenes: [ - { - id: "scene-main", - name: "Main scene", - isMain: true, - tracks: [ - { - id: "track-graphic", - type: "sticker", - name: "Sticker Track", - hidden: false, - elements: [ - { - id: "sticker-1", - type: "sticker", - name: "Logo", - stickerId: "icons:mdi:home", - duration: 5, - startTime: 0, - trimStart: 0, - trimEnd: 0, - transform: { - scaleX: 1, - scaleY: 1, - position: { x: 0, y: 0 }, - rotate: 0, - }, - opacity: 1, - }, - ], - }, - ], - bookmarks: [], - createdAt: "2024-01-01T00:00:00.000Z", - updatedAt: "2024-01-01T00:00:00.000Z", - }, - ], - }, - }); - - expect(result.skipped).toBe(false); - expect(result.project.version).toBe(16); - expect( - (result.project.scenes as Array<{ tracks: Array<{ type: string }> }>)[0] - .tracks[0].type, - ).toBe("graphic"); - }); - - test("skips projects already on v16", () => { - const result = transformProjectV15ToV16({ - project: { - id: "project-v16", - version: 16, - }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("already v16"); - }); - - test("skips projects with no id", () => { - const result = transformProjectV15ToV16({ - project: { - version: 15, - scenes: [], - }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("no project id"); - }); -}); +import { describe, expect, test } from "bun:test";
+import { transformProjectV15ToV16 } from "../transformers/v15-to-v16";
+
+describe("V15 to V16 Migration", () => {
+ test("renames sticker tracks to graphic tracks", () => {
+ const result = transformProjectV15ToV16({
+ project: {
+ id: "project-v15",
+ version: 15,
+ metadata: {
+ id: "project-v15",
+ name: "Project",
+ createdAt: "2024-01-01T00:00:00.000Z",
+ updatedAt: "2024-01-01T00:00:00.000Z",
+ },
+ settings: {
+ fps: 30,
+ canvasSize: { width: 1920, height: 1080 },
+ background: { type: "color", color: "#000000" },
+ },
+ currentSceneId: "scene-main",
+ scenes: [
+ {
+ id: "scene-main",
+ name: "Main scene",
+ isMain: true,
+ tracks: [
+ {
+ id: "track-graphic",
+ type: "sticker",
+ name: "Sticker Track",
+ hidden: false,
+ elements: [
+ {
+ id: "sticker-1",
+ type: "sticker",
+ name: "Logo",
+ stickerId: "icons:mdi:home",
+ duration: 5,
+ startTime: 0,
+ trimStart: 0,
+ trimEnd: 0,
+ transform: {
+ scaleX: 1,
+ scaleY: 1,
+ position: { x: 0, y: 0 },
+ rotate: 0,
+ },
+ opacity: 1,
+ },
+ ],
+ },
+ ],
+ bookmarks: [],
+ createdAt: "2024-01-01T00:00:00.000Z",
+ updatedAt: "2024-01-01T00:00:00.000Z",
+ },
+ ],
+ },
+ });
+
+ expect(result.skipped).toBe(false);
+ expect(result.project.version).toBe(16);
+ expect(
+ (result.project.scenes as Array<{ tracks: Array<{ type: string }> }>)[0]
+ .tracks[0].type,
+ ).toBe("graphic");
+ });
+
+ test("skips projects already on v16", () => {
+ const result = transformProjectV15ToV16({
+ project: {
+ id: "project-v16",
+ version: 16,
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("already v16");
+ });
+
+ test("skips projects with no id", () => {
+ const result = transformProjectV15ToV16({
+ project: {
+ version: 15,
+ scenes: [],
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("no project id");
+ });
+});
diff --git a/apps/web/src/services/storage/migrations/__tests__/v16-to-v17.test.ts b/apps/web/src/services/storage/migrations/__tests__/v16-to-v17.test.ts index e246943e..352ca762 100644 --- a/apps/web/src/services/storage/migrations/__tests__/v16-to-v17.test.ts +++ b/apps/web/src/services/storage/migrations/__tests__/v16-to-v17.test.ts @@ -1,132 +1,132 @@ -import { describe, expect, test } from "bun:test"; -import { transformProjectV16ToV17 } from "../transformers/v16-to-v17"; - -describe("V16 to V17 Migration", () => { - test("adds center stroke alignment to masks that do not have it", () => { - const result = transformProjectV16ToV17({ - project: { - id: "project-v16", - version: 16, - metadata: { - id: "project-v16", - name: "Project", - createdAt: "2024-01-01T00:00:00.000Z", - updatedAt: "2024-01-01T00:00:00.000Z", - }, - settings: { - fps: 30, - canvasSize: { width: 1920, height: 1080 }, - background: { type: "color", color: "#000000" }, - }, - currentSceneId: "scene-main", - scenes: [ - { - id: "scene-main", - name: "Main scene", - isMain: true, - tracks: [ - { - id: "track-video", - type: "video", - name: "Video Track", - hidden: false, - elements: [ - { - id: "video-1", - type: "video", - name: "Clip", - mediaId: "media-1", - duration: 5, - startTime: 0, - trimStart: 0, - trimEnd: 0, - transform: { - scaleX: 1, - scaleY: 1, - position: { x: 0, y: 0 }, - rotate: 0, - }, - opacity: 1, - masks: [ - { - id: "mask-1", - type: "rectangle", - params: { - feather: 0, - inverted: false, - strokeColor: "#ffffff", - strokeWidth: 8, - centerX: 0, - centerY: 0, - width: 0.6, - height: 0.6, - rotation: 0, - scale: 1, - }, - }, - { - id: "mask-2", - type: "ellipse", - params: { - feather: 0, - inverted: false, - strokeColor: "#ffffff", - strokeWidth: 8, - strokeAlign: "outside", - centerX: 0, - centerY: 0, - width: 0.6, - height: 0.6, - rotation: 0, - scale: 1, - }, - }, - ], - }, - ], - }, - ], - bookmarks: [], - createdAt: "2024-01-01T00:00:00.000Z", - updatedAt: "2024-01-01T00:00:00.000Z", - }, - ], - }, - }); - - expect(result.skipped).toBe(false); - expect(result.project.version).toBe(17); - - const migratedMasks = ( - ((result.project.scenes as Array<{ tracks: Array<{ elements: Array<{ masks: Array<{ params: Record<string, unknown> }> }> }> }>)[0] - .tracks[0].elements[0].masks) - ); - - expect(migratedMasks[0].params.strokeAlign).toBe("center"); - expect(migratedMasks[1].params.strokeAlign).toBe("outside"); - }); - - test("skips projects already on v17", () => { - const result = transformProjectV16ToV17({ - project: { - id: "project-v17", - version: 17, - }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("already v17"); - }); - - test("skips projects with no id", () => { - const result = transformProjectV16ToV17({ - project: { - version: 16, - scenes: [], - }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("no project id"); - }); -}); +import { describe, expect, test } from "bun:test";
+import { transformProjectV16ToV17 } from "../transformers/v16-to-v17";
+
+describe("V16 to V17 Migration", () => {
+ test("adds center stroke alignment to masks that do not have it", () => {
+ const result = transformProjectV16ToV17({
+ project: {
+ id: "project-v16",
+ version: 16,
+ metadata: {
+ id: "project-v16",
+ name: "Project",
+ createdAt: "2024-01-01T00:00:00.000Z",
+ updatedAt: "2024-01-01T00:00:00.000Z",
+ },
+ settings: {
+ fps: 30,
+ canvasSize: { width: 1920, height: 1080 },
+ background: { type: "color", color: "#000000" },
+ },
+ currentSceneId: "scene-main",
+ scenes: [
+ {
+ id: "scene-main",
+ name: "Main scene",
+ isMain: true,
+ tracks: [
+ {
+ id: "track-video",
+ type: "video",
+ name: "Video Track",
+ hidden: false,
+ elements: [
+ {
+ id: "video-1",
+ type: "video",
+ name: "Clip",
+ mediaId: "media-1",
+ duration: 5,
+ startTime: 0,
+ trimStart: 0,
+ trimEnd: 0,
+ transform: {
+ scaleX: 1,
+ scaleY: 1,
+ position: { x: 0, y: 0 },
+ rotate: 0,
+ },
+ opacity: 1,
+ masks: [
+ {
+ id: "mask-1",
+ type: "rectangle",
+ params: {
+ feather: 0,
+ inverted: false,
+ strokeColor: "#ffffff",
+ strokeWidth: 8,
+ centerX: 0,
+ centerY: 0,
+ width: 0.6,
+ height: 0.6,
+ rotation: 0,
+ scale: 1,
+ },
+ },
+ {
+ id: "mask-2",
+ type: "ellipse",
+ params: {
+ feather: 0,
+ inverted: false,
+ strokeColor: "#ffffff",
+ strokeWidth: 8,
+ strokeAlign: "outside",
+ centerX: 0,
+ centerY: 0,
+ width: 0.6,
+ height: 0.6,
+ rotation: 0,
+ scale: 1,
+ },
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ bookmarks: [],
+ createdAt: "2024-01-01T00:00:00.000Z",
+ updatedAt: "2024-01-01T00:00:00.000Z",
+ },
+ ],
+ },
+ });
+
+ expect(result.skipped).toBe(false);
+ expect(result.project.version).toBe(17);
+
+ const migratedMasks = (
+ ((result.project.scenes as Array<{ tracks: Array<{ elements: Array<{ masks: Array<{ params: Record<string, unknown> }> }> }> }>)[0]
+ .tracks[0].elements[0].masks)
+ );
+
+ expect(migratedMasks[0].params.strokeAlign).toBe("center");
+ expect(migratedMasks[1].params.strokeAlign).toBe("outside");
+ });
+
+ test("skips projects already on v17", () => {
+ const result = transformProjectV16ToV17({
+ project: {
+ id: "project-v17",
+ version: 17,
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("already v17");
+ });
+
+ test("skips projects with no id", () => {
+ const result = transformProjectV16ToV17({
+ project: {
+ version: 16,
+ scenes: [],
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("no project id");
+ });
+});
diff --git a/apps/web/src/services/storage/migrations/__tests__/v18-to-v19.test.ts b/apps/web/src/services/storage/migrations/__tests__/v18-to-v19.test.ts index 7524a8d4..0f679b6d 100644 --- a/apps/web/src/services/storage/migrations/__tests__/v18-to-v19.test.ts +++ b/apps/web/src/services/storage/migrations/__tests__/v18-to-v19.test.ts @@ -1,63 +1,63 @@ -import { describe, expect, test } from "bun:test"; -import { transformProjectV18ToV19 } from "../transformers/v18-to-v19"; - -describe("V18 to V19 Migration", () => { - test("adds canvas size mode and empty remembered custom size defaults", () => { - const result = transformProjectV18ToV19({ - project: { - id: "project-v18-defaults", - version: 18, - metadata: { - id: "project-v18-defaults", - name: "Project", - createdAt: "2024-01-01T00:00:00.000Z", - updatedAt: "2024-01-01T00:00:00.000Z", - }, - settings: { - fps: 30, - canvasSize: { width: 1920, height: 1080 }, - originalCanvasSize: { width: 1920, height: 1080 }, - background: { type: "color", color: "#000000" }, - }, - currentSceneId: "scene-main", - scenes: [], - }, - }); - - expect(result.skipped).toBe(false); - expect(result.project.version).toBe(19); - expect( - (result.project.settings as Record<string, unknown>).canvasSizeMode, - ).toBe("preset"); - expect( - (result.project.settings as Record<string, unknown>).lastCustomCanvasSize, - ).toBeNull(); - expect( - (result.project.settings as Record<string, unknown>).originalCanvasSize, - ).toEqual({ width: 1920, height: 1080 }); - }); - - test("skips projects already on v19", () => { - const result = transformProjectV18ToV19({ - project: { - id: "project-v19", - version: 19, - }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("already v19"); - }); - - test("skips projects with no id", () => { - const result = transformProjectV18ToV19({ - project: { - version: 18, - scenes: [], - }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("no project id"); - }); -}); +import { describe, expect, test } from "bun:test";
+import { transformProjectV18ToV19 } from "../transformers/v18-to-v19";
+
+describe("V18 to V19 Migration", () => {
+ test("adds canvas size mode and empty remembered custom size defaults", () => {
+ const result = transformProjectV18ToV19({
+ project: {
+ id: "project-v18-defaults",
+ version: 18,
+ metadata: {
+ id: "project-v18-defaults",
+ name: "Project",
+ createdAt: "2024-01-01T00:00:00.000Z",
+ updatedAt: "2024-01-01T00:00:00.000Z",
+ },
+ settings: {
+ fps: 30,
+ canvasSize: { width: 1920, height: 1080 },
+ originalCanvasSize: { width: 1920, height: 1080 },
+ background: { type: "color", color: "#000000" },
+ },
+ currentSceneId: "scene-main",
+ scenes: [],
+ },
+ });
+
+ expect(result.skipped).toBe(false);
+ expect(result.project.version).toBe(19);
+ expect(
+ (result.project.settings as Record<string, unknown>).canvasSizeMode,
+ ).toBe("preset");
+ expect(
+ (result.project.settings as Record<string, unknown>).lastCustomCanvasSize,
+ ).toBeNull();
+ expect(
+ (result.project.settings as Record<string, unknown>).originalCanvasSize,
+ ).toEqual({ width: 1920, height: 1080 });
+ });
+
+ test("skips projects already on v19", () => {
+ const result = transformProjectV18ToV19({
+ project: {
+ id: "project-v19",
+ version: 19,
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("already v19");
+ });
+
+ test("skips projects with no id", () => {
+ const result = transformProjectV18ToV19({
+ project: {
+ version: 18,
+ scenes: [],
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("no project id");
+ });
+});
diff --git a/apps/web/src/services/storage/migrations/__tests__/v3-to-v4.test.ts b/apps/web/src/services/storage/migrations/__tests__/v3-to-v4.test.ts index 81d03147..6c2d6597 100644 --- a/apps/web/src/services/storage/migrations/__tests__/v3-to-v4.test.ts +++ b/apps/web/src/services/storage/migrations/__tests__/v3-to-v4.test.ts @@ -1,140 +1,140 @@ -import { describe, expect, test } from "bun:test"; -import { transformProjectV3ToV4 } from "../transformers/v3-to-v4"; -import { v3Project } from "./fixtures"; - -describe("V3 to V4 Migration", () => { - test("normalizes legacy text fontWeight values", () => { - const projectWithLegacyTextWeight = { - ...v3Project, - scenes: [ - { - ...v3Project.scenes[0], - tracks: [ - { - id: "track-text", - type: "text", - name: "Text Track", - hidden: false, - elements: [ - { - id: "text-1", - type: "text", - name: "Title", - content: "Hello", - duration: 5, - startTime: 0, - trimStart: 0, - trimEnd: 0, - fontSize: 64, - fontFamily: "Inter", - color: "#ffffff", - backgroundColor: "transparent", - textAlign: "center", - fontWeight: "bold", - fontStyle: "normal", - textDecoration: "none", - transform: { - scale: 1, - position: { x: 0, y: 0 }, - rotate: 0, - }, - opacity: 1, - }, - ], - }, - ], - }, - ], - }; - - const result = transformProjectV3ToV4({ - project: projectWithLegacyTextWeight, - }); - - expect(result.skipped).toBe(false); - expect(result.project.version).toBe(4); - - const migratedScene = ( - result.project.scenes as Array<Record<string, unknown>> - )[0]; - const migratedTrack = ( - migratedScene.tracks as Array<Record<string, unknown>> - )[0]; - const migratedElement = ( - migratedTrack.elements as Array<Record<string, unknown>> - )[0]; - - expect(migratedElement.fontWeight).toBe("700"); - }); - - test("does not mutate non-text tracks", () => { - const projectWithoutTextTrack = { - ...v3Project, - scenes: [ - { - ...v3Project.scenes[0], - tracks: [ - { - id: "track-sticker", - type: "sticker", - name: "Sticker Track", - hidden: false, - elements: [ - { - id: "sticker-1", - type: "sticker", - name: "Flag", - iconName: "mdi:home", - duration: 5, - startTime: 0, - trimStart: 0, - trimEnd: 0, - transform: { - scale: 1, - position: { x: 0, y: 0 }, - rotate: 0, - }, - opacity: 1, - }, - ], - }, - ], - }, - ], - }; - - const result = transformProjectV3ToV4({ project: projectWithoutTextTrack }); - const migratedScene = ( - result.project.scenes as Array<Record<string, unknown>> - )[0]; - const migratedTrack = ( - migratedScene.tracks as Array<Record<string, unknown>> - )[0]; - const migratedElement = ( - migratedTrack.elements as Array<Record<string, unknown>> - )[0]; - - expect(migratedElement.iconName).toBe("mdi:home"); - }); - - test("skips projects that are already v4", () => { - const result = transformProjectV3ToV4({ - project: { ...v3Project, version: 4 }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("already v4"); - }); - - test("skips projects with no id", () => { - const result = transformProjectV3ToV4({ - project: { - version: 3, - scenes: [], - }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("no project id"); - }); -}); +import { describe, expect, test } from "bun:test";
+import { transformProjectV3ToV4 } from "../transformers/v3-to-v4";
+import { v3Project } from "./fixtures";
+
+describe("V3 to V4 Migration", () => {
+ test("normalizes legacy text fontWeight values", () => {
+ const projectWithLegacyTextWeight = {
+ ...v3Project,
+ scenes: [
+ {
+ ...v3Project.scenes[0],
+ tracks: [
+ {
+ id: "track-text",
+ type: "text",
+ name: "Text Track",
+ hidden: false,
+ elements: [
+ {
+ id: "text-1",
+ type: "text",
+ name: "Title",
+ content: "Hello",
+ duration: 5,
+ startTime: 0,
+ trimStart: 0,
+ trimEnd: 0,
+ fontSize: 64,
+ fontFamily: "Inter",
+ color: "#ffffff",
+ backgroundColor: "transparent",
+ textAlign: "center",
+ fontWeight: "bold",
+ fontStyle: "normal",
+ textDecoration: "none",
+ transform: {
+ scale: 1,
+ position: { x: 0, y: 0 },
+ rotate: 0,
+ },
+ opacity: 1,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ };
+
+ const result = transformProjectV3ToV4({
+ project: projectWithLegacyTextWeight,
+ });
+
+ expect(result.skipped).toBe(false);
+ expect(result.project.version).toBe(4);
+
+ const migratedScene = (
+ result.project.scenes as Array<Record<string, unknown>>
+ )[0];
+ const migratedTrack = (
+ migratedScene.tracks as Array<Record<string, unknown>>
+ )[0];
+ const migratedElement = (
+ migratedTrack.elements as Array<Record<string, unknown>>
+ )[0];
+
+ expect(migratedElement.fontWeight).toBe("700");
+ });
+
+ test("does not mutate non-text tracks", () => {
+ const projectWithoutTextTrack = {
+ ...v3Project,
+ scenes: [
+ {
+ ...v3Project.scenes[0],
+ tracks: [
+ {
+ id: "track-sticker",
+ type: "sticker",
+ name: "Sticker Track",
+ hidden: false,
+ elements: [
+ {
+ id: "sticker-1",
+ type: "sticker",
+ name: "Flag",
+ iconName: "mdi:home",
+ duration: 5,
+ startTime: 0,
+ trimStart: 0,
+ trimEnd: 0,
+ transform: {
+ scale: 1,
+ position: { x: 0, y: 0 },
+ rotate: 0,
+ },
+ opacity: 1,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ };
+
+ const result = transformProjectV3ToV4({ project: projectWithoutTextTrack });
+ const migratedScene = (
+ result.project.scenes as Array<Record<string, unknown>>
+ )[0];
+ const migratedTrack = (
+ migratedScene.tracks as Array<Record<string, unknown>>
+ )[0];
+ const migratedElement = (
+ migratedTrack.elements as Array<Record<string, unknown>>
+ )[0];
+
+ expect(migratedElement.iconName).toBe("mdi:home");
+ });
+
+ test("skips projects that are already v4", () => {
+ const result = transformProjectV3ToV4({
+ project: { ...v3Project, version: 4 },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("already v4");
+ });
+
+ test("skips projects with no id", () => {
+ const result = transformProjectV3ToV4({
+ project: {
+ version: 3,
+ scenes: [],
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("no project id");
+ });
+});
diff --git a/apps/web/src/services/storage/migrations/__tests__/v4-to-v5.test.ts b/apps/web/src/services/storage/migrations/__tests__/v4-to-v5.test.ts index ce0c3019..95386137 100644 --- a/apps/web/src/services/storage/migrations/__tests__/v4-to-v5.test.ts +++ b/apps/web/src/services/storage/migrations/__tests__/v4-to-v5.test.ts @@ -1,137 +1,137 @@ -import { describe, expect, test } from "bun:test"; -import { transformProjectV4ToV5 } from "../transformers/v4-to-v5"; -import { v3Project } from "./fixtures"; - -describe("V4 to V5 Migration", () => { - test("migrates sticker iconName to stickerId and removes legacy color", () => { - const projectWithLegacySticker = { - ...v3Project, - version: 4, - scenes: [ - { - ...v3Project.scenes[0], - tracks: [ - { - id: "track-sticker", - type: "sticker", - name: "Sticker Track", - hidden: false, - elements: [ - { - id: "sticker-1", - type: "sticker", - name: "Home", - iconName: "mdi:home", - color: "#ff0000", - duration: 5, - startTime: 0, - trimStart: 0, - trimEnd: 0, - transform: { - scale: 1, - position: { x: 0, y: 0 }, - rotate: 0, - }, - opacity: 1, - }, - ], - }, - ], - }, - ], - }; - - const result = transformProjectV4ToV5({ - project: projectWithLegacySticker, - }); - - expect(result.skipped).toBe(false); - expect(result.project.version).toBe(5); - - const migratedScene = ( - result.project.scenes as Array<Record<string, unknown>> - )[0]; - const migratedTrack = ( - migratedScene.tracks as Array<Record<string, unknown>> - )[0]; - const migratedElement = ( - migratedTrack.elements as Array<Record<string, unknown>> - )[0]; - - expect(migratedElement.stickerId).toBe("icons:mdi:home"); - expect("iconName" in migratedElement).toBe(false); - expect("color" in migratedElement).toBe(false); - }); - - test("keeps provider-prefixed stickerId values unchanged", () => { - const projectWithStickerId = { - ...v3Project, - version: 4, - scenes: [ - { - ...v3Project.scenes[0], - tracks: [ - { - id: "track-sticker", - type: "sticker", - name: "Sticker Track", - hidden: false, - elements: [ - { - id: "sticker-1", - type: "sticker", - name: "Flag", - stickerId: "flags:AD", - duration: 5, - startTime: 0, - trimStart: 0, - trimEnd: 0, - transform: { - scale: 1, - position: { x: 0, y: 0 }, - rotate: 0, - }, - opacity: 1, - }, - ], - }, - ], - }, - ], - }; - - const result = transformProjectV4ToV5({ project: projectWithStickerId }); - const migratedScene = ( - result.project.scenes as Array<Record<string, unknown>> - )[0]; - const migratedTrack = ( - migratedScene.tracks as Array<Record<string, unknown>> - )[0]; - const migratedElement = ( - migratedTrack.elements as Array<Record<string, unknown>> - )[0]; - - expect(migratedElement.stickerId).toBe("flags:AD"); - }); - - test("skips projects that are already v5", () => { - const result = transformProjectV4ToV5({ - project: { ...v3Project, version: 5 }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("already v5"); - }); - - test("skips projects with no id", () => { - const result = transformProjectV4ToV5({ - project: { - version: 4, - scenes: [], - }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("no project id"); - }); -}); +import { describe, expect, test } from "bun:test";
+import { transformProjectV4ToV5 } from "../transformers/v4-to-v5";
+import { v3Project } from "./fixtures";
+
+describe("V4 to V5 Migration", () => {
+ test("migrates sticker iconName to stickerId and removes legacy color", () => {
+ const projectWithLegacySticker = {
+ ...v3Project,
+ version: 4,
+ scenes: [
+ {
+ ...v3Project.scenes[0],
+ tracks: [
+ {
+ id: "track-sticker",
+ type: "sticker",
+ name: "Sticker Track",
+ hidden: false,
+ elements: [
+ {
+ id: "sticker-1",
+ type: "sticker",
+ name: "Home",
+ iconName: "mdi:home",
+ color: "#ff0000",
+ duration: 5,
+ startTime: 0,
+ trimStart: 0,
+ trimEnd: 0,
+ transform: {
+ scale: 1,
+ position: { x: 0, y: 0 },
+ rotate: 0,
+ },
+ opacity: 1,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ };
+
+ const result = transformProjectV4ToV5({
+ project: projectWithLegacySticker,
+ });
+
+ expect(result.skipped).toBe(false);
+ expect(result.project.version).toBe(5);
+
+ const migratedScene = (
+ result.project.scenes as Array<Record<string, unknown>>
+ )[0];
+ const migratedTrack = (
+ migratedScene.tracks as Array<Record<string, unknown>>
+ )[0];
+ const migratedElement = (
+ migratedTrack.elements as Array<Record<string, unknown>>
+ )[0];
+
+ expect(migratedElement.stickerId).toBe("icons:mdi:home");
+ expect("iconName" in migratedElement).toBe(false);
+ expect("color" in migratedElement).toBe(false);
+ });
+
+ test("keeps provider-prefixed stickerId values unchanged", () => {
+ const projectWithStickerId = {
+ ...v3Project,
+ version: 4,
+ scenes: [
+ {
+ ...v3Project.scenes[0],
+ tracks: [
+ {
+ id: "track-sticker",
+ type: "sticker",
+ name: "Sticker Track",
+ hidden: false,
+ elements: [
+ {
+ id: "sticker-1",
+ type: "sticker",
+ name: "Flag",
+ stickerId: "flags:AD",
+ duration: 5,
+ startTime: 0,
+ trimStart: 0,
+ trimEnd: 0,
+ transform: {
+ scale: 1,
+ position: { x: 0, y: 0 },
+ rotate: 0,
+ },
+ opacity: 1,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ };
+
+ const result = transformProjectV4ToV5({ project: projectWithStickerId });
+ const migratedScene = (
+ result.project.scenes as Array<Record<string, unknown>>
+ )[0];
+ const migratedTrack = (
+ migratedScene.tracks as Array<Record<string, unknown>>
+ )[0];
+ const migratedElement = (
+ migratedTrack.elements as Array<Record<string, unknown>>
+ )[0];
+
+ expect(migratedElement.stickerId).toBe("flags:AD");
+ });
+
+ test("skips projects that are already v5", () => {
+ const result = transformProjectV4ToV5({
+ project: { ...v3Project, version: 5 },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("already v5");
+ });
+
+ test("skips projects with no id", () => {
+ const result = transformProjectV4ToV5({
+ project: {
+ version: 4,
+ scenes: [],
+ },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("no project id");
+ });
+});
diff --git a/apps/web/src/services/storage/migrations/__tests__/v5-to-v6.test.ts b/apps/web/src/services/storage/migrations/__tests__/v5-to-v6.test.ts index 6bbd5634..66e87713 100644 --- a/apps/web/src/services/storage/migrations/__tests__/v5-to-v6.test.ts +++ b/apps/web/src/services/storage/migrations/__tests__/v5-to-v6.test.ts @@ -1,92 +1,92 @@ -import { describe, expect, test } from "bun:test"; -import { transformProjectV5ToV6 } from "../transformers/v5-to-v6"; -import { v5Project } from "./fixtures"; - -describe("V5 to V6 Migration", () => { - test("converts number bookmarks to Bookmark objects", async () => { - const result = transformProjectV5ToV6({ - project: v5Project as Parameters< - typeof transformProjectV5ToV6 - >[0]["project"], - }); - - expect(result.skipped).toBe(false); - expect(result.project.version).toBe(6); - - const mainScene = ( - result.project.scenes as Array<{ bookmarks: unknown[] }> - )[0]; - expect(mainScene.bookmarks).toEqual([ - { time: 2.0 }, - { time: 5.5 }, - { time: 12.0 }, - ]); - - const introScene = ( - result.project.scenes as Array<{ bookmarks: unknown[] }> - )[1]; - expect(introScene.bookmarks).toEqual([]); - }); - - test("skips projects that are already v6", () => { - const result = transformProjectV5ToV6({ - project: { - ...v5Project, - version: 6, - scenes: [ - { - ...(v5Project as { scenes: unknown[] }).scenes[0], - bookmarks: [{ time: 2 }, { time: 5 }], - }, - ], - } as Parameters<typeof transformProjectV5ToV6>[0]["project"], - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("already v6"); - }); - - test("skips projects with no id", () => { - const result = transformProjectV5ToV6({ - project: { - version: 5, - scenes: [], - } as Parameters<typeof transformProjectV5ToV6>[0]["project"], - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("no project id"); - }); - - test("preserves existing Bookmark objects with note, color, duration", () => { - const projectWithRichBookmarks = { - ...v5Project, - version: 5, - scenes: [ - { - ...(v5Project as { scenes: Array<Record<string, unknown>> }) - .scenes[0], - bookmarks: [ - { time: 1, note: "Intro", color: "#ef4444" }, - { time: 5.5, duration: 2 }, - ], - }, - ], - }; - - const result = transformProjectV5ToV6({ - project: projectWithRichBookmarks as Parameters< - typeof transformProjectV5ToV6 - >[0]["project"], - }); - - expect(result.skipped).toBe(false); - const mainScene = ( - result.project.scenes as Array<{ bookmarks: unknown[] }> - )[0]; - expect(mainScene.bookmarks).toEqual([ - { time: 1, note: "Intro", color: "#ef4444" }, - { time: 5.5, duration: 2 }, - ]); - }); -}); +import { describe, expect, test } from "bun:test";
+import { transformProjectV5ToV6 } from "../transformers/v5-to-v6";
+import { v5Project } from "./fixtures";
+
+describe("V5 to V6 Migration", () => {
+ test("converts number bookmarks to Bookmark objects", async () => {
+ const result = transformProjectV5ToV6({
+ project: v5Project as Parameters<
+ typeof transformProjectV5ToV6
+ >[0]["project"],
+ });
+
+ expect(result.skipped).toBe(false);
+ expect(result.project.version).toBe(6);
+
+ const mainScene = (
+ result.project.scenes as Array<{ bookmarks: unknown[] }>
+ )[0];
+ expect(mainScene.bookmarks).toEqual([
+ { time: 2.0 },
+ { time: 5.5 },
+ { time: 12.0 },
+ ]);
+
+ const introScene = (
+ result.project.scenes as Array<{ bookmarks: unknown[] }>
+ )[1];
+ expect(introScene.bookmarks).toEqual([]);
+ });
+
+ test("skips projects that are already v6", () => {
+ const result = transformProjectV5ToV6({
+ project: {
+ ...v5Project,
+ version: 6,
+ scenes: [
+ {
+ ...(v5Project as { scenes: unknown[] }).scenes[0],
+ bookmarks: [{ time: 2 }, { time: 5 }],
+ },
+ ],
+ } as Parameters<typeof transformProjectV5ToV6>[0]["project"],
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("already v6");
+ });
+
+ test("skips projects with no id", () => {
+ const result = transformProjectV5ToV6({
+ project: {
+ version: 5,
+ scenes: [],
+ } as Parameters<typeof transformProjectV5ToV6>[0]["project"],
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("no project id");
+ });
+
+ test("preserves existing Bookmark objects with note, color, duration", () => {
+ const projectWithRichBookmarks = {
+ ...v5Project,
+ version: 5,
+ scenes: [
+ {
+ ...(v5Project as { scenes: Array<Record<string, unknown>> })
+ .scenes[0],
+ bookmarks: [
+ { time: 1, note: "Intro", color: "#ef4444" },
+ { time: 5.5, duration: 2 },
+ ],
+ },
+ ],
+ };
+
+ const result = transformProjectV5ToV6({
+ project: projectWithRichBookmarks as Parameters<
+ typeof transformProjectV5ToV6
+ >[0]["project"],
+ });
+
+ expect(result.skipped).toBe(false);
+ const mainScene = (
+ result.project.scenes as Array<{ bookmarks: unknown[] }>
+ )[0];
+ expect(mainScene.bookmarks).toEqual([
+ { time: 1, note: "Intro", color: "#ef4444" },
+ { time: 5.5, duration: 2 },
+ ]);
+ });
+});
diff --git a/apps/web/src/services/storage/migrations/__tests__/v8-to-v9.test.ts b/apps/web/src/services/storage/migrations/__tests__/v8-to-v9.test.ts index 51e91f78..aa79a6ea 100644 --- a/apps/web/src/services/storage/migrations/__tests__/v8-to-v9.test.ts +++ b/apps/web/src/services/storage/migrations/__tests__/v8-to-v9.test.ts @@ -1,175 +1,175 @@ -import { describe, expect, test } from "bun:test"; -import { transformProjectV8ToV9 } from "../transformers/v8-to-v9"; - -const v8ProjectWithText = { - id: "project-v8-text", - version: 8, - metadata: { - id: "project-v8-text", - name: "V8 Project with Text", - createdAt: "2024-01-01T00:00:00.000Z", - updatedAt: "2024-01-01T00:00:00.000Z", - }, - settings: { - fps: 30, - canvasSize: { width: 1920, height: 1080 }, - background: { type: "color", color: "#000000" }, - }, - currentSceneId: "scene-main", - scenes: [ - { - id: "scene-main", - name: "Main scene", - isMain: true, - tracks: [ - { - id: "track-text", - type: "text", - name: "Text Track", - hidden: false, - elements: [ - { - id: "el-1", - type: "text", - content: "With color", - startTime: 0, - duration: 5, - background: { - color: "#ff0000", - cornerRadius: 0, - paddingX: 8, - paddingY: 4, - }, - }, - { - id: "el-2", - type: "text", - content: "Transparent", - startTime: 5, - duration: 5, - background: { - color: "transparent", - paddingX: 30, - paddingY: 42, - }, - }, - ], - }, - ], - bookmarks: [], - createdAt: "2024-01-01T00:00:00.000Z", - updatedAt: "2024-01-01T00:00:00.000Z", - }, - ], -} as Parameters<typeof transformProjectV8ToV9>[0]["project"]; - -describe("V8 to V9 Migration", () => { - test("adds background.enabled from color (transparent => false, otherwise true)", () => { - const result = transformProjectV8ToV9({ project: v8ProjectWithText }); - - expect(result.skipped).toBe(false); - expect(result.project.version).toBe(9); - - const track = ( - result.project.scenes as Array<{ tracks: Array<{ elements: unknown[] }> }> - )[0].tracks[0]; - const elements = track.elements as Array<{ background: { enabled: boolean; color: string } }>; - - expect(elements[0].background.enabled).toBe(true); - expect(elements[0].background.color).toBe("#ff0000"); - - expect(elements[1].background.enabled).toBe(false); - expect(elements[1].background.color).toBe("transparent"); - }); - - test("preserves existing background.enabled if already present", () => { - const projectWithEnabled = { - ...v8ProjectWithText, - scenes: [ - { - ...(v8ProjectWithText.scenes as Record<string, unknown>[])[0], - tracks: [ - { - id: "track-text", - type: "text", - name: "Text Track", - hidden: false, - elements: [ - { - id: "el-1", - type: "text", - content: "Already has enabled", - startTime: 0, - duration: 5, - background: { - enabled: false, - color: "#00ff00", - }, - }, - ], - }, - ], - }, - ], - } as Parameters<typeof transformProjectV8ToV9>[0]["project"]; - - const result = transformProjectV8ToV9({ project: projectWithEnabled }); - - expect(result.skipped).toBe(false); - const elements = ( - result.project.scenes as Array<{ tracks: Array<{ elements: unknown[] }> }> - )[0].tracks[0].elements as Array<{ background: { enabled: boolean } }>; - expect(elements[0].background.enabled).toBe(false); - }); - - test("skips non-text elements and tracks", () => { - const projectWithVideoOnly = { - ...v8ProjectWithText, - scenes: [ - { - id: "scene-main", - name: "Main scene", - isMain: true, - tracks: [ - { - id: "track-video", - type: "video", - name: "Video Track", - isMain: true, - elements: [], - }, - ], - bookmarks: [], - createdAt: "2024-01-01T00:00:00.000Z", - updatedAt: "2024-01-01T00:00:00.000Z", - }, - ], - } as Parameters<typeof transformProjectV8ToV9>[0]["project"]; - - const result = transformProjectV8ToV9({ project: projectWithVideoOnly }); - - expect(result.skipped).toBe(false); - expect(result.project.version).toBe(9); - }); - - test("skips projects that are already v9", () => { - const result = transformProjectV8ToV9({ - project: { ...v8ProjectWithText, version: 9 }, - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("already v9"); - }); - - test("skips projects with no id", () => { - const result = transformProjectV8ToV9({ - project: { - version: 8, - scenes: [], - } as Parameters<typeof transformProjectV8ToV9>[0]["project"], - }); - - expect(result.skipped).toBe(true); - expect(result.reason).toBe("no project id"); - }); -}); +import { describe, expect, test } from "bun:test";
+import { transformProjectV8ToV9 } from "../transformers/v8-to-v9";
+
+const v8ProjectWithText = {
+ id: "project-v8-text",
+ version: 8,
+ metadata: {
+ id: "project-v8-text",
+ name: "V8 Project with Text",
+ createdAt: "2024-01-01T00:00:00.000Z",
+ updatedAt: "2024-01-01T00:00:00.000Z",
+ },
+ settings: {
+ fps: 30,
+ canvasSize: { width: 1920, height: 1080 },
+ background: { type: "color", color: "#000000" },
+ },
+ currentSceneId: "scene-main",
+ scenes: [
+ {
+ id: "scene-main",
+ name: "Main scene",
+ isMain: true,
+ tracks: [
+ {
+ id: "track-text",
+ type: "text",
+ name: "Text Track",
+ hidden: false,
+ elements: [
+ {
+ id: "el-1",
+ type: "text",
+ content: "With color",
+ startTime: 0,
+ duration: 5,
+ background: {
+ color: "#ff0000",
+ cornerRadius: 0,
+ paddingX: 8,
+ paddingY: 4,
+ },
+ },
+ {
+ id: "el-2",
+ type: "text",
+ content: "Transparent",
+ startTime: 5,
+ duration: 5,
+ background: {
+ color: "transparent",
+ paddingX: 30,
+ paddingY: 42,
+ },
+ },
+ ],
+ },
+ ],
+ bookmarks: [],
+ createdAt: "2024-01-01T00:00:00.000Z",
+ updatedAt: "2024-01-01T00:00:00.000Z",
+ },
+ ],
+} as Parameters<typeof transformProjectV8ToV9>[0]["project"];
+
+describe("V8 to V9 Migration", () => {
+ test("adds background.enabled from color (transparent => false, otherwise true)", () => {
+ const result = transformProjectV8ToV9({ project: v8ProjectWithText });
+
+ expect(result.skipped).toBe(false);
+ expect(result.project.version).toBe(9);
+
+ const track = (
+ result.project.scenes as Array<{ tracks: Array<{ elements: unknown[] }> }>
+ )[0].tracks[0];
+ const elements = track.elements as Array<{ background: { enabled: boolean; color: string } }>;
+
+ expect(elements[0].background.enabled).toBe(true);
+ expect(elements[0].background.color).toBe("#ff0000");
+
+ expect(elements[1].background.enabled).toBe(false);
+ expect(elements[1].background.color).toBe("transparent");
+ });
+
+ test("preserves existing background.enabled if already present", () => {
+ const projectWithEnabled = {
+ ...v8ProjectWithText,
+ scenes: [
+ {
+ ...(v8ProjectWithText.scenes as Record<string, unknown>[])[0],
+ tracks: [
+ {
+ id: "track-text",
+ type: "text",
+ name: "Text Track",
+ hidden: false,
+ elements: [
+ {
+ id: "el-1",
+ type: "text",
+ content: "Already has enabled",
+ startTime: 0,
+ duration: 5,
+ background: {
+ enabled: false,
+ color: "#00ff00",
+ },
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ } as Parameters<typeof transformProjectV8ToV9>[0]["project"];
+
+ const result = transformProjectV8ToV9({ project: projectWithEnabled });
+
+ expect(result.skipped).toBe(false);
+ const elements = (
+ result.project.scenes as Array<{ tracks: Array<{ elements: unknown[] }> }>
+ )[0].tracks[0].elements as Array<{ background: { enabled: boolean } }>;
+ expect(elements[0].background.enabled).toBe(false);
+ });
+
+ test("skips non-text elements and tracks", () => {
+ const projectWithVideoOnly = {
+ ...v8ProjectWithText,
+ scenes: [
+ {
+ id: "scene-main",
+ name: "Main scene",
+ isMain: true,
+ tracks: [
+ {
+ id: "track-video",
+ type: "video",
+ name: "Video Track",
+ isMain: true,
+ elements: [],
+ },
+ ],
+ bookmarks: [],
+ createdAt: "2024-01-01T00:00:00.000Z",
+ updatedAt: "2024-01-01T00:00:00.000Z",
+ },
+ ],
+ } as Parameters<typeof transformProjectV8ToV9>[0]["project"];
+
+ const result = transformProjectV8ToV9({ project: projectWithVideoOnly });
+
+ expect(result.skipped).toBe(false);
+ expect(result.project.version).toBe(9);
+ });
+
+ test("skips projects that are already v9", () => {
+ const result = transformProjectV8ToV9({
+ project: { ...v8ProjectWithText, version: 9 },
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("already v9");
+ });
+
+ test("skips projects with no id", () => {
+ const result = transformProjectV8ToV9({
+ project: {
+ version: 8,
+ scenes: [],
+ } as Parameters<typeof transformProjectV8ToV9>[0]["project"],
+ });
+
+ expect(result.skipped).toBe(true);
+ expect(result.reason).toBe("no project id");
+ });
+});
|
