fix: 收口批次D并修复本地垃圾箱清空
This commit is contained in:
@@ -159,11 +159,15 @@ async function main() {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), `mnote-${TASK}-`));
|
||||
const rootUri = fileUrl(root);
|
||||
|
||||
// ── 测试数据:松散 Markdown 页面和非 md 资源 ──
|
||||
// ── 测试数据:两个松散 Markdown 页面和非 md 资源 ──
|
||||
const mdRelativePath = "docs/test-page.md";
|
||||
const mdDocId = `local-md:${encodeLocalIdSegment(mdRelativePath)}`; // local-md:docs~2Ftest-page.md
|
||||
const mdSourcePath = path.join(root, mdRelativePath);
|
||||
|
||||
const md2RelativePath = "docs/second-page.md";
|
||||
const md2DocId = `local-md:${encodeLocalIdSegment(md2RelativePath)}`; // local-md:docs~2Fsecond-page.md
|
||||
const md2SourcePath = path.join(root, md2RelativePath);
|
||||
|
||||
const assetRelativePath = "docs/resource.txt";
|
||||
const assetId = `local-file:${assetRelativePath}`; // local-file:docs/resource.txt
|
||||
const assetSourcePath = path.join(root, assetRelativePath);
|
||||
@@ -173,6 +177,7 @@ async function main() {
|
||||
writeWorkspaceManifest(root);
|
||||
fs.writeFileSync(path.join(root, "README.md"), "# Local Root\n", "utf8");
|
||||
fs.writeFileSync(mdSourcePath, "# Test Page\n\nPage content for empty-trash smoke.\n", "utf8");
|
||||
fs.writeFileSync(md2SourcePath, "# Second Page\n\nSecond page content for multi-purge smoke.\n", "utf8");
|
||||
fs.writeFileSync(assetSourcePath, "resource body for empty-trash smoke\n", "utf8");
|
||||
|
||||
const browser = await chromium.launch({
|
||||
@@ -203,6 +208,8 @@ async function main() {
|
||||
root,
|
||||
mdRelativePath,
|
||||
mdDocId,
|
||||
md2RelativePath,
|
||||
md2DocId,
|
||||
assetRelativePath,
|
||||
assetId,
|
||||
steps: [],
|
||||
@@ -227,6 +234,16 @@ async function main() {
|
||||
|| getTrashFilePath(root, mdDocId);
|
||||
assert.ok(mdTrashPath, `MD archive 应返回 trashPath, got: ${JSON.stringify(mdArchiveResult)}`);
|
||||
|
||||
// 归档第二个 Markdown 页面,覆盖清空页面垃圾箱多条目串行 purge
|
||||
const md2ArchiveResult = await postTreeCommand(rootUri, "delete", md2DocId);
|
||||
assert.equal(md2ArchiveResult.result?.execution?.resourceKind, "markdown",
|
||||
`MD2 archive resourceKind should be markdown, got: ${JSON.stringify(md2ArchiveResult)}`);
|
||||
assert.equal(fs.existsSync(md2SourcePath), false, "archive 后第二个 Markdown 源文件应移入垃圾箱");
|
||||
const md2TrashPath = md2ArchiveResult.result?.execution?.trashPath
|
||||
|| md2ArchiveResult.trashPath
|
||||
|| getTrashFilePath(root, md2DocId);
|
||||
assert.ok(md2TrashPath, `MD2 archive 应返回 trashPath, got: ${JSON.stringify(md2ArchiveResult)}`);
|
||||
|
||||
// 归档非 md 资源
|
||||
const assetArchiveResult = await postTreeCommand(rootUri, "delete", assetId);
|
||||
assert.equal(assetArchiveResult.result?.execution?.canonicalCommand, "tree.resource.archive",
|
||||
@@ -242,12 +259,14 @@ async function main() {
|
||||
label: "通过 tree command 归档 Markdown 页面和非 md 资源到垃圾箱",
|
||||
ok: true,
|
||||
mdTrashPath,
|
||||
md2TrashPath,
|
||||
assetTrashPath,
|
||||
});
|
||||
|
||||
// 验证 trash-index.json 包含两个 entry
|
||||
// 验证 trash-index.json 包含三个 entry
|
||||
const entriesBefore = readTrashIndex(root);
|
||||
assert.ok(entriesBefore[mdDocId], `trash-index 应包含 MD entry: ${mdDocId}`);
|
||||
assert.ok(entriesBefore[md2DocId], `trash-index 应包含第二个 MD entry: ${md2DocId}`);
|
||||
assert.ok(entriesBefore[assetId], `trash-index 应包含 asset entry: ${assetId}`);
|
||||
|
||||
// ════════════════════════════════════════════
|
||||
@@ -263,6 +282,11 @@ async function main() {
|
||||
const mdResourceKind = await mdTrashRow.getAttribute("data-resource-kind");
|
||||
assert.equal(mdResourceKind, "markdown", `MD trash row data-resource-kind 应为 "markdown", 实际: ${mdResourceKind}`);
|
||||
|
||||
const md2TrashRow = page.locator(`article[data-trash-row="local"][data-trash-entry-id="${md2DocId}"]`);
|
||||
await md2TrashRow.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
|
||||
const md2ResourceKind = await md2TrashRow.getAttribute("data-resource-kind");
|
||||
assert.equal(md2ResourceKind, "markdown", `第二个 MD trash row data-resource-kind 应为 "markdown", 实际: ${md2ResourceKind}`);
|
||||
|
||||
// Asset 行(资源垃圾箱)
|
||||
const assetTrashRow = page.locator(`article[data-trash-row="local"][data-trash-entry-id="${assetId}"]`);
|
||||
await assetTrashRow.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
|
||||
@@ -305,11 +329,19 @@ async function main() {
|
||||
mdDocId,
|
||||
{ timeout: UI_TIMEOUT_MS },
|
||||
);
|
||||
await page.waitForFunction(
|
||||
(id) => !document.querySelector(`[data-trash-entry-id="${id}"]`),
|
||||
md2DocId,
|
||||
{ timeout: UI_TIMEOUT_MS },
|
||||
);
|
||||
|
||||
// 现在重新获取 DOM 引用验证
|
||||
const mdRowAfterEmptyDocs = page.locator(`article[data-trash-row="local"][data-trash-entry-id="${mdDocId}"]`);
|
||||
const mdRowCountAfterEmptyDocs = await mdRowAfterEmptyDocs.count();
|
||||
assert.equal(mdRowCountAfterEmptyDocs, 0, "清空页面垃圾箱后 MD 行应消失");
|
||||
const md2RowAfterEmptyDocs = page.locator(`article[data-trash-row="local"][data-trash-entry-id="${md2DocId}"]`);
|
||||
const md2RowCountAfterEmptyDocs = await md2RowAfterEmptyDocs.count();
|
||||
assert.equal(md2RowCountAfterEmptyDocs, 0, "清空页面垃圾箱后第二个 MD 行应消失");
|
||||
|
||||
// 文档行消失后,资源行应仍然存在
|
||||
const assetRowAfterEmptyDocs = page.locator(`article[data-trash-row="local"][data-trash-entry-id="${assetId}"]`);
|
||||
@@ -323,9 +355,13 @@ async function main() {
|
||||
// 验证文件系统:trash 文件和 trash-index
|
||||
const mdEntryAfterEmptyDocs = getTrashEntry(root, mdDocId);
|
||||
assert.equal(mdEntryAfterEmptyDocs, null, `清空页面垃圾箱后 trash-index 不应包含 MD entry: ${mdDocId}`);
|
||||
const md2EntryAfterEmptyDocs = getTrashEntry(root, md2DocId);
|
||||
assert.equal(md2EntryAfterEmptyDocs, null, `清空页面垃圾箱后 trash-index 不应包含第二个 MD entry: ${md2DocId}`);
|
||||
|
||||
const resolvedMdTrashPath = path.resolve(root, mdTrashPath);
|
||||
assert.equal(fs.existsSync(resolvedMdTrashPath), false, `清空页面垃圾箱后 trash 文件应删除: ${resolvedMdTrashPath}`);
|
||||
const resolvedMd2TrashPath = path.resolve(root, md2TrashPath);
|
||||
assert.equal(fs.existsSync(resolvedMd2TrashPath), false, `清空页面垃圾箱后第二个 trash 文件应删除: ${resolvedMd2TrashPath}`);
|
||||
|
||||
// 导航断言:清空操作不应触发页面导航
|
||||
const navAfterEmptyDocs = navigationEvents.length;
|
||||
@@ -338,7 +374,9 @@ async function main() {
|
||||
navDelta: emptyDocsNavDelta,
|
||||
dialogAccepted: true,
|
||||
mdEntryClean: mdEntryAfterEmptyDocs === null,
|
||||
md2EntryClean: md2EntryAfterEmptyDocs === null,
|
||||
mdFileGone: !fs.existsSync(resolvedMdTrashPath),
|
||||
md2FileGone: !fs.existsSync(resolvedMd2TrashPath),
|
||||
};
|
||||
evidence.steps.push({
|
||||
step: 3,
|
||||
@@ -415,6 +453,7 @@ async function main() {
|
||||
|
||||
// 验证原始源文件不应恢复
|
||||
assert.equal(fs.existsSync(mdSourcePath), false, "清空垃圾箱后 MD 源文件不应恢复");
|
||||
assert.equal(fs.existsSync(md2SourcePath), false, "清空垃圾箱后第二个 MD 源文件不应恢复");
|
||||
assert.equal(fs.existsSync(assetSourcePath), false, "清空垃圾箱后资源源文件不应恢复");
|
||||
|
||||
evidence.steps.push({
|
||||
|
||||
Reference in New Issue
Block a user