task-208: JavaApiResponse 包装契约(前端 node --test:success/message/data 解包、失败抛 message、null data、多余字段容忍、LegacyApiSuccess(msg) 兼容、extractErrorMessage 各字段回退)+ 8 条测试

This commit is contained in:
2026-09-05 00:21:27 +08:00
parent f5d4410063
commit 541e397ca6
@@ -0,0 +1,63 @@
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { AxiosError } from 'axios'
import {
unwrapJavaResponse,
extractErrorMessage,
type JavaApiResponse,
type LegacyApiSuccess,
} from '../src/shared/api/http.ts'
/** task-208JavaApiResponse 包装契约(success/message/data+ LegacyApiSuccess(msg) 兼容。 */
test('java success shape unwraps to data', async () => {
const response: JavaApiResponse<number> = { success: true, message: 'ok', data: 42 }
assert.equal(await unwrapJavaResponse(Promise.resolve(response)), 42)
})
test('java failure shape throws message', async () => {
const response: JavaApiResponse<never> = { success: false, message: '系统错误', data: null }
await assert.rejects(unwrapJavaResponse(Promise.resolve(response)), /系统错误/)
})
test('java failure without message defaults to 请求失败', async () => {
const response: JavaApiResponse<never> = { success: false, message: '', data: null }
await assert.rejects(unwrapJavaResponse(Promise.resolve(response)), /请求失败/)
})
test('null data does not throw on success', async () => {
const response: JavaApiResponse<null> = { success: true, message: 'ok', data: null }
assert.equal(await unwrapJavaResponse(Promise.resolve(response)), null)
})
test('extra fields are tolerated', async () => {
const response = { success: true, message: 'ok', data: 7, extraField: 'x', another: true }
assert.equal(await unwrapJavaResponse(Promise.resolve(response)), 7)
})
test('legacy success shape keeps msg-compatible fields', () => {
const legacy: LegacyApiSuccess<string> = { success: true, msg: 'legacy-ok', data: 'v' }
assert.equal(legacy.success, true)
assert.ok('msg' in legacy && 'data' in legacy, 'LegacyApiSuccess 应含 msg/data')
})
test('extractErrorMessage reads error field first', () => {
const err = new AxiosError('http', undefined, undefined, undefined,
{ status: 500, data: { error: 'E1', message: 'M', msg: 'm' } } as never)
assert.equal(extractErrorMessage(err), 'E1')
})
test('extractErrorMessage falls back to message/msg/string/generic', () => {
const withMessage = new AxiosError('http', undefined, undefined, undefined,
{ status: 500, data: { message: 'M', msg: 'm' } } as never)
assert.equal(extractErrorMessage(withMessage), 'M')
const withMsg = new AxiosError('http', undefined, undefined, undefined,
{ status: 500, data: { msg: 'm' } } as never)
assert.equal(extractErrorMessage(withMsg), 'm')
const stringBody = new AxiosError('http', undefined, undefined, undefined,
{ status: 500, data: 'plain-body' } as never)
assert.equal(extractErrorMessage(stringBody), 'plain-body')
const messageOnly = new AxiosError('boom')
assert.equal(extractErrorMessage(messageOnly), 'boom')
assert.equal(extractErrorMessage(null), '请求失败')
})