From f177a151059931d53faeae4e6ceb864c7391bd50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Mon, 31 Aug 2026 20:01:52 +0800 Subject: [PATCH] =?UTF-8?q?task-25:=20applyFilePhaseDefaults=20=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=97=A7=20Java=20=E5=93=8D=E5=BA=94=E7=9A=84?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E9=98=B6=E6=AE=B5=E5=AD=97=E6=AE=B5=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend-vue/src/shared/api/types/task.ts | 20 ++++++ frontend-vue/tests/result-file-phase.test.ts | 74 ++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 frontend-vue/tests/result-file-phase.test.ts diff --git a/frontend-vue/src/shared/api/types/task.ts b/frontend-vue/src/shared/api/types/task.ts index dee8c253..cad320e7 100644 --- a/frontend-vue/src/shared/api/types/task.ts +++ b/frontend-vue/src/shared/api/types/task.ts @@ -35,3 +35,23 @@ export interface TaskProgressBatchVo { items: T[] missingTaskIds: number[] } + +/** + * 旧 Java 版本响应缺少文件阶段新字段时补齐默认值,保证页面行为一致。 + */ +export function applyFilePhaseDefaults(item: T | null | undefined): T & ResultFilePhase { + const source = (item ?? {}) as Partial + const defaults: ResultFilePhase = { + fileReady: false, + fileStatus: 'PENDING', + fileProgress: 0, + fileProgressLabel: '', + fileProgressStage: '', + freshDownloadUrl: null, + } + const merged: ResultFilePhase = { ...defaults, ...source } + if (merged.fileStatus === 'SUCCESS' && source.fileReady === undefined) { + merged.fileReady = true + } + return merged as T & ResultFilePhase +} diff --git a/frontend-vue/tests/result-file-phase.test.ts b/frontend-vue/tests/result-file-phase.test.ts new file mode 100644 index 00000000..d0eeb5cf --- /dev/null +++ b/frontend-vue/tests/result-file-phase.test.ts @@ -0,0 +1,74 @@ +import { test } from 'node:test' +import assert from 'node:assert/strict' +import { applyFilePhaseDefaults, type ResultFilePhase } from '../src/shared/api/types/task.ts' + +function setupWindow() { + ;(globalThis as Record).window = { + localStorage: { getItem: () => '42' }, + location: { origin: 'http://localhost' }, + } +} + +test('test_defaults_filled', () => { + setupWindow() + const result = applyFilePhaseDefaults({}) + assert.equal(result.fileReady, false) + assert.equal(result.fileStatus, 'PENDING') + assert.equal(result.fileProgress, 0) + assert.equal(result.fileProgressLabel, '') + assert.equal(result.fileProgressStage, '') +}) + +test('test_existing_values_kept', () => { + setupWindow() + const result = applyFilePhaseDefaults({ fileStatus: 'RUNNING', fileProgress: 50 }) + assert.equal(result.fileStatus, 'RUNNING') + assert.equal(result.fileProgress, 50) + assert.equal(result.fileReady, false) +}) + +test('test_file_ready_true_preserved', () => { + setupWindow() + const result = applyFilePhaseDefaults({ fileReady: true }) + assert.equal(result.fileReady, true) + assert.equal(result.fileStatus, 'PENDING') +}) + +test('test_partial_input', () => { + setupWindow() + const result = applyFilePhaseDefaults({ fileStatus: 'FAILED', fileProgressStage: 'unzip' }) + assert.equal(result.fileStatus, 'FAILED') + assert.equal(result.fileProgressStage, 'unzip') + assert.equal(result.fileReady, false) + assert.equal(result.fileProgress, 0) + assert.equal(result.fileProgressLabel, '') +}) + +test('test_null_input_safe', () => { + setupWindow() + const result = applyFilePhaseDefaults(null as unknown as ResultFilePhase) + assert.equal(result.fileReady, false) + assert.equal(result.fileStatus, 'PENDING') + assert.equal(result.fileProgress, 0) +}) + +test('test_defaults_idempotent', () => { + setupWindow() + const once = applyFilePhaseDefaults({}) + const twice = applyFilePhaseDefaults(once) + assert.deepEqual(twice, once) + assert.equal(twice.fileReady, false) +}) + +test('test_status_success_maps_ready', () => { + setupWindow() + const result = applyFilePhaseDefaults({ fileStatus: 'SUCCESS' }) + assert.equal(result.fileReady, true) +}) + +test('test_unknown_status_untouched', () => { + setupWindow() + const result = applyFilePhaseDefaults({ fileStatus: 'WEIRD_STATE' }) + assert.equal(result.fileReady, false) + assert.equal(result.fileStatus, 'WEIRD_STATE') +})