Files
openclaw/src/config/plugin-auto-enable.prefer-over.test.ts
2026-05-02 03:34:17 +01:00

122 lines
3.6 KiB
TypeScript

import fs from "node:fs";
import path from "node:path";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { PluginManifestRegistry } from "../plugins/manifest-registry.js";
import { cleanupTrackedTempDirs } from "../plugins/test-helpers/fs-fixtures.js";
vi.mock("../plugins/bundled-dir.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../plugins/bundled-dir.js")>();
return {
...actual,
resolveBundledPluginsDir: (env: NodeJS.ProcessEnv = process.env) =>
env.OPENCLAW_BUNDLED_PLUGINS_DIR,
};
});
const tempDirs: string[] = [];
function makeTempDir(): string {
const trustedRoot = path.resolve("dist-runtime", "extensions");
fs.mkdirSync(trustedRoot, { recursive: true });
const dir = fs.mkdtempSync(path.join(trustedRoot, ".openclaw-plugin-prefer-over-"));
tempDirs.push(dir);
return dir;
}
function writeBundledChannelPackage(rootDir: string, channelId: string): void {
const pluginDir = path.join(rootDir, channelId);
fs.mkdirSync(pluginDir, { recursive: true });
fs.writeFileSync(
path.join(pluginDir, "package.json"),
JSON.stringify({
openclaw: {
channel: {
id: channelId,
label: "Cache Drift",
selectionLabel: "Cache Drift",
docsPath: `/channels/${channelId}`,
blurb: "Cache drift fixture",
},
},
}),
"utf-8",
);
fs.writeFileSync(
path.join(pluginDir, "openclaw.plugin.json"),
JSON.stringify({
id: channelId,
configSchema: { type: "object" },
channels: [channelId],
}),
"utf-8",
);
fs.writeFileSync(
path.join(pluginDir, "index.js"),
"export default { register() {} };\n",
"utf-8",
);
}
const EMPTY_MANIFEST_REGISTRY: PluginManifestRegistry = {
plugins: [],
diagnostics: [],
};
async function setBundledPluginsDirFixture(dir: string | undefined): Promise<void> {
const { setBundledPluginsDirOverrideForTest } = await import("../plugins/bundled-dir.js");
setBundledPluginsDirOverrideForTest(dir);
}
afterEach(async () => {
await setBundledPluginsDirFixture(undefined);
vi.unstubAllEnvs();
vi.resetModules();
cleanupTrackedTempDirs(tempDirs);
});
describe("plugin auto-enable preferOver", () => {
it("tolerates bundled channel id metadata drift during auto-enable", async () => {
vi.resetModules();
const rootDir = makeTempDir();
const channelId = "cache-drift-channel";
writeBundledChannelPackage(rootDir, channelId);
vi.stubEnv("OPENCLAW_BUNDLED_PLUGINS_DIR", rootDir);
await setBundledPluginsDirFixture(rootDir);
const { normalizeChatChannelId } = await import("../channels/ids.js");
expect(normalizeChatChannelId(channelId)).toBe(channelId);
vi.stubEnv("OPENCLAW_BUNDLED_PLUGINS_DIR", path.join(rootDir, "missing"));
await setBundledPluginsDirFixture(undefined);
const { materializePluginAutoEnableCandidates } = await import("./plugin-auto-enable.js");
const result = materializePluginAutoEnableCandidates({
config: {
channels: {
[channelId]: { token: "configured" },
fallback: { token: "configured" },
},
},
candidates: [
{
pluginId: channelId,
kind: "channel-configured",
channelId,
},
{
pluginId: "fallback",
kind: "channel-configured",
channelId: "fallback",
},
],
env: {
OPENCLAW_STATE_DIR: path.join(rootDir, "state"),
OPENCLAW_BUNDLED_PLUGINS_DIR: path.join(rootDir, "missing"),
},
manifestRegistry: EMPTY_MANIFEST_REGISTRY,
});
expect(result.config.channels?.[channelId]?.enabled).toBe(true);
});
});