Expand tests for local draft storage and project scenes

This commit is contained in:
2026-04-11 03:50:56 +02:00
parent fe1d81b3a4
commit e80b75e7e0

View File

@@ -1,7 +1,13 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { createBoxBrush } from "../../src/document/brushes"; import { createBoxBrush } from "../../src/document/brushes";
import { SCENE_DOCUMENT_VERSION, createEmptySceneDocument } from "../../src/document/scene-document"; import {
SCENE_DOCUMENT_VERSION,
createEmptyProjectDocument,
createEmptyProjectScene,
createEmptySceneDocument,
createProjectDocumentFromSceneDocument
} from "../../src/document/scene-document";
import { serializeSceneDocument } from "../../src/serialization/scene-document-json"; import { serializeSceneDocument } from "../../src/serialization/scene-document-json";
import { import {
DEFAULT_SCENE_DRAFT_STORAGE_KEY, DEFAULT_SCENE_DRAFT_STORAGE_KEY,
@@ -67,7 +73,7 @@ describe("local draft storage", () => {
const result = loadOrCreateSceneDocument(storage); const result = loadOrCreateSceneDocument(storage);
expect(result.document.version).toBe(SCENE_DOCUMENT_VERSION); expect(result.document.version).toBe(SCENE_DOCUMENT_VERSION);
expect(result.document).toEqual(createEmptySceneDocument()); expect(result.document).toEqual(createEmptyProjectDocument());
expect(result.diagnostic).toContain("Stored autosave could not be loaded."); expect(result.diagnostic).toContain("Stored autosave could not be loaded.");
expect(result.diagnostic).toContain("Starting with a fresh empty document."); expect(result.diagnostic).toContain("Starting with a fresh empty document.");
}); });
@@ -113,7 +119,7 @@ describe("local draft storage", () => {
new ThrowingStorage({ new ThrowingStorage({
onSetItem: new Error("quota exceeded") onSetItem: new Error("quota exceeded")
}), }),
createEmptySceneDocument() createEmptyProjectDocument()
); );
expect(result.status).toBe("error"); expect(result.status).toBe("error");
@@ -139,60 +145,109 @@ describe("local draft storage", () => {
status: "saved", status: "saved",
message: "Autosave updated." message: "Autosave updated."
}); });
const result = loadSceneDocumentDraft(storage); const result = loadSceneDocumentDraft(storage);
expect(result).toMatchObject({ expect(result.status).toBe("loaded");
status: "loaded",
document: { if (result.status !== "loaded") {
name: "Viewport Draft" return;
}, }
viewportLayoutState: {
layoutMode: "quad", expect(
activePanelId: "bottomRight", result.document.scenes[result.document.activeSceneId]?.name
panels: { ).toBe("Viewport Draft");
topLeft: { expect(result.viewportLayoutState).toMatchObject({
displayMode: "wireframe", layoutMode: "quad",
cameraState: { activePanelId: "bottomRight",
target: { panels: {
x: 8, topLeft: {
y: 3, displayMode: "wireframe",
z: -5 cameraState: {
}, target: {
perspectiveOrbit: { x: 8,
theta: 1.25 y: 3,
}, z: -5
orthographicZoom: 2.5 },
} perspectiveOrbit: {
theta: 1.25
},
orthographicZoom: 2.5
} }
} }
} }
}); });
}); });
it("stores and restores all project scenes in autosave drafts", () => {
const storage = new MemoryStorage();
const document = {
...createEmptyProjectDocument({ sceneName: "Entry" }),
activeSceneId: "scene-hall",
scenes: {
scene-main: createEmptyProjectScene({
id: "scene-main",
name: "Entry"
}),
scene-hall: createEmptyProjectScene({
id: "scene-hall",
name: "Hallway"
})
}
};
expect(saveSceneDocumentDraft(storage, document)).toEqual({
status: "saved",
message: "Autosave updated."
});
const result = loadSceneDocumentDraft(storage);
expect(result.status).toBe("loaded");
if (result.status !== "loaded") {
return;
}
expect(result.document.activeSceneId).toBe("scene-hall");
expect(Object.keys(result.document.scenes)).toEqual([
"scene-main",
"scene-hall"
]);
});
it("loads older raw scene-document drafts without requiring viewport layout state", () => { it("loads older raw scene-document drafts without requiring viewport layout state", () => {
const storage = new MemoryStorage(); const storage = new MemoryStorage();
storage.setItem(DEFAULT_SCENE_DRAFT_STORAGE_KEY, serializeSceneDocument(createEmptySceneDocument({ name: "Legacy Draft" }))); storage.setItem(DEFAULT_SCENE_DRAFT_STORAGE_KEY, serializeSceneDocument(createEmptySceneDocument({ name: "Legacy Draft" })));
const result = loadSceneDocumentDraft(storage); const result = loadSceneDocumentDraft(storage);
expect(result).toMatchObject({ expect(result.status).toBe("loaded");
status: "loaded",
document: { if (result.status !== "loaded") {
name: "Legacy Draft" return;
}, }
viewportLayoutState: null,
message: "Recovered latest autosave." expect(
}); result.document.scenes[result.document.activeSceneId]?.name
).toBe("Legacy Draft");
expect(result.viewportLayoutState).toBeNull();
expect(result.message).toBe("Recovered latest autosave.");
}); });
it("reports recovered autosaves through bootstrap diagnostics", () => { it("reports recovered autosaves through bootstrap diagnostics", () => {
const storage = new MemoryStorage(); const storage = new MemoryStorage();
saveSceneDocumentDraft(storage, createEmptySceneDocument({ name: "Recovered Scene" })); saveSceneDocumentDraft(
storage,
createProjectDocumentFromSceneDocument(
createEmptySceneDocument({ name: "Recovered Scene" })
)
);
const result = loadOrCreateSceneDocument(storage); const result = loadOrCreateSceneDocument(storage);
expect(result.document.name).toBe("Recovered Scene"); expect(
result.document.scenes[result.document.activeSceneId]?.name
).toBe("Recovered Scene");
expect(result.diagnostic).toBe("Recovered latest autosave."); expect(result.diagnostic).toBe("Recovered latest autosave.");
}); });
@@ -203,9 +258,19 @@ describe("local draft storage", () => {
invalidBrush.faces.posX.materialId = "missing-material"; invalidBrush.faces.posX.materialId = "missing-material";
const result = saveSceneDocumentDraft(new MemoryStorage(), { const result = saveSceneDocumentDraft(new MemoryStorage(), {
...createEmptySceneDocument(), ...createProjectDocumentFromSceneDocument(createEmptySceneDocument()),
brushes: { scenes: {
[invalidBrush.id]: invalidBrush scene-main: {
id: "scene-main",
name: "Untitled Scene",
world: createEmptySceneDocument().world,
brushes: {
[invalidBrush.id]: invalidBrush
},
modelInstances: {},
entities: {},
interactionLinks: {}
}
} }
}); });