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();
});
});