Files
openclaw/src/plugins/web-provider-resolution-candidates.test.ts
2026-05-09 05:44:40 +01:00

122 lines
4.0 KiB
TypeScript

import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
loadPluginRegistrySnapshot: vi.fn(),
loadPluginManifestRegistryForInstalledIndex: vi.fn(),
loadPluginMetadataSnapshot: vi.fn(),
}));
vi.mock("./plugin-registry.js", () => ({
loadPluginRegistrySnapshot: (...args: unknown[]) => mocks.loadPluginRegistrySnapshot(...args),
loadPluginManifestRegistryForPluginRegistry: (...args: unknown[]) =>
mocks.loadPluginManifestRegistryForInstalledIndex({
...(args[0] && typeof args[0] === "object" ? args[0] : {}),
index: mocks.loadPluginRegistrySnapshot(...args),
}),
}));
vi.mock("./manifest-registry-installed.js", () => ({
loadPluginManifestRegistryForInstalledIndex: (...args: unknown[]) =>
mocks.loadPluginManifestRegistryForInstalledIndex(...args),
}));
vi.mock("./plugin-metadata-snapshot.js", () => ({
loadPluginMetadataSnapshot: (...args: unknown[]) => mocks.loadPluginMetadataSnapshot(...args),
}));
let resolveManifestDeclaredWebProviderCandidatePluginIds: typeof import("./web-provider-resolution-shared.js").resolveManifestDeclaredWebProviderCandidatePluginIds;
describe("resolveManifestDeclaredWebProviderCandidatePluginIds", () => {
beforeAll(async () => {
({ resolveManifestDeclaredWebProviderCandidatePluginIds } =
await import("./web-provider-resolution-shared.js"));
});
beforeEach(() => {
mocks.loadPluginRegistrySnapshot.mockReset();
mocks.loadPluginRegistrySnapshot.mockReturnValue({ plugins: [] });
mocks.loadPluginManifestRegistryForInstalledIndex.mockReset();
mocks.loadPluginManifestRegistryForInstalledIndex.mockReturnValue({
plugins: [
{
id: "alpha",
origin: "bundled",
configSchema: {
properties: {
webSearch: {},
},
},
},
{
id: "beta",
origin: "bundled",
contracts: {
webSearchProviders: ["beta-search"],
},
},
],
diagnostics: [],
});
mocks.loadPluginMetadataSnapshot.mockReset();
mocks.loadPluginMetadataSnapshot.mockImplementation((...args: unknown[]) => ({
plugins: mocks.loadPluginManifestRegistryForInstalledIndex(...args).plugins,
}));
});
it("treats explicit empty plugin scopes as scoped-empty", () => {
expect(
resolveManifestDeclaredWebProviderCandidatePluginIds({
contract: "webSearchProviders",
configKey: "webSearch",
onlyPluginIds: [],
}),
).toStrictEqual([]);
expect(mocks.loadPluginManifestRegistryForInstalledIndex).not.toHaveBeenCalled();
});
it("keeps scoped plugins with no declared web candidates scoped-empty", () => {
expect(
resolveManifestDeclaredWebProviderCandidatePluginIds({
contract: "webSearchProviders",
configKey: "webSearch",
onlyPluginIds: ["missing-plugin"],
}),
).toStrictEqual([]);
expect(mocks.loadPluginMetadataSnapshot).toHaveBeenCalledOnce();
});
it("keeps origin filters with no declared web candidates scoped-empty", () => {
mocks.loadPluginManifestRegistryForInstalledIndex.mockReturnValue({
plugins: [
{
id: "workspace-tool",
origin: "workspace",
configSchema: {
properties: {},
},
},
],
diagnostics: [],
});
expect(
resolveManifestDeclaredWebProviderCandidatePluginIds({
contract: "webSearchProviders",
configKey: "webSearch",
origin: "bundled",
}),
).toStrictEqual([]);
});
it("derives provider candidates from a single manifest-registry read", () => {
expect(
resolveManifestDeclaredWebProviderCandidatePluginIds({
contract: "webSearchProviders",
configKey: "webSearch",
}),
).toEqual(["alpha", "beta"]);
expect(mocks.loadPluginMetadataSnapshot).toHaveBeenCalledTimes(1);
expect(mocks.loadPluginManifestRegistryForInstalledIndex).toHaveBeenCalledTimes(1);
});
});