import { describe, it, expect } from 'vitest'; import { render, screen } from '@testing-library/react'; import { PasswordStrengthIndicator } from './PasswordStrengthIndicator'; describe('PasswordStrengthIndicator', () => { it('should not render when password is empty', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('should show "Very Weak" for very weak password', () => { render(); expect(screen.getByText('Very Weak')).toBeInTheDocument(); }); it('should show "Weak" for weak password with only length', () => { render(); expect(screen.getByText('Weak')).toBeInTheDocument(); }); it('should show "Fair" for password with length, uppercase, and lowercase', () => { render(); expect(screen.getByText('Fair')).toBeInTheDocument(); }); it('should show "Good" for password with length, uppercase, lowercase, and number', () => { render(); expect(screen.getByText('Good')).toBeInTheDocument(); }); it('should show "Strong" for password with all requirements', () => { render(); expect(screen.getByText('Strong')).toBeInTheDocument(); }); it('should display all validation rules', () => { render(); expect(screen.getByText(/at least 12 characters/i)).toBeInTheDocument(); expect(screen.getByText(/one uppercase letter/i)).toBeInTheDocument(); expect(screen.getByText(/one lowercase letter/i)).toBeInTheDocument(); expect(screen.getByText(/one number/i)).toBeInTheDocument(); expect(screen.getByText(/one special character/i)).toBeInTheDocument(); }); it('should show checkmarks for fulfilled requirements', () => { render(); const checks = screen.getAllByText('✓'); expect(checks.length).toBe(5); // All 5 requirements met }); it('should show circles for unfulfilled requirements', () => { render(); const circles = screen.getAllByText('○'); expect(circles.length).toBeGreaterThan(0); }); it('should have correct progress bar width for score', () => { const { container } = render( , ); const progressBar = container.querySelector( '[role="progressbar"]', ) as HTMLElement; expect(progressBar).toBeInTheDocument(); expect(progressBar.style.width).toBe('100%'); // 5/5 = 100% expect(progressBar.getAttribute('aria-valuenow')).toBe('5'); }); it('should have correct progress bar width for partial score', () => { // Password1234 has 12 characters, upper, lower, number = 4 points = 80% const { container } = render( , ); const progressBar = container.querySelector( '[role="progressbar"]', ) as HTMLElement; expect(progressBar).toBeInTheDocument(); expect(progressBar.getAttribute('aria-valuenow')).toBe('4'); expect(progressBar.style.width).toContain('%'); // Should have percentage width }); it('should correctly identify special characters', () => { // Test with a single special character const { container } = render( , ); expect(container.firstChild).not.toBeNull(); // Should show "Strong" for password with all requirements including special char expect(screen.getByText('Strong')).toBeInTheDocument(); }); it('should have accessible progress bar attributes', () => { const { container } = render( , ); const progressBar = container.querySelector( '[role="progressbar"]', ) as HTMLElement; expect(progressBar.getAttribute('role')).toBe('progressbar'); expect(progressBar.getAttribute('aria-valuenow')).toBe('5'); expect(progressBar.getAttribute('aria-valuemin')).toBe('0'); expect(progressBar.getAttribute('aria-valuemax')).toBe('5'); expect(progressBar.getAttribute('aria-label')).toContain( 'Password strength', ); }); it('should update score when password changes', () => { const { rerender } = render(); expect(screen.getByText('Very Weak')).toBeInTheDocument(); rerender(); expect(screen.getByText('Strong')).toBeInTheDocument(); }); });