import { describe, it, expect } from 'vitest'; import { validatePasswordStrength, calculatePasswordStrength, } from './passwordValidator'; describe('passwordValidator', () => { describe('validatePasswordStrength', () => { it('should validate a password with all requirements', () => { const result = validatePasswordStrength('SecurePass123!'); expect(result.isValid).toBe(true); expect(result.errors).toHaveLength(0); expect(result.strength.length).toBe(true); expect(result.strength.upper).toBe(true); expect(result.strength.lower).toBe(true); expect(result.strength.number).toBe(true); expect(result.strength.special).toBe(true); }); it('should reject password shorter than 8 characters', () => { const result = validatePasswordStrength('Test123'); expect(result.isValid).toBe(false); expect(result.errors).toContain('password must be at least 8 characters'); expect(result.strength.length).toBe(false); }); it('should reject password longer than 128 characters', () => { const longPassword = `${'A'.repeat(129)}a1!`; const result = validatePasswordStrength(longPassword); expect(result.isValid).toBe(false); expect(result.errors).toContain( 'password must be less than 128 characters', ); }); it('should reject password without uppercase letter', () => { const result = validatePasswordStrength('test123!@#'); expect(result.isValid).toBe(false); expect(result.errors).toContain( 'password must contain at least one uppercase letter', ); expect(result.strength.upper).toBe(false); }); it('should reject password without lowercase letter', () => { const result = validatePasswordStrength('TEST123!@#'); expect(result.isValid).toBe(false); expect(result.errors).toContain( 'password must contain at least one lowercase letter', ); expect(result.strength.lower).toBe(false); }); it('should reject password without number', () => { const result = validatePasswordStrength('TestPass!@#'); expect(result.isValid).toBe(false); expect(result.errors).toContain( 'password must contain at least one number', ); expect(result.strength.number).toBe(false); }); it('should reject password without special character', () => { const result = validatePasswordStrength('TestPass123'); expect(result.isValid).toBe(false); expect(result.errors).toContain( 'password must contain at least one special character', ); expect(result.strength.special).toBe(false); }); it('should accept password exactly 8 characters', () => { const result = validatePasswordStrength('Test123!'); expect(result.isValid).toBe(true); expect(result.errors).toHaveLength(0); }); it('should return multiple errors for password missing multiple requirements', () => { const result = validatePasswordStrength('test'); expect(result.isValid).toBe(false); expect(result.errors.length).toBeGreaterThan(1); }); it('should validate password with various special characters', () => { const specialChars = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')']; specialChars.forEach((char) => { const password = `Test123${char}`; const result = validatePasswordStrength(password); expect(result.isValid).toBe(true); expect(result.strength.special).toBe(true); }); }); }); describe('calculatePasswordStrength', () => { it('should return score 5 for strong password', () => { const score = calculatePasswordStrength('SecurePass123!'); expect(score).toBe(5); }); it('should return score 0 for empty password', () => { const score = calculatePasswordStrength(''); expect(score).toBe(0); }); it('should return score 2 for password with length and lowercase', () => { const score = calculatePasswordStrength('testpass'); expect(score).toBe(2); // length + lowercase }); it('should return score 2 for password with length and uppercase', () => { const score = calculatePasswordStrength('TESTPASS'); expect(score).toBe(2); }); it('should return score 3 for password with length, uppercase, and lowercase', () => { const score = calculatePasswordStrength('TestPass'); expect(score).toBe(3); }); it('should return score 4 for password with length, uppercase, lowercase, and number', () => { const score = calculatePasswordStrength('TestPass123'); expect(score).toBe(4); }); }); });