mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-26 14:35:22 +08:00
fix: pre-release fixes for code formatting, i18n, and test suite
- Run cargo fmt to fix Rust code formatting (lib.rs) - Add missing i18n keys: migration.success, agents.title (zh/en/ja) - Replace hardcoded strings "Agents" and "MCP" with t() calls in App.tsx - Fix test mocks and assertions: - Add providersApi.updateTrayMenu to useSettings.test.tsx mock - Update SettingsPage mock path in App.test.tsx - Fix toast message assertion in integration/SettingsDialog.test.tsx - Add autoSaveSettings to SettingsDialog component test mock - Fix loading state test to check spinner instead of title - Update import button name matching for selected file state - Fix save button test to switch to advanced tab first - Remove obsolete cancel button test (button no longer exists) Test results improved from 99 passed / 17 failed to 104 passed / 11 failed
This commit is contained in:
@@ -71,7 +71,8 @@ impl TrayTexts {
|
||||
},
|
||||
"ja" => Self {
|
||||
show_main: "メインウィンドウを開く",
|
||||
no_provider_hint: " (プロバイダーがまだありません。メイン画面から追加してください)",
|
||||
no_provider_hint:
|
||||
" (プロバイダーがまだありません。メイン画面から追加してください)",
|
||||
quit: "終了",
|
||||
},
|
||||
_ => Self {
|
||||
@@ -521,7 +522,8 @@ pub fn run() {
|
||||
|
||||
unsafe {
|
||||
use objc2::msg_send;
|
||||
let _: () = msg_send![&*ns_window, setBackgroundColor: &*bg_color];
|
||||
let _: () =
|
||||
msg_send![&*ns_window, setBackgroundColor: &*bg_color];
|
||||
}
|
||||
} else {
|
||||
log::warn!("Failed to retain NSWindow reference");
|
||||
|
||||
+2
-2
@@ -391,7 +391,7 @@ function App() {
|
||||
t("prompts.title", { appName: t(`apps.${activeApp}`) })}
|
||||
{currentView === "skills" && t("skills.title")}
|
||||
{currentView === "mcp" && t("mcp.unifiedPanel.title")}
|
||||
{currentView === "agents" && "Agents"}
|
||||
{currentView === "agents" && t("agents.title")}
|
||||
</h1>
|
||||
</div>
|
||||
) : (
|
||||
@@ -512,7 +512,7 @@ function App() {
|
||||
size="sm"
|
||||
onClick={() => setCurrentView("mcp")}
|
||||
className="text-muted-foreground hover:text-foreground hover:bg-black/5 dark:hover:bg-white/5"
|
||||
title="MCP"
|
||||
title={t("mcp.title")}
|
||||
>
|
||||
<Server className="h-4 w-4" />
|
||||
</Button>
|
||||
|
||||
@@ -833,5 +833,11 @@
|
||||
"colorLabel": "Icon Color",
|
||||
"selectIcon": "Select Icon",
|
||||
"preview": "Preview"
|
||||
},
|
||||
"migration": {
|
||||
"success": "Configuration migrated successfully"
|
||||
},
|
||||
"agents": {
|
||||
"title": "Agents"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,5 +833,11 @@
|
||||
"colorLabel": "アイコンカラー",
|
||||
"selectIcon": "アイコンを選択",
|
||||
"preview": "プレビュー"
|
||||
},
|
||||
"migration": {
|
||||
"success": "設定の移行が完了しました"
|
||||
},
|
||||
"agents": {
|
||||
"title": "エージェント"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,5 +833,11 @@
|
||||
"colorLabel": "图标颜色",
|
||||
"selectIcon": "选择图标",
|
||||
"preview": "预览"
|
||||
},
|
||||
"migration": {
|
||||
"success": "配置迁移成功"
|
||||
},
|
||||
"agents": {
|
||||
"title": "智能体"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ interface SettingsMock {
|
||||
resetDirectory: ReturnType<typeof vi.fn>;
|
||||
resetAppConfigDir: ReturnType<typeof vi.fn>;
|
||||
saveSettings: ReturnType<typeof vi.fn>;
|
||||
autoSaveSettings: ReturnType<typeof vi.fn>;
|
||||
resetSettings: ReturnType<typeof vi.fn>;
|
||||
acknowledgeRestart: ReturnType<typeof vi.fn>;
|
||||
}
|
||||
@@ -66,6 +67,7 @@ const createSettingsMock = (overrides: Partial<SettingsMock> = {}) => {
|
||||
resetDirectory: vi.fn(),
|
||||
resetAppConfigDir: vi.fn(),
|
||||
saveSettings: vi.fn().mockResolvedValue({ requiresRestart: false }),
|
||||
autoSaveSettings: vi.fn().mockResolvedValue({ requiresRestart: false }),
|
||||
resetSettings: vi.fn(),
|
||||
acknowledgeRestart: vi.fn(),
|
||||
};
|
||||
@@ -247,7 +249,8 @@ describe("SettingsPage Component", () => {
|
||||
render(<SettingsPage open={true} onOpenChange={vi.fn()} />);
|
||||
|
||||
expect(screen.queryByText("language:zh")).not.toBeInTheDocument();
|
||||
expect(screen.getByText("settings.title")).toBeInTheDocument();
|
||||
// 加载状态下显示 spinner 而不是表单内容
|
||||
expect(document.querySelector(".animate-spin")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should reset import/export status when dialog transitions to open", () => {
|
||||
@@ -264,6 +267,7 @@ describe("SettingsPage Component", () => {
|
||||
|
||||
it("should render general and advanced tabs and trigger child callbacks", () => {
|
||||
const onOpenChange = vi.fn();
|
||||
// 设置 selectedFile 后,按钮显示 settings.import(可执行导入)
|
||||
importExportMock = createImportExportMock({
|
||||
selectedFile: "/tmp/config.json",
|
||||
});
|
||||
@@ -284,21 +288,20 @@ describe("SettingsPage Component", () => {
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText("settings.tabAdvanced"));
|
||||
fireEvent.click(
|
||||
screen.getByRole("button", { name: "settings.selectConfigFile" }),
|
||||
);
|
||||
|
||||
expect(importExportMock.selectImportFile).toHaveBeenCalled();
|
||||
// 有文件时,点击导入按钮执行 importConfig
|
||||
fireEvent.click(
|
||||
screen.getByRole("button", { name: /settings\.import/ }),
|
||||
);
|
||||
expect(importExportMock.importConfig).toHaveBeenCalled();
|
||||
|
||||
fireEvent.click(
|
||||
screen.getByRole("button", { name: "settings.exportConfig" }),
|
||||
);
|
||||
expect(importExportMock.exportConfig).toHaveBeenCalled();
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "settings.import" }));
|
||||
expect(importExportMock.importConfig).toHaveBeenCalled();
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "common.clear" }));
|
||||
// 清除选择按钮
|
||||
fireEvent.click(screen.getByRole("button", { name: "Clear selection" }));
|
||||
expect(importExportMock.clearSelection).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -330,7 +333,9 @@ describe("SettingsPage Component", () => {
|
||||
|
||||
render(<SettingsPage open={true} onOpenChange={onOpenChange} />);
|
||||
|
||||
fireEvent.click(screen.getByText("common.save"));
|
||||
// 保存按钮在 advanced tab 中
|
||||
fireEvent.click(screen.getByText("settings.tabAdvanced"));
|
||||
fireEvent.click(screen.getByRole("button", { name: /common\.save/ }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(settingsMock.saveSettings).toHaveBeenCalledTimes(1);
|
||||
@@ -341,20 +346,6 @@ describe("SettingsPage Component", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should reset settings and close dialog when clicking cancel", () => {
|
||||
const onOpenChange = vi.fn();
|
||||
|
||||
render(<SettingsPage open={true} onOpenChange={onOpenChange} />);
|
||||
|
||||
fireEvent.click(screen.getByText("common.cancel"));
|
||||
|
||||
expect(settingsMock.resetSettings).toHaveBeenCalledTimes(1);
|
||||
expect(settingsMock.acknowledgeRestart).toHaveBeenCalledTimes(1);
|
||||
expect(importExportMock.clearSelection).toHaveBeenCalledTimes(1);
|
||||
expect(importExportMock.resetStatus).toHaveBeenCalledTimes(2);
|
||||
expect(onOpenChange).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it("should show restart prompt and allow immediate restart after save", async () => {
|
||||
settingsMock = createSettingsMock({
|
||||
requiresRestart: true,
|
||||
|
||||
@@ -8,6 +8,7 @@ const useSettingsQueryMock = vi.fn();
|
||||
const setAppConfigDirOverrideMock = vi.fn();
|
||||
const applyClaudePluginConfigMock = vi.fn();
|
||||
const syncCurrentProvidersLiveMock = vi.fn();
|
||||
const updateTrayMenuMock = vi.fn();
|
||||
const toastErrorMock = vi.fn();
|
||||
const toastSuccessMock = vi.fn();
|
||||
|
||||
@@ -52,6 +53,9 @@ vi.mock("@/lib/api", () => ({
|
||||
syncCurrentProvidersLive: (...args: unknown[]) =>
|
||||
syncCurrentProvidersLiveMock(...args),
|
||||
},
|
||||
providersApi: {
|
||||
updateTrayMenu: (...args: unknown[]) => updateTrayMenuMock(...args),
|
||||
},
|
||||
}));
|
||||
|
||||
const createSettingsFormMock = (overrides: Record<string, unknown> = {}) => ({
|
||||
|
||||
@@ -109,8 +109,8 @@ vi.mock("@/components/ConfirmDialog", () => ({
|
||||
) : null,
|
||||
}));
|
||||
|
||||
vi.mock("@/components/settings/SettingsDialog", () => ({
|
||||
SettingsDialog: ({ open, onOpenChange, onImportSuccess }: any) =>
|
||||
vi.mock("@/components/settings/SettingsPage", () => ({
|
||||
SettingsPage: ({ open, onOpenChange, onImportSuccess }: any) =>
|
||||
open ? (
|
||||
<div data-testid="settings-dialog">
|
||||
<button onClick={() => onImportSuccess?.()}>
|
||||
|
||||
@@ -264,7 +264,7 @@ describe("SettingsPage integration", () => {
|
||||
await waitFor(() => expect(toastErrorMock).toHaveBeenCalled());
|
||||
const cancelMessage = toastErrorMock.mock.calls.at(-1)?.[0] as string;
|
||||
expect(cancelMessage).toMatch(
|
||||
/settings\.selectFileFailed|选择保存位置失败/,
|
||||
/settings\.selectFileFailed|请选择.*保存路径/,
|
||||
);
|
||||
|
||||
toastErrorMock.mockClear();
|
||||
|
||||
Reference in New Issue
Block a user