Initial commit: KOC LOOP platform
This commit is contained in:
177
tests/feishu-client.test.mjs
Normal file
177
tests/feishu-client.test.mjs
Normal file
@@ -0,0 +1,177 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import {
|
||||
clearFeishuAccessTokenCacheForTests,
|
||||
readFeishuSource,
|
||||
} from "../lib/feishu-client.ts";
|
||||
|
||||
const bindings = {
|
||||
FEISHU_APP_ID: "cli_test",
|
||||
FEISHU_APP_SECRET: "secret_test",
|
||||
};
|
||||
|
||||
function apiResponse(data) {
|
||||
return Response.json({ code: 0, msg: "success", data });
|
||||
}
|
||||
|
||||
function fakeFeishu(options = {}) {
|
||||
const calls = [];
|
||||
const fetchImpl = async (input, init = {}) => {
|
||||
const url = new URL(String(input));
|
||||
calls.push({ url, init });
|
||||
if (url.pathname.endsWith("/tenant_access_token/internal")) {
|
||||
return Response.json({
|
||||
code: 0,
|
||||
msg: "success",
|
||||
tenant_access_token: "tenant-test",
|
||||
expire: 7200,
|
||||
});
|
||||
}
|
||||
if (url.pathname.endsWith("/wiki/v2/spaces/get_node")) {
|
||||
return apiResponse({
|
||||
node: {
|
||||
obj_type: "sheet",
|
||||
obj_token: "spreadsheet-test",
|
||||
},
|
||||
});
|
||||
}
|
||||
if (url.pathname.endsWith("/sheets/query")) {
|
||||
return apiResponse({
|
||||
sheets:
|
||||
options.sheets ??
|
||||
[
|
||||
{
|
||||
sheet_id: "sheet-one",
|
||||
title: "内容池",
|
||||
resource_type: "sheet",
|
||||
hidden: false,
|
||||
grid_properties: { row_count: 20, column_count: 10 },
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
if (url.pathname.endsWith("/values_batch_get")) {
|
||||
return apiResponse({
|
||||
valueRanges: [
|
||||
{
|
||||
values: [
|
||||
["作品ID", "标题", "标签", "正文", null, null],
|
||||
[
|
||||
7,
|
||||
"一篇测试笔记",
|
||||
"#测试 #KOC",
|
||||
"测试正文",
|
||||
{
|
||||
type: "embed-image",
|
||||
fileToken: "file-token-one",
|
||||
width: 1080,
|
||||
height: 1440,
|
||||
},
|
||||
[
|
||||
{
|
||||
type: "embed-image",
|
||||
fileToken: "file-token-two",
|
||||
width: 1080,
|
||||
height: 1440,
|
||||
},
|
||||
],
|
||||
],
|
||||
[8, "", "", "空标题不会导入"],
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
throw new Error(`Unexpected request: ${url.pathname}`);
|
||||
};
|
||||
return { calls, fetchImpl };
|
||||
}
|
||||
|
||||
test("resolves a wiki sheet and imports title, body, tags, and all images", async () => {
|
||||
clearFeishuAccessTokenCacheForTests();
|
||||
const { calls, fetchImpl } = fakeFeishu();
|
||||
const source = await readFeishuSource(
|
||||
"https://tenant.feishu.cn/wiki/wiki-test",
|
||||
bindings,
|
||||
fetchImpl,
|
||||
);
|
||||
|
||||
assert.equal(source.spreadsheetToken, "spreadsheet-test");
|
||||
assert.equal(source.sheetId, "sheet-one");
|
||||
assert.equal(source.sheetName, "内容池");
|
||||
assert.equal(source.rows.length, 1);
|
||||
assert.equal(source.rows[0].sourceRow, 7);
|
||||
assert.equal(source.rows[0].body, "测试正文\n\n#测试 #KOC");
|
||||
assert.deepEqual(
|
||||
source.rows[0].images.map((image) => image.fileToken),
|
||||
["file-token-one", "file-token-two"],
|
||||
);
|
||||
assert.deepEqual(source.columns, [
|
||||
"作品ID",
|
||||
"标题",
|
||||
"标签",
|
||||
"正文",
|
||||
"图片1",
|
||||
"图片2",
|
||||
]);
|
||||
const valuesCall = calls.find((call) =>
|
||||
call.url.pathname.endsWith("/values_batch_get"),
|
||||
);
|
||||
assert.equal(valuesCall.url.searchParams.get("ranges"), "sheet-one!A1:J20");
|
||||
});
|
||||
|
||||
test("requires an exact sheet link when a workbook has multiple visible sheets", async () => {
|
||||
clearFeishuAccessTokenCacheForTests();
|
||||
const { fetchImpl } = fakeFeishu({
|
||||
sheets: [
|
||||
{
|
||||
sheet_id: "one",
|
||||
title: "内容A",
|
||||
resource_type: "sheet",
|
||||
hidden: false,
|
||||
},
|
||||
{
|
||||
sheet_id: "two",
|
||||
title: "内容B",
|
||||
resource_type: "sheet",
|
||||
hidden: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await assert.rejects(
|
||||
readFeishuSource(
|
||||
"https://tenant.feishu.cn/wiki/wiki-test",
|
||||
bindings,
|
||||
fetchImpl,
|
||||
),
|
||||
/包含多个工作表/,
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects a wiki node that is not a spreadsheet", async () => {
|
||||
clearFeishuAccessTokenCacheForTests();
|
||||
const fetchImpl = async (input) => {
|
||||
const url = new URL(String(input));
|
||||
if (url.pathname.endsWith("/tenant_access_token/internal")) {
|
||||
return Response.json({
|
||||
code: 0,
|
||||
msg: "success",
|
||||
tenant_access_token: "tenant-test",
|
||||
expire: 7200,
|
||||
});
|
||||
}
|
||||
return apiResponse({
|
||||
node: { obj_type: "docx", obj_token: "document-test" },
|
||||
});
|
||||
};
|
||||
|
||||
await assert.rejects(
|
||||
readFeishuSource(
|
||||
"https://tenant.feishu.cn/wiki/wiki-test",
|
||||
bindings,
|
||||
fetchImpl,
|
||||
),
|
||||
/不是电子表格/,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user