import { beforeEach, describe, expect, it, vi } from 'vitest' const messageSuccessMock = vi.fn() const messageErrorMock = vi.fn() const isAxiosErrorMock = vi.fn((value: any) => Boolean(value?.isAxiosError)) vi.mock('element-plus', () => ({ ElMessage: { success: messageSuccessMock, error: messageErrorMock } })) vi.mock('axios', () => ({ default: { isAxiosError: isAxiosErrorMock } })) vi.mock('../../../i18n', () => ({ i18n: { global: { t: (key: string) => `i18n:${key}` } } })) import { serverApi } from '../../../script/serverApi' describe('serverApi', () => { beforeEach(() => { vi.clearAllMocks() window.$t = ((key: string) => `t:${key}`) as any }) it('未传 interface 时会走默认空实现并返回 null', async () => { const loading = { isLoading: false } await expect(serverApi({ loading })).resolves.toBeNull() expect(loading.isLoading).toBe(false) }) it('旧版成功响应会关闭 loading、触发 success,并在 tips=true 时提示成功', async () => { const loading = { isLoading: false } const success = vi.fn() const api = vi.fn().mockResolvedValue({ status: 200, data: { list: [1, 2, 3] } }) await serverApi({ interface: api, params: { page: 1 }, loading, tips: true, success }) expect(api).toHaveBeenCalledWith({ page: 1 }) expect(loading.isLoading).toBe(false) expect(success).toHaveBeenCalledWith({ list: [1, 2, 3] }) expect(messageSuccessMock).toHaveBeenCalledWith({ message: 'i18n:operationSuccess' }) }) it('新版成功响应默认把 response.data.content 传给 success', async () => { const loading = { isLoading: false } const success = vi.fn() await serverApi({ interface: vi.fn().mockResolvedValue({ status: 200, data: { status: 0, content: { id: 1, name: 'tom' } } }), loading, success }) expect(loading.isLoading).toBe(false) expect(success).toHaveBeenCalledWith({ id: 1, name: 'tom' }) }) it('returnResp=true 时 success 接收完整 response', async () => { const loading = { isLoading: false } const success = vi.fn() const response = { status: 200, data: { status: 0, content: { id: 2 } } } await serverApi({ interface: vi.fn().mockResolvedValue({ response }), loading, success, returnResp: true }) expect(success).toHaveBeenCalledWith(response) }) it('interface 返回空值时会关闭 loading 并返回 null', async () => { const loading = { isLoading: false } await expect( serverApi({ interface: vi.fn().mockResolvedValue(null), loading }) ).resolves.toBeNull() expect(loading.isLoading).toBe(false) }) it('网络错误对象会走错误提示与 error 回调,并返回 null', async () => { const loading = { isLoading: false } const error = vi.fn() const axiosError = { isAxiosError: true, code: 'ERR_NETWORK', message: 'Network Error' } await expect( serverApi({ interface: vi.fn().mockResolvedValue(axiosError), loading, error }) ).resolves.toBeNull() expect(loading.isLoading).toBe(false) expect(messageErrorMock).toHaveBeenCalledWith({ dangerouslyUseHTMLString: false, message: 't:networkRequestError' }) expect(error).toHaveBeenCalledWith(axiosError) }) it('超时错误会提示 networkRequestTimeout', async () => { const loading = { isLoading: false } await serverApi({ interface: vi.fn().mockResolvedValue({ isAxiosError: true, code: 'ETIMEDOUT', message: 'timeout of 1000ms exceeded' }), loading, error: vi.fn() }) expect(messageErrorMock).toHaveBeenCalledWith({ dangerouslyUseHTMLString: false, message: 't:networkRequestTimeout' }) }) it('非 2xx 响应会走错误提示,并支持 html message', async () => { const loading = { isLoading: false } const error = vi.fn() const response = { status: 500, data: { message: 'line1
line2' } } await serverApi({ interface: vi.fn().mockResolvedValue(response), loading, error }) expect(loading.isLoading).toBe(false) expect(messageErrorMock).toHaveBeenCalledWith({ dangerouslyUseHTMLString: true, message: '
line1
line2
' }) expect(error).toHaveBeenCalledWith(response) }) it('新版业务状态非 0 时会走错误回调', async () => { const loading = { isLoading: false } const success = vi.fn() const error = vi.fn() const response = { status: 200, data: { status: 1, message: 'failed' } } await serverApi({ interface: vi.fn().mockResolvedValue(response), loading, success, error }) expect(success).not.toHaveBeenCalled() expect(error).toHaveBeenCalledWith(response) }) it('interface reject 时会先提示错误,再继续抛出异常', async () => { const loading = { isLoading: false } const error = { data: { message: 'boom' } } await expect( serverApi({ interface: vi.fn().mockRejectedValue(error), loading }) ).rejects.toBe(error) expect(loading.isLoading).toBe(false) expect(messageErrorMock).toHaveBeenCalledWith({ dangerouslyUseHTMLString: false, message: 'boom' }) }) })