You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

155 lines
4.4 KiB

import { render, screen } from "@testing-library/react";
import { afterEach, 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: () => <div data-testid="model-parameters" />,
}));
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;
}
function llmNode(): WorkflowNode {
return {
id: "llm-1",
type: "llmGenerate",
selected: true,
position: { x: 0, y: 0 },
data: {
inputPrompt: null,
inputImages: [],
inputVideos: [],
outputText: null,
provider: "newapiwg",
model: "doubao-seed-2-0-lite-260428",
temperature: 0.7,
maxTokens: 2048,
status: "idle",
error: null,
},
} as WorkflowNode;
}
describe("ControlPanel", () => {
const originalProviderMode = process.env.NEXT_PUBLIC_PROVIDER_MODE;
beforeEach(() => {
vi.clearAllMocks();
useWorkflowStore.setState({
nodes: [],
edges: [],
isRunning: false,
});
});
afterEach(() => {
if (originalProviderMode === undefined) {
delete process.env.NEXT_PUBLIC_PROVIDER_MODE;
} else {
process.env.NEXT_PUBLIC_PROVIDER_MODE = originalProviderMode;
}
});
it("does not render duplicate settings for image generation nodes controlled by the composer", () => {
useWorkflowStore.setState({ nodes: [imageNode()] });
const { container } = render(<ControlPanel />);
expect(container).toBeEmptyDOMElement();
expect(screen.queryByText("Generate Image Settings")).not.toBeInTheDocument();
expect(screen.queryByText("1024x1024")).not.toBeInTheDocument();
});
it("keeps the right-side panel for generation nodes not yet owned by the composer", () => {
useWorkflowStore.setState({ nodes: [videoNode()] });
render(<ControlPanel />);
expect(screen.getByText("Generate Video Settings")).toBeInTheDocument();
expect(screen.getByTestId("model-parameters")).toBeInTheDocument();
});
it("hides provider labels in Popi provider mode", () => {
process.env.NEXT_PUBLIC_PROVIDER_MODE = "popi";
useWorkflowStore.setState({ nodes: [videoNode()] });
render(<ControlPanel />);
expect(screen.getByText("Video Model")).toBeInTheDocument();
expect(screen.queryByText("Popi Models")).not.toBeInTheDocument();
});
it("does not render the side control panel for LLM nodes", () => {
process.env.NEXT_PUBLIC_PROVIDER_MODE = "popi";
useWorkflowStore.setState({ nodes: [llmNode()] });
render(<ControlPanel />);
expect(screen.queryByText("Provider")).not.toBeInTheDocument();
expect(screen.queryByText("Model")).not.toBeInTheDocument();
expect(screen.queryByText((content) => content.includes("0.70"))).not.toBeInTheDocument();
expect(screen.queryByText((content) => content.includes("2,048"))).not.toBeInTheDocument();
expect(screen.queryByText("模型配置")).not.toBeInTheDocument();
});
});