import { beforeEach, describe, expect, it, vi } from "vitest"; const createFeishuClientMock = vi.hoisted(() => vi.fn()); const resolveFeishuAccountMock = vi.hoisted(() => vi.fn()); const normalizeFeishuTargetMock = vi.hoisted(() => vi.fn()); const resolveReceiveIdTypeMock = vi.hoisted(() => vi.fn()); const fileCreateMock = vi.hoisted(() => vi.fn()); const messageCreateMock = vi.hoisted(() => vi.fn()); const messageReplyMock = vi.hoisted(() => vi.fn()); vi.mock("./client.js", () => ({ createFeishuClient: createFeishuClientMock, })); vi.mock("./accounts.js", () => ({ resolveFeishuAccount: resolveFeishuAccountMock, })); vi.mock("./targets.js", () => ({ normalizeFeishuTarget: normalizeFeishuTargetMock, resolveReceiveIdType: resolveReceiveIdTypeMock, })); import { sendMediaFeishu } from "./media.js"; describe("sendMediaFeishu msg_type routing", () => { beforeEach(() => { vi.clearAllMocks(); resolveFeishuAccountMock.mockReturnValue({ configured: true, accountId: "main", appId: "app_id", appSecret: "app_secret", domain: "feishu", }); normalizeFeishuTargetMock.mockReturnValue("ou_target"); resolveReceiveIdTypeMock.mockReturnValue("open_id"); createFeishuClientMock.mockReturnValue({ im: { file: { create: fileCreateMock, }, message: { create: messageCreateMock, reply: messageReplyMock, }, }, }); fileCreateMock.mockResolvedValue({ code: 0, data: { file_key: "file_key_1" }, }); messageCreateMock.mockResolvedValue({ code: 0, data: { message_id: "msg_1" }, }); messageReplyMock.mockResolvedValue({ code: 0, data: { message_id: "reply_1" }, }); }); it("uses msg_type=media for mp4", async () => { await sendMediaFeishu({ cfg: {} as any, to: "user:ou_target", mediaBuffer: Buffer.from("video"), fileName: "clip.mp4", }); expect(fileCreateMock).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ file_type: "mp4" }), }), ); expect(messageCreateMock).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ msg_type: "media" }), }), ); }); it("uses msg_type=media for opus", async () => { await sendMediaFeishu({ cfg: {} as any, to: "user:ou_target", mediaBuffer: Buffer.from("audio"), fileName: "voice.opus", }); expect(fileCreateMock).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ file_type: "opus" }), }), ); expect(messageCreateMock).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ msg_type: "media" }), }), ); }); it("uses msg_type=file for documents", async () => { await sendMediaFeishu({ cfg: {} as any, to: "user:ou_target", mediaBuffer: Buffer.from("doc"), fileName: "paper.pdf", }); expect(fileCreateMock).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ file_type: "pdf" }), }), ); expect(messageCreateMock).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ msg_type: "file" }), }), ); }); it("uses msg_type=media when replying with mp4", async () => { await sendMediaFeishu({ cfg: {} as any, to: "user:ou_target", mediaBuffer: Buffer.from("video"), fileName: "reply.mp4", replyToMessageId: "om_parent", }); expect(messageReplyMock).toHaveBeenCalledWith( expect.objectContaining({ path: { message_id: "om_parent" }, data: expect.objectContaining({ msg_type: "media" }), }), ); expect(messageCreateMock).not.toHaveBeenCalled(); }); });