修复工单权限收回后上传队列继续执行

This commit is contained in:
cieanyau committed 2026-11-07 01:06:59 +08:00
1 parent c3467875c6
commit 339df89fcf
2 files changed
+100

No files matched your search

+99
View File
@@ -435,3 +435,102 @@ for (const [routePath, status] of [
}),
);
}
test(
"in-flight ticket uploads stop the remaining files when server permission is revoked",
{ timeout: 25000 },
(t) =>
scenario(t, { loginMode: "password-only" }, async (page) => {
const uploads = [];
const ticket = {
id: 2,
ticket_num: "AUDIT-2",
title: "上传期间关闭工单",
content: "<p>本机权限并发验收</p>",
status: "处理中",
can_operate: 1,
create_time: 1730000000,
username: "audit-user",
client_id: 1,
color: "#777",
attachment: [],
replies: [],
};
let releaseFirstUpload;
const firstUploadResponse = new Promise((resolve) => {
releaseFirstUpload = resolve;
});
await page.route(
(url) =>
url.origin === backendOrigin &&
(url.pathname.startsWith("/console/v1/ticket/") ||
url.pathname === "/console/v1/upload"),
async (route) => {
const request = route.request();
const path = new URL(request.url()).pathname.replace(
"/console/v1",
"",
);
if (path === "/ticket/config")
return fulfillApi(route, { ticket_notice_open: 0 });
if (request.method() === "GET" && path === "/ticket/2")
return fulfillApi(route, { ticket });
if (request.method() === "PUT" && path === "/ticket/2/close") {
ticket.can_operate = 0;
ticket.status = "处理完毕";
return fulfillApi(route, {});
}
if (request.method() === "POST" && path === "/upload") {
const index = uploads.push({ method: "POST", path });
if (index === 1) await firstUploadResponse;
return fulfillApi(route, { save_name: `attachment-${index}.txt` });
}
return route.fallback();
},
);
try {
await login(page, "/tickets/2");
await page
.getByRole("heading", { name: ticket.title, exact: true })
.waitFor();
await page.locator("#reply-files").setInputFiles(
["first.txt", "second.txt"].map((name) => ({
name,
mimeType: "text/plain",
buffer: Buffer.from("local permission regression"),
})),
);
await eventually(
() => uploads.length,
(count) => count === 1,
"First upload reached the local HTTP boundary",
);
await page
.getByRole("button", { name: "关闭工单", exact: true })
.click();
await page
.getByRole("button", { name: "关闭工单", exact: true })
.waitFor({ state: "hidden" });
releaseFirstUpload();
await page
.getByText("正在上传…", { exact: true })
.waitFor({ state: "hidden" });
assert.equal(
uploads.length,
1,
"Revoked permission must stop the second upload",
);
assert.equal(await page.locator(".reply-file-list").count(), 0);
return {
selectedFiles: 2,
uploadsStarted: uploads.length,
serverCanOperate: ticket.can_operate,
alreadyStartedUploadCompleted: true,
remainingUploadsStopped: true,
revokedUploadNotAddedToDraft: true,
};
} finally {
releaseFirstUpload();
}
}),
);