refactor: deduplicate shared helpers and test setup

This commit is contained in:
Peter Steinberger
2026-02-23 20:40:38 +00:00
parent 1f5e6444ee
commit 75423a00d6
33 changed files with 999 additions and 1112 deletions

View File

@@ -12,6 +12,26 @@ const fixtureRoot = path.join(os.tmpdir(), `openclaw-plugin-${randomUUID()}`);
let tempDirIndex = 0;
const prevBundledDir = process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
const EMPTY_PLUGIN_SCHEMA = { type: "object", additionalProperties: false, properties: {} };
const BUNDLED_TELEGRAM_PLUGIN_BODY = `export default { id: "telegram", register(api) {
api.registerChannel({
plugin: {
id: "telegram",
meta: {
id: "telegram",
label: "Telegram",
selectionLabel: "Telegram",
docsPath: "/channels/telegram",
blurb: "telegram channel"
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => [],
resolveAccount: () => ({ accountId: "default" })
},
outbound: { deliveryMode: "direct" }
}
});
} };`;
function makeTempDir() {
const dir = path.join(fixtureRoot, `case-${tempDirIndex++}`);
@@ -94,6 +114,23 @@ function loadBundledMemoryPluginRegistry(options?: {
});
}
function setupBundledTelegramPlugin() {
const bundledDir = makeTempDir();
writePlugin({
id: "telegram",
body: BUNDLED_TELEGRAM_PLUGIN_BODY,
dir: bundledDir,
filename: "telegram.js",
});
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir;
}
function expectTelegramLoaded(registry: ReturnType<typeof loadOpenClawPlugins>) {
const telegram = registry.plugins.find((entry) => entry.id === "telegram");
expect(telegram?.status).toBe("loaded");
expect(registry.channels.some((entry) => entry.plugin.id === "telegram")).toBe(true);
}
afterEach(() => {
if (prevBundledDir === undefined) {
delete process.env.OPENCLAW_BUNDLED_PLUGINS_DIR;
@@ -150,33 +187,7 @@ describe("loadOpenClawPlugins", () => {
});
it("loads bundled telegram plugin when enabled", () => {
const bundledDir = makeTempDir();
writePlugin({
id: "telegram",
body: `export default { id: "telegram", register(api) {
api.registerChannel({
plugin: {
id: "telegram",
meta: {
id: "telegram",
label: "Telegram",
selectionLabel: "Telegram",
docsPath: "/channels/telegram",
blurb: "telegram channel"
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => [],
resolveAccount: () => ({ accountId: "default" })
},
outbound: { deliveryMode: "direct" }
}
});
} };`,
dir: bundledDir,
filename: "telegram.js",
});
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir;
setupBundledTelegramPlugin();
const registry = loadOpenClawPlugins({
cache: false,
@@ -190,39 +201,11 @@ describe("loadOpenClawPlugins", () => {
},
});
const telegram = registry.plugins.find((entry) => entry.id === "telegram");
expect(telegram?.status).toBe("loaded");
expect(registry.channels.some((entry) => entry.plugin.id === "telegram")).toBe(true);
expectTelegramLoaded(registry);
});
it("loads bundled channel plugins when channels.<id>.enabled=true", () => {
const bundledDir = makeTempDir();
writePlugin({
id: "telegram",
body: `export default { id: "telegram", register(api) {
api.registerChannel({
plugin: {
id: "telegram",
meta: {
id: "telegram",
label: "Telegram",
selectionLabel: "Telegram",
docsPath: "/channels/telegram",
blurb: "telegram channel"
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => [],
resolveAccount: () => ({ accountId: "default" })
},
outbound: { deliveryMode: "direct" }
}
});
} };`,
dir: bundledDir,
filename: "telegram.js",
});
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir;
setupBundledTelegramPlugin();
const registry = loadOpenClawPlugins({
cache: false,
@@ -238,39 +221,11 @@ describe("loadOpenClawPlugins", () => {
},
});
const telegram = registry.plugins.find((entry) => entry.id === "telegram");
expect(telegram?.status).toBe("loaded");
expect(registry.channels.some((entry) => entry.plugin.id === "telegram")).toBe(true);
expectTelegramLoaded(registry);
});
it("still respects explicit disable via plugins.entries for bundled channels", () => {
const bundledDir = makeTempDir();
writePlugin({
id: "telegram",
body: `export default { id: "telegram", register(api) {
api.registerChannel({
plugin: {
id: "telegram",
meta: {
id: "telegram",
label: "Telegram",
selectionLabel: "Telegram",
docsPath: "/channels/telegram",
blurb: "telegram channel"
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => [],
resolveAccount: () => ({ accountId: "default" })
},
outbound: { deliveryMode: "direct" }
}
});
} };`,
dir: bundledDir,
filename: "telegram.js",
});
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir;
setupBundledTelegramPlugin();
const registry = loadOpenClawPlugins({
cache: false,

View File

@@ -52,6 +52,25 @@ function setRegistry(entries: MockRegistryToolEntry[]) {
return registry;
}
function setMultiToolRegistry() {
return setRegistry([
{
pluginId: "multi",
optional: false,
source: "/tmp/multi.js",
factory: () => [makeTool("message"), makeTool("other_tool")],
},
]);
}
function resolveWithConflictingCoreName(options?: { suppressNameConflicts?: boolean }) {
return resolvePluginTools({
context: createContext() as never,
existingToolNames: new Set(["message"]),
...(options?.suppressNameConflicts ? { suppressNameConflicts: true } : {}),
});
}
describe("resolvePluginTools optional tools", () => {
beforeEach(() => {
loadOpenClawPluginsMock.mockClear();
@@ -136,19 +155,8 @@ describe("resolvePluginTools optional tools", () => {
});
it("skips conflicting tool names but keeps other tools", () => {
const registry = setRegistry([
{
pluginId: "multi",
optional: false,
source: "/tmp/multi.js",
factory: () => [makeTool("message"), makeTool("other_tool")],
},
]);
const tools = resolvePluginTools({
context: createContext() as never,
existingToolNames: new Set(["message"]),
});
const registry = setMultiToolRegistry();
const tools = resolveWithConflictingCoreName();
expect(tools.map((tool) => tool.name)).toEqual(["other_tool"]);
expect(registry.diagnostics).toHaveLength(1);
@@ -156,20 +164,8 @@ describe("resolvePluginTools optional tools", () => {
});
it("suppresses conflict diagnostics when requested", () => {
const registry = setRegistry([
{
pluginId: "multi",
optional: false,
source: "/tmp/multi.js",
factory: () => [makeTool("message"), makeTool("other_tool")],
},
]);
const tools = resolvePluginTools({
context: createContext() as never,
existingToolNames: new Set(["message"]),
suppressNameConflicts: true,
});
const registry = setMultiToolRegistry();
const tools = resolveWithConflictingCoreName({ suppressNameConflicts: true });
expect(tools.map((tool) => tool.name)).toEqual(["other_tool"]);
expect(registry.diagnostics).toHaveLength(0);