mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-29 23:25:03 +00:00
PR: Feishu Plugin - Auto-grant document permissions to requesting user (openclaw#28295) thanks @zhoulongchao77
Verified: - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: zhoulongchao77 <65058500+zhoulongchao77@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -21,9 +21,11 @@ import { registerFeishuDocTools } from "./docx.js";
|
||||
|
||||
describe("feishu_doc image fetch hardening", () => {
|
||||
const convertMock = vi.hoisted(() => vi.fn());
|
||||
const documentCreateMock = vi.hoisted(() => vi.fn());
|
||||
const blockListMock = vi.hoisted(() => vi.fn());
|
||||
const blockChildrenCreateMock = vi.hoisted(() => vi.fn());
|
||||
const driveUploadAllMock = vi.hoisted(() => vi.fn());
|
||||
const permissionMemberCreateMock = vi.hoisted(() => vi.fn());
|
||||
const blockPatchMock = vi.hoisted(() => vi.fn());
|
||||
const scopeListMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
@@ -34,6 +36,7 @@ describe("feishu_doc image fetch hardening", () => {
|
||||
docx: {
|
||||
document: {
|
||||
convert: convertMock,
|
||||
create: documentCreateMock,
|
||||
},
|
||||
documentBlock: {
|
||||
list: blockListMock,
|
||||
@@ -47,6 +50,9 @@ describe("feishu_doc image fetch hardening", () => {
|
||||
media: {
|
||||
uploadAll: driveUploadAllMock,
|
||||
},
|
||||
permissionMember: {
|
||||
create: permissionMemberCreateMock,
|
||||
},
|
||||
},
|
||||
application: {
|
||||
scope: {
|
||||
@@ -78,6 +84,11 @@ describe("feishu_doc image fetch hardening", () => {
|
||||
});
|
||||
|
||||
driveUploadAllMock.mockResolvedValue({ file_token: "token_1" });
|
||||
documentCreateMock.mockResolvedValue({
|
||||
code: 0,
|
||||
data: { document: { document_id: "doc_created", title: "Created Doc" } },
|
||||
});
|
||||
permissionMemberCreateMock.mockResolvedValue({ code: 0 });
|
||||
blockPatchMock.mockResolvedValue({ code: 0 });
|
||||
scopeListMock.mockResolvedValue({ code: 0, data: { scopes: [] } });
|
||||
});
|
||||
@@ -121,4 +132,107 @@ describe("feishu_doc image fetch hardening", () => {
|
||||
expect(consoleErrorSpy).toHaveBeenCalled();
|
||||
consoleErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("reports owner permission details when grant succeeds", async () => {
|
||||
const registerTool = vi.fn();
|
||||
registerFeishuDocTools({
|
||||
config: {
|
||||
channels: {
|
||||
feishu: {
|
||||
appId: "app_id",
|
||||
appSecret: "app_secret",
|
||||
},
|
||||
},
|
||||
} as any,
|
||||
logger: { debug: vi.fn(), info: vi.fn() } as any,
|
||||
registerTool,
|
||||
} as any);
|
||||
|
||||
const feishuDocTool = registerTool.mock.calls
|
||||
.map((call) => call[0])
|
||||
.map((tool) => (typeof tool === "function" ? tool({}) : tool))
|
||||
.find((tool) => tool.name === "feishu_doc");
|
||||
expect(feishuDocTool).toBeDefined();
|
||||
|
||||
const result = await feishuDocTool.execute("tool-call", {
|
||||
action: "create",
|
||||
title: "Demo",
|
||||
owner_open_id: "ou_123",
|
||||
owner_perm_type: "edit",
|
||||
});
|
||||
|
||||
expect(permissionMemberCreateMock).toHaveBeenCalled();
|
||||
expect(result.details.owner_permission_added).toBe(true);
|
||||
expect(result.details.owner_open_id).toBe("ou_123");
|
||||
expect(result.details.owner_perm_type).toBe("edit");
|
||||
});
|
||||
|
||||
it("does not report owner permission details when grant fails", async () => {
|
||||
const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
permissionMemberCreateMock.mockRejectedValueOnce(new Error("permission denied"));
|
||||
|
||||
const registerTool = vi.fn();
|
||||
registerFeishuDocTools({
|
||||
config: {
|
||||
channels: {
|
||||
feishu: {
|
||||
appId: "app_id",
|
||||
appSecret: "app_secret",
|
||||
},
|
||||
},
|
||||
} as any,
|
||||
logger: { debug: vi.fn(), info: vi.fn() } as any,
|
||||
registerTool,
|
||||
} as any);
|
||||
|
||||
const feishuDocTool = registerTool.mock.calls
|
||||
.map((call) => call[0])
|
||||
.map((tool) => (typeof tool === "function" ? tool({}) : tool))
|
||||
.find((tool) => tool.name === "feishu_doc");
|
||||
expect(feishuDocTool).toBeDefined();
|
||||
|
||||
const result = await feishuDocTool.execute("tool-call", {
|
||||
action: "create",
|
||||
title: "Demo",
|
||||
owner_open_id: "ou_123",
|
||||
owner_perm_type: "edit",
|
||||
});
|
||||
|
||||
expect(permissionMemberCreateMock).toHaveBeenCalled();
|
||||
expect(result.details.owner_permission_added).toBeUndefined();
|
||||
expect(result.details.owner_open_id).toBeUndefined();
|
||||
expect(result.details.owner_perm_type).toBeUndefined();
|
||||
expect(consoleWarnSpy).toHaveBeenCalled();
|
||||
consoleWarnSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("skips permission grant when owner_open_id is omitted", async () => {
|
||||
const registerTool = vi.fn();
|
||||
registerFeishuDocTools({
|
||||
config: {
|
||||
channels: {
|
||||
feishu: {
|
||||
appId: "app_id",
|
||||
appSecret: "app_secret",
|
||||
},
|
||||
},
|
||||
} as any,
|
||||
logger: { debug: vi.fn(), info: vi.fn() } as any,
|
||||
registerTool,
|
||||
} as any);
|
||||
|
||||
const feishuDocTool = registerTool.mock.calls
|
||||
.map((call) => call[0])
|
||||
.map((tool) => (typeof tool === "function" ? tool({}) : tool))
|
||||
.find((tool) => tool.name === "feishu_doc");
|
||||
expect(feishuDocTool).toBeDefined();
|
||||
|
||||
const result = await feishuDocTool.execute("tool-call", {
|
||||
action: "create",
|
||||
title: "Demo",
|
||||
});
|
||||
|
||||
expect(permissionMemberCreateMock).not.toHaveBeenCalled();
|
||||
expect(result.details.owner_permission_added).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user