fix local folder upload intent contract

This commit is contained in:
lix-2026
2026-05-24 02:34:52 +08:00
parent 6d9d8ce9cd
commit ae6bbc9656
5 changed files with 136 additions and 29 deletions
@@ -109,6 +109,20 @@ async function waitForFileExists(filePath, timeoutMs) {
return fs.existsSync(filePath);
}
async function waitForUploadAsset(uploadResponses, startIndex, predicate, timeoutMs) {
const startedAt = Date.now();
let seen = [];
while (Date.now() - startedAt < timeoutMs) {
seen = uploadResponses.slice(startIndex);
for (const entry of seen) {
const asset = entry?.payload?.asset;
if (asset && predicate(asset, entry)) return asset;
}
await new Promise((resolve) => setTimeout(resolve, 100));
}
throw new Error(`未捕获到符合条件的上传响应: ${JSON.stringify(seen).slice(0, 1000)}`);
}
async function waitForFileContent(filePath, predicate, timeoutMs) {
const startedAt = Date.now();
let lastContent = "";
@@ -257,6 +271,12 @@ async function main() {
const page = await context.newPage();
const popups = [];
page.on("popup", (popup) => popups.push(popup));
const uploadResponses = [];
page.on("response", async (response) => {
if (!response.url().includes("/api/local-folder/assets/upload")) return;
const payload = await response.json().catch(() => null);
uploadResponses.push({ status: response.status(), payload });
});
const screenshots = [];
const checks = {};
@@ -282,8 +302,15 @@ async function main() {
timeout: UI_TIMEOUT_MS,
});
const uploadStart = uploadResponses.length;
// 通过主编辑区斜杠上传上传一个 MD 文件
await uploadAttachmentViaPrimarySlash(page, "uploaded-one.md", "# Uploaded One\n\n第一个上传附件\n");
const uploadAsset = await waitForUploadAsset(
uploadResponses,
uploadStart,
(asset) => asset.file_name === "uploaded-one.md",
UI_TIMEOUT_MS,
);
// 等待后端 write_local_markdown_asset() 落盘
const correctPath = path.join(resourceDir, "uploaded-one.md");
@@ -296,12 +323,17 @@ async function main() {
`上传文件应落在 page resource directory (${correctPath})。`
+ ` landedInRoot=${landedInRoot} correctPath=${correctPath}`,
);
assert.equal(uploadAsset.uploadIntent, "editor.markdown.attach", "主编辑区上传响应应返回 editor.markdown.attach intent");
assert.equal(uploadAsset.rootRelativePath, "README/uploaded-one.md", "主编辑区上传响应应返回 page resource rootRelativePath");
assert.equal(uploadAsset.markdownRelativePath, "README/uploaded-one.md", "主编辑区上传响应应返回 markdownRelativePath");
assert.equal(uploadAsset.ownerDocumentId, "local-md:README.md", "主编辑区上传响应应返回 ownerDocumentId");
checks[checkId] = {
ok: true,
message: `上传文件落在资源目录 ${correctPath}`,
landedInResourceDir,
landedInRoot,
uploadAsset,
};
} catch (err) {
overallOk = false;
@@ -332,6 +364,7 @@ async function main() {
const droppedFileName = "drag-dropped-note.md";
const droppedContent = "# Drag Dropped\n\n从外部拖入\n";
const uploadStart = uploadResponses.length;
// 使用 dispatchEvent 模拟外部文件拖入 docs 文件夹
await docsFolderRow.dispatchEvent("dragover", {
@@ -358,7 +391,18 @@ async function main() {
// 等待文件落盘
const droppedPath = path.join(root, "docs", droppedFileName);
const exists = await waitForFileExists(droppedPath, UI_TIMEOUT_MS);
const uploadAsset = await waitForUploadAsset(
uploadResponses,
uploadStart,
(asset) => asset.file_name === droppedFileName,
UI_TIMEOUT_MS,
);
assert(exists, `拖入 docs 文件夹后文件应出现在 ${droppedPath}`);
assert.equal(uploadAsset.uploadIntent, "filetree.folder.drop", "文件树 folder drop 响应应返回 filetree.folder.drop intent");
assert.equal(uploadAsset.rootRelativePath, "docs/drag-dropped-note.md", "文件树 folder drop 响应应返回目标目录 rootRelativePath");
assert.equal(uploadAsset.targetRelativePath, "docs", "文件树 folder drop 响应应返回 targetRelativePath");
assert.equal(uploadAsset.markdownRelativePath, null, "文件树 folder drop 不应返回 markdownRelativePath");
assert.equal(uploadAsset.ownerDocumentId, null, "文件树 folder drop 不应返回 ownerDocumentId");
// 确保没有出现在 root 或 README/ 下
const wrongPath = path.join(root, droppedFileName);
@@ -373,6 +417,7 @@ async function main() {
message: `外部拖入文件进入目标文件夹 docs/`,
droppedPath,
exists,
uploadAsset,
};
} catch (err) {
overallOk = false;