Files
openclaw/src/plugins/active-runtime-registry.test.ts
2026-05-25 15:42:18 +01:00

145 lines
4.1 KiB
TypeScript

import { afterEach, describe, expect, it } from "vitest";
import { getLoadedRuntimePluginRegistry } from "./active-runtime-registry.js";
import { testing, clearPluginLoaderCache } from "./loader.js";
import { createEmptyPluginRegistry } from "./registry-empty.js";
import type { PluginRegistry } from "./registry-types.js";
import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "./runtime.js";
afterEach(() => {
clearPluginLoaderCache();
resetPluginRuntimeStateForTest();
});
function createRegistryWithPlugin(pluginId: string): PluginRegistry {
const registry = createEmptyPluginRegistry();
registry.plugins.push({
id: pluginId,
status: "loaded",
} as never);
return registry;
}
describe("getLoadedRuntimePluginRegistry", () => {
it("treats an explicit empty plugin scope as empty", () => {
setActivePluginRegistry(createRegistryWithPlugin("stale"), "stale", "default", "/tmp/ws");
expect(
getLoadedRuntimePluginRegistry({
workspaceDir: "/tmp/ws",
requiredPluginIds: [],
}),
).toBeUndefined();
const emptyRegistry = createEmptyPluginRegistry();
setActivePluginRegistry(emptyRegistry, "empty", "default", "/tmp/ws");
expect(
getLoadedRuntimePluginRegistry({
workspaceDir: "/tmp/ws",
requiredPluginIds: [],
}),
).toBe(emptyRegistry);
});
it("does not treat disabled plugin records as an empty plugin scope", () => {
const disabledRegistry = createEmptyPluginRegistry();
disabledRegistry.plugins.push({
id: "disabled",
status: "disabled",
} as never);
setActivePluginRegistry(disabledRegistry, "disabled", "default", "/tmp/ws");
expect(
getLoadedRuntimePluginRegistry({
workspaceDir: "/tmp/ws",
requiredPluginIds: [],
}),
).toBeUndefined();
});
it("does not treat diagnostics as loaded plugin records", () => {
const failedRegistry = createEmptyPluginRegistry();
failedRegistry.plugins.push({
id: "failed",
status: "error",
} as never);
failedRegistry.diagnostics.push({
level: "error",
pluginId: "failed",
message: "failed to load",
} as never);
setActivePluginRegistry(failedRegistry, "failed", "default", "/tmp/ws");
expect(
getLoadedRuntimePluginRegistry({
workspaceDir: "/tmp/ws",
requiredPluginIds: ["failed"],
}),
).toBeUndefined();
});
it("does not treat setup-only registrations as loaded plugin records", () => {
const setupRegistry = createEmptyPluginRegistry();
setupRegistry.plugins.push({
id: "setup-only",
status: "disabled",
} as never);
setupRegistry.channelSetups.push({
pluginId: "setup-only",
} as never);
setActivePluginRegistry(setupRegistry, "setup-only", "default", "/tmp/ws");
expect(
getLoadedRuntimePluginRegistry({
workspaceDir: "/tmp/ws",
requiredPluginIds: ["setup-only"],
}),
).toBeUndefined();
});
it("does not reuse workspace-agnostic registries for workspace-specific requests", () => {
setActivePluginRegistry(createRegistryWithPlugin("demo"), "demo");
expect(
getLoadedRuntimePluginRegistry({
workspaceDir: "/tmp/ws",
requiredPluginIds: ["demo"],
}),
).toBeUndefined();
});
it("validates full loader cache compatibility when load options are provided", () => {
const registry = createRegistryWithPlugin("demo");
const loadOptions = {
config: {
plugins: {
allow: ["demo"],
},
},
onlyPluginIds: ["demo"],
workspaceDir: "/tmp/ws",
};
const { cacheKey } = testing.resolvePluginLoadCacheContext(loadOptions);
setActivePluginRegistry(registry, cacheKey, "default", "/tmp/ws");
expect(
getLoadedRuntimePluginRegistry({
loadOptions,
}),
).toBe(registry);
expect(
getLoadedRuntimePluginRegistry({
loadOptions: {
...loadOptions,
config: {
plugins: {
allow: ["other"],
},
},
},
}),
).toBeUndefined();
});
});