100 lines
3.8 KiB
TypeScript
100 lines
3.8 KiB
TypeScript
import axios, { type InternalAxiosRequestConfig } from 'axios'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { registerAuthRefreshHandler } from './http'
|
|
import { clearOverseasAccessToken, overseasHttp, replaceOverseasAccessToken } from './overseasHttp'
|
|
|
|
const originalOverseasAdapter = overseasHttp.defaults.adapter
|
|
|
|
function success(config: InternalAxiosRequestConfig, data: unknown) {
|
|
return Promise.resolve({ status: 200, statusText: 'OK', headers: {}, config, data })
|
|
}
|
|
|
|
describe('overseas HTTP client', () => {
|
|
beforeEach(() => {
|
|
localStorage.setItem('cc-admin-token', 'domestic-token')
|
|
clearOverseasAccessToken()
|
|
registerAuthRefreshHandler(async () => 'domestic-token')
|
|
})
|
|
|
|
afterEach(() => {
|
|
overseasHttp.defaults.adapter = originalOverseasAdapter
|
|
localStorage.clear()
|
|
clearOverseasAccessToken()
|
|
})
|
|
|
|
it('uses the overseas token supplied by the login session for concurrent requests', async () => {
|
|
replaceOverseasAccessToken('overseas-token', 900)
|
|
const authorizations: unknown[] = []
|
|
overseasHttp.defaults.adapter = async (config) => {
|
|
authorizations.push(config.headers.Authorization)
|
|
return success(config, { code: '200', message: 'success', data: [] })
|
|
}
|
|
|
|
await Promise.all([
|
|
overseasHttp.get('/platform/v1/last-leg/orders'),
|
|
overseasHttp.get('/platform/v1/warehouse-admin'),
|
|
])
|
|
|
|
expect(authorizations).toEqual(['Bearer overseas-token', 'Bearer overseas-token'])
|
|
})
|
|
|
|
it('refreshes the unified session once and replays once after an overseas 401', async () => {
|
|
replaceOverseasAccessToken('overseas-1', 900)
|
|
const refresh = vi.fn(async () => {
|
|
replaceOverseasAccessToken('overseas-2', 900)
|
|
return 'domestic-2'
|
|
})
|
|
registerAuthRefreshHandler(refresh)
|
|
let requests = 0
|
|
const authorizations: unknown[] = []
|
|
overseasHttp.defaults.adapter = async (config) => {
|
|
authorizations.push(config.headers.Authorization)
|
|
if (requests++ === 0) {
|
|
throw new axios.AxiosError('Unauthorized', 'ERR_BAD_REQUEST', config, undefined, {
|
|
status: 401,
|
|
statusText: 'Unauthorized',
|
|
headers: {},
|
|
config,
|
|
data: { code: 'A0401', message: '海外令牌失效' },
|
|
})
|
|
}
|
|
return success(config, { code: '200', message: 'success', data: [] })
|
|
}
|
|
|
|
await overseasHttp.get('/platform/v1/last-leg/orders')
|
|
|
|
expect(refresh).toHaveBeenCalledTimes(1)
|
|
expect(requests).toBe(2)
|
|
expect(authorizations).toEqual(['Bearer overseas-1', 'Bearer overseas-2'])
|
|
})
|
|
|
|
it('refreshes the unified session when no usable overseas token is present', async () => {
|
|
const refresh = vi.fn(async () => {
|
|
replaceOverseasAccessToken('overseas-refreshed', 900)
|
|
return 'domestic-refreshed'
|
|
})
|
|
registerAuthRefreshHandler(refresh)
|
|
let authorization: unknown
|
|
overseasHttp.defaults.adapter = async (config) => {
|
|
authorization = config.headers.Authorization
|
|
return success(config, { code: '200', message: 'success', data: [] })
|
|
}
|
|
|
|
await overseasHttp.get('/platform/v1/last-leg/orders')
|
|
|
|
expect(refresh).toHaveBeenCalledTimes(1)
|
|
expect(authorization).toBe('Bearer overseas-refreshed')
|
|
})
|
|
|
|
it('fails before sending a business request when refresh is domestic-only', async () => {
|
|
const refresh = vi.fn(async () => 'domestic-only')
|
|
registerAuthRefreshHandler(refresh)
|
|
const adapter = vi.fn(async (config: InternalAxiosRequestConfig) => success(config, { code: '200', message: 'success', data: [] }))
|
|
overseasHttp.defaults.adapter = adapter
|
|
|
|
await expect(overseasHttp.get('/platform/v1/last-leg/orders')).rejects.toThrow('当前环境未签发海外访问令牌')
|
|
expect(refresh).toHaveBeenCalledTimes(1)
|
|
expect(adapter).not.toHaveBeenCalled()
|
|
})
|
|
})
|