import { describe, expect, it } from "vitest"; import { normalizeControlsPanelLayout } from "./controls-panel-normalization"; import { materializeControlTestDefinition } from "./define-toolcraft.control-sections.test-support"; import { defineToolcraft } from "./define-toolcraft"; import type { ToolcraftControlSectionSchema } from "./types"; const opacityControl = { applicability: { mode: "always" as const }, defaultValue: 75, max: 100, min: 0, target: "appearance.opacity", type: "slider", } as const; function cloneSectionWithoutInternalMarker( section: ToolcraftControlSectionSchema | undefined, ): ToolcraftControlSectionSchema { const clone = JSON.parse( JSON.stringify(section), ) as ToolcraftControlSectionSchema; for (const control of Object.values(clone.controls)) { if (control.applicability && "origin" in control.applicability) { delete (control.applicability as { origin?: unknown }).origin; } } return clone; } function createSchemaWithGeneratedExport() { return defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [ { id: "test-section-1", controls: { export: { applicability: { mode: "always" as const }, actions: [{ label: "Export PNG", value: "export" }], target: "output.export", type: "panelActions", }, }, title: "Export", }, ], title: "Controls", }, }, }, modules: [], }); } describe("Toolcraft control section identity", () => { it.each(["appearance", "product.section", "product-section_2"])( "preserves a valid explicit stable section id %j byte-for-byte", (id) => { const panel = normalizeControlsPanelLayout({ sections: [ { controls: { opacity: opacityControl }, id, title: "Appearance", }, ], title: "Controls", }); expect(panel.sections[0]?.id).toBe(id); }, ); it.each([ "", " appearance ", "Appearance", "appearance controls", "appearance!", ".appearance", "appearance..controls", ])("rejects an invalid explicit id %j", (id) => { expect(() => normalizeControlsPanelLayout({ sections: [{ controls: { opacity: opacityControl }, id }], title: "Controls", }), ).toThrow(/lowercase ASCII segments/iu); }); it("rejects an authored section without an explicit id", () => { expect(() => normalizeControlsPanelLayout({ sections: [ { controls: { opacity: opacityControl }, title: "Missing id", } as never, ], title: "Controls", }), ).toThrow(/require an explicit stable id/iu); }); it("rejects duplicate resolved section ids", () => { expect(() => normalizeControlsPanelLayout({ sections: [ { controls: { opacity: opacityControl }, id: "appearance", }, { controls: { strength: { ...opacityControl, target: "appearance.strength", }, }, id: "appearance", }, ], title: "Controls", }), ).toThrow(/duplicate control section id "appearance"/iu); }); it.each([ "runtime.setup", "runtime.export", "legacy.appearance.deadbeef", "appearance.part-appearance.opacity-deadbeef", ])("rejects a public authored reserved id %j", (id) => { expect(() => normalizeControlsPanelLayout({ sections: [ { controls: { opacity: opacityControl }, id, title: "Appearance", }, ], title: "Controls", }), ).toThrow(/reserved .* namespace/iu); }); it.each(["runtime.setup", "runtime.defaults", "runtime.export"])( "rejects an exact unmarked public lookalike for generated section %j", (reservedId) => { const generated = createSchemaWithGeneratedExport(); const generatedSection = generated.panels.controls?.sections.find( (section) => section.id === reservedId, ); const forgedSection = cloneSectionWithoutInternalMarker(generatedSection); expect(() => defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [forgedSection], title: "Controls", }, }, }, modules: [], }), ).toThrow( /reserved runtime namespace|reserved standard artifact ownership/iu, ); }, ); it("does not expose internal provenance as own section symbols", () => { const generated = createSchemaWithGeneratedExport(); const reservedSections = generated.panels.controls?.sections.filter( (section) => section.id.startsWith("runtime."), ); expect(reservedSections).toHaveLength(3); expect( reservedSections?.every( (section) => Object.getOwnPropertySymbols(section).length === 0, ), ).toBe(true); }); it("rejects provenance forged from every discoverable setup descriptor", () => { const generated = createSchemaWithGeneratedExport(); const setupSection = generated.panels.controls?.sections.find( (section) => section.id === "runtime.setup", ); const exportSection = generated.panels.controls?.sections.find( (section) => section.id === "runtime.export", ); const forgedDescriptors = Object.fromEntries( Object.entries(Object.getOwnPropertyDescriptors(setupSection)).map( ([key, descriptor]) => [ key, "value" in descriptor ? { ...descriptor, configurable: true, writable: true } : { ...descriptor, configurable: true }, ], ), ); const forgedSection = Object.create( Object.getPrototypeOf(setupSection), forgedDescriptors, ) as ToolcraftControlSectionSchema; Object.assign( forgedSection, cloneSectionWithoutInternalMarker(exportSection), ); for (const symbol of Object.getOwnPropertySymbols(setupSection ?? {})) { const descriptor = Object.getOwnPropertyDescriptor( setupSection ?? {}, symbol, ); Object.defineProperty(forgedSection, symbol, { ...descriptor, value: "runtime.export", }); } expect(() => materializeControlTestDefinition({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [forgedSection], title: "Controls", }, }, }, modules: [], }), ).toThrow( /reserved runtime namespace|reserved standard artifact ownership/iu, ); }); it.each(["spread", "structuredClone"] as const)( "rejects a %s copy of a reserved internal section", (cloneKind) => { const generated = createSchemaWithGeneratedExport(); const exportSection = generated.panels.controls?.sections.find( (section) => section.id === "runtime.export", ); const clonedSection = cloneKind === "spread" ? { ...exportSection } : structuredClone(exportSection); expect(() => defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [clonedSection as ToolcraftControlSectionSchema], title: "Controls", }, }, }, modules: [], }), ).toThrow( /reserved runtime namespace|reserved standard artifact ownership/iu, ); }, ); it("rejects an exact unmarked public lookalike for a mixed-layout child", () => { const generated = defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [ { controls: { opacity: opacityControl, palette: { applicability: { mode: "always" as const }, target: "appearance.palette", type: "palette", }, }, id: "appearance", title: "Appearance", }, ], title: "Controls", }, }, }, modules: [], }); const generatedSection = generated.panels.controls?.sections.find( (section) => section.id.startsWith("appearance.part-"), ); expect(() => defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [cloneSectionWithoutInternalMarker(generatedSection)], title: "Controls", }, }, }, modules: [], }), ).toThrow(/reserved internally derived namespace/iu); }); it("uses reserved stable ids for runtime setup and export", () => { const schema = defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true }, panels: { controls: { sections: [ { controls: { export: { applicability: { mode: "always" as const }, actions: [{ label: "Export PNG", value: "export" }], target: "output.export", type: "panelActions", }, }, id: "output-actions", }, ], title: "Controls", }, }, }, modules: [], }); expect(schema.panels.controls?.sections[1]?.id).toBe("runtime.setup"); expect(schema.panels.controls?.sections.at(-1)?.id).toBe("runtime.export"); }); });