mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-03 11:24:36 +00:00
* Tests: stabilize detect-secrets fixtures * Tests: fix rebased detect-secrets false positives * Docs: keep snippets valid under detect-secrets * Tests: finalize detect-secrets false-positive fixes * Tests: reduce detect-secrets false positives * Tests: keep detect-secrets pragmas inline * Tests: remediate next detect-secrets batch * Tests: tighten detect-secrets allowlists * Tests: stabilize detect-secrets formatter drift
130 lines
4.1 KiB
TypeScript
130 lines
4.1 KiB
TypeScript
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu";
|
|
import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
import { registerFeishuBitableTools } from "./bitable.js";
|
|
import { registerFeishuDriveTools } from "./drive.js";
|
|
import { registerFeishuPermTools } from "./perm.js";
|
|
import { createToolFactoryHarness } from "./tool-factory-test-harness.js";
|
|
import { registerFeishuWikiTools } from "./wiki.js";
|
|
|
|
const createFeishuClientMock = vi.fn((account: { appId?: string } | undefined) => ({
|
|
__appId: account?.appId,
|
|
}));
|
|
|
|
vi.mock("./client.js", () => ({
|
|
createFeishuClient: (account: { appId?: string } | undefined) => createFeishuClientMock(account),
|
|
}));
|
|
|
|
function createConfig(params: {
|
|
toolsA?: {
|
|
wiki?: boolean;
|
|
drive?: boolean;
|
|
perm?: boolean;
|
|
};
|
|
toolsB?: {
|
|
wiki?: boolean;
|
|
drive?: boolean;
|
|
perm?: boolean;
|
|
};
|
|
defaultAccount?: string;
|
|
}): OpenClawPluginApi["config"] {
|
|
return {
|
|
channels: {
|
|
feishu: {
|
|
enabled: true,
|
|
defaultAccount: params.defaultAccount,
|
|
accounts: {
|
|
a: {
|
|
appId: "app-a",
|
|
appSecret: "sec-a", // pragma: allowlist secret
|
|
tools: params.toolsA,
|
|
},
|
|
b: {
|
|
appId: "app-b",
|
|
appSecret: "sec-b", // pragma: allowlist secret
|
|
tools: params.toolsB,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
} as OpenClawPluginApi["config"];
|
|
}
|
|
|
|
describe("feishu tool account routing", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
test("wiki tool registers when first account disables it and routes to agentAccountId", async () => {
|
|
const { api, resolveTool } = createToolFactoryHarness(
|
|
createConfig({
|
|
toolsA: { wiki: false },
|
|
toolsB: { wiki: true },
|
|
}),
|
|
);
|
|
registerFeishuWikiTools(api);
|
|
|
|
const tool = resolveTool("feishu_wiki", { agentAccountId: "b" });
|
|
await tool.execute("call", { action: "search" });
|
|
|
|
expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-b");
|
|
});
|
|
|
|
test("wiki tool prefers configured defaultAccount over inherited default account context", async () => {
|
|
const { api, resolveTool } = createToolFactoryHarness(
|
|
createConfig({
|
|
defaultAccount: "b",
|
|
toolsA: { wiki: true },
|
|
toolsB: { wiki: true },
|
|
}),
|
|
);
|
|
registerFeishuWikiTools(api);
|
|
|
|
const tool = resolveTool("feishu_wiki", { agentAccountId: "a" });
|
|
await tool.execute("call", { action: "search" });
|
|
|
|
expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-b");
|
|
});
|
|
|
|
test("drive tool registers when first account disables it and routes to agentAccountId", async () => {
|
|
const { api, resolveTool } = createToolFactoryHarness(
|
|
createConfig({
|
|
toolsA: { drive: false },
|
|
toolsB: { drive: true },
|
|
}),
|
|
);
|
|
registerFeishuDriveTools(api);
|
|
|
|
const tool = resolveTool("feishu_drive", { agentAccountId: "b" });
|
|
await tool.execute("call", { action: "unknown_action" });
|
|
|
|
expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-b");
|
|
});
|
|
|
|
test("perm tool registers when only second account enables it and routes to agentAccountId", async () => {
|
|
const { api, resolveTool } = createToolFactoryHarness(
|
|
createConfig({
|
|
toolsA: { perm: false },
|
|
toolsB: { perm: true },
|
|
}),
|
|
);
|
|
registerFeishuPermTools(api);
|
|
|
|
const tool = resolveTool("feishu_perm", { agentAccountId: "b" });
|
|
await tool.execute("call", { action: "unknown_action" });
|
|
|
|
expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-b");
|
|
});
|
|
|
|
test("bitable tool routes to agentAccountId and allows explicit accountId override", async () => {
|
|
const { api, resolveTool } = createToolFactoryHarness(createConfig({}));
|
|
registerFeishuBitableTools(api);
|
|
|
|
const tool = resolveTool("feishu_bitable_get_meta", { agentAccountId: "b" });
|
|
await tool.execute("call-ctx", { url: "invalid-url" });
|
|
await tool.execute("call-override", { url: "invalid-url", accountId: "a" });
|
|
|
|
expect(createFeishuClientMock.mock.calls[0]?.[0]?.appId).toBe("app-b");
|
|
expect(createFeishuClientMock.mock.calls[1]?.[0]?.appId).toBe("app-a");
|
|
});
|
|
});
|