2026-07-30 12:06:41 +08:00
|
|
|
|
import assert from "node:assert/strict";
|
|
|
|
|
|
import { access, readFile } from "node:fs/promises";
|
|
|
|
|
|
import test from "node:test";
|
|
|
|
|
|
import {
|
|
|
|
|
|
formatShanghaiDate,
|
|
|
|
|
|
parseStoredDate,
|
|
|
|
|
|
} from "../app/date-utils.ts";
|
|
|
|
|
|
|
|
|
|
|
|
test("builds the branded external task shell", async () => {
|
|
|
|
|
|
const [page, layout] = await Promise.all([
|
|
|
|
|
|
readFile(new URL("../app/page.tsx", import.meta.url), "utf8"),
|
|
|
|
|
|
readFile(new URL("../app/layout.tsx", import.meta.url), "utf8"),
|
|
|
|
|
|
]);
|
|
|
|
|
|
assert.match(layout, /KOC LOOP|外部任务领取/);
|
|
|
|
|
|
assert.match(layout, /og\.png/);
|
|
|
|
|
|
assert.match(page, /正在打开任务/);
|
2026-08-11 23:07:26 +08:00
|
|
|
|
await access(new URL("../out/index.html", import.meta.url));
|
2026-07-30 12:06:41 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test("keeps claiming minimal and backfill one-to-one", async () => {
|
2026-08-12 20:44:57 +08:00
|
|
|
|
const [page, layout, packageJson, nextConfig, styles] =
|
2026-07-30 12:06:41 +08:00
|
|
|
|
await Promise.all([
|
|
|
|
|
|
readFile(new URL("../app/page.tsx", import.meta.url), "utf8"),
|
|
|
|
|
|
readFile(new URL("../app/layout.tsx", import.meta.url), "utf8"),
|
|
|
|
|
|
readFile(new URL("../package.json", import.meta.url), "utf8"),
|
2026-08-11 23:07:26 +08:00
|
|
|
|
readFile(new URL("../next.config.ts", import.meta.url), "utf8"),
|
2026-08-12 20:44:57 +08:00
|
|
|
|
readFile(new URL("../app/globals.css", import.meta.url), "utf8"),
|
2026-07-30 12:06:41 +08:00
|
|
|
|
]);
|
|
|
|
|
|
|
2026-08-03 13:48:01 +08:00
|
|
|
|
assert.match(page, /微信号\s*\/\s*手机号/);
|
|
|
|
|
|
assert.doesNotMatch(page, /企微昵称\s*\/\s*联系人/);
|
|
|
|
|
|
assert.match(page, /claimantIdentifier:\s*claimantName/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.match(page, /const \[quantity, setQuantity\] = useState\(1\)/);
|
|
|
|
|
|
assert.match(page, /distributionId:\s*selected\.id/);
|
2026-08-05 11:40:29 +08:00
|
|
|
|
assert.doesNotMatch(page, /发布账号昵称/);
|
|
|
|
|
|
assert.doesNotMatch(page, /accountNickname/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.match(page, /发布链接/);
|
2026-08-05 11:40:29 +08:00
|
|
|
|
assert.match(page, /识别发布账号/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.match(page, /inputMode="url"/);
|
2026-08-15 03:53:09 +08:00
|
|
|
|
assert.match(page, /作品链接或整段分享文案/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.doesNotMatch(page, /type="url"/);
|
|
|
|
|
|
assert.match(page, /发布截图/);
|
|
|
|
|
|
assert.match(page, /发布配图/);
|
|
|
|
|
|
assert.match(page, /复制标题/);
|
|
|
|
|
|
assert.match(page, /复制文案/);
|
|
|
|
|
|
assert.match(page, /下载原图/);
|
2026-08-15 03:53:09 +08:00
|
|
|
|
assert.match(page, /下载视频/);
|
|
|
|
|
|
assert.match(page, /download\s*=\s*false/);
|
|
|
|
|
|
assert.match(page, /params\.set\("download", "1"\)/);
|
|
|
|
|
|
assert.match(page, /视频-\$\{index \+ 1\}\.mp4/);
|
|
|
|
|
|
assert.match(page, /function PlatformBadge/);
|
|
|
|
|
|
assert.match(page, /platform-logo/);
|
|
|
|
|
|
assert.match(page, /logoOnly/);
|
|
|
|
|
|
assert.match(page, /platform-video-thumb/);
|
|
|
|
|
|
assert.match(styles, /\.platform-logo\.xiaohongshu/);
|
|
|
|
|
|
assert.match(styles, /\.platform-logo\.douyin/);
|
|
|
|
|
|
assert.match(styles, /\.platform-badge\.logo-only/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.match(page, /批量保存图片/);
|
2026-08-15 03:53:09 +08:00
|
|
|
|
assert.match(page, /导出Excel/);
|
|
|
|
|
|
assert.match(page, /上传回填表/);
|
|
|
|
|
|
assert.match(page, /\/api\/partner-batch-workbook/);
|
|
|
|
|
|
assert.match(page, /compactPartnerBatchWorkbookForUpload/);
|
|
|
|
|
|
assert.match(page, /Content-Type/);
|
|
|
|
|
|
assert.match(page, /response\.status === 413/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.match(page, /navigator\.share/);
|
|
|
|
|
|
assert.match(page, /zipSync/);
|
|
|
|
|
|
assert.match(page, /navigator\.clipboard\.writeText/);
|
|
|
|
|
|
assert.match(page, /URL\.createObjectURL/);
|
|
|
|
|
|
assert.match(page, /\/api\/partner-image/);
|
|
|
|
|
|
assert.match(page, /找回领取记录/);
|
|
|
|
|
|
assert.match(page, /action:\s*"recover"/);
|
|
|
|
|
|
assert.match(page, /同一任务多次领取会分批展示/);
|
2026-08-16 22:22:50 +08:00
|
|
|
|
assert.match(page, /这篇笔记的发布记录回填成功啦~/);
|
|
|
|
|
|
assert.match(page, /toastClassName\(toast\)/);
|
|
|
|
|
|
assert.match(styles, /\.toast\.success/);
|
2026-08-12 20:44:57 +08:00
|
|
|
|
assert.match(page, /笔记内容已收起/);
|
|
|
|
|
|
assert.match(page, /展开笔记内容/);
|
|
|
|
|
|
assert.match(page, /收起笔记内容/);
|
|
|
|
|
|
assert.match(page, /isFirstBackfill/);
|
|
|
|
|
|
assert.match(page, /scrollIntoView/);
|
|
|
|
|
|
assert.match(page, /matchMedia\("\(max-width: 620px\)"\)/);
|
|
|
|
|
|
assert.match(styles, /\.note-document\.mobile-collapsed/);
|
2026-08-15 03:53:09 +08:00
|
|
|
|
assert.match(page, /批量回填/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.doesNotMatch(page, /复制标题和正文/);
|
2026-08-11 23:07:26 +08:00
|
|
|
|
assert.match(page, /CONFIGURED_ADMIN_ORIGIN/);
|
|
|
|
|
|
assert.match(page, /window\.location\.origin/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.match(page, /\/api\/partner-upload/);
|
|
|
|
|
|
assert.match(page, /"X-KOC-Distribution":\s*selectedItem\.id/);
|
|
|
|
|
|
assert.match(page, /"X-KOC-Upload-Kind":\s*kind/);
|
|
|
|
|
|
assert.match(page, /上传截图并填写数据/);
|
|
|
|
|
|
assert.match(page, /提交创作者数据/);
|
|
|
|
|
|
assert.match(page, /submit_creator_metrics/);
|
|
|
|
|
|
assert.match(page, /creatorExposure/);
|
|
|
|
|
|
assert.match(page, /creatorViews/);
|
2026-08-19 15:08:17 +08:00
|
|
|
|
assert.match(page, /上传后自动识别曝光量和阅读量,识别失败可手动填写/);
|
2026-08-11 23:07:26 +08:00
|
|
|
|
assert.match(page, /evidenceImageUrl/);
|
2026-08-16 22:22:50 +08:00
|
|
|
|
assert.match(page, /params\.set\("v", evidenceKey\)/);
|
2026-08-11 23:07:26 +08:00
|
|
|
|
assert.match(page, /evidenceImageUrl\(selected, "publish"\)/);
|
|
|
|
|
|
assert.match(page, /evidenceImageUrl\(selected, "creator"\)/);
|
|
|
|
|
|
assert.match(page, /ImageLightbox/);
|
|
|
|
|
|
assert.match(page, /点击查看大图/);
|
|
|
|
|
|
assert.match(page, /publishScreenshotPreview/);
|
|
|
|
|
|
assert.match(page, /creatorScreenshotPreview/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.match(page, /曝光量/);
|
|
|
|
|
|
assert.match(page, /阅读量/);
|
2026-08-16 22:22:50 +08:00
|
|
|
|
assert.match(page, /placeholder="填写截图中的曝光量"\s*\/>/);
|
|
|
|
|
|
assert.match(page, /placeholder="填写截图中的阅读量"\s*\/>/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.doesNotMatch(page, /recognizeCreatorMetrics/);
|
2026-08-11 23:07:26 +08:00
|
|
|
|
assert.match(page, /note-index \$\{\(isScreenshotTask \? item\.result_submitted_at : item\.publish_url\) \? "done" : ""\}/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.match(packageJson, /"fflate":\s*"0\.7\.4"/);
|
|
|
|
|
|
assert.doesNotMatch(packageJson, /tesseract\.js/);
|
|
|
|
|
|
assert.match(layout, /逐篇查看笔记详情并一一回填/);
|
|
|
|
|
|
assert.doesNotMatch(packageJson, /react-loading-skeleton/);
|
2026-08-11 23:07:26 +08:00
|
|
|
|
assert.match(nextConfig, /output: "export"/);
|
|
|
|
|
|
assert.match(nextConfig, /basePath: "\/koc"/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
|
|
|
|
|
|
await access(new URL("../public/og.png", import.meta.url));
|
|
|
|
|
|
await access(new URL("../public/favicon.svg", import.meta.url));
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2026-08-11 23:07:26 +08:00
|
|
|
|
test("renders screenshot-only tasks with anonymous delegation and multi-image uploads", async () => {
|
|
|
|
|
|
const [page, styles] = await Promise.all([
|
|
|
|
|
|
readFile(new URL("../app/page.tsx", import.meta.url), "utf8"),
|
|
|
|
|
|
readFile(new URL("../app/globals.css", import.meta.url), "utf8"),
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
assert.match(page, /screenshot_collect/);
|
|
|
|
|
|
assert.match(page, /小红书搜索关键词/);
|
|
|
|
|
|
assert.match(page, /上传小红书 AI 总结截图/);
|
|
|
|
|
|
assert.match(page, /submit_screenshot_result/);
|
|
|
|
|
|
assert.match(page, /"task-result"/);
|
|
|
|
|
|
assert.match(page, /不需要填写发布链接或其他数据/);
|
|
|
|
|
|
assert.match(page, /multiple/);
|
|
|
|
|
|
assert.match(page, /taskResultScreenshots/);
|
|
|
|
|
|
assert.match(page, /task-result-thumb/);
|
|
|
|
|
|
assert.match(page, /最多9张/);
|
|
|
|
|
|
assert.doesNotMatch(page, /target="_blank"[\s\S]{0,200}task-result-thumb uploaded/);
|
|
|
|
|
|
assert.match(styles, /\.task-result-gallery/);
|
|
|
|
|
|
assert.match(styles, /\.image-lightbox/);
|
|
|
|
|
|
assert.match(styles, /\.evidence-preview-button/);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2026-08-19 15:08:17 +08:00
|
|
|
|
test("shows D1 and MySQL UTC timestamps in Beijing time", () => {
|
2026-07-30 12:06:41 +08:00
|
|
|
|
const stored = "2026-07-29 05:36:00";
|
|
|
|
|
|
assert.equal(parseStoredDate(stored).toISOString(), "2026-07-29T05:36:00.000Z");
|
|
|
|
|
|
assert.match(formatShanghaiDate(stored, true), /07\/29.*13:36/);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
test("creates anonymous delegation bundles and reuses one-to-one backfill", async () => {
|
|
|
|
|
|
const [page, layout, styles] = await Promise.all([
|
|
|
|
|
|
readFile(new URL("../app/page.tsx", import.meta.url), "utf8"),
|
|
|
|
|
|
readFile(new URL("../app/layout.tsx", import.meta.url), "utf8"),
|
|
|
|
|
|
readFile(new URL("../app/globals.css", import.meta.url), "utf8"),
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
assert.match(page, /选择笔记并分享/);
|
|
|
|
|
|
assert.match(page, /生成并复制分享链接/);
|
|
|
|
|
|
assert.match(page, /action:\s*"create_delegation"/);
|
|
|
|
|
|
assert.match(page, /action:\s*"revoke_delegation"/);
|
|
|
|
|
|
assert.match(page, /合作社转派 · 无需登录/);
|
|
|
|
|
|
assert.match(page, /"X-KOC-Delegation"/);
|
2026-08-12 19:53:19 +08:00
|
|
|
|
assert.match(page, /const url = new URL\(window\.location\.href\)/);
|
|
|
|
|
|
assert.match(page, /url\.search = ""/);
|
|
|
|
|
|
assert.doesNotMatch(page, /const url = new URL\(window\.location\.origin\)/);
|
2026-07-30 12:06:41 +08:00
|
|
|
|
assert.match(page, /url\.searchParams\.set\("share", shareToken\)/);
|
|
|
|
|
|
assert.match(page, /请保存当前分享链接/);
|
|
|
|
|
|
assert.doesNotMatch(page, /底层KOC手机号|底层KOC企微|底层KOC微信/);
|
|
|
|
|
|
assert.match(layout, /index:\s*false/);
|
|
|
|
|
|
assert.match(layout, /referrer:\s*"no-referrer"/);
|
|
|
|
|
|
assert.match(styles, /\.share-checkbox/);
|
|
|
|
|
|
assert.match(styles, /\.delegation-history/);
|
|
|
|
|
|
});
|