import test from 'node:test' import assert from 'node:assert/strict' import { COMPLETION_PHASE, completionPresentation, refreshCompletionAttempt, resolveCompletionPhase, shouldReconcileCompletion } from '../utils/loading-completion-state.js' test('accepted completion is processing and blocks every repeated mutation', () => { for (const facts of [ { taskStatus: 'COMPLETING' }, { commandStatus: 'PROCESSING' }, { taskStatus: 'COMPLETING', commandStatus: 'PROCESSING' } ]) { const phase = resolveCompletionPhase(facts) assert.equal(phase, COMPLETION_PHASE.PROCESSING) assert.deepEqual(completionPresentation(phase), { label: '完成处理中', action: '', blocked: true }) } }) test('submission and uncertain-result reconciliation block duplicate completion immediately', () => { assert.equal(resolveCompletionPhase({ submitting: true }), COMPLETION_PHASE.SUBMITTING) assert.equal(resolveCompletionPhase({ reconciling: true }), COMPLETION_PHASE.RECONCILING) assert.equal(completionPresentation(COMPLETION_PHASE.SUBMITTING).blocked, true) assert.equal(completionPresentation(COMPLETION_PHASE.RECONCILING).blocked, true) }) test('completion failure exposes a readable stage and retry entry', () => { const phase = resolveCompletionPhase({ taskStatus: 'COMPLETION_FAILED' }) assert.equal(phase, COMPLETION_PHASE.FAILED) assert.deepEqual(completionPresentation(phase, '费用结算'), { label: '完成失败:费用结算', action: '重试完成', blocked: true, retryable: true }) }) test('retry reuses the original operation id and request-hashed task version', () => { const attempt = refreshCompletionAttempt( { operationId: 'complete-task-8-v3', expectedTaskVersion: 3, commandId: 'cmd-old' }, { taskVersion: 7, commandId: 'cmd-latest', commandStatus: 'COMPLETION_FAILED' } ) assert.equal(attempt.operationId, 'complete-task-8-v3') assert.equal(attempt.expectedTaskVersion, 3) assert.equal(attempt.commandId, 'cmd-latest') assert.throws(() => refreshCompletionAttempt({}, { taskVersion: 7 }), /缺少原完成操作标识/) assert.throws(() => refreshCompletionAttempt({ operationId: 'stable-id' }), /缺少服务端最新任务版本/) }) test('network and timeout failures reconcile before any retry while business conflicts stay intact', () => { assert.equal(shouldReconcileCompletion({ network: true }), true) assert.equal(shouldReconcileCompletion({ timeout: true }), true) assert.equal(shouldReconcileCompletion({ code: 'REQUEST_TIMEOUT' }), true) assert.equal(shouldReconcileCompletion({ code: 'A0409', apiErrorMeta: { requestId: 'req-1' } }), false) }) test('completed facts win over stale processing facts', () => { const phase = resolveCompletionPhase({ taskStatus: 'COMPLETED', commandStatus: 'PROCESSING' }) assert.equal(phase, COMPLETION_PHASE.COMPLETED) assert.equal(completionPresentation(phase).label, '装柜已完成') })