From 3e6c8376fb636076b5b82331b4406c1216833ef6 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 13 Mar 2026 21:19:15 +0000 Subject: [PATCH] test: tighten outbound send service coverage --- .../outbound/outbound-send-service.test.ts | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/src/infra/outbound/outbound-send-service.test.ts b/src/infra/outbound/outbound-send-service.test.ts index 68c956d93fc..391abee8dda 100644 --- a/src/infra/outbound/outbound-send-service.test.ts +++ b/src/infra/outbound/outbound-send-service.test.ts @@ -156,6 +156,78 @@ describe("executeSendAction", () => { ); }); + it("falls back to message and media params for plugin-handled mirror writes", async () => { + mocks.dispatchChannelMessageAction.mockResolvedValue(pluginActionResult("msg-plugin")); + + await executeSendAction({ + ctx: { + cfg: {}, + channel: "discord", + params: { to: "channel:123", message: "hello" }, + dryRun: false, + mirror: { + sessionKey: "agent:main:discord:channel:123", + agentId: "agent-9", + }, + }, + to: "channel:123", + message: "hello", + mediaUrls: ["https://example.com/a.png", "https://example.com/b.png"], + }); + + expect(mocks.appendAssistantMessageToSessionTranscript).toHaveBeenCalledWith( + expect.objectContaining({ + agentId: "agent-9", + sessionKey: "agent:main:discord:channel:123", + text: "hello", + mediaUrls: ["https://example.com/a.png", "https://example.com/b.png"], + }), + ); + }); + + it("skips plugin dispatch during dry-run sends and forwards gateway + silent to sendMessage", async () => { + mocks.sendMessage.mockResolvedValue({ + channel: "discord", + to: "channel:123", + via: "gateway", + mediaUrl: null, + }); + + await executeSendAction({ + ctx: { + cfg: {}, + channel: "discord", + params: { to: "channel:123", message: "hello" }, + dryRun: true, + silent: true, + gateway: { + url: "http://127.0.0.1:18789", + token: "tok", + timeoutMs: 5000, + clientName: "gateway", + mode: "gateway", + }, + }, + to: "channel:123", + message: "hello", + }); + + expect(mocks.dispatchChannelMessageAction).not.toHaveBeenCalled(); + expect(mocks.sendMessage).toHaveBeenCalledWith( + expect.objectContaining({ + to: "channel:123", + content: "hello", + dryRun: true, + silent: true, + gateway: expect.objectContaining({ + url: "http://127.0.0.1:18789", + token: "tok", + timeoutMs: 5000, + }), + }), + ); + }); + it("forwards poll args to sendPoll on core outbound path", async () => { mocks.dispatchChannelMessageAction.mockResolvedValue(null); mocks.sendPoll.mockResolvedValue({ @@ -200,4 +272,55 @@ describe("executeSendAction", () => { }), ); }); + + it("skips plugin dispatch during dry-run polls and forwards durationHours + silent", async () => { + mocks.sendPoll.mockResolvedValue({ + channel: "discord", + to: "channel:123", + question: "Lunch?", + options: ["Pizza", "Sushi"], + maxSelections: 1, + durationSeconds: null, + durationHours: 6, + via: "gateway", + }); + + await executePollAction({ + ctx: { + cfg: {}, + channel: "discord", + params: {}, + dryRun: true, + silent: true, + gateway: { + url: "http://127.0.0.1:18789", + token: "tok", + timeoutMs: 5000, + clientName: "gateway", + mode: "gateway", + }, + }, + to: "channel:123", + question: "Lunch?", + options: ["Pizza", "Sushi"], + maxSelections: 1, + durationHours: 6, + }); + + expect(mocks.dispatchChannelMessageAction).not.toHaveBeenCalled(); + expect(mocks.sendPoll).toHaveBeenCalledWith( + expect.objectContaining({ + to: "channel:123", + question: "Lunch?", + durationHours: 6, + dryRun: true, + silent: true, + gateway: expect.objectContaining({ + url: "http://127.0.0.1:18789", + token: "tok", + timeoutMs: 5000, + }), + }), + ); + }); });