import { describe, expect, it } from 'vitest' import { ConfigLoadError, handleConfigError, parseApiError } from '../../utils/error-handler' describe('ConfigLoadError', () => { it('should create error with correct properties', () => { const error = new ConfigLoadError('Test message', 'INVALID_URL') expect(error.message).toBe('Test message') expect(error.code).toBe('INVALID_URL') expect(error.name).toBe('ConfigLoadError') }) it('should default to UNKNOWN_ERROR code', () => { const error = new ConfigLoadError('Test message') expect(error.code).toBe('UNKNOWN_ERROR') }) it('should store original error', () => { const originalError = new Error('Original error') const error = new ConfigLoadError('Test message', 'NETWORK_ERROR', originalError) expect(error.originalError).toBe(originalError) }) it('should support all error codes', () => { const codes: Array = ['INVALID_URL', 'STORAGE_ERROR', 'NETWORK_ERROR', 'UNKNOWN_ERROR'] codes.forEach(code => { const error = new ConfigLoadError('Test', code) expect(error.code).toBe(code) }) }) }) describe('parseApiError', () => { it('should parse JSON error response', async () => { const response = new Response(JSON.stringify({ message: 'API Error' }), { status: 400, statusText: 'Bad Request' }) const result = await parseApiError(response) expect(result).toBe('API Error') }) it('should stringify JSON when no message property exists', async () => { const errorData = { error: 'Something went wrong', code: 500 } const response = new Response(JSON.stringify(errorData), { status: 500 }) const result = await parseApiError(response) expect(result).toBe(JSON.stringify(errorData)) }) it('should parse XML error with Message tag', async () => { const xmlError = 'XML Error Message' const response = new Response(xmlError, { status: 400 }) const result = await parseApiError(response) expect(result).toBe('XML Error Message') }) it('should parse XML error with Error tag', async () => { const xmlError = 'XML Error Content' const response = new Response(xmlError, { status: 400 }) const result = await parseApiError(response) expect(result).toBe('XML Error Content') }) it('should return plain text when not JSON or XML', async () => { const response = new Response('Plain text error', { status: 400 }) const result = await parseApiError(response) expect(result).toBe('Plain text error') }) it('should return statusText when response body cannot be parsed', async () => { const response = new Response(null, { status: 500, statusText: 'Internal Server Error', }) const result = await parseApiError(response) expect(result).toBe('Internal Server Error') }) it('should handle empty response body', async () => { const response = new Response('', { status: 404, statusText: 'Not Found', }) const result = await parseApiError(response) expect(result).toBe('Not Found') }) it('should extract message from nested XML structure', async () => { const xmlError = ` NoSuchBucket The specified bucket does not exist ` const response = new Response(xmlError, { status: 404 }) const result = await parseApiError(response) expect(result).toBe('The specified bucket does not exist') }) }) describe('handleConfigError', () => { it('should return ConfigLoadError as-is', () => { const originalError = new ConfigLoadError('Original', 'INVALID_URL') const result = handleConfigError(originalError, 'test context') expect(result).toBe(originalError) }) it('should detect invalid URL errors', () => { const error = new Error('Invalid URL: http://') const result = handleConfigError(error, 'config loading') expect(result).toBeInstanceOf(ConfigLoadError) expect(result.code).toBe('INVALID_URL') expect(result.message).toContain('Invalid URL') expect(result.message).toContain('config loading') expect(result.originalError).toBe(error) }) it('should detect storage errors', () => { const error = new Error('localStorage is not available') const result = handleConfigError(error, 'save config') expect(result).toBeInstanceOf(ConfigLoadError) expect(result.code).toBe('STORAGE_ERROR') expect(result.message).toContain('Storage error') expect(result.message).toContain('save config') }) it('should detect network errors', () => { const error = new Error('fetch failed due to network') const result = handleConfigError(error, 'fetch config') expect(result).toBeInstanceOf(ConfigLoadError) expect(result.code).toBe('NETWORK_ERROR') expect(result.message).toContain('Network error') expect(result.message).toContain('fetch config') }) it('should handle unknown errors', () => { const error = new Error('Some random error') const result = handleConfigError(error, 'process') expect(result).toBeInstanceOf(ConfigLoadError) expect(result.code).toBe('UNKNOWN_ERROR') expect(result.message).toContain('Unknown error') expect(result.message).toContain('process') }) it('should handle non-Error objects', () => { const error = 'String error message' const result = handleConfigError(error, 'operation') expect(result).toBeInstanceOf(ConfigLoadError) expect(result.code).toBe('UNKNOWN_ERROR') expect(result.message).toContain('String error message') }) it('should handle null/undefined errors', () => { const result1 = handleConfigError(null, 'null test') const result2 = handleConfigError(undefined, 'undefined test') expect(result1).toBeInstanceOf(ConfigLoadError) expect(result1.code).toBe('UNKNOWN_ERROR') expect(result2).toBeInstanceOf(ConfigLoadError) expect(result2.code).toBe('UNKNOWN_ERROR') }) it('should preserve context in error message', () => { const error = new Error('Test error') const context = 'loading user configuration' const result = handleConfigError(error, context) expect(result.message).toContain(context) }) it('should detect storage error with "storage" keyword', () => { const error = new Error('Failed to access storage') const result = handleConfigError(error, 'test') expect(result.code).toBe('STORAGE_ERROR') }) })