diff --git a/src/cli/program/message/helpers.test.ts b/src/cli/program/message/helpers.test.ts index 9ade2278a9..67b716cd35 100644 --- a/src/cli/program/message/helpers.test.ts +++ b/src/cli/program/message/helpers.test.ts @@ -53,6 +53,22 @@ vi.mock("../../deps.js", () => ({ const { createMessageCliHelpers } = await import("./helpers.js"); +const baseSendOptions = { + channel: "discord", + target: "123", + message: "hi", +}; + +function createRunMessageAction() { + const fakeCommand = { help: vi.fn() } as never; + return createMessageCliHelpers(fakeCommand, "discord").runMessageAction; +} + +async function runSendAction(opts: Record = {}) { + const runMessageAction = createRunMessageAction(); + await expect(runMessageAction("send", { ...baseSendOptions, ...opts })).rejects.toThrow("exit"); +} + describe("runMessageAction", () => { beforeEach(() => { vi.clearAllMocks(); @@ -66,12 +82,7 @@ describe("runMessageAction", () => { }); it("calls exit(0) after successful message delivery", async () => { - const fakeCommand = { help: vi.fn() } as never; - const { runMessageAction } = createMessageCliHelpers(fakeCommand, "discord"); - - await expect( - runMessageAction("send", { channel: "discord", target: "123", message: "hi" }), - ).rejects.toThrow("exit"); + await runSendAction(); expect(exitMock).toHaveBeenCalledOnce(); expect(exitMock).toHaveBeenCalledWith(0); @@ -79,12 +90,7 @@ describe("runMessageAction", () => { it("runs gateway_stop hooks before exit when registered", async () => { hasHooksMock.mockReturnValueOnce(true); - const fakeCommand = { help: vi.fn() } as never; - const { runMessageAction } = createMessageCliHelpers(fakeCommand, "discord"); - - await expect( - runMessageAction("send", { channel: "discord", target: "123", message: "hi" }), - ).rejects.toThrow("exit"); + await runSendAction(); expect(runGatewayStopMock).toHaveBeenCalledWith({ reason: "cli message action complete" }, {}); expect(exitMock).toHaveBeenCalledWith(0); @@ -92,12 +98,7 @@ describe("runMessageAction", () => { it("calls exit(1) when message delivery fails", async () => { messageCommandMock.mockRejectedValueOnce(new Error("send failed")); - const fakeCommand = { help: vi.fn() } as never; - const { runMessageAction } = createMessageCliHelpers(fakeCommand, "discord"); - - await expect( - runMessageAction("send", { channel: "discord", target: "123", message: "hi" }), - ).rejects.toThrow("exit"); + await runSendAction(); expect(errorMock).toHaveBeenCalledWith("Error: send failed"); expect(exitMock).toHaveBeenCalledOnce(); @@ -107,12 +108,7 @@ describe("runMessageAction", () => { it("runs gateway_stop hooks on failure before exit(1)", async () => { hasHooksMock.mockReturnValueOnce(true); messageCommandMock.mockRejectedValueOnce(new Error("send failed")); - const fakeCommand = { help: vi.fn() } as never; - const { runMessageAction } = createMessageCliHelpers(fakeCommand, "discord"); - - await expect( - runMessageAction("send", { channel: "discord", target: "123", message: "hi" }), - ).rejects.toThrow("exit"); + await runSendAction(); expect(runGatewayStopMock).toHaveBeenCalledWith({ reason: "cli message action complete" }, {}); expect(exitMock).toHaveBeenCalledWith(1); @@ -121,12 +117,7 @@ describe("runMessageAction", () => { it("logs gateway_stop failure and still exits with success code", async () => { hasHooksMock.mockReturnValueOnce(true); runGatewayStopMock.mockRejectedValueOnce(new Error("hook failed")); - const fakeCommand = { help: vi.fn() } as never; - const { runMessageAction } = createMessageCliHelpers(fakeCommand, "discord"); - - await expect( - runMessageAction("send", { channel: "discord", target: "123", message: "hi" }), - ).rejects.toThrow("exit"); + await runSendAction(); expect(errorMock).toHaveBeenCalledWith("gateway_stop hook failed: Error: hook failed"); expect(exitMock).toHaveBeenCalledWith(0); @@ -136,12 +127,7 @@ describe("runMessageAction", () => { hasHooksMock.mockReturnValueOnce(true); messageCommandMock.mockRejectedValueOnce(new Error("send failed")); runGatewayStopMock.mockRejectedValueOnce(new Error("hook failed")); - const fakeCommand = { help: vi.fn() } as never; - const { runMessageAction } = createMessageCliHelpers(fakeCommand, "discord"); - - await expect( - runMessageAction("send", { channel: "discord", target: "123", message: "hi" }), - ).rejects.toThrow("exit"); + await runSendAction(); expect(errorMock).toHaveBeenNthCalledWith(1, "Error: send failed"); expect(errorMock).toHaveBeenNthCalledWith(2, "gateway_stop hook failed: Error: hook failed"); @@ -150,12 +136,7 @@ describe("runMessageAction", () => { it("does not call exit(0) when the action throws", async () => { messageCommandMock.mockRejectedValueOnce(new Error("boom")); - const fakeCommand = { help: vi.fn() } as never; - const { runMessageAction } = createMessageCliHelpers(fakeCommand, "discord"); - - await expect( - runMessageAction("send", { channel: "discord", target: "123", message: "hi" }), - ).rejects.toThrow("exit"); + await runSendAction(); // exit should only be called once with code 1, never with 0 expect(exitMock).toHaveBeenCalledOnce(); @@ -165,12 +146,8 @@ describe("runMessageAction", () => { it("does not call exit(0) if the error path returns", async () => { messageCommandMock.mockRejectedValueOnce(new Error("boom")); exitMock.mockReset().mockImplementation(() => undefined as never); - const fakeCommand = { help: vi.fn() } as never; - const { runMessageAction } = createMessageCliHelpers(fakeCommand, "discord"); - - await expect( - runMessageAction("send", { channel: "discord", target: "123", message: "hi" }), - ).resolves.toBeUndefined(); + const runMessageAction = createRunMessageAction(); + await expect(runMessageAction("send", baseSendOptions)).resolves.toBeUndefined(); expect(errorMock).toHaveBeenCalledWith("Error: boom"); expect(exitMock).toHaveBeenCalledOnce(); @@ -212,4 +189,36 @@ describe("runMessageAction", () => { } expect(passedOpts).not.toHaveProperty("account"); }); + + it("strips non-string account values instead of passing accountId", async () => { + const runMessageAction = createRunMessageAction(); + + await expect( + runMessageAction("send", { + channel: "discord", + target: "789", + account: 42, + message: "hi", + }), + ).rejects.toThrow("exit"); + + expect(messageCommandMock).toHaveBeenCalledWith( + expect.objectContaining({ + action: "send", + channel: "discord", + target: "789", + accountId: undefined, + }), + expect.anything(), + expect.anything(), + ); + const passedOpts = ( + messageCommandMock.mock.calls as unknown as Array<[Record]> + )?.[0]?.[0]; + expect(passedOpts).toBeTruthy(); + if (!passedOpts) { + throw new Error("expected message command call"); + } + expect(passedOpts).not.toHaveProperty("account"); + }); });