Files
CC-Switch/tests/components/UnifiedSkillsPanel.test.tsx
Thefool 1c0ee0c58a feat(grokbuild): add first-class Grok Build support (#5453)
* feat(grokbuild): add backend integration

* feat(grokbuild): add provider and management UI

* test(grokbuild): cover configuration and integrations

* fix(grokbuild): address backend review feedback

* fix(grokbuild): complete UI review feedback

* feat(grokbuild): add CLI lifecycle management

* fix(grokbuild): align provider icon fallback

* test(grokbuild): cover provider icon persistence
2026-07-17 15:50:50 +08:00

134 lines
3.3 KiB
TypeScript

import { createRef } from "react";
import { render, screen, waitFor, act } from "@testing-library/react";
import { describe, expect, it, vi, beforeEach } from "vitest";
import UnifiedSkillsPanel, {
type UnifiedSkillsPanelHandle,
} from "@/components/skills/UnifiedSkillsPanel";
const scanUnmanagedMock = vi.fn();
const toggleSkillAppMock = vi.fn();
const uninstallSkillMock = vi.fn();
const importSkillsMock = vi.fn();
const installFromZipMock = vi.fn();
const deleteSkillBackupMock = vi.fn();
const restoreSkillBackupMock = vi.fn();
vi.mock("sonner", () => ({
toast: {
success: vi.fn(),
error: vi.fn(),
info: vi.fn(),
},
}));
vi.mock("@/hooks/useSkills", () => ({
useInstalledSkills: () => ({
data: [],
isLoading: false,
}),
useSkillBackups: () => ({
data: [],
refetch: vi.fn(),
isFetching: false,
}),
useDeleteSkillBackup: () => ({
mutateAsync: deleteSkillBackupMock,
isPending: false,
}),
useToggleSkillApp: () => ({
mutateAsync: toggleSkillAppMock,
}),
useRestoreSkillBackup: () => ({
mutateAsync: restoreSkillBackupMock,
isPending: false,
}),
useUninstallSkill: () => ({
mutateAsync: uninstallSkillMock,
}),
useScanUnmanagedSkills: () => ({
data: [
{
directory: "shared-skill",
name: "Shared Skill",
description: "Imported from Grok Build",
foundIn: ["grokbuild"],
path: "/tmp/shared-skill",
},
],
refetch: scanUnmanagedMock,
}),
useImportSkillsFromApps: () => ({
mutateAsync: importSkillsMock,
}),
useInstallSkillsFromZip: () => ({
mutateAsync: installFromZipMock,
}),
useCheckSkillUpdates: () => ({
data: [],
refetch: vi.fn(),
isFetching: false,
}),
useUpdateSkill: () => ({
mutateAsync: vi.fn(),
isPending: false,
}),
}));
describe("UnifiedSkillsPanel", () => {
beforeEach(() => {
scanUnmanagedMock.mockResolvedValue({
data: [
{
directory: "shared-skill",
name: "Shared Skill",
description: "Imported from Grok Build",
foundIn: ["grokbuild"],
path: "/tmp/shared-skill",
},
],
});
toggleSkillAppMock.mockReset();
uninstallSkillMock.mockReset();
importSkillsMock.mockReset();
installFromZipMock.mockReset();
deleteSkillBackupMock.mockReset();
restoreSkillBackupMock.mockReset();
});
it("opens the import dialog without crashing when app toggles render", async () => {
const ref = createRef<UnifiedSkillsPanelHandle>();
render(
<UnifiedSkillsPanel
ref={ref}
onOpenDiscovery={() => {}}
currentApp="claude"
/>,
);
await act(async () => {
await ref.current?.openImport();
});
await waitFor(() => {
expect(screen.getByText("skills.import")).toBeInTheDocument();
expect(screen.getByText("Shared Skill")).toBeInTheDocument();
expect(screen.getByText("/tmp/shared-skill")).toBeInTheDocument();
});
await act(async () => {
screen.getByText("skills.importSelected").click();
});
await waitFor(() => {
expect(importSkillsMock).toHaveBeenCalledWith([
{
directory: "shared-skill",
apps: expect.objectContaining({ grokbuild: true }),
},
]);
});
});
});