117 行
4.2 KiB
TypeScript
117 行
4.2 KiB
TypeScript
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||
|
|
import { configureHttp, http } from '../../../src/core/http'
|
||
|
|
|
||
|
|
describe('core/http', () => {
|
||
|
|
beforeEach(() => {
|
||
|
|
configureHttp('https://api.test.com', () => 'test_token')
|
||
|
|
vi.restoreAllMocks()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should configure base URL and token getter', async () => {
|
||
|
|
globalThis.fetch = vi.fn().mockResolvedValue({
|
||
|
|
json: vi.fn().mockResolvedValue({ code: 200, data: { id: 1 }, message: 'ok' }),
|
||
|
|
} as unknown as Response)
|
||
|
|
|
||
|
|
await http.get('/api/test')
|
||
|
|
expect(fetch).toHaveBeenCalledWith(
|
||
|
|
'https://api.test.com/api/test',
|
||
|
|
expect.objectContaining({
|
||
|
|
method: 'GET',
|
||
|
|
headers: expect.objectContaining({
|
||
|
|
Authorization: 'Bearer test_token',
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
}),
|
||
|
|
})
|
||
|
|
)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should build URL with query parameters', async () => {
|
||
|
|
globalThis.fetch = vi.fn().mockResolvedValue({
|
||
|
|
json: vi.fn().mockResolvedValue({ code: 200, data: [], message: 'ok' }),
|
||
|
|
} as unknown as Response)
|
||
|
|
|
||
|
|
await http.get('/api/list', { page: 0, size: 20, keyword: 'hello' })
|
||
|
|
const url = (fetch as ReturnType<typeof vi.fn>).mock.calls[0][0] as string
|
||
|
|
expect(url).toContain('page=0')
|
||
|
|
expect(url).toContain('size=20')
|
||
|
|
expect(url).toContain('keyword=hello')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should omit null, undefined and empty query values', async () => {
|
||
|
|
globalThis.fetch = vi.fn().mockResolvedValue({
|
||
|
|
json: vi.fn().mockResolvedValue({ code: 200, data: [], message: 'ok' }),
|
||
|
|
} as unknown as Response)
|
||
|
|
|
||
|
|
await http.get('/api/list', { a: null, b: undefined, c: '', d: 'value' })
|
||
|
|
const url = (fetch as ReturnType<typeof vi.fn>).mock.calls[0][0] as string
|
||
|
|
expect(url).not.toContain('a=')
|
||
|
|
expect(url).not.toContain('b=')
|
||
|
|
expect(url).not.toContain('c=')
|
||
|
|
expect(url).toContain('d=value')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should send POST with JSON body', async () => {
|
||
|
|
globalThis.fetch = vi.fn().mockResolvedValue({
|
||
|
|
json: vi.fn().mockResolvedValue({ code: 200, data: { id: 1 }, message: 'ok' }),
|
||
|
|
} as unknown as Response)
|
||
|
|
|
||
|
|
const body = { name: 'test' }
|
||
|
|
await http.post('/api/create', body)
|
||
|
|
expect(fetch).toHaveBeenCalledWith(
|
||
|
|
'https://api.test.com/api/create',
|
||
|
|
expect.objectContaining({
|
||
|
|
method: 'POST',
|
||
|
|
body: JSON.stringify(body),
|
||
|
|
})
|
||
|
|
)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should throw when response code is not 200', async () => {
|
||
|
|
globalThis.fetch = vi.fn().mockResolvedValue({
|
||
|
|
json: vi.fn().mockResolvedValue({ code: 500, data: null, message: 'Server Error' }),
|
||
|
|
} as unknown as Response)
|
||
|
|
|
||
|
|
await expect(http.get('/api/error')).rejects.toThrow('Server Error')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should handle Date query parameters as ISO string', async () => {
|
||
|
|
globalThis.fetch = vi.fn().mockResolvedValue({
|
||
|
|
json: vi.fn().mockResolvedValue({ code: 200, data: [], message: 'ok' }),
|
||
|
|
} as unknown as Response)
|
||
|
|
|
||
|
|
const date = new Date('2026-04-30T00:00:00.000Z')
|
||
|
|
await http.get('/api/list', { createdAt: date })
|
||
|
|
const url = (fetch as ReturnType<typeof vi.fn>).mock.calls[0][0] as string
|
||
|
|
expect(decodeURIComponent(url)).toContain('createdAt=2026-04-30T00:00:00.000Z')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should strip trailing slash from base URL', async () => {
|
||
|
|
configureHttp('https://api.test.com/', () => 'token')
|
||
|
|
globalThis.fetch = vi.fn().mockResolvedValue({
|
||
|
|
json: vi.fn().mockResolvedValue({ code: 200, data: [], message: 'ok' }),
|
||
|
|
} as unknown as Response)
|
||
|
|
|
||
|
|
await http.get('/api/test')
|
||
|
|
const url = (fetch as ReturnType<typeof vi.fn>).mock.calls[0][0] as string
|
||
|
|
expect(url).toBe('https://api.test.com/api/test')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('should handle PUT and DELETE methods', async () => {
|
||
|
|
globalThis.fetch = vi.fn().mockResolvedValue({
|
||
|
|
json: vi.fn().mockResolvedValue({ code: 200, data: null, message: 'ok' }),
|
||
|
|
} as unknown as Response)
|
||
|
|
|
||
|
|
await http.put('/api/update', { name: 'new' })
|
||
|
|
expect(fetch).toHaveBeenCalledWith(
|
||
|
|
expect.stringContaining('/api/update'),
|
||
|
|
expect.objectContaining({ method: 'PUT' })
|
||
|
|
)
|
||
|
|
|
||
|
|
await http.delete('/api/delete', { id: 1 })
|
||
|
|
expect(fetch).toHaveBeenCalledWith(
|
||
|
|
expect.stringContaining('/api/delete'),
|
||
|
|
expect.objectContaining({ method: 'DELETE' })
|
||
|
|
)
|
||
|
|
})
|
||
|
|
})
|