






















@@ -63,6 +63,30 @@ type ToolResultWithDetails = {
63636464const WORKSPACE_ROOT = path.resolve("/workspace");
656566+function requireRecord(value: unknown, label: string): Record<string, unknown> {
67+expect(value, label).toBeTypeOf("object");
68+expect(value, label).not.toBeNull();
69+return value as Record<string, unknown>;
70+}
71+72+function callArg(mock: unknown, callIndex: number, argIndex: number, label: string) {
73+const calls = (mock as { mock?: { calls?: Array<Array<unknown>> } }).mock?.calls ?? [];
74+const call = calls.at(callIndex);
75+expect(call, label).toBeDefined();
76+return call?.[argIndex];
77+}
78+79+function expectLoadWebMediaCall(fileName: string, localRoots: unknown[] | undefined) {
80+const source = callArg(loadWebMediaMock, 0, 0, "loadWebMedia source");
81+const options = requireRecord(
82+callArg(loadWebMediaMock, 0, 1, "loadWebMedia options"),
83+"loadWebMedia options",
84+);
85+expect(String(source)).toContain(fileName);
86+expect(options.optimizeImages).toBe(false);
87+expect(options.localRoots).toEqual(localRoots);
88+}
89+6690describe("feishu_doc image fetch hardening", () => {
6791afterAll(() => {
6892vi.restoreAllMocks();
@@ -208,7 +232,9 @@ describe("feishu_doc image fetch hardening", () => {
208232expect(blockDescendantCreateMock).toHaveBeenCalledTimes(1);
209233const call = blockDescendantCreateMock.mock.calls[0]?.[0];
210234expect(call?.data.children_id).toEqual(["h1", "t1", "h2"]);
211-expect(call?.data.descendants).toEqual(expect.arrayContaining(blocks));
235+for (const block of blocks) {
236+expect(call?.data.descendants).toContainEqual(block);
237+}
212238expect(call?.data.descendants).toHaveLength(3);
213239214240expect(result.details.blocks_added).toBe(3);
@@ -398,15 +424,14 @@ describe("feishu_doc image fetch hardening", () => {
398424expect(result.details.requester_permission_added).toBe(true);
399425expect(result.details.requester_open_id).toBe("ou_123");
400426expect(result.details.requester_perm_type).toBe("edit");
401-expect(permissionMemberCreateMock).toHaveBeenCalledWith(
402-expect.objectContaining({
403-data: expect.objectContaining({
404-member_type: "openid",
405-member_id: "ou_123",
406-perm: "edit",
407-}),
408-}),
427+const permissionPayload = requireRecord(
428+callArg(permissionMemberCreateMock, 0, 0, "permission create payload"),
429+"permission create payload",
409430);
431+const permissionData = requireRecord(permissionPayload.data, "permission data");
432+expect(permissionData.member_type).toBe("openid");
433+expect(permissionData.member_id).toBe("ou_123");
434+expect(permissionData.perm).toBe("edit");
410435});
411436412437it("create skips requester grant when trusted requester identity is unavailable", async () => {
@@ -484,20 +509,16 @@ describe("feishu_doc image fetch hardening", () => {
484509485510// Without workspace-only policy, localRoots stays undefined so loadWebMedia
486511// applies its default managed-root access behavior.
487-expect(loadWebMediaMock).toHaveBeenCalledWith(
488-expect.stringContaining("test-local.txt"),
489-expect.objectContaining({ optimizeImages: false, localRoots: undefined }),
490-);
512+expectLoadWebMediaCall("test-local.txt", undefined);
491513492-expect(driveUploadAllMock).toHaveBeenCalledWith(
493-expect.objectContaining({
494-data: expect.objectContaining({
495-parent_type: "docx_file",
496-parent_node: "doc_1",
497-file_name: "test-local.txt",
498-}),
499-}),
514+const uploadPayload = requireRecord(
515+callArg(driveUploadAllMock, 0, 0, "drive upload payload"),
516+"drive upload payload",
500517);
518+const uploadData = requireRecord(uploadPayload.data, "drive upload data");
519+expect(uploadData.parent_type).toBe("docx_file");
520+expect(uploadData.parent_node).toBe("doc_1");
521+expect(uploadData.file_name).toBe("test-local.txt");
501522});
502523503524it("passes workspace localRoots for upload_file when workspace-only policy is active", async () => {
@@ -525,10 +546,7 @@ describe("feishu_doc image fetch hardening", () => {
525546filename: "test-local.txt",
526547});
527548528-expect(loadWebMediaMock).toHaveBeenCalledWith(
529-expect.stringContaining("test-local.txt"),
530-expect.objectContaining({ optimizeImages: false, localRoots: [WORKSPACE_ROOT] }),
531-);
549+expectLoadWebMediaCall("test-local.txt", [WORKSPACE_ROOT]);
532550});
533551534552it("passes empty localRoots when workspace-only policy is active without workspaceDir", async () => {
@@ -555,10 +573,7 @@ describe("feishu_doc image fetch hardening", () => {
555573filename: "test-local.txt",
556574});
557575558-expect(loadWebMediaMock).toHaveBeenCalledWith(
559-expect.stringContaining("test-local.txt"),
560-expect.objectContaining({ optimizeImages: false, localRoots: [] }),
561-);
576+expectLoadWebMediaCall("test-local.txt", []);
562577});
563578564579it("passes workspace localRoots for upload_image local paths when workspace-only policy is active", async () => {
@@ -579,10 +594,7 @@ describe("feishu_doc image fetch hardening", () => {
579594filename: "test-local.png",
580595});
581596582-expect(loadWebMediaMock).toHaveBeenCalledWith(
583-expect.stringContaining("test-local.png"),
584-expect.objectContaining({ optimizeImages: false, localRoots: [WORKSPACE_ROOT] }),
585-);
597+expectLoadWebMediaCall("test-local.png", [WORKSPACE_ROOT]);
586598});
587599588600it("passes workspace localRoots for upload_image absolute local paths when workspace-only policy is active", async () => {
@@ -609,10 +621,7 @@ describe("feishu_doc image fetch hardening", () => {
609621filename: "absolute-image.png",
610622});
611623612-expect(loadWebMediaMock).toHaveBeenCalledWith(
613-expect.stringContaining("absolute-image.png"),
614-expect.objectContaining({ optimizeImages: false, localRoots: [WORKSPACE_ROOT] }),
615-);
624+expectLoadWebMediaCall("absolute-image.png", [WORKSPACE_ROOT]);
616625} finally {
617626rmSync(fixtureDir, { recursive: true, force: true });
618627}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。