/** * Tests for Error Message Utilities */ import { getErrorMessage, getActionHint, validateEmail, validatePhone, validateRequired, validateMinLength, validateMaxLength, validateOtp, formatErrorMessage, combineFieldErrors, getErrorCountText, ErrorMessages, } from '@/utils/errorMessages'; import { ErrorCodes } from '@/types/errors'; describe('errorMessages', () => { describe('getErrorMessage', () => { it('should return network error message', () => { const message = getErrorMessage(ErrorCodes.NETWORK_ERROR); expect(message).toBe(ErrorMessages.networkError); }); it('should return session expired message for unauthorized', () => { const message = getErrorMessage(ErrorCodes.UNAUTHORIZED); expect(message).toBe(ErrorMessages.sessionExpired); }); it('should return fallback for unknown code', () => { const message = getErrorMessage('UNKNOWN_CODE', 'Custom fallback'); expect(message).toBe('Custom fallback'); }); it('should return generic error for unknown code without fallback', () => { const message = getErrorMessage('UNKNOWN_CODE'); expect(message).toBe(ErrorMessages.genericError); }); }); describe('getActionHint', () => { it('should return hint for network error', () => { const hint = getActionHint(ErrorCodes.NETWORK_ERROR); expect(hint).toContain('connection'); }); it('should return hint for BLE error', () => { const hint = getActionHint(ErrorCodes.BLE_NOT_ENABLED); expect(hint).toContain('Bluetooth'); }); it('should return undefined for code without hint', () => { const hint = getActionHint('UNKNOWN_CODE'); expect(hint).toBeUndefined(); }); }); describe('validateEmail', () => { it('should return null for valid email', () => { expect(validateEmail('test@example.com')).toBeNull(); expect(validateEmail('user.name@domain.co.uk')).toBeNull(); expect(validateEmail('user+tag@example.org')).toBeNull(); }); it('should return error for empty email', () => { expect(validateEmail('')).toBe(ErrorMessages.required); expect(validateEmail(' ')).toBe(ErrorMessages.required); }); it('should return error for invalid email', () => { expect(validateEmail('notanemail')).toBe(ErrorMessages.invalidEmail); expect(validateEmail('missing@domain')).toBe(ErrorMessages.invalidEmail); expect(validateEmail('@nodomain.com')).toBe(ErrorMessages.invalidEmail); expect(validateEmail('spaces in@email.com')).toBe(ErrorMessages.invalidEmail); }); }); describe('validatePhone', () => { it('should return null for valid phone numbers', () => { expect(validatePhone('+14155551234')).toBeNull(); expect(validatePhone('14155551234')).toBeNull(); expect(validatePhone('+7 (999) 123-45-67')).toBeNull(); expect(validatePhone('999.123.4567')).toBeNull(); }); it('should return null for empty phone (optional)', () => { expect(validatePhone('')).toBeNull(); expect(validatePhone(' ')).toBeNull(); }); it('should return error for invalid phone', () => { expect(validatePhone('123')).toBe(ErrorMessages.invalidPhone); expect(validatePhone('abcdefghij')).toBe(ErrorMessages.invalidPhone); }); }); describe('validateRequired', () => { it('should return null for non-empty value', () => { expect(validateRequired('test')).toBeNull(); expect(validateRequired(' test ')).toBeNull(); }); it('should return error for empty value', () => { expect(validateRequired('')).toBe(ErrorMessages.required); expect(validateRequired(' ')).toBe(ErrorMessages.required); expect(validateRequired(null)).toBe(ErrorMessages.required); expect(validateRequired(undefined)).toBe(ErrorMessages.required); }); it('should include field name in error when provided', () => { const error = validateRequired('', 'Email'); expect(error).toBe('Email is required.'); }); }); describe('validateMinLength', () => { it('should return null when value meets minimum', () => { expect(validateMinLength('abc', 3)).toBeNull(); expect(validateMinLength('abcde', 3)).toBeNull(); }); it('should return error when value is too short', () => { expect(validateMinLength('ab', 3)).toBe(ErrorMessages.tooShort(3)); expect(validateMinLength('', 1)).toBe(ErrorMessages.tooShort(1)); }); }); describe('validateMaxLength', () => { it('should return null when value meets maximum', () => { expect(validateMaxLength('abc', 3)).toBeNull(); expect(validateMaxLength('ab', 3)).toBeNull(); }); it('should return error when value is too long', () => { expect(validateMaxLength('abcd', 3)).toBe(ErrorMessages.tooLong(3)); }); }); describe('validateOtp', () => { it('should return null for valid OTP', () => { expect(validateOtp('123456')).toBeNull(); expect(validateOtp('000000')).toBeNull(); }); it('should return error for empty OTP', () => { expect(validateOtp('')).toBe(ErrorMessages.required); expect(validateOtp(' ')).toBe(ErrorMessages.required); }); it('should return error for invalid OTP', () => { expect(validateOtp('12345')).toBe(ErrorMessages.invalidOtp); // Too short expect(validateOtp('1234567')).toBe(ErrorMessages.invalidOtp); // Too long expect(validateOtp('12345a')).toBe(ErrorMessages.invalidOtp); // Contains letter expect(validateOtp('12 345')).toBe(ErrorMessages.invalidOtp); // Contains space }); it('should respect custom length', () => { expect(validateOtp('1234', 4)).toBeNull(); expect(validateOtp('123456', 4)).toBe(ErrorMessages.invalidOtp); }); }); describe('formatErrorMessage', () => { it('should capitalize first letter', () => { expect(formatErrorMessage('error message')).toBe('Error message.'); }); it('should add period if missing', () => { expect(formatErrorMessage('Error message')).toBe('Error message.'); }); it('should not add period if already ends with punctuation', () => { expect(formatErrorMessage('Error message.')).toBe('Error message.'); expect(formatErrorMessage('Error message!')).toBe('Error message!'); expect(formatErrorMessage('Error message?')).toBe('Error message?'); }); it('should return generic error for empty input', () => { expect(formatErrorMessage('')).toBe(ErrorMessages.genericError); }); it('should trim whitespace', () => { expect(formatErrorMessage(' error ')).toBe('Error.'); }); }); describe('combineFieldErrors', () => { it('should return empty string for no errors', () => { expect(combineFieldErrors([])).toBe(''); }); it('should return single message for one error', () => { const errors = [{ field: 'email', message: 'Invalid email' }]; expect(combineFieldErrors(errors)).toBe('Invalid email'); }); it('should combine multiple errors', () => { const errors = [ { field: 'email', message: 'Invalid email' }, { field: 'phone', message: 'Invalid phone' }, ]; const result = combineFieldErrors(errors); expect(result).toContain('2 errors'); expect(result).toContain('Invalid email'); expect(result).toContain('Invalid phone'); }); }); describe('getErrorCountText', () => { it('should return "No errors" for 0', () => { expect(getErrorCountText(0)).toBe('No errors'); }); it('should return "1 error" for 1', () => { expect(getErrorCountText(1)).toBe('1 error'); }); it('should return plural for multiple errors', () => { expect(getErrorCountText(2)).toBe('2 errors'); expect(getErrorCountText(5)).toBe('5 errors'); }); }); });