import { describe, it, expect, beforeEach, vi } from 'vitest' import { ElMessage } from 'element-plus' import { handleApiError, ApiErrorHandler } from '@/utils/errorHandler' vi.mock('element-plus', () => ({ ElMessage: { error: vi.fn(), success: vi.fn(), }, })) describe('errorHandler', () => { beforeEach(() => { vi.clearAllMocks() vi.stubGlobal('localStorage', { removeItem: vi.fn(), }) vi.stubGlobal('window', { location: { href: '' }, }) }) describe('handleApiError', () => { it('should call ApiErrorHandler.handle', () => { const mockError = { response: { status: 500, data: {} } } const handleSpy = vi.spyOn(ApiErrorHandler, 'handle') handleApiError(mockError) expect(handleSpy).toHaveBeenCalledWith(mockError) }) }) describe('ApiErrorHandler.handle', () => { it('should handle network error', () => { const mockError = new Error('Network Error') const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('网络连接失败,请检查网络设置') expect(consoleSpy).toHaveBeenCalledWith('Network Error:', mockError) }) it('should handle 400 Bad Request', () => { const mockError = { response: { status: 400, data: { message: 'Invalid parameters' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('Invalid parameters') expect(consoleSpy).toHaveBeenCalledWith('Bad Request:', mockError.response.data) }) it('should handle 401 Unauthorized', () => { const mockError = { response: { status: 401, data: { message: 'Unauthorized' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('登录已过期,请重新登录') expect(localStorage.removeItem).toHaveBeenCalledWith('token') expect(window.location.href).toBe('/login') expect(consoleSpy).toHaveBeenCalledWith('Unauthorized:', mockError.response.data) }) it('should handle 403 Forbidden', () => { const mockError = { response: { status: 403, data: { message: 'Access denied' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('没有权限访问该资源') expect(consoleSpy).toHaveBeenCalledWith('Forbidden:', mockError.response.data) }) it('should handle 404 Not Found', () => { const mockError = { response: { status: 404, data: { message: 'Resource not found' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('Resource not found') expect(consoleSpy).toHaveBeenCalledWith('Not Found:', mockError.response.data) }) it('should handle 409 Conflict', () => { const mockError = { response: { status: 409, data: { message: 'Resource conflict' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('Resource conflict') expect(consoleSpy).toHaveBeenCalledWith('Conflict:', mockError.response.data) }) it('should handle 422 Validation Error with details', () => { const mockError = { response: { status: 422, data: { message: 'Validation failed', details: { username: 'Username is required', password: 'Password is too short', }, }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('Username is required、Password is too short') expect(consoleSpy).toHaveBeenCalledWith('Validation Error:', mockError.response.data) }) it('should handle 422 Validation Error without details', () => { const mockError = { response: { status: 422, data: { message: 'Validation failed' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('Validation failed') expect(consoleSpy).toHaveBeenCalledWith('Validation Error:', mockError.response.data) }) it('should handle 500 Internal Server Error', () => { const mockError = { response: { status: 500, data: { message: 'Server error' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('服务器内部错误,请稍后重试') expect(consoleSpy).toHaveBeenCalledWith('Internal Server Error:', mockError.response.data) }) it('should handle 502 Service Unavailable', () => { const mockError = { response: { status: 502, data: { message: 'Service unavailable' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('服务暂时不可用,请稍后重试') expect(consoleSpy).toHaveBeenCalledWith('Service Unavailable:', mockError.response.data) }) it('should handle 503 Service Unavailable', () => { const mockError = { response: { status: 503, data: { message: 'Service unavailable' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('服务暂时不可用,请稍后重试') expect(consoleSpy).toHaveBeenCalledWith('Service Unavailable:', mockError.response.data) }) it('should handle 504 Gateway Timeout', () => { const mockError = { response: { status: 504, data: { message: 'Gateway timeout' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('服务暂时不可用,请稍后重试') expect(consoleSpy).toHaveBeenCalledWith('Service Unavailable:', mockError.response.data) }) it('should handle unknown status code', () => { const mockError = { response: { status: 418, data: { message: 'I am a teapot' }, }, } const consoleSpy = vi.spyOn(console, 'error') ApiErrorHandler.handle(mockError) expect(ElMessage.error).toHaveBeenCalledWith('I am a teapot') expect(consoleSpy).toHaveBeenCalledWith('Unknown Error:', mockError.response.data) }) }) })