import { AxiosError, type InternalAxiosRequestConfig } from 'axios'; import { describe, expect, it } from 'vitest'; import { resolveAxiosErrorMessage } from '@/utils/http/resolveAxiosErrorMessage'; const fallback = 'Upload failed'; const axiosErrorWithResponse = (data: unknown, message = 'Request failed'): AxiosError => { return new AxiosError( message, AxiosError.ERR_BAD_REQUEST, {} as InternalAxiosRequestConfig, {}, { status: 400, statusText: 'Bad Request', headers: {}, config: {} as InternalAxiosRequestConfig, data } ); }; describe('resolveAxiosErrorMessage', () => { it('falls back for non-Axios errors', () => { expect(resolveAxiosErrorMessage(new Error('network'), fallback)).toBe('network'); expect(resolveAxiosErrorMessage('oops', fallback)).toBe(fallback); }); it('falls back when Axios error has no response', () => { const error = new AxiosError('timeout', AxiosError.ETIMEDOUT); expect(resolveAxiosErrorMessage(error, fallback)).toBe('timeout'); }); it('uses string response data', () => { const error = axiosErrorWithResponse('Rate limit exceeded'); expect(resolveAxiosErrorMessage(error, fallback)).toBe('Rate limit exceeded'); }); it('uses object message string (Nest-style)', () => { const error = axiosErrorWithResponse({ message: 'Invalid ciphertext' }); expect(resolveAxiosErrorMessage(error, fallback)).toBe('Invalid ciphertext'); }); it('uses a single string from message array', () => { const error = axiosErrorWithResponse({ message: ['iv must be valid base64'] }); expect(resolveAxiosErrorMessage(error, fallback)).toBe('iv must be valid base64'); }); it('joins multiple strings in message array', () => { const error = axiosErrorWithResponse({ message: ['expiresAt must be a date', 'maxViews must be a number'] }); expect(resolveAxiosErrorMessage(error, fallback)).toBe( 'expiresAt must be a date, maxViews must be a number' ); }); it('ignores non-string entries in message array', () => { const error = axiosErrorWithResponse({ message: ['valid', 42, null, 'also valid'] }); expect(resolveAxiosErrorMessage(error, fallback)).toBe('valid, also valid'); }); it('falls back when response data has no usable message', () => { const error = axiosErrorWithResponse({ message: [] }, 'HTTP 400'); expect(resolveAxiosErrorMessage(error, fallback)).toBe('HTTP 400'); }); it('falls back when response data is an object without message', () => { const error = axiosErrorWithResponse({ statusCode: 400 }, 'HTTP 400'); expect(resolveAxiosErrorMessage(error, fallback)).toBe('HTTP 400'); }); });