import { fireEvent, screen, waitFor } from "@testing-library/react"; import { describe, expect, mock, test } from "bun:test"; import { createElement } from "react"; import type { Model, Provider } from "../../../src/shared/api"; import { ModelFormModal } from "../../../src/web/pages/models/components/ModelFormModal"; import { ProviderFormModal } from "../../../src/web/pages/models/components/ProviderFormModal"; import { renderWithProviders } from "../test-utils"; const ENABLED_PROVIDER: Provider = { apiKey: "sk-test", baseUrl: "https://api.openai.com/v1", createdAt: "2024-01-01T00:00:00.000Z", enabled: true, id: "pv1", name: "OpenAI", type: "openai", updatedAt: "2024-01-01T00:00:00.000Z", }; const DISABLED_PROVIDER: Provider = { apiKey: "sk-off", baseUrl: "https://api.deepseek.com/v1", createdAt: "2024-01-01T00:00:00.000Z", enabled: false, id: "pv2", name: "DeepSeek", type: "openai-compatible", updatedAt: "2024-01-01T00:00:00.000Z", }; const ENABLED_MODEL: Model = { capabilities: ["text", "reasoning"], contextLength: 128000, createdAt: "2024-01-01T00:00:00.000Z", enabled: true, id: "m1", maxOutputTokens: 4096, modelId: "gpt-4o", name: "GPT-4o", providerId: "pv1", updatedAt: "2024-01-01T00:00:00.000Z", }; function clickLatestConfirmButton() { const buttons = screen.getAllByRole("button", { name: /OK|确\s*定/ }); fireEvent.click(buttons[buttons.length - 1]!); } describe("ProviderFormModal", () => { test("编辑供应商表单只提交变更字段", async () => { const updateCalls: unknown[] = []; renderWithProviders( createElement(ProviderFormModal, { editingProvider: ENABLED_PROVIDER, onCancel: () => undefined, onCreate: () => Promise.resolve(), onOpenChange: () => undefined, onUpdate: (args: unknown) => { updateCalls.push(args); return Promise.resolve(); }, open: true, submitting: false, }), ); await waitFor(() => expect(screen.getByPlaceholderText("请输入供应商名称")).not.toBeNull()); fireEvent.change(screen.getByPlaceholderText("请输入供应商名称"), { target: { value: "New OpenAI" } }); clickLatestConfirmButton(); await waitFor(() => expect(updateCalls.length).toBe(1)); expect(updateCalls[0]).toEqual({ data: { name: "New OpenAI" }, id: "pv1" }); }); }); describe("ModelFormModal", () => { test("编辑模型表单只提交变更字段", async () => { const updateCalls: unknown[] = []; renderWithProviders( createElement(ModelFormModal, { editingModel: ENABLED_MODEL, onCancel: () => undefined, onCreate: () => Promise.resolve(), onOpenChange: () => undefined, onUpdate: (args: unknown) => { updateCalls.push(args); return Promise.resolve(); }, open: true, providers: [ENABLED_PROVIDER, DISABLED_PROVIDER], submitting: false, }), ); await waitFor(() => expect(screen.getByPlaceholderText("请输入模型名称")).not.toBeNull()); fireEvent.change(screen.getByPlaceholderText("请输入模型名称"), { target: { value: "GPT-4o Mini" } }); clickLatestConfirmButton(); await waitFor(() => expect(updateCalls.length).toBe(1)); expect(updateCalls[0]).toEqual({ data: { name: "GPT-4o Mini" }, id: "m1" }); }); test("模型表单校验失败不会提交", async () => { const onCreate = mock(() => Promise.resolve()); renderWithProviders( createElement(ModelFormModal, { editingModel: null, onCancel: () => undefined, onCreate, onOpenChange: () => undefined, onUpdate: () => Promise.resolve(), open: true, providers: [ENABLED_PROVIDER], submitting: false, }), ); await waitFor(() => expect(screen.getByPlaceholderText("请输入模型名称")).not.toBeNull()); clickLatestConfirmButton(); expect(onCreate).not.toHaveBeenCalled(); }); });