Files
fusion/packages/dashboard/app/hooks/__tests__/usePluginUiContributions.test.ts
Fusion f499f10818 feat(FN-3564): isolate plugin loader test state to prevent cross-test conta
Refactored plugin-loader tests and implementation to isolate plugin test contamination, improving test independence in `@fusion/core`.

Fusion-Task-Id: FN-3564
2026-05-06 02:14:05 -07:00

74 lines
2.7 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
import { renderHook, waitFor } from "@testing-library/react";
import { usePluginUiContributions, __test_clearContributionsCache } from "../usePluginUiContributions";
import * as api from "../../api";
import type { PluginUiContributionEntry } from "../../api";
vi.mock("../../api", () => ({
fetchPluginUiContributions: vi.fn(),
}));
const mockFetchPluginUiContributions = vi.mocked(api.fetchPluginUiContributions);
function createContributionEntry(surface: PluginUiContributionEntry["contribution"]["surface"]): PluginUiContributionEntry {
return {
pluginId: "plugin-a",
contribution: {
surface,
contributionId: `${surface}-id`,
title: `${surface} title`,
providerId: "openai",
providerType: "api_key",
} as PluginUiContributionEntry["contribution"],
};
}
describe("usePluginUiContributions", () => {
beforeEach(() => {
mockFetchPluginUiContributions.mockReset();
__test_clearContributionsCache();
});
it("fetches contributions and returns them", async () => {
const data = [createContributionEntry("settings-provider-card")];
mockFetchPluginUiContributions.mockResolvedValueOnce(data);
const { result } = renderHook(() => usePluginUiContributions());
await waitFor(() => expect(result.current.loading).toBe(false));
expect(result.current.error).toBeNull();
expect(result.current.contributions).toEqual(data);
});
it("filters contributions by surface", async () => {
const data = [
createContributionEntry("settings-provider-card"),
createContributionEntry("onboarding-provider-card"),
];
mockFetchPluginUiContributions.mockResolvedValueOnce(data);
const { result } = renderHook(() => usePluginUiContributions());
await waitFor(() => expect(result.current.loading).toBe(false));
const filtered = result.current.getContributionsForSurface("settings-provider-card");
expect(filtered).toHaveLength(1);
expect(filtered[0]?.contribution.surface).toBe("settings-provider-card");
});
it("uses cache on repeated load", async () => {
const data = [createContributionEntry("post-onboarding-recommendation")];
mockFetchPluginUiContributions.mockResolvedValueOnce(data);
const { result: first } = renderHook(() => usePluginUiContributions("proj"));
await waitFor(() => expect(first.current.loading).toBe(false));
mockFetchPluginUiContributions.mockClear();
const { result: second } = renderHook(() => usePluginUiContributions("proj"));
await waitFor(() => expect(second.current.loading).toBe(false));
expect(second.current.contributions).toEqual(data);
expect(mockFetchPluginUiContributions).not.toHaveBeenCalled();
});
});