import { describe, expect, it } from "vitest"; import { defineToolcraft } from "../schema/define-toolcraft"; import { createToolcraftState } from "./create-template-state"; import { getToolcraftPersistedValueTargets } from "./persistence-value-targets"; import { createToolcraftPersistenceSnapshot, parseToolcraftPersistenceSnapshot, } from "../composition/public-persistence"; const layout = { elements: [{ id: "title", width: 320, x: 120, y: 80 }], }; function createSchema() { return defineToolcraft({ base: { canvas: { enabled: true }, identity: { id: "additional-values", title: "Additional Values" }, panels: {}, persistence: { additionalValueTargets: [ " composition.layout ", "composition.layout", "", ], storage: "localStorage", }, }, modules: [], }); } describe("Toolcraft persistence additional value targets", () => { it("uses an ordered exact-identity union of own default keys and additional targets", () => { const defaults = Object.assign(Object.create({ inherited: 1 }), { amount: 50, "composition.layout": null }); expect(getToolcraftPersistedValueTargets(defaults, ["composition.layout", "layers", "layers"])).toEqual([ "amount", "composition.layout", "layers", ]); }); it("normalizes and freezes the explicit target allowlist", () => { const schema = createSchema(); expect(schema.persistence).toMatchObject({ additionalValueTargets: ["composition.layout"], }); expect( schema.persistence.storage === "localStorage" && Object.isFrozen(schema.persistence.additionalValueTargets), ).toBe(true); }); it("round-trips declared non-control values and excludes unknown values", () => { const schema = createSchema(); const state = createToolcraftState(schema, { values: { "composition.layout": layout, "unknown.target": "remove me", }, }); const snapshot = createToolcraftPersistenceSnapshot( state, schema.persistence, ); const restored = parseToolcraftPersistenceSnapshot( schema, JSON.stringify(snapshot), ); expect(snapshot?.state.values).toEqual({ "composition.layout": layout }); expect(restored?.values).toEqual({ "composition.layout": layout }); expect(restored?.values).not.toHaveProperty("unknown.target"); }); });