Update tests for project document serialization and add project name handling
This commit is contained in:
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
import { createBoxBrush } from "../../src/document/brushes";
|
||||
import {
|
||||
DEFAULT_PROJECT_NAME,
|
||||
SCENE_DOCUMENT_VERSION,
|
||||
createEmptyProjectDocument,
|
||||
createEmptyProjectScene,
|
||||
@@ -196,7 +197,10 @@ describe("local draft storage", () => {
|
||||
it("stores and restores all project scenes in autosave drafts", () => {
|
||||
const storage = new MemoryStorage();
|
||||
const document = {
|
||||
...createEmptyProjectDocument({ sceneName: "Entry" }),
|
||||
...createEmptyProjectDocument({
|
||||
name: "Castle Campaign",
|
||||
sceneName: "Entry"
|
||||
}),
|
||||
activeSceneId: "scene-hall",
|
||||
scenes: {
|
||||
"scene-main": createEmptyProjectScene({
|
||||
@@ -228,6 +232,7 @@ describe("local draft storage", () => {
|
||||
return;
|
||||
}
|
||||
|
||||
expect(result.document.name).toBe("Castle Campaign");
|
||||
expect(result.document.activeSceneId).toBe("scene-hall");
|
||||
expect(Object.keys(result.document.scenes)).toEqual([
|
||||
"scene-main",
|
||||
@@ -255,6 +260,7 @@ describe("local draft storage", () => {
|
||||
return;
|
||||
}
|
||||
|
||||
expect(result.document.name).toBe(DEFAULT_PROJECT_NAME);
|
||||
expect(result.document.scenes[result.document.activeSceneId]?.name).toBe(
|
||||
"Legacy Draft"
|
||||
);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
DEFAULT_PROJECT_NAME,
|
||||
PLAYER_START_GAMEPAD_CAMERA_LOOK_SCENE_DOCUMENT_VERSION,
|
||||
RUNNER_LOADING_SCREEN_SCENE_DOCUMENT_VERSION,
|
||||
SCENE_DOCUMENT_VERSION,
|
||||
createEmptyProjectDocument,
|
||||
@@ -16,7 +18,7 @@ import {
|
||||
} from "../../src/serialization/scene-document-json";
|
||||
|
||||
describe("project document JSON", () => {
|
||||
it("round-trips authored scene loading overlay settings", () => {
|
||||
it("round-trips the project name and authored scene loading overlay settings", () => {
|
||||
const cellarEntry = createSceneEntryEntity({
|
||||
id: "entity-scene-entry-cellar-stairs",
|
||||
position: {
|
||||
@@ -37,7 +39,10 @@ describe("project document JSON", () => {
|
||||
targetEntryEntityId: cellarEntry.id
|
||||
});
|
||||
const document = {
|
||||
...createEmptyProjectDocument({ sceneName: "Entry" }),
|
||||
...createEmptyProjectDocument({
|
||||
name: "Castle Project",
|
||||
sceneName: "Entry"
|
||||
}),
|
||||
activeSceneId: "scene-cellar",
|
||||
scenes: {
|
||||
"scene-main": createEmptyProjectScene({
|
||||
@@ -63,6 +68,28 @@ describe("project document JSON", () => {
|
||||
expect(parseProjectDocumentJson(serializedDocument)).toEqual(document);
|
||||
});
|
||||
|
||||
it("migrates pre-project-name multi-scene documents to Untitled Project", () => {
|
||||
const migratedDocument = parseProjectDocumentJson(
|
||||
JSON.stringify({
|
||||
version: PLAYER_START_GAMEPAD_CAMERA_LOOK_SCENE_DOCUMENT_VERSION,
|
||||
activeSceneId: "scene-main",
|
||||
scenes: {
|
||||
"scene-main": createEmptyProjectScene({
|
||||
id: "scene-main",
|
||||
name: "Legacy Entry"
|
||||
})
|
||||
},
|
||||
materials: createEmptyProjectDocument().materials,
|
||||
textures: {},
|
||||
assets: {}
|
||||
})
|
||||
);
|
||||
|
||||
expect(migratedDocument.version).toBe(SCENE_DOCUMENT_VERSION);
|
||||
expect(migratedDocument.name).toBe(DEFAULT_PROJECT_NAME);
|
||||
expect(migratedDocument.scenes["scene-main"]?.name).toBe("Legacy Entry");
|
||||
});
|
||||
|
||||
it("migrates v23 project documents without Scene Entry and Scene Exit entities", () => {
|
||||
const legacyScene = createEmptyProjectScene({
|
||||
id: "scene-main",
|
||||
|
||||
@@ -136,6 +136,7 @@ describe("project package serialization", () => {
|
||||
...createProjectDocument(
|
||||
createEmptySceneDocument({ name: "Portable Entry" })
|
||||
),
|
||||
name: "Portable Campaign",
|
||||
activeSceneId: "scene-dungeon",
|
||||
scenes: {
|
||||
"scene-main": createEmptyProjectScene({
|
||||
|
||||
@@ -94,7 +94,10 @@ import { App } from "../../src/app/App";
|
||||
import { createEditorStore } from "../../src/app/editor-store";
|
||||
|
||||
describe("App project persistence controls", () => {
|
||||
let clickedDownloads: string[];
|
||||
|
||||
beforeEach(() => {
|
||||
clickedDownloads = [];
|
||||
viewportHostInstances.length = 0;
|
||||
saveProjectPackageMock.mockClear();
|
||||
loadProjectPackageMock.mockClear();
|
||||
@@ -103,7 +106,11 @@ describe("App project persistence controls", () => {
|
||||
createObjectURL: vi.fn(() => "blob:project"),
|
||||
revokeObjectURL: vi.fn()
|
||||
});
|
||||
vi.spyOn(HTMLAnchorElement.prototype, "click").mockImplementation(() => undefined);
|
||||
vi.spyOn(HTMLAnchorElement.prototype, "click").mockImplementation(
|
||||
function (this: HTMLAnchorElement) {
|
||||
clickedDownloads.push(this.download);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -147,4 +154,42 @@ describe("App project persistence controls", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("uses the project name rather than the active scene name for saved packages", async () => {
|
||||
const store = createEditorStore();
|
||||
|
||||
render(<App store={store} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(viewportHostInstances.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
fireEvent.change(screen.getByTestId("toolbar-scene-name"), {
|
||||
target: { value: "Dungeon Scene" }
|
||||
});
|
||||
fireEvent.blur(screen.getByTestId("toolbar-scene-name"));
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Save Project" }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(clickedDownloads).toEqual(["untitled-project.we3d"]);
|
||||
});
|
||||
|
||||
fireEvent.change(screen.getByTestId("toolbar-project-name"), {
|
||||
target: { value: "Castle Layout" }
|
||||
});
|
||||
fireEvent.blur(screen.getByTestId("toolbar-project-name"));
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Save Project" }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(clickedDownloads).toEqual([
|
||||
"untitled-project.we3d",
|
||||
"castle-layout.we3d"
|
||||
]);
|
||||
});
|
||||
|
||||
expect(store.getState().document.name).toBe("Dungeon Scene");
|
||||
expect(store.getState().projectDocument.name).toBe("Castle Layout");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user