import test from 'node:test' import assert from 'node:assert/strict' import { readSource } from './helpers.ts' import { isTerminalTaskStatus, normalizeResultFile, normalizeTaskStatus, toResultId, toTaskId, } from '../src/pages/tasks/task-model.ts' test('test_task_101_task_types_normal_primary_path', () => { // 正常主路径:任务/结果 id 归一与结果文件解析(蛇形 payload)为类型化描述。 assert.equal(normalizeTaskStatus('SUCCESS'), 'SUCCESS') assert.equal(toResultId(123), '123') const file = normalizeResultFile({ result_id: 123, output_filename: 'shop_data_DE.xlsx', file_url: 'https://oss.aishufu.top/shop_data_DE.xlsx', file_size: 2048, status: 'SUCCESS', }) assert.ok(file) assert.equal(file!.resultId, '123') assert.equal(file!.filename, 'shop_data_DE.xlsx') assert.equal(file!.url, 'https://oss.aishufu.top/shop_data_DE.xlsx') assert.equal(file!.size, 2048) assert.equal(file!.status, 'SUCCESS') }) test('test_task_101_task_types_normal_variant_input', () => { // 正常变体:camel payload 与状态同义词归一。 const file = normalizeResultFile({ resultId: 9, filename: 'a.zip', fileUrl: 'http://x/a.zip', status: 'completed' }) assert.ok(file) assert.equal(file!.status, 'SUCCESS') assert.equal(normalizeTaskStatus('done'), 'SUCCESS') assert.equal(normalizeTaskStatus('running'), 'RUNNING') assert.equal(toTaskId('task-7'), 'task-7') }) test('test_task_101_task_types_repeated_is_idempotent', () => { // 正常重复:归一稳定、不改输入。 const raw = { result_id: 2, filename: 'b', status: 'pending' } assert.deepEqual(normalizeResultFile(raw), normalizeResultFile(raw)) assert.deepEqual(raw, { result_id: 2, filename: 'b', status: 'pending' }) assert.equal(normalizeTaskStatus('SUCCESS'), normalizeTaskStatus('success')) }) test('test_task_101_task_types_boundary_empty_input', () => { // 边界空值:缺 id/文件名视为无效描述。 assert.equal(normalizeResultFile(null), null) assert.equal(normalizeResultFile({ filename: 'no-id' }), null) }) test('test_task_101_task_types_boundary_single_item', () => { // 边界单元素:单条描述字段完整;未知状态归 UNKNOWN。 const file = normalizeResultFile({ result_id: 1, filename: 'f', url: 'http://u', status: 'weird' }) assert.ok(file) assert.equal(file!.status, 'UNKNOWN') }) test('test_task_101_task_types_boundary_limit_or_missing_field', () => { // 边界上限/缺字段:可选 size/error 缺省可空。 const file = normalizeResultFile({ result_id: 4, filename: 'g', fileUrl: 'http://u/g' }) assert.ok(file) assert.equal(file!.size, undefined) assert.equal(file!.error, undefined) assert.equal(file!.url, 'http://u/g') }) test('test_task_101_task_types_invalid_input_rejected', () => { // 异常输入:空白/非法 id 与未知状态被拒绝或归 UNKNOWN。 assert.equal(normalizeResultFile({ result_id: '', filename: 'x' }), null) assert.equal(toResultId(''), '') assert.equal(isTerminalTaskStatus('SUCCESS'), true) assert.equal(isTerminalTaskStatus('RUNNING'), false) assert.equal(isTerminalTaskStatus('CANCELLED'), true) }) test('test_task_101_task_types_dependency_failure_returns_actionable_message', () => { // 依赖失败/可操作:类型模块纯逻辑、无框架/http。 const mod = readSource('src/pages/tasks/task-model.ts') assert.equal(/axios|http\.|vue/.test(mod), false, '任务类型保持纯逻辑') assert.match(mod, /ResultFileDescriptor/) assert.match(mod, /ResultId/) })