task-208: JavaApiResponse 包装契约(前端 node --test:success/message/data 解包、失败抛 message、null data、多余字段容忍、LegacyApiSuccess(msg) 兼容、extractErrorMessage 各字段回退)+ 8 条测试
This commit is contained in:
@@ -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-208:JavaApiResponse 包装契约(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), '请求失败')
|
||||
})
|
||||
Reference in New Issue
Block a user