import { validateSerial, isValidSerial, isDemoSerial, getSerialErrorMessage, formatSerialForDisplay, getSerialPlaceholder, } from '../serialValidation'; describe('Serial Validation', () => { describe('validateSerial', () => { // Production format tests it('should validate production format WELLNUO-XXXX-XXXX', () => { const result = validateSerial('WELLNUO-1234-5678'); expect(result.isValid).toBe(true); expect(result.format).toBe('production'); expect(result.normalized).toBe('WELLNUO-1234-5678'); expect(result.error).toBeUndefined(); }); it('should validate production format with lowercase', () => { const result = validateSerial('wellnuo-abcd-efgh'); expect(result.isValid).toBe(true); expect(result.format).toBe('production'); expect(result.normalized).toBe('WELLNUO-ABCD-EFGH'); }); it('should validate production format with mixed case and spaces', () => { const result = validateSerial(' WeLlNuO-1a2B-3c4D '); expect(result.isValid).toBe(true); expect(result.format).toBe('production'); expect(result.normalized).toBe('WELLNUO-1A2B-3C4D'); }); // Demo serial tests it('should validate demo serial DEMO-00000', () => { const result = validateSerial('DEMO-00000'); expect(result.isValid).toBe(true); expect(result.format).toBe('demo'); expect(result.normalized).toBe('DEMO-00000'); }); it('should validate demo serial DEMO-1234-5678', () => { const result = validateSerial('DEMO-1234-5678'); expect(result.isValid).toBe(true); expect(result.format).toBe('demo'); expect(result.normalized).toBe('DEMO-1234-5678'); }); it('should validate demo serial with lowercase', () => { const result = validateSerial('demo-00000'); expect(result.isValid).toBe(true); expect(result.format).toBe('demo'); expect(result.normalized).toBe('DEMO-00000'); }); // Legacy format tests it('should validate legacy 8-character alphanumeric', () => { const result = validateSerial('ABC12345'); expect(result.isValid).toBe(true); expect(result.format).toBe('legacy'); expect(result.normalized).toBe('ABC12345'); }); it('should validate legacy format with hyphens', () => { const result = validateSerial('ABC-123-456'); expect(result.isValid).toBe(true); expect(result.format).toBe('legacy'); expect(result.normalized).toBe('ABC-123-456'); }); it('should validate legacy 16-character serial', () => { const result = validateSerial('ABCDEFGH12345678'); expect(result.isValid).toBe(true); expect(result.format).toBe('legacy'); expect(result.normalized).toBe('ABCDEFGH12345678'); }); // Invalid format tests it('should reject empty string', () => { const result = validateSerial(''); expect(result.isValid).toBe(false); expect(result.format).toBe('invalid'); expect(result.error).toBe('Serial number is required'); }); it('should reject null', () => { const result = validateSerial(null); expect(result.isValid).toBe(false); expect(result.format).toBe('invalid'); expect(result.error).toBe('Serial number is required'); }); it('should reject undefined', () => { const result = validateSerial(undefined); expect(result.isValid).toBe(false); expect(result.format).toBe('invalid'); expect(result.error).toBe('Serial number is required'); }); it('should reject strings with only spaces', () => { const result = validateSerial(' '); expect(result.isValid).toBe(false); expect(result.format).toBe('invalid'); expect(result.error).toBe('Serial number is required'); }); it('should reject too short serial (less than 8 chars)', () => { const result = validateSerial('ABC123'); expect(result.isValid).toBe(false); expect(result.format).toBe('invalid'); expect(result.error).toBe('Serial number must be at least 8 characters'); }); it('should reject serial with special characters', () => { const result = validateSerial('ABC123!@#'); expect(result.isValid).toBe(false); expect(result.format).toBe('invalid'); expect(result.error).toBe('Serial number can only contain letters, numbers, and hyphens'); }); it('should accept serials with wrong prefix as legacy format', () => { const result = validateSerial('BADNAME-1234-5678'); expect(result.isValid).toBe(true); expect(result.format).toBe('legacy'); // Valid as legacy, not production }); it('should accept malformed production format as legacy', () => { const result = validateSerial('WELLNUO-123-5678'); // only 3 chars in middle expect(result.isValid).toBe(true); expect(result.format).toBe('legacy'); // Valid as legacy, not production }); it('should accept serials with extra hyphens as legacy', () => { const result = validateSerial('WELLNUO-12-34-5678'); expect(result.isValid).toBe(true); expect(result.format).toBe('legacy'); // Valid as legacy, not production }); it('should reject production format without hyphens', () => { const result = validateSerial('WELLNUO12345678'); expect(result.isValid).toBe(true); // Actually valid as legacy format expect(result.format).toBe('legacy'); // Not production }); }); describe('isValidSerial', () => { it('should return true for valid production serial', () => { expect(isValidSerial('WELLNUO-1234-5678')).toBe(true); }); it('should return true for valid demo serial', () => { expect(isValidSerial('DEMO-00000')).toBe(true); }); it('should return true for valid legacy serial', () => { expect(isValidSerial('ABC12345')).toBe(true); }); it('should return false for invalid serial', () => { expect(isValidSerial('ABC')).toBe(false); }); it('should return false for null', () => { expect(isValidSerial(null)).toBe(false); }); it('should return false for undefined', () => { expect(isValidSerial(undefined)).toBe(false); }); }); describe('isDemoSerial', () => { it('should return true for DEMO-00000', () => { expect(isDemoSerial('DEMO-00000')).toBe(true); }); it('should return true for DEMO-1234-5678', () => { expect(isDemoSerial('DEMO-1234-5678')).toBe(true); }); it('should return true for lowercase demo serial', () => { expect(isDemoSerial('demo-00000')).toBe(true); }); it('should return true for demo serial with spaces', () => { expect(isDemoSerial(' DEMO-00000 ')).toBe(true); }); it('should return false for production serial', () => { expect(isDemoSerial('WELLNUO-1234-5678')).toBe(false); }); it('should return false for legacy serial', () => { expect(isDemoSerial('ABC12345')).toBe(false); }); it('should return false for null', () => { expect(isDemoSerial(null)).toBe(false); }); it('should return false for undefined', () => { expect(isDemoSerial(undefined)).toBe(false); }); }); describe('getSerialErrorMessage', () => { it('should return empty string for valid serial', () => { expect(getSerialErrorMessage('WELLNUO-1234-5678')).toBe(''); }); it('should return error for empty string', () => { const error = getSerialErrorMessage(''); expect(error).toBeTruthy(); expect(error).toContain('required'); }); it('should return error for null', () => { const error = getSerialErrorMessage(null); expect(error).toBeTruthy(); expect(error).toContain('required'); }); it('should return error for too short serial', () => { const error = getSerialErrorMessage('ABC'); expect(error).toBeTruthy(); expect(error).toContain('8 characters'); }); it('should return error for serial with special characters', () => { const error = getSerialErrorMessage('ABC123!@#'); expect(error).toBeTruthy(); expect(error).toContain('letters, numbers, and hyphens'); }); it('should return specific error for too short serial', () => { const error = getSerialErrorMessage('ABC'); expect(error).toContain('8 characters'); }); }); describe('formatSerialForDisplay', () => { it('should add hyphens to production serial without hyphens', () => { const formatted = formatSerialForDisplay('WELLNUO12345678'); expect(formatted).toBe('WELLNUO-1234-5678'); }); it('should keep hyphens in production serial with hyphens', () => { const formatted = formatSerialForDisplay('WELLNUO-1234-5678'); expect(formatted).toBe('WELLNUO-1234-5678'); }); it('should uppercase and trim', () => { const formatted = formatSerialForDisplay(' wellnuo-abcd-efgh '); expect(formatted).toBe('WELLNUO-ABCD-EFGH'); }); it('should not modify demo serial', () => { const formatted = formatSerialForDisplay('DEMO-00000'); expect(formatted).toBe('DEMO-00000'); }); it('should not modify legacy serial', () => { const formatted = formatSerialForDisplay('ABC12345'); expect(formatted).toBe('ABC12345'); }); it('should uppercase lowercase serial', () => { const formatted = formatSerialForDisplay('abc12345'); expect(formatted).toBe('ABC12345'); }); }); describe('getSerialPlaceholder', () => { it('should return production placeholder by default', () => { const placeholder = getSerialPlaceholder(); expect(placeholder).toBe('WELLNUO-XXXX-XXXX'); }); it('should return production placeholder when preferProduction is true', () => { const placeholder = getSerialPlaceholder(true); expect(placeholder).toBe('WELLNUO-XXXX-XXXX'); }); it('should return generic placeholder when preferProduction is false', () => { const placeholder = getSerialPlaceholder(false); expect(placeholder).toBe('Enter serial number'); }); }); describe('Edge cases', () => { it('should handle very long serials', () => { const longSerial = 'A'.repeat(100); const result = validateSerial(longSerial); expect(result.isValid).toBe(true); // Valid as legacy expect(result.format).toBe('legacy'); }); it('should handle serials with multiple hyphens', () => { const result = validateSerial('ABC-123-456-789'); expect(result.isValid).toBe(true); // Valid as legacy expect(result.format).toBe('legacy'); }); it('should handle numeric-only serials', () => { const result = validateSerial('12345678'); expect(result.isValid).toBe(true); // Valid as legacy expect(result.format).toBe('legacy'); }); it('should handle mixed case in production format', () => { const result = validateSerial('WeLlNuO-AbCd-EfGh'); expect(result.isValid).toBe(true); expect(result.format).toBe('production'); expect(result.normalized).toBe('WELLNUO-ABCD-EFGH'); }); }); });