fix: 修复两端走查发现的4个UI断点
- 门户回填表单:缺发布截图时提交按钮前置禁用并提示「先上传发布截图,
链接回填需以截图为凭证」,不再等提交后才 toast 报错(服务端守卫保留)
- 门户笔记详情:回填链接前收起回收区块的说明与示例图,只留一行锁定提示,
降低回填阶段信息密度
- 运营端分发表:数据状态按任务采集计划显示等待日(等待D{首个采集日}),
未设置计划时显示「待设置采集计划」,不再写死「等待D2」
- 截图包回收清单:序号列对无 source_row 的内容回退行号;种子内容补
source_row,演示数据导出不再出现空序号
This commit is contained in:
67
tests/ui-walkthrough-fixes.test.mjs
Normal file
67
tests/ui-walkthrough-fixes.test.mjs
Normal file
@@ -0,0 +1,67 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
|
||||
// 2026-10-08 两端走查发现的 UI 断点修复:
|
||||
// 1) 回填提交在缺发布截图时前置禁用并说明原因(原本只在提交后 toast 报错)
|
||||
// 2) 未回填链接时收起回收区块的说明/示例图,只留锁定提示
|
||||
// 3) 分发表「数据状态」按任务采集计划显示等待日,没计划时明说待设置
|
||||
// 4) 截图包回收清单的序号列对无 source_row 的内容回退为行号;种子内容补 source_row
|
||||
|
||||
test("portal gates the backfill submit button on the publish screenshot", async () => {
|
||||
const source = await readFile(
|
||||
new URL("../koc-portal/app/page.tsx", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
assert.match(
|
||||
source,
|
||||
/disabled=\{working \|\| !\(screenshot \|\| selected\.publish_screenshot_key\)\}/,
|
||||
);
|
||||
assert.match(source, /先上传发布截图,链接回填需以截图为凭证/);
|
||||
// 服务端/提交守卫仍保留,双保险
|
||||
assert.match(source, /请上传这篇笔记的发布截图/);
|
||||
});
|
||||
|
||||
test("portal collapses recovery instructions until the link is backfilled", async () => {
|
||||
const source = await readFile(
|
||||
new URL("../koc-portal/app/page.tsx", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
const lockedHint = "回填发布链接后,这里会开放回收截图上传。";
|
||||
assert.ok(source.includes(lockedHint), "锁定提示必须保留");
|
||||
const tipIndex = source.indexOf(
|
||||
`{selected.publish_url && (\n <p className="creator-recovery-tip">`,
|
||||
);
|
||||
assert.ok(tipIndex > 0, "回收说明必须由 publish_url 门控");
|
||||
// 示例图区块同样门控
|
||||
assert.match(
|
||||
source,
|
||||
/\{selected\.publish_url &&\n \(payload\.task\.recoveryExampleImages\?\.length \?\? 0\) > 0 && \(/,
|
||||
);
|
||||
});
|
||||
|
||||
test("admin waiting label follows the task collection plan", async () => {
|
||||
const [adminApp, mvpDb] = await Promise.all([
|
||||
readFile(new URL("../app/admin-app.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../lib/mvp-db.ts", import.meta.url), "utf8"),
|
||||
]);
|
||||
assert.match(adminApp, /waitingCollectionLabel/);
|
||||
assert.match(adminApp, /待设置采集计划/);
|
||||
assert.match(adminApp, /等待D\$\{Math\.min\(\.\.\.days\)\}/);
|
||||
assert.doesNotMatch(adminApp, /"等待D2"/);
|
||||
// 分发查询带上任务级采集计划字段
|
||||
assert.match(mvpDb, /t\.collection_days AS task_collection_days/);
|
||||
assert.match(mvpDb, /t\.collection_start_date AS task_collection_start_date/);
|
||||
});
|
||||
|
||||
test("export manifest and seed contents always carry a sequence number", async () => {
|
||||
const [exportRoute, seed] = await Promise.all([
|
||||
readFile(
|
||||
new URL("../app/api/screenshot-task-export/route.ts", import.meta.url),
|
||||
"utf8",
|
||||
),
|
||||
readFile(new URL("../lib/mvp-db.ts", import.meta.url), "utf8"),
|
||||
]);
|
||||
assert.match(exportRoute, /String\(row\.source_row \?\? rowIndex \+ 1\)/);
|
||||
assert.match(seed, /INSERT INTO contents \(id, task_id, title, body, status, source_row\)/);
|
||||
});
|
||||
Reference in New Issue
Block a user