diff --git a/src/components/__tests__/ControlPanel.test.tsx b/src/components/__tests__/ControlPanel.test.tsx new file mode 100644 index 00000000..fbea6ff1 --- /dev/null +++ b/src/components/__tests__/ControlPanel.test.tsx @@ -0,0 +1,101 @@ +import { render, screen } from "@testing-library/react"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { ControlPanel } from "@/components/nodes/ControlPanel"; +import { useWorkflowStore } from "@/store/workflowStore"; +import type { WorkflowNode } from "@/types"; + +vi.mock("@/hooks/useInlineParameters", () => ({ + useInlineParameters: () => ({ inlineParametersEnabled: false }), +})); + +vi.mock("@/components/nodes/ModelParameters", () => ({ + ModelParameters: () =>
, +})); + +vi.mock("@/components/modals/ModelSearchDialog", () => ({ + ModelSearchDialog: () => null, +})); + +function imageNode(): WorkflowNode { + return { + id: "image-1", + type: "nanoBanana", + selected: true, + position: { x: 0, y: 0 }, + data: { + inputImages: [], + inputPrompt: "coffee spilled", + outputImage: null, + aspectRatio: "16:9", + resolution: "1K", + model: "nano-banana-pro", + selectedModel: { + provider: "newapiwg", + modelId: "apiyi_nano_banana_2", + displayName: "apiyi_nano_banana_2", + capabilities: ["text-to-image", "image-to-image"], + }, + parameters: { quality: "auto", size: "1024x1024" }, + useGoogleSearch: false, + useImageSearch: false, + status: "idle", + error: null, + imageHistory: [], + selectedHistoryIndex: 0, + }, + } as WorkflowNode; +} + +function videoNode(): WorkflowNode { + return { + id: "video-1", + type: "generateVideo", + selected: true, + position: { x: 0, y: 0 }, + data: { + prompt: "camera pan", + inputImage: null, + outputVideo: null, + selectedModel: { + provider: "newapiwg", + modelId: "video-model", + displayName: "Video Model", + capabilities: ["text-to-video"], + }, + parameters: {}, + status: "idle", + error: null, + progress: 0, + }, + } as WorkflowNode; +} + +describe("ControlPanel", () => { + beforeEach(() => { + vi.clearAllMocks(); + useWorkflowStore.setState({ + nodes: [], + edges: [], + isRunning: false, + }); + }); + + it("does not render duplicate settings for image generation nodes controlled by the composer", () => { + useWorkflowStore.setState({ nodes: [imageNode()] }); + + const { container } = render(