mirror of https://github.com/openclaw/openclaw.git
176 lines
5.2 KiB
TypeScript
176 lines
5.2 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { createHookRunner } from "./hooks.js";
|
|
import { createMockPluginRegistry } from "./hooks.test-helpers.js";
|
|
|
|
describe("inbound_claim hook runner", () => {
|
|
it("stops at the first handler that claims the event", async () => {
|
|
const first = vi.fn().mockResolvedValue({ handled: true });
|
|
const second = vi.fn().mockResolvedValue({ handled: true });
|
|
const registry = createMockPluginRegistry([
|
|
{ hookName: "inbound_claim", handler: first },
|
|
{ hookName: "inbound_claim", handler: second },
|
|
]);
|
|
const runner = createHookRunner(registry);
|
|
|
|
const result = await runner.runInboundClaim(
|
|
{
|
|
content: "who are you",
|
|
channel: "telegram",
|
|
accountId: "default",
|
|
conversationId: "123:topic:77",
|
|
isGroup: true,
|
|
},
|
|
{
|
|
channelId: "telegram",
|
|
accountId: "default",
|
|
conversationId: "123:topic:77",
|
|
},
|
|
);
|
|
|
|
expect(result).toEqual({ handled: true });
|
|
expect(first).toHaveBeenCalledTimes(1);
|
|
expect(second).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("continues to the next handler when a higher-priority handler throws", async () => {
|
|
const logger = {
|
|
warn: vi.fn(),
|
|
error: vi.fn(),
|
|
};
|
|
const failing = vi.fn().mockRejectedValue(new Error("boom"));
|
|
const succeeding = vi.fn().mockResolvedValue({ handled: true });
|
|
const registry = createMockPluginRegistry([
|
|
{ hookName: "inbound_claim", handler: failing },
|
|
{ hookName: "inbound_claim", handler: succeeding },
|
|
]);
|
|
const runner = createHookRunner(registry, { logger });
|
|
|
|
const result = await runner.runInboundClaim(
|
|
{
|
|
content: "hi",
|
|
channel: "telegram",
|
|
accountId: "default",
|
|
conversationId: "123",
|
|
isGroup: false,
|
|
},
|
|
{
|
|
channelId: "telegram",
|
|
accountId: "default",
|
|
conversationId: "123",
|
|
},
|
|
);
|
|
|
|
expect(result).toEqual({ handled: true });
|
|
expect(logger.error).toHaveBeenCalledWith(
|
|
expect.stringContaining("inbound_claim handler from test-plugin failed: Error: boom"),
|
|
);
|
|
expect(succeeding).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("can target a single plugin when core already owns the binding", async () => {
|
|
const first = vi.fn().mockResolvedValue({ handled: true });
|
|
const second = vi.fn().mockResolvedValue({ handled: true });
|
|
const registry = createMockPluginRegistry([
|
|
{ hookName: "inbound_claim", handler: first },
|
|
{ hookName: "inbound_claim", handler: second },
|
|
]);
|
|
registry.typedHooks[1].pluginId = "other-plugin";
|
|
const runner = createHookRunner(registry);
|
|
|
|
const result = await runner.runInboundClaimForPlugin(
|
|
"test-plugin",
|
|
{
|
|
content: "who are you",
|
|
channel: "discord",
|
|
accountId: "default",
|
|
conversationId: "channel:1",
|
|
isGroup: true,
|
|
},
|
|
{
|
|
channelId: "discord",
|
|
accountId: "default",
|
|
conversationId: "channel:1",
|
|
},
|
|
);
|
|
|
|
expect(result).toEqual({ handled: true });
|
|
expect(first).toHaveBeenCalledTimes(1);
|
|
expect(second).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("reports missing_plugin when the bound plugin is not loaded", async () => {
|
|
const registry = createMockPluginRegistry([]);
|
|
registry.plugins = [];
|
|
const runner = createHookRunner(registry);
|
|
|
|
const result = await runner.runInboundClaimForPluginOutcome(
|
|
"missing-plugin",
|
|
{
|
|
content: "who are you",
|
|
channel: "discord",
|
|
accountId: "default",
|
|
conversationId: "channel:1",
|
|
isGroup: true,
|
|
},
|
|
{
|
|
channelId: "discord",
|
|
accountId: "default",
|
|
conversationId: "channel:1",
|
|
},
|
|
);
|
|
|
|
expect(result).toEqual({ status: "missing_plugin" });
|
|
});
|
|
|
|
it("reports no_handler when the plugin is loaded but has no targeted hooks", async () => {
|
|
const registry = createMockPluginRegistry([]);
|
|
const runner = createHookRunner(registry);
|
|
|
|
const result = await runner.runInboundClaimForPluginOutcome(
|
|
"test-plugin",
|
|
{
|
|
content: "who are you",
|
|
channel: "discord",
|
|
accountId: "default",
|
|
conversationId: "channel:1",
|
|
isGroup: true,
|
|
},
|
|
{
|
|
channelId: "discord",
|
|
accountId: "default",
|
|
conversationId: "channel:1",
|
|
},
|
|
);
|
|
|
|
expect(result).toEqual({ status: "no_handler" });
|
|
});
|
|
|
|
it("reports error when a targeted handler throws and none claim the event", async () => {
|
|
const logger = {
|
|
warn: vi.fn(),
|
|
error: vi.fn(),
|
|
};
|
|
const failing = vi.fn().mockRejectedValue(new Error("boom"));
|
|
const registry = createMockPluginRegistry([{ hookName: "inbound_claim", handler: failing }]);
|
|
const runner = createHookRunner(registry, { logger });
|
|
|
|
const result = await runner.runInboundClaimForPluginOutcome(
|
|
"test-plugin",
|
|
{
|
|
content: "who are you",
|
|
channel: "discord",
|
|
accountId: "default",
|
|
conversationId: "channel:1",
|
|
isGroup: true,
|
|
},
|
|
{
|
|
channelId: "discord",
|
|
accountId: "default",
|
|
conversationId: "channel:1",
|
|
},
|
|
);
|
|
|
|
expect(result).toEqual({ status: "error", error: "boom" });
|
|
});
|
|
});
|