Files
huangzd1997 a816bfa899 task-104(任务与重复分析中心): 实现视频任务详情展示
image-video-model.ts 增加 ImageVideoDetail 与 parseImageVideoDetail(脱敏 request/
submit_response/result + error_message/archived_at),image-video-api.ts 增加
fetchImageVideoTaskDetail(GET /api/admin/image-video-tasks/{id})。

TDD: task-104.test.ts 8 用例先 RED 后 GREEN。
2026-09-05 17:08:58 +08:00

85 lines
3.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import test from 'node:test'
import assert from 'node:assert/strict'
import { readSource } from './helpers.ts'
import { parseImageVideoDetail } from '../src/pages/tasks/image-video-model.ts'
test('test_task_104_video_detail_normal_primary_path', () => {
// 正常主路径:详情负载(data.item + request/result JSON)解析为类型化详情。
const detail = parseImageVideoDetail({
success: true,
data: {
item: {
task_id: 21,
username: '张伟',
status: 'FAILED',
error_message: '上游生成失败',
archived_at: '2026-01-02 03:00:00',
request: { prompt: '下雨场景', api_key: '**masked**' },
submit_response: { run_id: 'r-1' },
result: { video_url: 'https://oss/x.mp4' },
},
},
})
assert.equal(detail.taskId, '21')
assert.equal(detail.status, 'FAILED')
assert.equal(detail.errorMessage, '上游生成失败')
assert.equal(detail.archivedAt, '2026-01-02 03:00:00')
assert.deepEqual(detail.request, { prompt: '下雨场景', api_key: '**masked**' })
assert.deepEqual(detail.submitResponse, { run_id: 'r-1' })
assert.deepEqual(detail.result, { video_url: 'https://oss/x.mp4' })
})
test('test_task_104_video_detail_normal_variant_input', () => {
// 正常变体:已解包 data.item 直传;缺 includeJson 字段回空对象。
const detail = parseImageVideoDetail({ item: { task_id: 8, status: 'SUCCESS' } })
assert.equal(detail.taskId, '8')
assert.equal(detail.errorMessage, '')
assert.deepEqual(detail.request, {})
assert.deepEqual(detail.result, {})
})
test('test_task_104_video_detail_repeated_is_idempotent', () => {
// 正常重复:解析稳定、不改输入。
const payload = { item: { task_id: 3, status: 'SUCCESS', request: { a: 1 } } }
assert.deepEqual(parseImageVideoDetail(payload), parseImageVideoDetail(payload))
assert.equal((payload.item as { request: Record<string, unknown> }).request.a, 1)
})
test('test_task_104_video_detail_boundary_empty_input', () => {
// 边界空值:无 item 详情抛可操作错误。
assert.throws(() => parseImageVideoDetail({ data: {} }), /详情/)
})
test('test_task_104_video_detail_boundary_single_item', () => {
// 边界单元素:单任务详情含单视频对象。
const detail = parseImageVideoDetail({
item: { task_id: 5, status: 'SUCCESS', videos: [{ display_url: 'https://oss/5.mp4' }] },
})
assert.equal(detail.videos.length, 1)
assert.equal(detail.videos[0].displayUrl, 'https://oss/5.mp4')
})
test('test_task_104_video_detail_boundary_limit_or_missing_field', () => {
// 边界上限/缺字段:request/result 为非对象字符串时按空对象处理。
const detail = parseImageVideoDetail({ item: { task_id: 2, status: 'RUNNING', request: 'raw-json' } })
assert.equal(detail.taskId, '2')
assert.deepEqual(detail.request, {})
})
test('test_task_104_video_detail_invalid_input_rejected', () => {
// 异常输入:success=false 抛后端 message;缺 task_id 视为无效详情。
assert.throws(() => parseImageVideoDetail({ success: false, message: '视频任务不存在或无权访问' }), /无权访问/)
assert.throws(() => parseImageVideoDetail({ item: { status: 'SUCCESS' } }), /详情/)
})
test('test_task_104_video_detail_dependency_failure_returns_actionable_message', () => {
// 依赖失败/加载走 adapterGET /api/admin/image-video-tasks/{id} + http.get + 解析。
const api = readSource('src/pages/tasks/image-video-api.ts')
assert.match(api, /\/api\/admin\/image-video-tasks/)
assert.match(api, /http\.get/)
assert.match(api, /fetchImageVideoTaskDetail/)
assert.match(api, /parseImageVideoDetail/)
const model = readSource('src/pages/tasks/image-video-model.ts')
assert.equal(/axios|http\./.test(model), false, '详情解析保持纯逻辑')
})