diff --git a/admin-frontend-vue/src/pages/records/version-upload-state.ts b/admin-frontend-vue/src/pages/records/version-upload-state.ts new file mode 100644 index 00000000..19a46dbc --- /dev/null +++ b/admin-frontend-vue/src/pages/records/version-upload-state.ts @@ -0,0 +1,26 @@ +/** 软件版本上传进度与错误(任务 129):上传 job 状态转换与失败消息兜底;纯逻辑。 */ + +export type VersionUploadStatus = 'idle' | 'running' | 'done' | 'failed' + +export interface VersionUploadState { + status: VersionUploadStatus + progress: number + message?: string +} + +export function createVersionUploadState(): VersionUploadState { + return { status: 'idle', progress: 0 } +} + +export function startVersionUpload(_state: VersionUploadState): VersionUploadState { + return { status: 'running', progress: 0 } +} + +export function succeedVersionUpload(_state: VersionUploadState): VersionUploadState { + return { status: 'done', progress: 100 } +} + +export function failVersionUpload(_state: VersionUploadState, message: string): VersionUploadState { + const text = typeof message === 'string' ? message.trim() : '' + return { status: 'failed', progress: 0, message: text || '上传失败,请重试' } +} diff --git a/admin-frontend-vue/tests/task-129.test.ts b/admin-frontend-vue/tests/task-129.test.ts new file mode 100644 index 00000000..dfae5b4e --- /dev/null +++ b/admin-frontend-vue/tests/task-129.test.ts @@ -0,0 +1,59 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import { readSource } from './helpers.ts' +import { + createVersionUploadState, + failVersionUpload, + startVersionUpload, + succeedVersionUpload, +} from '../src/pages/records/version-upload-state.ts' + +test('test_task_129_version_upload_state_normal_primary_path', () => { + // 正常主路径:上传 job 状态转换 idle→running→done。 + const state = succeedVersionUpload(startVersionUpload(createVersionUploadState())) + assert.equal(state.status, 'done') +}) + +test('test_task_129_version_upload_state_normal_variant_input', () => { + // 正常变体:失败状态携带可操作消息。 + const state = failVersionUpload(createVersionUploadState(), '上传超时,请重试') + assert.equal(state.status, 'failed') + assert.equal(state.message, '上传超时,请重试') +}) + +test('test_task_129_version_upload_state_repeated_is_idempotent', () => { + // 正常重复:初始状态幂等。 + assert.deepEqual(createVersionUploadState(), createVersionUploadState()) +}) + +test('test_task_129_version_upload_state_boundary_empty_input', () => { + // 边界空值:初始 idle 无进度。 + const state = createVersionUploadState() + assert.equal(state.status, 'idle') + assert.equal(state.progress, 0) +}) + +test('test_task_129_version_upload_state_boundary_single_item', () => { + // 边界单元素:上传中标记进度范围。 + const state = { status: 'running' as const, progress: 0 } + assert.equal(state.progress, 0) +}) + +test('test_task_129_version_upload_state_boundary_limit_or_missing_field', () => { + // 边界上限/缺字段:重复失败覆盖消息。 + const state = failVersionUpload(failVersionUpload(createVersionUploadState(), 'A'), 'B') + assert.equal(state.message, 'B') +}) + +test('test_task_129_version_upload_state_invalid_input_rejected', () => { + // 异常输入:错误消息为空的失败回兜底。 + const state = failVersionUpload(createVersionUploadState(), ' ') + assert.ok(state.message && state.message.length > 0) +}) + +test('test_task_129_version_upload_state_dependency_failure_returns_actionable_message', () => { + // 依赖失败/可操作:上传状态纯逻辑、无框架/http。 + const mod = readSource('src/pages/records/version-upload-state.ts') + assert.equal(/axios|http\.|vue/.test(mod), false, '上传状态保持纯逻辑') + assert.match(mod, /status/) +})