Files
openclaw/src/plugins/discovery-threading.test.ts
T
Peter Steinberger e74be5d41d refactor: eliminate final wrapper-shadowing hazards (#122157)
* refactor: disambiguate wrapper-shadowed exports

* test: align renamed session and facade boundaries

* test: cover renamed runtime mock exports

* refactor: align remaining wrapper owner call sites

* test: align overlap-rebased runtime mocks

* refactor: preserve public SDK names after overlap rebase

* chore: regenerate wrapper shadowing baselines

* test: align cron model selection mocks
2026-08-11 13:34:24 -07:00

77 lines
3.0 KiB
TypeScript

// Covers plugin discovery threading and concurrency behavior.
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { PluginDiscoveryResult } from "./discovery.js";
import * as installedPluginIndexRecordReader from "./installed-plugin-index-record-reader.js";
const discoverOpenClawPluginsMock = vi.fn();
vi.mock("./discovery.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("./discovery.js")>();
return {
...actual,
discoverOpenClawPlugins: (...args: unknown[]) => discoverOpenClawPluginsMock(...args),
};
});
const { loadPluginManifestRegistryCore } = await import("./manifest-registry.js");
const { loadInstalledPluginIndexWithDiscovery } = await import("./installed-plugin-index.js");
const emptyDiscovery: PluginDiscoveryResult = { candidates: [], diagnostics: [] };
describe("discovery threading", () => {
beforeEach(() => {
discoverOpenClawPluginsMock.mockReset();
discoverOpenClawPluginsMock.mockReturnValue(emptyDiscovery);
});
it("skips internal discoverOpenClawPlugins when discovery is supplied", () => {
loadPluginManifestRegistryCore({ discovery: emptyDiscovery });
expect(discoverOpenClawPluginsMock).not.toHaveBeenCalled();
discoverOpenClawPluginsMock.mockClear();
loadInstalledPluginIndexWithDiscovery({ discovery: emptyDiscovery, installRecords: {} });
expect(discoverOpenClawPluginsMock).not.toHaveBeenCalled();
});
it("calls discoverOpenClawPlugins when neither discovery nor candidates supplied", () => {
loadPluginManifestRegistryCore({});
expect(discoverOpenClawPluginsMock).toHaveBeenCalledTimes(1);
discoverOpenClawPluginsMock.mockClear();
loadInstalledPluginIndexWithDiscovery({ installRecords: {} });
expect(discoverOpenClawPluginsMock).toHaveBeenCalledTimes(1);
});
it("prefers explicit candidates over discovery when both are supplied", () => {
loadPluginManifestRegistryCore({ candidates: [], diagnostics: [], discovery: emptyDiscovery });
expect(discoverOpenClawPluginsMock).not.toHaveBeenCalled();
discoverOpenClawPluginsMock.mockClear();
loadInstalledPluginIndexWithDiscovery({
candidates: [],
discovery: emptyDiscovery,
installRecords: {},
});
expect(discoverOpenClawPluginsMock).not.toHaveBeenCalled();
});
it("preserves explicit candidate diagnostics without loading persisted install records", () => {
const readInstallRecords = vi.spyOn(
installedPluginIndexRecordReader,
"loadInstalledPluginIndexInstallRecordsSync",
);
const diagnostics = [{ level: "warn" as const, message: "explicit candidate diagnostic" }];
const result = loadInstalledPluginIndexWithDiscovery({
candidates: [],
diagnostics,
installRecords: {},
});
expect(result.manifestRegistry.diagnostics).toEqual(diagnostics);
expect(result.discovery).toBeUndefined();
expect(readInstallRecords).not.toHaveBeenCalled();
expect(discoverOpenClawPluginsMock).not.toHaveBeenCalled();
});
});