1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
import { describe, expect, test } from "bun:test";
import { getProjectId, transformProjectV0ToV1 } from "../transformers/v0-to-v1";
import {
projectMalformed,
projectWithNoId,
v0Project,
v0ProjectEmpty,
v0ProjectWithMetadata,
v1Project,
} from "./fixtures";
import { asArray, asRecord, asRecordArray } from "./helpers";
describe("V0 to V1 Migration", () => {
const fixedDate = new Date("2024-06-01T12:00:00.000Z");
describe("transformProjectV0ToV1", () => {
test("adds scenes array to v0 project", () => {
const result = transformProjectV0ToV1({
project: v0Project,
options: { now: fixedDate },
});
expect(result.skipped).toBe(false);
expect(result.project.version).toBe(1);
expect(Array.isArray(result.project.scenes)).toBe(true);
expect(asArray(result.project.scenes).length).toBe(1);
expect(result.project.currentSceneId).toBeDefined();
});
test("creates main scene with correct structure", () => {
const result = transformProjectV0ToV1({
project: v0Project,
options: { now: fixedDate },
});
const scenes = asRecordArray(result.project.scenes);
const mainScene = scenes[0];
expect(mainScene.isMain).toBe(true);
expect(mainScene.name).toBe("Main scene");
expect(typeof mainScene.id).toBe("string");
expect(Array.isArray(mainScene.tracks)).toBe(true);
expect(Array.isArray(mainScene.bookmarks)).toBe(true);
});
test("updates metadata.updatedAt when metadata exists", () => {
const result = transformProjectV0ToV1({
project: v0ProjectWithMetadata,
options: { now: fixedDate },
});
const metadata = asRecord(result.project.metadata);
expect(metadata.updatedAt).toBe(fixedDate.toISOString());
});
test("updates root updatedAt when no metadata", () => {
const result = transformProjectV0ToV1({
project: v0ProjectEmpty,
options: { now: fixedDate },
});
expect(result.project.updatedAt).toBe(fixedDate.toISOString());
});
test("skips project that already has scenes", () => {
const result = transformProjectV0ToV1({
project: v1Project,
options: { now: fixedDate },
});
expect(result.skipped).toBe(true);
expect(result.reason).toBe("already has scenes");
});
test("preserves original project properties", () => {
const result = transformProjectV0ToV1({
project: v0Project,
options: { now: fixedDate },
});
expect(result.project.id).toBe(v0Project.id);
expect(result.project.name).toBe(v0Project.name);
expect(result.project.fps).toBe(v0Project.fps);
expect(result.project.canvasSize).toEqual(v0Project.canvasSize);
});
});
describe("getProjectId", () => {
test("returns id from root level", () => {
const id = getProjectId({ project: v0Project });
expect(id).toBe("project-v0-123");
});
test("returns id from metadata when root id missing", () => {
const project = {
metadata: { id: "from-metadata" },
};
const id = getProjectId({ project });
expect(id).toBe("from-metadata");
});
test("returns null when no id found", () => {
const id = getProjectId({ project: projectWithNoId });
expect(id).toBe(null);
});
test("returns null for malformed project", () => {
const id = getProjectId({ project: projectMalformed });
expect(id).toBe("project-malformed");
});
});
});
|