refactor(test): reduce dispatch-from-config setup duplication

This commit is contained in:
Peter Steinberger
2026-02-16 18:09:49 +00:00
parent 74c49c943d
commit 5d40d47501

View File

@@ -57,6 +57,9 @@ vi.mock("../../plugins/hook-runner-global.js", () => ({
const { dispatchReplyFromConfig } = await import("./dispatch-from-config.js");
const { resetInboundDedupe } = await import("./inbound-dedupe.js");
const noAbortResult = { handled: false, aborted: false } as const;
const emptyConfig = {} as OpenClawConfig;
function createDispatcher(): ReplyDispatcher {
return {
sendToolResult: vi.fn(() => true),
@@ -68,6 +71,16 @@ function createDispatcher(): ReplyDispatcher {
};
}
function setNoAbort() {
mocks.tryFastAbortFromMessage.mockResolvedValue(noAbortResult);
}
function firstToolResultPayload(dispatcher: ReplyDispatcher): ReplyPayload | undefined {
return (dispatcher.sendToolResult as ReturnType<typeof vi.fn>).mock.calls[0]?.[0] as
| ReplyPayload
| undefined;
}
describe("dispatchReplyFromConfig", () => {
beforeEach(() => {
resetInboundDedupe();
@@ -79,12 +92,9 @@ describe("dispatchReplyFromConfig", () => {
hookMocks.runner.runMessageReceived.mockReset();
});
it("does not route when Provider matches OriginatingChannel (even if Surface is missing)", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
setNoAbort();
mocks.routeReply.mockClear();
const cfg = {} as OpenClawConfig;
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "slack",
@@ -105,12 +115,9 @@ describe("dispatchReplyFromConfig", () => {
});
it("routes when OriginatingChannel differs from Provider", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
setNoAbort();
mocks.routeReply.mockClear();
const cfg = {} as OpenClawConfig;
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "slack",
@@ -139,12 +146,9 @@ describe("dispatchReplyFromConfig", () => {
});
it("routes media-only tool results when summaries are suppressed", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
setNoAbort();
mocks.routeReply.mockClear();
const cfg = {} as OpenClawConfig;
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "slack",
@@ -178,12 +182,9 @@ describe("dispatchReplyFromConfig", () => {
});
it("provides onToolResult in DM sessions", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
setNoAbort();
mocks.routeReply.mockClear();
const cfg = {} as OpenClawConfig;
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "telegram",
@@ -205,11 +206,8 @@ describe("dispatchReplyFromConfig", () => {
});
it("suppresses group tool summaries but still forwards tool media", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
const cfg = {} as OpenClawConfig;
setNoAbort();
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "telegram",
@@ -233,20 +231,15 @@ describe("dispatchReplyFromConfig", () => {
await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
expect(dispatcher.sendToolResult).toHaveBeenCalledTimes(1);
const sent = (dispatcher.sendToolResult as ReturnType<typeof vi.fn>).mock.calls[0]?.[0] as
| ReplyPayload
| undefined;
const sent = firstToolResultPayload(dispatcher);
expect(sent?.mediaUrls).toEqual(["https://example.com/tts-group.opus"]);
expect(sent?.text).toBeUndefined();
expect(dispatcher.sendFinalReply).toHaveBeenCalledTimes(1);
});
it("sends tool results via dispatcher in DM sessions", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
const cfg = {} as OpenClawConfig;
setNoAbort();
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "telegram",
@@ -271,11 +264,8 @@ describe("dispatchReplyFromConfig", () => {
});
it("suppresses native tool summaries but still forwards tool media", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
const cfg = {} as OpenClawConfig;
setNoAbort();
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "telegram",
@@ -299,9 +289,7 @@ describe("dispatchReplyFromConfig", () => {
await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
expect(dispatcher.sendToolResult).toHaveBeenCalledTimes(1);
const sent = (dispatcher.sendToolResult as ReturnType<typeof vi.fn>).mock.calls[0]?.[0] as
| ReplyPayload
| undefined;
const sent = firstToolResultPayload(dispatcher);
expect(sent?.mediaUrl).toBe("https://example.com/tts-native.opus");
expect(sent?.text).toBeUndefined();
expect(dispatcher.sendFinalReply).toHaveBeenCalledTimes(1);
@@ -312,7 +300,7 @@ describe("dispatchReplyFromConfig", () => {
handled: true,
aborted: true,
});
const cfg = {} as OpenClawConfig;
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "telegram",
@@ -334,7 +322,7 @@ describe("dispatchReplyFromConfig", () => {
aborted: true,
stoppedSubagents: 2,
});
const cfg = {} as OpenClawConfig;
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "telegram",
@@ -354,11 +342,8 @@ describe("dispatchReplyFromConfig", () => {
});
it("deduplicates inbound messages by MessageSid and origin", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
const cfg = {} as OpenClawConfig;
setNoAbort();
const cfg = emptyConfig;
const ctx = buildTestCtx({
Provider: "whatsapp",
OriginatingChannel: "whatsapp",
@@ -384,12 +369,9 @@ describe("dispatchReplyFromConfig", () => {
});
it("emits message_received hook with originating channel metadata", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
setNoAbort();
hookMocks.runner.hasHooks.mockReturnValue(true);
const cfg = {} as OpenClawConfig;
const cfg = emptyConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
Provider: "slack",
@@ -435,10 +417,7 @@ describe("dispatchReplyFromConfig", () => {
});
it("emits diagnostics when enabled", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
setNoAbort();
const cfg = { diagnostics: { enabled: true } } as OpenClawConfig;
const dispatcher = createDispatcher();
const ctx = buildTestCtx({
@@ -468,10 +447,7 @@ describe("dispatchReplyFromConfig", () => {
});
it("marks diagnostics skipped for duplicate inbound messages", async () => {
mocks.tryFastAbortFromMessage.mockResolvedValue({
handled: false,
aborted: false,
});
setNoAbort();
const cfg = { diagnostics: { enabled: true } } as OpenClawConfig;
const ctx = buildTestCtx({
Provider: "whatsapp",