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 Claude", foundIn: ["claude"], 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 Claude", foundIn: ["claude"], 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(); render( {}} 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(); }); }); });