mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-16 13:34:04 +08:00
84bac6dce6
Adapt to Claude Desktop 1.6259.1+ fail-all validation which only accepts claude-(sonnet|opus|haiku)-* route IDs. Branded model names (DeepSeek, Kimi, GLM, etc.) now live in a new labelOverride field instead of being embedded in route IDs. - Backend auto-repairs legacy unsafe routes to the next free sonnet/opus/haiku slot instead of erroring - Frontend swaps the free-form route input for a role dropdown plus menu display name field - Add CLAUDE_DESKTOP_ROLE_ROUTE_IDS as the single source of truth for role-to-route mapping; presets and form both consume it - Drop the dead displayName alias on ClaudeDesktopModelRoute and the ineffective /v1/models display_name injection (UI ignores it) - Update i18n (en/ja/zh) and form focus test for the new fields
97 lines
2.7 KiB
TypeScript
97 lines
2.7 KiB
TypeScript
import { fireEvent, render, screen } from "@testing-library/react";
|
|
import { QueryClientProvider } from "@tanstack/react-query";
|
|
import type { ComponentProps } from "react";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { ClaudeDesktopProviderForm } from "@/components/providers/forms/ClaudeDesktopProviderForm";
|
|
import { createTestQueryClient } from "../utils/testQueryClient";
|
|
|
|
vi.mock("@/lib/api/providers", () => ({
|
|
providersApi: {
|
|
getClaudeDesktopDefaultRoutes: () => Promise.resolve([]),
|
|
},
|
|
}));
|
|
|
|
function renderForm(
|
|
initialData: ComponentProps<typeof ClaudeDesktopProviderForm>["initialData"],
|
|
) {
|
|
const queryClient = createTestQueryClient();
|
|
return render(
|
|
<QueryClientProvider client={queryClient}>
|
|
<ClaudeDesktopProviderForm
|
|
submitLabel="保存"
|
|
onSubmit={vi.fn()}
|
|
onCancel={vi.fn()}
|
|
initialData={initialData}
|
|
/>
|
|
</QueryClientProvider>,
|
|
);
|
|
}
|
|
|
|
describe("ClaudeDesktopProviderForm", () => {
|
|
it("编辑模型映射的菜单显示名时保持输入框焦点", () => {
|
|
renderForm({
|
|
name: "Proxy Provider",
|
|
settingsConfig: {
|
|
env: {
|
|
ANTHROPIC_BASE_URL: "https://api.example.com",
|
|
ANTHROPIC_AUTH_TOKEN: "sk-test",
|
|
},
|
|
},
|
|
meta: {
|
|
claudeDesktopMode: "proxy",
|
|
claudeDesktopModelRoutes: {
|
|
"claude-old": {
|
|
model: "upstream-old",
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText(
|
|
"DeepSeek V4 Pro",
|
|
) as HTMLInputElement;
|
|
input.focus();
|
|
|
|
fireEvent.change(input, { target: { value: "DeepSeek V4 Pro" } });
|
|
|
|
const currentInput = screen.getByPlaceholderText(
|
|
"DeepSeek V4 Pro",
|
|
) as HTMLInputElement;
|
|
expect(currentInput).toHaveValue("DeepSeek V4 Pro");
|
|
expect(document.activeElement).toBe(currentInput);
|
|
});
|
|
|
|
it("编辑直连模型列表的模型 ID 时保持输入框焦点", () => {
|
|
renderForm({
|
|
name: "Direct Provider",
|
|
settingsConfig: {
|
|
env: {
|
|
ANTHROPIC_BASE_URL: "https://api.example.com",
|
|
ANTHROPIC_AUTH_TOKEN: "sk-test",
|
|
},
|
|
},
|
|
meta: {
|
|
claudeDesktopMode: "direct",
|
|
claudeDesktopModelRoutes: {
|
|
"claude-old": {
|
|
model: "claude-old",
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
const input = screen.getByPlaceholderText(
|
|
"claude-deepseek-chat",
|
|
) as HTMLInputElement;
|
|
input.focus();
|
|
|
|
fireEvent.change(input, { target: { value: "claude-12345" } });
|
|
|
|
const currentInput = screen.getByPlaceholderText(
|
|
"claude-deepseek-chat",
|
|
) as HTMLInputElement;
|
|
expect(currentInput).toHaveValue("claude-12345");
|
|
expect(document.activeElement).toBe(currentInput);
|
|
});
|
|
});
|