Files
koc-loop/tests/ui-walkthrough-fixes.test.mjs
ABAPPLO c54649258b fix: 修复两端走查发现的4个UI断点
- 门户回填表单:缺发布截图时提交按钮前置禁用并提示「先上传发布截图,
  链接回填需以截图为凭证」,不再等提交后才 toast 报错(服务端守卫保留)
- 门户笔记详情:回填链接前收起回收区块的说明与示例图,只留一行锁定提示,
  降低回填阶段信息密度
- 运营端分发表:数据状态按任务采集计划显示等待日(等待D{首个采集日}),
  未设置计划时显示「待设置采集计划」,不再写死「等待D2」
- 截图包回收清单:序号列对无 source_row 的内容回退行号;种子内容补
  source_row,演示数据导出不再出现空序号
2026-10-08 14:44:47 +08:00

68 lines
3.0 KiB
JavaScript

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\)/);
});