Files
hermes-agent/web/src/lib/api-plugins-catalog.test.ts
T
Teknium fe9dc06071 feat(dashboard): plugin catalog surface — browse, capability-confirm install, removed banners
- GET /api/dashboard/plugins/catalog: catalog entries merged with
  installed-state (sidecar SHA, update_available, runtime_status) +
  removed blocklist + generated_at
- agent-plugins/install accepts catalog_name: resolves the catalog
  entry, refuses removed plugins (400, no dashboard bypass), installs
  at the pinned SHA and writes the .hermes-catalog.json sidecar
- plugins/hub rows annotated with removed_reason
- PluginsPage: Catalog section with search, tier badges, capability
  chips, sha/docs links, capability-summary confirm dialog install
  flow, and red removed banners on catalog + installed rows
- en i18n keys with en-only optional-key fallback convention
2026-07-22 07:57:39 -07:00

59 lines
1.7 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "vitest";
import { api } from "./api";
afterEach(() => {
vi.restoreAllMocks();
vi.unstubAllGlobals();
});
function jsonFetchMock(body: unknown = { ok: true }) {
return vi.fn<typeof fetch>(
async () =>
new Response(JSON.stringify(body), {
headers: { "Content-Type": "application/json" },
status: 200,
}),
);
}
describe("api.getPluginsCatalog", () => {
it("fetches the dashboard plugins catalog endpoint", async () => {
vi.stubGlobal("window", {});
const fetchMock = jsonFetchMock({ entries: [], removed: [], generated_at: "" });
vi.stubGlobal("fetch", fetchMock);
const result = await api.getPluginsCatalog();
expect(fetchMock).toHaveBeenCalledWith(
"/api/dashboard/plugins/catalog",
expect.objectContaining({ credentials: "include" }),
);
expect(result.entries).toEqual([]);
expect(result.removed).toEqual([]);
});
});
describe("api.installAgentPlugin with catalog_name", () => {
it("posts catalog_name through to the install endpoint", async () => {
vi.stubGlobal("window", {});
const fetchMock = jsonFetchMock({ ok: true, plugin_name: "alpha-plugin" });
vi.stubGlobal("fetch", fetchMock);
await api.installAgentPlugin({
identifier: "",
catalog_name: "alpha-plugin",
enable: false,
});
const [url, init] = fetchMock.mock.calls[0]!;
expect(url).toBe("/api/dashboard/agent-plugins/install");
const body = JSON.parse(String((init as RequestInit).body));
expect(body.catalog_name).toBe("alpha-plugin");
expect(body.identifier).toBe("");
expect(body.enable).toBe(false);
});
});