feat: add project management features including open/save functionality and recovery support
This commit is contained in:
58
operations/project/format.test.ts
Normal file
58
operations/project/format.test.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import type { ImageDocument } from "@core/document";
|
||||
import { CURRENT_PROJECT_VERSION, parseProject, projectFileName, serializeProject } from "./format";
|
||||
|
||||
describe("project format", () => {
|
||||
test("round-trips a versioned project with embedded assets", () => {
|
||||
const document = projectDocument();
|
||||
const result = parseProject(serializeProject(document, "2026-07-10T12:00:00.000Z"));
|
||||
|
||||
expect(result.version).toBe(CURRENT_PROJECT_VERSION);
|
||||
expect(result.savedAt).toBe("2026-07-10T12:00:00.000Z");
|
||||
expect(result.document).toEqual(document);
|
||||
});
|
||||
|
||||
test("migrates a legacy bare document", () => {
|
||||
const result = parseProject(JSON.stringify(projectDocument()));
|
||||
expect(result.version).toBe(1);
|
||||
expect(result.savedAt).toBe("1970-01-01T00:00:00.000Z");
|
||||
});
|
||||
|
||||
test("rejects unknown versions and invalid JSON", () => {
|
||||
expect(() => parseProject("not json")).toThrow("not valid JSON");
|
||||
expect(() => parseProject(JSON.stringify({ format: "image-studio-project", version: 99, savedAt: "now", document: projectDocument() }))).toThrow("Unsupported project version");
|
||||
});
|
||||
|
||||
test("enforces project-owned embedded assets and valid references", () => {
|
||||
const externalAsset = projectDocument();
|
||||
externalAsset.assets[0]!.source = "blob:https://example.test/asset";
|
||||
expect(() => serializeProject(externalAsset)).toThrow("not embedded");
|
||||
|
||||
const missingAsset = projectDocument();
|
||||
missingAsset.assets = [];
|
||||
expect(() => serializeProject(missingAsset)).toThrow("references missing asset");
|
||||
});
|
||||
|
||||
test("creates safe project file names", () => {
|
||||
expect(projectFileName(" Summer / Study ")).toBe("Summer-Study.image-studio.json");
|
||||
expect(projectFileName("***")).toBe("untitled.image-studio.json");
|
||||
});
|
||||
});
|
||||
|
||||
function projectDocument(): ImageDocument {
|
||||
return {
|
||||
id: "document-1",
|
||||
name: "Test Project",
|
||||
version: 1,
|
||||
assets: [{ id: "asset-1", name: "pixels.png", mimeType: "image/png", source: "data:image/png;base64,AA==", intrinsicSize: { w: 10, h: 20 } }],
|
||||
artboards: [{
|
||||
id: "artboard-1",
|
||||
name: "Board",
|
||||
bounds: { x: 0, y: 0, w: 100, h: 100 },
|
||||
backgroundColor: "transparent",
|
||||
visible: true,
|
||||
locked: false,
|
||||
layers: [{ id: "layer-1", type: "image", name: "Pixels", visible: true, locked: false, opacity: 1, assetId: "asset-1", transform: { position: { x: 0, y: 0 }, scale: { x: 1, y: 1 }, rotation: 0 } }],
|
||||
}],
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user