openclaw/extensions/feishu/src/send.reply-fallback.test.ts

106 lines
2.7 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
const resolveFeishuSendTargetMock = vi.hoisted(() => vi.fn());
const resolveMarkdownTableModeMock = vi.hoisted(() => vi.fn(() => "preserve"));
const convertMarkdownTablesMock = vi.hoisted(() => vi.fn((text: string) => text));
vi.mock("./send-target.js", () => ({
resolveFeishuSendTarget: resolveFeishuSendTargetMock,
}));
vi.mock("./runtime.js", () => ({
getFeishuRuntime: () => ({
channel: {
text: {
resolveMarkdownTableMode: resolveMarkdownTableModeMock,
convertMarkdownTables: convertMarkdownTablesMock,
},
},
}),
}));
import { sendCardFeishu, sendMessageFeishu } from "./send.js";
describe("Feishu reply fallback for withdrawn/deleted targets", () => {
const replyMock = vi.fn();
const createMock = vi.fn();
beforeEach(() => {
vi.clearAllMocks();
resolveFeishuSendTargetMock.mockReturnValue({
client: {
im: {
message: {
reply: replyMock,
create: createMock,
},
},
},
receiveId: "ou_target",
receiveIdType: "open_id",
});
});
it("falls back to create for withdrawn post replies", async () => {
replyMock.mockResolvedValue({
code: 230011,
msg: "The message was withdrawn.",
});
createMock.mockResolvedValue({
code: 0,
data: { message_id: "om_new" },
});
const result = await sendMessageFeishu({
cfg: {} as never,
to: "user:ou_target",
text: "hello",
replyToMessageId: "om_parent",
});
expect(replyMock).toHaveBeenCalledTimes(1);
expect(createMock).toHaveBeenCalledTimes(1);
expect(result.messageId).toBe("om_new");
});
it("falls back to create for withdrawn card replies", async () => {
replyMock.mockResolvedValue({
code: 231003,
msg: "The message is not found",
});
createMock.mockResolvedValue({
code: 0,
data: { message_id: "om_card_new" },
});
const result = await sendCardFeishu({
cfg: {} as never,
to: "user:ou_target",
card: { schema: "2.0" },
replyToMessageId: "om_parent",
});
expect(replyMock).toHaveBeenCalledTimes(1);
expect(createMock).toHaveBeenCalledTimes(1);
expect(result.messageId).toBe("om_card_new");
});
it("still throws for non-withdrawn reply failures", async () => {
replyMock.mockResolvedValue({
code: 999999,
msg: "unknown failure",
});
await expect(
sendMessageFeishu({
cfg: {} as never,
to: "user:ou_target",
text: "hello",
replyToMessageId: "om_parent",
}),
).rejects.toThrow("Feishu reply failed");
expect(createMock).not.toHaveBeenCalled();
});
});