150 lines
4.4 KiB
TypeScript
150 lines
4.4 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import {
|
|
countOpenClawArchiveRootFolders,
|
|
sanitizeOpenClawArchiveEntryPath,
|
|
sanitizeOpenClawArchiveName,
|
|
} from "@/lib/openclaw-chat/folder-archive";
|
|
import {
|
|
buildOpenClawArchiveDisplayText,
|
|
buildOpenClawArchiveReferenceText,
|
|
buildOpenClawFileReferenceText,
|
|
getOpenClawChatFileContentType,
|
|
isOpenClawChatFolderFileAllowed,
|
|
isOpenClawChatArchiveAttachment,
|
|
isOpenClawChatFileAttachment,
|
|
normalizeOpenClawChatMediaAttachments,
|
|
OPENCLAW_CHAT_FILE_MAX_BYTES,
|
|
} from "@/lib/openclaw-chat/media-attachments";
|
|
|
|
test.describe("OpenClaw folder attachments", () => {
|
|
test("keeps safe folder structure while removing traversal segments", () => {
|
|
expect(
|
|
sanitizeOpenClawArchiveEntryPath(
|
|
"../../设计资料/主图:终稿.png",
|
|
"主图.png",
|
|
0
|
|
)
|
|
).toBe("设计资料/主图-终稿.png");
|
|
expect(sanitizeOpenClawArchiveName(" 商品/资料:* ")).toBe("商品-资料--");
|
|
});
|
|
|
|
test("counts multiple selected root folders", () => {
|
|
expect(
|
|
countOpenClawArchiveRootFolders([
|
|
"产品A/图片/1.png",
|
|
"产品A/文档/readme.md",
|
|
"产品B/图片/2.png",
|
|
])
|
|
).toBe(2);
|
|
});
|
|
|
|
test("normalizes ZIP URLs as file attachments", () => {
|
|
const attachments = normalizeOpenClawChatMediaAttachments([
|
|
{
|
|
type: "file",
|
|
url: "https://cdn.example.com/产品资料.zip",
|
|
name: "产品资料.zip",
|
|
contentType: "application/zip",
|
|
},
|
|
]);
|
|
|
|
expect(attachments).toEqual([
|
|
{
|
|
type: "file",
|
|
url: "https://cdn.example.com/产品资料.zip",
|
|
name: "产品资料.zip",
|
|
content_type: "application/zip",
|
|
},
|
|
]);
|
|
expect(
|
|
isOpenClawChatArchiveAttachment(
|
|
attachments[0].url,
|
|
attachments[0].content_type
|
|
)
|
|
).toBe(true);
|
|
});
|
|
|
|
test("adds the public archive URL to the OpenClaw fallback message", () => {
|
|
const attachments = normalizeOpenClawChatMediaAttachments([
|
|
{
|
|
type: "file",
|
|
url: "https://cdn.example.com/catalog.zip",
|
|
name: "catalog.zip",
|
|
},
|
|
]);
|
|
|
|
expect(buildOpenClawArchiveDisplayText(attachments)).toContain("catalog.zip");
|
|
expect(buildOpenClawArchiveReferenceText(attachments)).toContain(
|
|
"https://cdn.example.com/catalog.zip"
|
|
);
|
|
expect(buildOpenClawArchiveReferenceText(attachments)).toContain("解压");
|
|
});
|
|
|
|
test("accepts 2GB spreadsheet and folder-manifest attachments", () => {
|
|
expect(OPENCLAW_CHAT_FILE_MAX_BYTES).toBe(2 * 1024 * 1024 * 1024);
|
|
expect(
|
|
getOpenClawChatFileContentType({
|
|
name: "清单.xlsx",
|
|
type: "application/octet-stream",
|
|
})
|
|
).toBe(
|
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
);
|
|
expect(
|
|
getOpenClawChatFileContentType({
|
|
name: "产品资料.folder.json",
|
|
type: "application/vnd.yedir.folder-manifest+json",
|
|
})
|
|
).toBe("application/vnd.yedir.folder-manifest+json");
|
|
|
|
const attachments = normalizeOpenClawChatMediaAttachments([
|
|
{
|
|
type: "file",
|
|
url: "https://cdn.example.com/清单.xlsx",
|
|
name: "清单.xlsx",
|
|
contentType:
|
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
},
|
|
{
|
|
type: "file",
|
|
url: "https://cdn.example.com/产品资料.folder.json",
|
|
name: "产品资料.folder.json",
|
|
contentType: "application/vnd.yedir.folder-manifest+json",
|
|
},
|
|
]);
|
|
|
|
expect(attachments).toHaveLength(2);
|
|
expect(
|
|
isOpenClawChatFileAttachment(
|
|
attachments[0].url,
|
|
attachments[0].content_type
|
|
)
|
|
).toBe(true);
|
|
expect(buildOpenClawFileReferenceText(attachments)).toContain("表格请下载");
|
|
expect(buildOpenClawFileReferenceText(attachments)).toContain(
|
|
"application/vnd.yedir.folder-manifest+json"
|
|
);
|
|
});
|
|
|
|
test("allows normal folder media while blocking executable web content", () => {
|
|
expect(
|
|
isOpenClawChatFolderFileAllowed({
|
|
name: "商品图/主图.png",
|
|
type: "image/png",
|
|
})
|
|
).toBe(true);
|
|
expect(
|
|
isOpenClawChatFolderFileAllowed({
|
|
name: "页面/index.html",
|
|
type: "text/html",
|
|
})
|
|
).toBe(false);
|
|
expect(
|
|
isOpenClawChatFolderFileAllowed({
|
|
name: "工具/setup.exe",
|
|
type: "application/octet-stream",
|
|
})
|
|
).toBe(false);
|
|
});
|
|
});
|