fix(regression): align feishu send helper runtime usage

This commit is contained in:
Tak Hoffman 2026-03-27 21:51:37 -05:00
parent c69a70714c
commit 684a1565a9
No known key found for this signature in database
2 changed files with 71 additions and 6 deletions

View File

@ -2,17 +2,33 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ClawdbotConfig } from "../runtime-api.js";
const {
mockConvertMarkdownTables,
mockClientGet,
mockClientList,
mockClientPatch,
mockCreateFeishuClient,
mockResolveMarkdownTableMode,
mockResolveFeishuAccount,
mockRuntimeConvertMarkdownTables,
mockRuntimeResolveMarkdownTableMode,
} = vi.hoisted(() => ({
mockConvertMarkdownTables: vi.fn((text: string) => text),
mockClientGet: vi.fn(),
mockClientList: vi.fn(),
mockClientPatch: vi.fn(),
mockCreateFeishuClient: vi.fn(),
mockResolveMarkdownTableMode: vi.fn(() => "preserve"),
mockResolveFeishuAccount: vi.fn(),
mockRuntimeConvertMarkdownTables: vi.fn((text: string) => text),
mockRuntimeResolveMarkdownTableMode: vi.fn(() => "preserve"),
}));
vi.mock("openclaw/plugin-sdk/config-runtime", () => ({
resolveMarkdownTableMode: mockResolveMarkdownTableMode,
}));
vi.mock("openclaw/plugin-sdk/text-runtime", () => ({
convertMarkdownTables: mockConvertMarkdownTables,
}));
vi.mock("./client.js", () => ({
@ -28,8 +44,8 @@ vi.mock("./runtime.js", () => ({
getFeishuRuntime: () => ({
channel: {
text: {
resolveMarkdownTableMode: () => "preserve",
convertMarkdownTables: (text: string) => text,
resolveMarkdownTableMode: mockRuntimeResolveMarkdownTableMode,
convertMarkdownTables: mockRuntimeConvertMarkdownTables,
},
},
}),
@ -40,6 +56,7 @@ let editMessageFeishu: typeof import("./send.js").editMessageFeishu;
let getMessageFeishu: typeof import("./send.js").getMessageFeishu;
let listFeishuThreadMessages: typeof import("./send.js").listFeishuThreadMessages;
let resolveFeishuCardTemplate: typeof import("./send.js").resolveFeishuCardTemplate;
let sendMessageFeishu: typeof import("./send.js").sendMessageFeishu;
describe("getMessageFeishu", () => {
beforeEach(async () => {
@ -50,8 +67,13 @@ describe("getMessageFeishu", () => {
getMessageFeishu,
listFeishuThreadMessages,
resolveFeishuCardTemplate,
sendMessageFeishu,
} = await import("./send.js"));
vi.clearAllMocks();
mockResolveMarkdownTableMode.mockReturnValue("preserve");
mockConvertMarkdownTables.mockImplementation((text: string) => text);
mockRuntimeResolveMarkdownTableMode.mockReturnValue("preserve");
mockRuntimeConvertMarkdownTables.mockImplementation((text: string) => text);
mockResolveFeishuAccount.mockReturnValue({
accountId: "default",
configured: true,
@ -59,6 +81,7 @@ describe("getMessageFeishu", () => {
mockCreateFeishuClient.mockReturnValue({
im: {
message: {
create: vi.fn(),
get: mockClientGet,
list: mockClientList,
patch: mockClientPatch,
@ -67,6 +90,40 @@ describe("getMessageFeishu", () => {
});
});
it("sends text without requiring Feishu runtime text helpers", async () => {
mockRuntimeResolveMarkdownTableMode.mockImplementation(() => {
throw new Error("Feishu runtime not initialized");
});
mockRuntimeConvertMarkdownTables.mockImplementation(() => {
throw new Error("Feishu runtime not initialized");
});
mockClientPatch.mockResolvedValueOnce({ code: 0 });
mockCreateFeishuClient.mockReturnValue({
im: {
message: {
create: vi.fn().mockResolvedValue({ code: 0, data: { message_id: "om_send" } }),
reply: vi.fn(),
get: mockClientGet,
list: mockClientList,
patch: mockClientPatch,
},
},
});
const result = await sendMessageFeishu({
cfg: {} as ClawdbotConfig,
to: "oc_send",
text: "hello",
});
expect(mockResolveMarkdownTableMode).toHaveBeenCalledWith({
cfg: {},
channel: "feishu",
});
expect(mockConvertMarkdownTables).toHaveBeenCalledWith("hello", "preserve");
expect(result).toEqual({ messageId: "om_send", chatId: "oc_send" });
});
it("extracts text content from interactive card elements", async () => {
mockClientGet.mockResolvedValueOnce({
code: 0,
@ -283,6 +340,12 @@ describe("editMessageFeishu", () => {
});
it("patches post content for text edits", async () => {
mockRuntimeResolveMarkdownTableMode.mockImplementation(() => {
throw new Error("Feishu runtime not initialized");
});
mockRuntimeConvertMarkdownTables.mockImplementation(() => {
throw new Error("Feishu runtime not initialized");
});
mockClientPatch.mockResolvedValueOnce({ code: 0 });
const result = await editMessageFeishu({

View File

@ -1,3 +1,5 @@
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";
import type { ClawdbotConfig } from "../runtime-api.js";
import { resolveFeishuRuntimeAccount } from "./accounts.js";
import { createFeishuClient } from "./client.js";
@ -445,7 +447,7 @@ export async function sendMessageFeishu(
): Promise<FeishuSendResult> {
const { cfg, to, text, replyToMessageId, replyInThread, mentions, accountId } = params;
const { client, receiveId, receiveIdType } = resolveFeishuSendTarget({ cfg, to, accountId });
const tableMode = getFeishuRuntime().channel.text.resolveMarkdownTableMode({
const tableMode = resolveMarkdownTableMode({
cfg,
channel: "feishu",
});
@ -455,7 +457,7 @@ export async function sendMessageFeishu(
if (mentions && mentions.length > 0) {
rawText = buildMentionedMessage(mentions, rawText);
}
const messageText = getFeishuRuntime().channel.text.convertMarkdownTables(rawText, tableMode);
const messageText = convertMarkdownTables(rawText, tableMode);
const { content, msgType } = buildFeishuPostMessagePayload({ messageText });
@ -533,11 +535,11 @@ export async function editMessageFeishu(params: {
return { messageId, contentType: "interactive" };
}
const tableMode = getFeishuRuntime().channel.text.resolveMarkdownTableMode({
const tableMode = resolveMarkdownTableMode({
cfg,
channel: "feishu",
});
const messageText = getFeishuRuntime().channel.text.convertMarkdownTables(text!, tableMode);
const messageText = convertMarkdownTables(text!, tableMode);
const payload = buildFeishuPostMessagePayload({ messageText });
const response = await client.im.message.patch({
path: { message_id: messageId },