import { describe, expect, it } from "vitest"; import { defineToolcraft, ControlsPanel, ToolcraftRoot, React, render, fireEvent, screen, renderControlsPanelWithSchema, } from "../testing/controls-panel-test-utils"; import { ToolcraftDefaultsAuthoringProvider } from "../../app-shell/toolcraft-defaults-authoring"; import { useToolcraftTheme } from "../../app-shell/theme-runtime"; import { applyToolcraftAppDefaults, createToolcraftAppDefaults } from "../../../schema/app-defaults"; import { createToolcraftState } from "../../../state/create-template-state"; function ThemeProbe() { const theme = useToolcraftTheme(); return ; } describe("ControlsPanel defaults authoring", () => { it("replaces settings file actions with local defaults authoring and keeps the header Reset", () => { const schema = defineToolcraft({ base: { identity: { id: "runtime-test", title: "Toolcraft App" }, canvas: { enabled: true, size: { height: 720, unit: "px", width: 1280 }, }, panels: { controls: { sections: [ { id: "test-section-3", controls: { prompt: { applicability: { mode: "always" as const }, defaultValue: "Initial prompt", label: "Prompt", target: "generation.prompt", type: "text", }, }, title: "Prompt", }, { id: "test-section-4", actionGroup: "secondary", controls: { footer: { applicability: { mode: "always" as const }, actions: [ { label: "Export PNG", value: "export.png", variant: "default", }, ], target: "panel.actions", type: "panelActions", }, }, }, ], title: "Generation Controls", }, }, settingsTransfer: true, }, modules: [], }); const { container } = render( {} }}> , ); expect(screen.queryByRole("button", { name: "Export Settings" })).toBeNull(); expect(screen.queryByRole("button", { name: "Import Settings" })).toBeNull(); expect(screen.getByRole("button", { name: "Save State as Default" })).toBeTruthy(); expect(container.querySelector('[data-toolcraft-theme="light"]')).not.toBeNull(); fireEvent.click(screen.getByRole("button", { name: "Test theme" })); expect(container.querySelector('[data-toolcraft-theme="dark"]')).not.toBeNull(); const prompt = screen.getByDisplayValue("Initial prompt") as HTMLInputElement; fireEvent.change(prompt, { target: { value: "Changed prompt" } }); fireEvent.blur(prompt); expect(prompt.value).toBe("Changed prompt"); fireEvent.click(screen.getByRole("button", { name: "Reset controls" })); expect(screen.getByDisplayValue("Initial prompt")).toBeTruthy(); expect(container.querySelector('[data-toolcraft-theme="light"]')).not.toBeNull(); const scrollContent = container.querySelector( '[data-slot="toolcraft-panel-content"]', ); const stickyFooter = container.querySelector( '[data-slot="toolcraft-panel-sticky-actions"]', ); const firstSection = container.querySelector("section"); const settingsSection = container.querySelectorAll("section")[1]; const firstInlineGroup = settingsSection?.querySelector( '[data-control-layout="inline"][data-control-layout-columns="2"]', ); expect(schema.panels.controls?.sections.slice(0, 2).map(({ id }) => id)).toEqual([ "runtime.defaults", "runtime.setup", ]); expect(firstSection?.querySelector('[data-slot="control-section-header"]')).toBeNull(); expect(firstSection?.getAttribute("data-collapsed")).toBeNull(); expect(firstSection?.querySelector("[data-control-list]")?.className).toContain("py-3"); expect(firstSection?.textContent).toBe("Save State as Default"); expect(settingsSection?.textContent).not.toContain("Save State as Default"); expect(firstInlineGroup?.textContent).toContain("Canvas width"); expect(firstInlineGroup?.textContent).toContain("Canvas height"); expect(screen.getByRole("button", { name: "Toggle Settings section" })).toBeTruthy(); const collapse = screen.getByRole("button", { name: "Collapse Settings section" }); expect(collapse.getAttribute("aria-expanded")).toBe("true"); expect(screen.queryByRole("button", { name: "Settings help" })).toBeNull(); fireEvent.change(screen.getByDisplayValue("Initial prompt"), { target: { value: "Keep product edit" } }); fireEvent.blur(screen.getByDisplayValue("Keep product edit")); const width = screen.getByDisplayValue("1280"); fireEvent.change(width, { target: { value: "640" } }); fireEvent.blur(width); fireEvent.click(screen.getByRole("button", { name: "Reset Settings section" })); expect(screen.getByDisplayValue("1280")).toBeTruthy(); expect(screen.getByDisplayValue("720")).toBeTruthy(); expect(screen.getByDisplayValue("Keep product edit")).toBeTruthy(); fireEvent.click(collapse); expect(settingsSection?.getAttribute("data-collapsed")).toBe("true"); expect(screen.getByRole("button", { name: "Save State as Default" })).toBeTruthy(); fireEvent.click(screen.getByRole("button", { name: "Expand Settings section" })); expect(settingsSection?.getAttribute("data-collapsed")).toBe("false"); expect(scrollContent?.textContent).toContain("Save State as Default"); expect(stickyFooter?.textContent).toContain("Export PNG"); expect(stickyFooter?.textContent).not.toContain("Save State as Default"); }); it("keeps Settings mounted without an authoring host or canvas controls", () => { const schema = defineToolcraft({ base: { identity: { id: "settings-only", title: "Settings only" }, canvas: { enabled: false }, panels: { controls: { title: "Controls", sections: [] } }, }, modules: [] }); const { container } = renderControlsPanelWithSchema(schema); expect(container.querySelectorAll("section")).toHaveLength(1); expect(screen.queryByRole("button", { name: "Save State as Default" })).toBeNull(); expect(screen.getByRole("button", { name: "Collapse Settings section" })).toBeTruthy(); expect(screen.getByRole("button", { name: "Reset Settings section" })).toBeTruthy(); }); });