const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const { Module } = require('node:module'); const ts = require('typescript'); const file = path.join(__dirname, '../src/utils/account-collection-status.ts'); const loaded = new Module(file, module); loaded.filename = file; loaded.paths = module.paths; loaded._compile(ts.transpileModule(fs.readFileSync(file, 'utf8'), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, }).outputText, file); const { collectionStatusPresentation, accountCollectionStatusPresentation } = loaded.exports; for (const [status, text, color] of [ ['idle', '待采集', 'default'], ['pending', '待采集', 'default'], ['running', '采集运行中', 'processing'], ['succeeded', '采集完成', 'success'], ['failed', '采集失败', 'error'], ['blocked', '采集受阻', 'warning'], ]) { test(`collection status ${status} has an explicit label`, () => { assert.deepEqual(collectionStatusPresentation({ status }), { text, color, reason: '' }); }); } test('login errors are visible in Chinese and never render healthy', () => { for (const status of ['blocked', 'failed', 'succeeded']) { const result = collectionStatusPresentation({ status, last_error: 'browser is awaiting user login' }); assert.equal(result.text, '需要登录'); assert.equal(result.color, 'warning'); assert.equal(result.reason, '浏览器需要登录,请登录并同步账号后重试。'); } }); test('unknown errors retain their original information', () => { const reason = 'Douyin response HTTP 502: unexpected identity payload'; assert.equal(collectionStatusPresentation({ status: 'blocked', last_error: reason }).reason, reason); }); test('missing and unrecognized states are unknown, never completed or pending', () => { for (const checkpoint of [undefined, null, {}, { status: 'unrecognized' }]) { assert.equal(collectionStatusPresentation(checkpoint).text, '状态未知'); assert.equal(collectionStatusPresentation(checkpoint).color, 'default'); } }); for (const [left, right, text] of [ ['succeeded', 'succeeded', '采集完成'], ['succeeded', 'pending', '待采集'], ['idle', 'idle', '待采集'], ['pending', 'running', '采集运行中'], ['running', 'blocked', '采集受阻'], ['blocked', 'failed', '采集失败'], ['failed', 'running', '采集失败'], ['succeeded', 'unknown', '状态未知'], ['running', 'unknown', '状态未知'], ]) { test(`combined collection state prioritizes ${text} for ${left}/${right}, independent of source order`, () => { assert.equal(accountCollectionStatusPresentation({ status: left }, { status: right }).text, text); assert.equal(accountCollectionStatusPresentation({ status: right }, { status: left }).text, text); }); } test('combined login-required state takes priority and preserves all distinct errors', () => { const result = accountCollectionStatusPresentation( { status: 'blocked', last_error: 'browser is awaiting user login' }, { status: 'failed', last_error: 'network HTTP 502' }, ); assert.deepEqual(result, { text: '需要登录', color: 'warning', reason: '浏览器需要登录,请登录并同步账号后重试。;network HTTP 502', }); }); test('combined errors are deduplicated without adding source labels or times', () => { const result = accountCollectionStatusPresentation( { status: 'failed', last_error: 'network HTTP 502', last_completed_at: '2026-10-06T16:47:46Z' }, { status: 'blocked', last_error: 'network HTTP 502', last_completed_at: '2026-10-06T15:00:00Z' }, ); assert.equal(result.text, '采集失败'); assert.equal(result.reason, 'network HTTP 502'); assert.doesNotMatch(JSON.stringify(result), /作品|评论|2026-10-06/); }); test('missing collection data must not become a combined healthy state', () => { assert.equal(accountCollectionStatusPresentation().text, '状态未知'); assert.equal(accountCollectionStatusPresentation({ status: 'succeeded' }).text, '状态未知'); assert.equal(accountCollectionStatusPresentation(undefined, { status: 'succeeded' }).text, '状态未知'); });