test: dedupe feishu drive mock calls

This commit is contained in:
Peter Steinberger
2026-05-12 17:19:11 +01:00
parent 0c5e33480e
commit 6cfb532afd

View File

@@ -58,6 +58,24 @@ function mockCallArg<T>(
return call[argIndex] as T;
}
type FeishuDriveTool = {
execute: (callId: string, input: Record<string, unknown>) => Promise<{ details?: unknown }>;
name?: string;
};
type FeishuDriveToolFactory = (context: {
agentAccountId?: string;
deliveryContext?: unknown;
}) => FeishuDriveTool;
function firstToolFactory(mock: { mock: { calls: unknown[][] } }): FeishuDriveToolFactory {
return mockCallArg<FeishuDriveToolFactory>(mock, 0, 0);
}
function firstLogMessage(mock: { mock: { calls: unknown[][] } }): string {
return String(mockCallArg<unknown>(mock, 0, 0));
}
type FeishuDriveRequest = {
data?: unknown;
method?: string;
@@ -140,8 +158,8 @@ describe("registerFeishuDriveTools", () => {
);
expect(registerTool).toHaveBeenCalledTimes(1);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
expect(tool?.name).toBe("feishu_drive");
requestMock.mockResolvedValueOnce({
@@ -358,8 +376,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock.mockResolvedValueOnce({
code: 0,
@@ -379,9 +397,7 @@ describe("registerFeishuDriveTools", () => {
file_type: "docx",
reply_elements: [{ type: "text", text: "defaulted file type" }],
});
expect(infoSpy.mock.calls.at(0)?.[0]).toContain(
"add_comment missing file_type; defaulting to docx",
);
expect(firstLogMessage(infoSpy)).toContain("add_comment missing file_type; defaulting to docx");
expect((result.details as { comment_id?: string; success?: boolean }).success).toBe(true);
expect((result.details as { comment_id?: string }).comment_id).toBe("c-default-docx");
});
@@ -405,8 +421,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock.mockResolvedValueOnce({
code: 0,
@@ -423,7 +439,7 @@ describe("registerFeishuDriveTools", () => {
expect(request.url).toBe(
"/open-apis/drive/v1/files/doc_1/comments?file_type=docx&user_id_type=open_id",
);
expect(infoSpy.mock.calls.at(0)?.[0]).toContain(
expect(firstLogMessage(infoSpy)).toContain(
"list_comments missing file_type; defaulting to docx",
);
});
@@ -447,8 +463,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock.mockResolvedValueOnce({
code: 0,
@@ -466,7 +482,7 @@ describe("registerFeishuDriveTools", () => {
expect(request.url).toBe(
"/open-apis/drive/v1/files/doc_1/comments/c1/replies?file_type=docx&user_id_type=open_id",
);
expect(infoSpy.mock.calls.at(0)?.[0]).toContain(
expect(firstLogMessage(infoSpy)).toContain(
"list_comment_replies missing file_type; defaulting to docx",
);
});
@@ -490,8 +506,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock
.mockResolvedValueOnce({
@@ -548,7 +564,7 @@ describe("registerFeishuDriveTools", () => {
],
},
});
expect(warnSpy.mock.calls.at(0)?.[0]).toContain("replyComment threw");
expect(firstLogMessage(warnSpy)).toContain("replyComment threw");
expect((replyCommentResult.details as { error?: string }).error).toBe(
"Request failed with status code 400",
);
@@ -572,8 +588,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({
agentAccountId: undefined,
deliveryContext: {
channel: "feishu",
@@ -670,8 +686,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({
agentAccountId: undefined,
deliveryContext: {
channel: "feishu",
@@ -747,8 +763,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({
agentAccountId: undefined,
deliveryContext: {
channel: "feishu",
@@ -774,9 +790,7 @@ describe("registerFeishuDriveTools", () => {
file_type: "docx",
reply_elements: [{ type: "text", text: "default add comment" }],
});
expect(infoSpy.mock.calls.at(0)?.[0]).toContain(
"add_comment missing file_type; defaulting to docx",
);
expect(firstLogMessage(infoSpy)).toContain("add_comment missing file_type; defaulting to docx");
expect((result.details as { comment_id?: string; success?: boolean }).success).toBe(true);
expect((result.details as { comment_id?: string }).comment_id).toBe("c-add-docx");
});
@@ -800,8 +814,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock
.mockResolvedValueOnce({
@@ -844,7 +858,7 @@ describe("registerFeishuDriveTools", () => {
},
},
});
expect(infoSpy.mock.calls.at(0)?.[0]).toContain(
expect(firstLogMessage(infoSpy)).toContain(
"reply_comment missing file_type; defaulting to docx",
);
expect((result.details as { reply_id?: string; success?: boolean }).success).toBe(true);
@@ -870,8 +884,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock
.mockResolvedValueOnce({
@@ -906,7 +920,7 @@ describe("registerFeishuDriveTools", () => {
reply_elements: [{ type: "text", text: "whole comment follow-up" }],
},
});
expect(infoSpy.mock.calls.at(0)?.[0]).toContain("whole-comment compatibility path");
expect(firstLogMessage(infoSpy)).toContain("whole-comment compatibility path");
const details = result.details as {
comment_id?: string;
delivery_mode?: string;
@@ -936,8 +950,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock.mockRejectedValueOnce(new Error("preflight unavailable")).mockResolvedValueOnce({
code: 0,
@@ -974,7 +988,7 @@ describe("registerFeishuDriveTools", () => {
},
},
});
expect(warnSpy.mock.calls.at(0)?.[0]).toContain("comment metadata preflight failed");
expect(firstLogMessage(warnSpy)).toContain("comment metadata preflight failed");
const details = result.details as {
delivery_mode?: string;
reply_id?: string;
@@ -1004,8 +1018,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock
.mockResolvedValueOnce({
@@ -1083,8 +1097,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock
.mockResolvedValueOnce({
@@ -1131,7 +1145,7 @@ describe("registerFeishuDriveTools", () => {
reply_elements: [{ type: "text", text: "compat follow-up" }],
},
});
expect(infoSpy.mock.calls.at(0)?.[0]).toContain("reply-not-allowed compatibility path");
expect(firstLogMessage(infoSpy)).toContain("reply-not-allowed compatibility path");
const details = result.details as {
comment_id?: string;
delivery_mode?: string;
@@ -1160,8 +1174,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
requestMock.mockResolvedValueOnce({ code: 0, data: { has_more: false, items: [] } });
await tool.execute("call-list", {
@@ -1207,8 +1221,8 @@ describe("registerFeishuDriveTools", () => {
}),
);
const toolFactory = registerTool.mock.calls.at(0)?.[0];
const tool = toolFactory?.({ agentAccountId: undefined });
const toolFactory = firstToolFactory(registerTool);
const tool = toolFactory({ agentAccountId: undefined });
const result = await tool.execute("call-5", {
action: "add_comment",
file_token: "doc_1",