mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-14 10:46:51 +08:00
010b163430
* style(FailoverQueueManager): 显示供应商备注信息 * style(FailoverQueueItem): 添加供应商备注字段以支持备注信息显示 * style(FailoverQueueManager): 显示供应商备注信息 * style(FailoverQueueItem): 添加供应商备注字段以支持备注信息显示 * style(FailoverQueueManager): 更新供应商备注信息的显示样式 * style(FailoverQueueItem): 添加条件序列化以优化供应商备注字段 * fix: 优化模型状态管理,确保配置更新时正确引用最新设置 * fix(skill): improve error handling for skill source directory resolution Co-authored-by: Copilot <copilot@github.com> * fix(gemini): simplify project directory retrieval in scan_sessions function * fix(useModelState): optimize latestConfigRef assignment in useModelState hook * fix(useModelState): remove unnecessary blank line in useModelState hook --------- Co-authored-by: Copilot <copilot@github.com>
63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { mergeImportedSkills } from "@/hooks/useSkills.helpers";
|
|
import type { InstalledSkill } from "@/lib/api/skills";
|
|
|
|
function makeSkill(overrides: Partial<InstalledSkill> = {}): InstalledSkill {
|
|
return {
|
|
id: "skill-a",
|
|
name: "Skill A",
|
|
directory: "skill-a",
|
|
apps: {
|
|
claude: true,
|
|
codex: false,
|
|
gemini: false,
|
|
opencode: false,
|
|
openclaw: false,
|
|
hermes: false,
|
|
},
|
|
installedAt: 0,
|
|
updatedAt: 0,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
// Regression coverage for issue #2139: when a user double-clicks the import
|
|
// button (or the mutation otherwise fires twice with the same payload), the
|
|
// installed cache must not accumulate duplicate entries for the same skill.
|
|
describe("mergeImportedSkills", () => {
|
|
it("returns the imported list as-is when no cache exists yet", () => {
|
|
const imported = [makeSkill()];
|
|
expect(mergeImportedSkills(undefined, imported)).toEqual(imported);
|
|
});
|
|
|
|
it("dedupes by id when the same skill is imported twice in a row", () => {
|
|
const existing = [makeSkill()];
|
|
const secondImport = [makeSkill()];
|
|
const merged = mergeImportedSkills(existing, secondImport);
|
|
expect(merged).toHaveLength(1);
|
|
expect(merged[0]).toBe(secondImport[0]);
|
|
});
|
|
|
|
it("replaces stale cache entries with fresh imports for the same id", () => {
|
|
const stale = [makeSkill({ name: "Stale Name" })];
|
|
const fresh = [makeSkill({ name: "Fresh Name" })];
|
|
const merged = mergeImportedSkills(stale, fresh);
|
|
expect(merged).toHaveLength(1);
|
|
expect(merged[0].name).toBe("Fresh Name");
|
|
});
|
|
|
|
it("returns the existing reference unchanged when the imported list is empty", () => {
|
|
const existing = [makeSkill()];
|
|
expect(mergeImportedSkills(existing, [])).toBe(existing);
|
|
});
|
|
|
|
it("appends newly imported skills without dropping existing unrelated ones", () => {
|
|
const existing = [makeSkill({ id: "skill-a", directory: "skill-a" })];
|
|
const imported = [
|
|
makeSkill({ id: "skill-b", directory: "skill-b", name: "Skill B" }),
|
|
];
|
|
const merged = mergeImportedSkills(existing, imported);
|
|
expect(merged.map((s) => s.id).sort()).toEqual(["skill-a", "skill-b"]);
|
|
});
|
|
});
|