test: dedupe feishu routing mock reads

This commit is contained in:
Peter Steinberger
2026-05-13 03:43:41 +01:00
parent cb613022ff
commit ff7beea3da

View File

@@ -50,6 +50,16 @@ function createConfig(params: {
} as OpenClawPluginApi["config"];
}
function clientAppIdAt(index: number): string | undefined {
const calls = createFeishuClientMock.mock.calls;
const resolvedIndex = index < 0 ? calls.length + index : index;
return calls[resolvedIndex]?.[0]?.appId;
}
function lastClientAppId(): string | undefined {
return clientAppIdAt(-1);
}
describe("feishu tool account routing", () => {
beforeAll(async () => {
({ registerFeishuBitableTools, registerFeishuDriveTools, registerFeishuPermTools } =
@@ -83,7 +93,7 @@ describe("feishu tool account routing", () => {
const tool = resolveTool("feishu_wiki", { agentAccountId: "b" });
await tool.execute("call", { action: "search" });
expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-b");
expect(lastClientAppId()).toBe("app-b");
});
test("wiki tool prefers the active contextual account over configured defaultAccount", async () => {
@@ -99,7 +109,7 @@ describe("feishu tool account routing", () => {
const tool = resolveTool("feishu_wiki", { agentAccountId: "a" });
await tool.execute("call", { action: "search" });
expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-a");
expect(lastClientAppId()).toBe("app-a");
});
test("drive tool registers when first account disables it and routes to agentAccountId", async () => {
@@ -114,7 +124,7 @@ describe("feishu tool account routing", () => {
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");
expect(lastClientAppId()).toBe("app-b");
});
test("perm tool registers when only second account enables it and routes to agentAccountId", async () => {
@@ -129,7 +139,7 @@ describe("feishu tool account routing", () => {
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");
expect(lastClientAppId()).toBe("app-b");
});
test("bitable tool routes to agentAccountId and allows explicit accountId override", async () => {
@@ -140,8 +150,8 @@ describe("feishu tool account routing", () => {
await tool.execute("call-ctx", { url: "invalid-url" });
await tool.execute("call-override", { url: "invalid-url", accountId: "a" });
expect(createFeishuClientMock.mock.calls.at(0)?.[0]?.appId).toBe("app-b");
expect(createFeishuClientMock.mock.calls.at(1)?.[0]?.appId).toBe("app-a");
expect(clientAppIdAt(0)).toBe("app-b");
expect(clientAppIdAt(1)).toBe("app-a");
});
test("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", () => {
const tool = resolveTool("feishu_wiki", { agentAccountId: "agent-spawner" });
await tool.execute("call", { action: "search" });
expect(createFeishuClientMock.mock.calls.at(-1)?.[0]?.appId).toBe("app-a");
expect(lastClientAppId()).toBe("app-a");
});
test("does not silently fall back when the contextual account is real but uses non-env SecretRefs", async () => {