mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-17 04:50:51 +00:00
Plugins: fail fast on channel and binding collisions (#45628)
* Plugins: reject duplicate channel ids * Bindings: reject duplicate adapter registration * Plugins: fail on export id mismatch
This commit is contained in:
@@ -825,6 +825,37 @@ describe("loadOpenClawPlugins", () => {
|
||||
expect(registry.diagnostics.some((d) => d.level === "error")).toBe(true);
|
||||
});
|
||||
|
||||
it("fails when plugin export id mismatches manifest id", () => {
|
||||
useNoBundledPlugins();
|
||||
const plugin = writePlugin({
|
||||
id: "manifest-id",
|
||||
filename: "manifest-id.cjs",
|
||||
body: `module.exports = { id: "export-id", register() {} };`,
|
||||
});
|
||||
|
||||
const registry = loadRegistryFromSinglePlugin({
|
||||
plugin,
|
||||
pluginConfig: {
|
||||
allow: ["manifest-id"],
|
||||
},
|
||||
});
|
||||
|
||||
const loaded = registry.plugins.find((entry) => entry.id === "manifest-id");
|
||||
expect(loaded?.status).toBe("error");
|
||||
expect(loaded?.error).toBe(
|
||||
'plugin id mismatch (config uses "manifest-id", export uses "export-id")',
|
||||
);
|
||||
expect(
|
||||
registry.diagnostics.some(
|
||||
(entry) =>
|
||||
entry.level === "error" &&
|
||||
entry.pluginId === "manifest-id" &&
|
||||
entry.message ===
|
||||
'plugin id mismatch (config uses "manifest-id", export uses "export-id")',
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("registers channel plugins", () => {
|
||||
useNoBundledPlugins();
|
||||
const plugin = writePlugin({
|
||||
@@ -863,6 +894,69 @@ describe("loadOpenClawPlugins", () => {
|
||||
expect(channel).toBeDefined();
|
||||
});
|
||||
|
||||
it("rejects duplicate channel ids during plugin registration", () => {
|
||||
useNoBundledPlugins();
|
||||
const plugin = writePlugin({
|
||||
id: "channel-dup",
|
||||
filename: "channel-dup.cjs",
|
||||
body: `module.exports = { id: "channel-dup", register(api) {
|
||||
api.registerChannel({
|
||||
plugin: {
|
||||
id: "demo",
|
||||
meta: {
|
||||
id: "demo",
|
||||
label: "Demo Override",
|
||||
selectionLabel: "Demo Override",
|
||||
docsPath: "/channels/demo-override",
|
||||
blurb: "override"
|
||||
},
|
||||
capabilities: { chatTypes: ["direct"] },
|
||||
config: {
|
||||
listAccountIds: () => [],
|
||||
resolveAccount: () => ({ accountId: "default" })
|
||||
},
|
||||
outbound: { deliveryMode: "direct" }
|
||||
}
|
||||
});
|
||||
api.registerChannel({
|
||||
plugin: {
|
||||
id: "demo",
|
||||
meta: {
|
||||
id: "demo",
|
||||
label: "Demo Duplicate",
|
||||
selectionLabel: "Demo Duplicate",
|
||||
docsPath: "/channels/demo-duplicate",
|
||||
blurb: "duplicate"
|
||||
},
|
||||
capabilities: { chatTypes: ["direct"] },
|
||||
config: {
|
||||
listAccountIds: () => [],
|
||||
resolveAccount: () => ({ accountId: "default" })
|
||||
},
|
||||
outbound: { deliveryMode: "direct" }
|
||||
}
|
||||
});
|
||||
} };`,
|
||||
});
|
||||
|
||||
const registry = loadRegistryFromSinglePlugin({
|
||||
plugin,
|
||||
pluginConfig: {
|
||||
allow: ["channel-dup"],
|
||||
},
|
||||
});
|
||||
|
||||
expect(registry.channels.filter((entry) => entry.plugin.id === "demo")).toHaveLength(1);
|
||||
expect(
|
||||
registry.diagnostics.some(
|
||||
(entry) =>
|
||||
entry.level === "error" &&
|
||||
entry.pluginId === "channel-dup" &&
|
||||
entry.message === "channel already registered: demo (channel-dup)",
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("registers http routes with auth and match options", () => {
|
||||
useNoBundledPlugins();
|
||||
const plugin = writePlugin({
|
||||
|
||||
Reference in New Issue
Block a user