
























@@ -50,6 +50,16 @@ function createConfig(params: {
5050} as OpenClawPluginApi["config"];
5151}
525253+function clientAppIdAt(index: number): string | undefined {
54+const calls = createFeishuClientMock.mock.calls;
55+const resolvedIndex = index < 0 ? calls.length + index : index;
56+return calls[resolvedIndex]?.[0]?.appId;
57+}
58+59+function lastClientAppId(): string | undefined {
60+return clientAppIdAt(-1);
61+}
62+5363describe("feishu tool account routing", () => {
5464beforeAll(async () => {
5565({ registerFeishuBitableTools, registerFeishuDriveTools, registerFeishuPermTools } =
@@ -83,7 +93,7 @@ describe("feishu tool account routing", () => {
8393const tool = resolveTool("feishu_wiki", { agentAccountId: "b" });
8494await tool.execute("call", { action: "search" });
859586-expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-b");
96+expect(lastClientAppId()).toBe("app-b");
8797});
88988999test("wiki tool prefers the active contextual account over configured defaultAccount", async () => {
@@ -99,7 +109,7 @@ describe("feishu tool account routing", () => {
99109const tool = resolveTool("feishu_wiki", { agentAccountId: "a" });
100110await tool.execute("call", { action: "search" });
101111102-expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-a");
112+expect(lastClientAppId()).toBe("app-a");
103113});
104114105115test("drive tool registers when first account disables it and routes to agentAccountId", async () => {
@@ -114,7 +124,7 @@ describe("feishu tool account routing", () => {
114124const tool = resolveTool("feishu_drive", { agentAccountId: "b" });
115125await tool.execute("call", { action: "unknown_action" });
116126117-expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-b");
127+expect(lastClientAppId()).toBe("app-b");
118128});
119129120130test("perm tool registers when only second account enables it and routes to agentAccountId", async () => {
@@ -129,7 +139,7 @@ describe("feishu tool account routing", () => {
129139const tool = resolveTool("feishu_perm", { agentAccountId: "b" });
130140await tool.execute("call", { action: "unknown_action" });
131141132-expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-b");
142+expect(lastClientAppId()).toBe("app-b");
133143});
134144135145test("bitable tool routes to agentAccountId and allows explicit accountId override", async () => {
@@ -140,8 +150,8 @@ describe("feishu tool account routing", () => {
140150await tool.execute("call-ctx", { url: "invalid-url" });
141151await tool.execute("call-override", { url: "invalid-url", accountId: "a" });
142152143-expect(createFeishuClientMock.mock.calls.at(0)?.[0]?.appId).toBe("app-b");
144-expect(createFeishuClientMock.mock.calls.at(1)?.[0]?.appId).toBe("app-a");
153+expect(clientAppIdAt(0)).toBe("app-b");
154+expect(clientAppIdAt(1)).toBe("app-a");
145155});
146156147157test("falls back to the configured Feishu default selection when agentAccountId is not a real account", async () => {
@@ -156,7 +166,7 @@ describe("feishu tool account routing", () => {
156166const tool = resolveTool("feishu_wiki", { agentAccountId: "agent-spawner" });
157167await tool.execute("call", { action: "search" });
158168159-expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-a");
169+expect(lastClientAppId()).toBe("app-a");
160170});
161171162172test("does not silently fall back when the contextual account is real but uses non-env SecretRefs", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。