test: mock durable channel send seam

This commit is contained in:
Peter Steinberger
2026-05-09 07:39:33 +01:00
parent 281f04e866
commit 3a8cfdf652

View File

@@ -16,6 +16,7 @@ import {
const deliverOutboundPayloads = vi.hoisted(() => vi.fn());
const resolveOutboundDurableFinalDeliverySupport = vi.hoisted(() => vi.fn());
const sendDurableMessageBatch = vi.hoisted(() => vi.fn());
vi.mock("../../infra/outbound/deliver.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../../infra/outbound/deliver.js")>();
@@ -26,6 +27,14 @@ vi.mock("../../infra/outbound/deliver.js", async (importOriginal) => {
};
});
vi.mock("../message/send.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../message/send.js")>();
return {
...actual,
sendDurableMessageBatch,
};
});
const cfg = {} as OpenClawConfig;
function createCtx(overrides: Partial<FinalizedMsgContext> = {}): FinalizedMsgContext {
@@ -62,6 +71,18 @@ function createDispatch(
}) as DispatchReplyWithBufferedBlockDispatcher;
}
function createDurableSendResult(messageIds: string[]) {
return {
status: "sent",
results: messageIds.map((messageId) => ({ messageId })),
receipt: {
platformMessageIds: messageIds,
parts: [],
sentAt: 1,
},
};
}
describe("channel turn kernel", () => {
beforeEach(() => {
vi.clearAllMocks();
@@ -69,7 +90,7 @@ describe("channel turn kernel", () => {
});
it("routes assembled final replies through durable outbound delivery", async () => {
deliverOutboundPayloads.mockResolvedValueOnce([{ messageId: "tg-1" }]);
sendDurableMessageBatch.mockResolvedValueOnce(createDurableSendResult(["tg-1"]));
const deliver = vi.fn();
const recordInboundSession = createRecordInboundSession();
const dispatchReplyWithBufferedBlockDispatcher = createDispatch();
@@ -96,13 +117,13 @@ describe("channel turn kernel", () => {
expect(result.dispatched).toBe(true);
expect(deliver).not.toHaveBeenCalled();
expect(deliverOutboundPayloads).toHaveBeenCalledWith(
expect(sendDurableMessageBatch).toHaveBeenCalledWith(
expect.objectContaining({
channel: "telegram",
to: "123",
accountId: "acct",
payloads: [expect.objectContaining({ text: "reply" })],
queuePolicy: "best_effort",
durability: "best_effort",
replyToMode: "first",
threadId: 777,
session: expect.objectContaining({
@@ -127,7 +148,7 @@ describe("channel turn kernel", () => {
});
it("returns durable delivery result to the buffered dispatcher", async () => {
deliverOutboundPayloads.mockResolvedValueOnce([{ messageId: "tg-1" }, { messageId: "tg-2" }]);
sendDurableMessageBatch.mockResolvedValueOnce(createDurableSendResult(["tg-1", "tg-2"]));
let deliveredResult: unknown;
const dispatchReplyWithBufferedBlockDispatcher = vi.fn(
async (params: Parameters<DispatchReplyWithBufferedBlockDispatcher>[0]) => {
@@ -167,7 +188,7 @@ describe("channel turn kernel", () => {
});
it("prepares payloads before durable enqueue and observes handled delivery", async () => {
deliverOutboundPayloads.mockResolvedValueOnce([{ messageId: "tlon-1" }]);
sendDurableMessageBatch.mockResolvedValueOnce(createDurableSendResult(["tlon-1"]));
const onDelivered = vi.fn();
const dispatchReplyWithBufferedBlockDispatcher = createDispatch();
@@ -195,7 +216,7 @@ describe("channel turn kernel", () => {
},
});
expect(deliverOutboundPayloads).toHaveBeenCalledWith(
expect(sendDurableMessageBatch).toHaveBeenCalledWith(
expect.objectContaining({
payloads: [expect.objectContaining({ text: "reply\n\n_[Generated by test]_" })],
}),