mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-19 05:14:46 +00:00
test: clear agent command delivery broad matchers
This commit is contained in:
@@ -105,6 +105,49 @@ function latestOutboundDeliveryArgs(): {
|
||||
return args as { payloads: ReplyPayload[]; bestEffort?: boolean; queuePolicy?: string };
|
||||
}
|
||||
|
||||
type DeliveryStatusLike = {
|
||||
requested?: unknown;
|
||||
attempted?: unknown;
|
||||
status?: unknown;
|
||||
succeeded?: unknown;
|
||||
reason?: unknown;
|
||||
error?: unknown;
|
||||
errorMessage?: unknown;
|
||||
resultCount?: unknown;
|
||||
sentBeforeError?: unknown;
|
||||
payloadOutcomes?: Array<Record<string, unknown>>;
|
||||
};
|
||||
|
||||
function deliveryStatus(delivered: { deliveryStatus?: unknown }): DeliveryStatusLike {
|
||||
return (delivered.deliveryStatus ?? {}) as DeliveryStatusLike;
|
||||
}
|
||||
|
||||
function expectDeliveryStatusFields(
|
||||
delivered: { deliveryStatus?: unknown },
|
||||
expected: Record<string, unknown>,
|
||||
) {
|
||||
const status = deliveryStatus(delivered);
|
||||
for (const [key, value] of Object.entries(expected)) {
|
||||
expect(status[key as keyof DeliveryStatusLike], key).toEqual(value);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
function expectRuntimeErrorIncludes(
|
||||
runtime: { error: { mock: { calls: Array<Array<unknown>> } } },
|
||||
text: string,
|
||||
) {
|
||||
expect(runtime.error.mock.calls.some(([message]) => String(message).includes(text))).toBe(true);
|
||||
}
|
||||
|
||||
function latestJsonOutput(runtime: { writeJson: { mock: { calls: Array<Array<unknown>> } } }) {
|
||||
const output = runtime.writeJson.mock.calls.at(-1)?.[0];
|
||||
if (!output || typeof output !== "object") {
|
||||
throw new Error("expected JSON output");
|
||||
}
|
||||
return output as { deliveryStatus?: DeliveryStatusLike };
|
||||
}
|
||||
|
||||
async function deliverMediaReplyForTest(
|
||||
outboundSession: DeliverParams["outboundSession"],
|
||||
optsOverrides: Partial<AgentCommandOpts> = {},
|
||||
@@ -267,7 +310,7 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
} as never);
|
||||
|
||||
expect(delivered.deliverySucceeded).toBe(true);
|
||||
expect(delivered.deliveryStatus).toMatchObject({
|
||||
expectDeliveryStatusFields(delivered, {
|
||||
requested: true,
|
||||
attempted: true,
|
||||
status: "suppressed",
|
||||
@@ -336,14 +379,14 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
});
|
||||
|
||||
expect(delivered.deliverySucceeded).toBe(false);
|
||||
expect(delivered.deliveryStatus).toMatchObject({
|
||||
expectDeliveryStatusFields(delivered, {
|
||||
requested: true,
|
||||
attempted: true,
|
||||
status: "failed",
|
||||
succeeded: false,
|
||||
error: true,
|
||||
});
|
||||
expect(runtime.error).toHaveBeenCalledWith(expect.stringContaining("send failed"));
|
||||
expectRuntimeErrorIncludes(runtime, "send failed");
|
||||
const deliverArgs = latestOutboundDeliveryArgs();
|
||||
expect(deliverArgs.bestEffort).toBe(true);
|
||||
expect(deliverArgs.queuePolicy).toBe("best_effort");
|
||||
@@ -471,18 +514,14 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
});
|
||||
|
||||
expect(runtime.writeJson).toHaveBeenCalledTimes(1);
|
||||
expect(runtime.writeJson).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
deliveryStatus: {
|
||||
requested: true,
|
||||
attempted: true,
|
||||
status: "sent",
|
||||
succeeded: true,
|
||||
resultCount: 1,
|
||||
},
|
||||
}),
|
||||
2,
|
||||
);
|
||||
const json = latestJsonOutput(runtime);
|
||||
expect(json.deliveryStatus).toEqual({
|
||||
requested: true,
|
||||
attempted: true,
|
||||
status: "sent",
|
||||
succeeded: true,
|
||||
resultCount: 1,
|
||||
});
|
||||
expect(delivered.deliverySucceeded).toBe(true);
|
||||
expect(delivered.deliveryStatus?.status).toBe("sent");
|
||||
});
|
||||
@@ -513,21 +552,21 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
} as never);
|
||||
|
||||
expect(delivered.deliverySucceeded).toBe(true);
|
||||
expect(delivered.deliveryStatus).toMatchObject({
|
||||
const status = expectDeliveryStatusFields(delivered, {
|
||||
requested: true,
|
||||
attempted: true,
|
||||
status: "suppressed",
|
||||
succeeded: true,
|
||||
reason: "cancelled_by_message_sending_hook",
|
||||
payloadOutcomes: [
|
||||
{
|
||||
index: 0,
|
||||
status: "suppressed",
|
||||
reason: "cancelled_by_message_sending_hook",
|
||||
hookEffect: { cancelReason: "owned-by-other-agent" },
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(status.payloadOutcomes).toEqual([
|
||||
{
|
||||
index: 0,
|
||||
status: "suppressed",
|
||||
reason: "cancelled_by_message_sending_hook",
|
||||
hookEffect: { cancelReason: "owned-by-other-agent" },
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("surfaces durable partial failures without clearing delivery retry state", async () => {
|
||||
@@ -561,25 +600,23 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
);
|
||||
|
||||
expect(delivered.deliverySucceeded).toBe(false);
|
||||
expect(delivered.deliveryStatus).toMatchObject({
|
||||
const status = expectDeliveryStatusFields(delivered, {
|
||||
requested: true,
|
||||
attempted: true,
|
||||
status: "partial_failed",
|
||||
succeeded: "partial",
|
||||
error: true,
|
||||
errorMessage: expect.stringContaining("second chunk failed"),
|
||||
resultCount: 1,
|
||||
sentBeforeError: true,
|
||||
payloadOutcomes: [
|
||||
{
|
||||
index: 1,
|
||||
status: "failed",
|
||||
error: expect.stringContaining("second chunk failed"),
|
||||
sentBeforeError: true,
|
||||
stage: "platform_send",
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(String(status.errorMessage)).toContain("second chunk failed");
|
||||
expect(status.payloadOutcomes).toHaveLength(1);
|
||||
const outcome = status.payloadOutcomes?.[0];
|
||||
expect(outcome?.index).toBe(1);
|
||||
expect(outcome?.status).toBe("failed");
|
||||
expect(String(outcome?.error)).toContain("second chunk failed");
|
||||
expect(outcome?.sentBeforeError).toBe(true);
|
||||
expect(outcome?.stage).toBe("platform_send");
|
||||
});
|
||||
|
||||
it("marks no-payload deliveryStatus as terminal delivery success", async () => {
|
||||
@@ -600,7 +637,7 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
});
|
||||
|
||||
expect(delivered.deliverySucceeded).toBe(true);
|
||||
expect(delivered.deliveryStatus).toMatchObject({
|
||||
expectDeliveryStatusFields(delivered, {
|
||||
requested: true,
|
||||
attempted: false,
|
||||
status: "suppressed",
|
||||
@@ -629,7 +666,7 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
|
||||
expect(delivered.payloads).toEqual([]);
|
||||
expect(delivered.deliverySucceeded).toBe(true);
|
||||
expect(delivered.deliveryStatus).toMatchObject({
|
||||
expectDeliveryStatusFields(delivered, {
|
||||
requested: true,
|
||||
attempted: false,
|
||||
status: "suppressed",
|
||||
@@ -660,7 +697,7 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
});
|
||||
|
||||
expect(delivered.deliverySucceeded).toBeUndefined();
|
||||
expect(delivered.deliveryStatus).toMatchObject({
|
||||
expectDeliveryStatusFields(delivered, {
|
||||
requested: true,
|
||||
attempted: false,
|
||||
status: "failed",
|
||||
@@ -668,7 +705,7 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
error: true,
|
||||
reason: "unknown_channel",
|
||||
});
|
||||
expect(runtime.error).toHaveBeenCalledWith(expect.stringContaining("Unknown channel"));
|
||||
expectRuntimeErrorIncludes(runtime, "Unknown channel");
|
||||
expect(deliverOutboundPayloadsMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -709,19 +746,13 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
).rejects.toThrow("Slack API timeout");
|
||||
|
||||
expect(runtime.writeJson).toHaveBeenCalledTimes(1);
|
||||
expect(runtime.writeJson).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
deliveryStatus: {
|
||||
requested: true,
|
||||
attempted: true,
|
||||
status: "failed",
|
||||
succeeded: false,
|
||||
error: true,
|
||||
errorMessage: expect.stringContaining("Slack API timeout"),
|
||||
},
|
||||
}),
|
||||
2,
|
||||
);
|
||||
const json = latestJsonOutput(runtime);
|
||||
expect(json.deliveryStatus?.requested).toBe(true);
|
||||
expect(json.deliveryStatus?.attempted).toBe(true);
|
||||
expect(json.deliveryStatus?.status).toBe("failed");
|
||||
expect(json.deliveryStatus?.succeeded).toBe(false);
|
||||
expect(json.deliveryStatus?.error).toBe(true);
|
||||
expect(String(json.deliveryStatus?.errorMessage)).toContain("Slack API timeout");
|
||||
});
|
||||
|
||||
it("emits JSON deliveryStatus before strict preflight failures rethrow", async () => {
|
||||
@@ -763,18 +794,14 @@ describe("normalizeAgentCommandReplyPayloads", () => {
|
||||
expect(deliverOutboundPayloadsMock).not.toHaveBeenCalled();
|
||||
expect(createReplyMediaPathNormalizerMock).not.toHaveBeenCalled();
|
||||
expect(runtime.writeJson).toHaveBeenCalledTimes(1);
|
||||
expect(runtime.writeJson).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
deliveryStatus: {
|
||||
requested: true,
|
||||
attempted: false,
|
||||
status: "failed",
|
||||
succeeded: false,
|
||||
error: true,
|
||||
reason: "unknown_channel",
|
||||
},
|
||||
}),
|
||||
2,
|
||||
);
|
||||
const json = latestJsonOutput(runtime);
|
||||
expect(json.deliveryStatus).toEqual({
|
||||
requested: true,
|
||||
attempted: false,
|
||||
status: "failed",
|
||||
succeeded: false,
|
||||
error: true,
|
||||
reason: "unknown_channel",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user