/** * ClientModeStep Component Tests * * Tests for the client interaction mode selection step. */ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { ClientModeStep } from '@/components/projects/wizard/steps/ClientModeStep'; import { clientModeOptions } from '@/components/projects/wizard/constants'; import type { WizardState } from '@/components/projects/wizard/types'; describe('ClientModeStep', () => { const defaultState: WizardState = { step: 3, projectName: 'Test Project', description: '', repoUrl: '', complexity: 'medium', clientMode: null, autonomyLevel: null, }; const mockUpdateState = jest.fn(); beforeEach(() => { jest.clearAllMocks(); }); describe('Rendering', () => { it('renders the step title', () => { render(); expect(screen.getByText('How Would You Like to Work?')).toBeInTheDocument(); }); it('renders the description text', () => { render(); expect(screen.getByText(/choose how you want to interact/i)).toBeInTheDocument(); }); it('renders all client mode options', () => { render(); clientModeOptions.forEach((option) => { expect(screen.getByText(option.label)).toBeInTheDocument(); expect(screen.getByText(option.description)).toBeInTheDocument(); }); }); it('renders detail items for each option', () => { render(); clientModeOptions.forEach((option) => { option.details.forEach((detail) => { expect(screen.getByText(detail)).toBeInTheDocument(); }); }); }); it('has accessible radiogroup role', () => { render(); expect(screen.getByRole('radiogroup', { name: /client interaction mode options/i })).toBeInTheDocument(); }); }); describe('Selection', () => { it('shows no selection initially', () => { render(); // No check icons should be visible for selected state const selectedIndicators = document.querySelectorAll('[data-selected="true"]'); expect(selectedIndicators.length).toBe(0); }); it('calls updateState when clicking the technical mode option', async () => { const user = userEvent.setup(); render(); const technicalOption = screen.getByRole('button', { name: /technical mode.*detailed technical/i }); await user.click(technicalOption); expect(mockUpdateState).toHaveBeenCalledWith({ clientMode: 'technical' }); }); it('calls updateState when clicking the auto mode option', async () => { const user = userEvent.setup(); render(); const autoOption = screen.getByRole('button', { name: /auto mode.*help me figure/i }); await user.click(autoOption); expect(mockUpdateState).toHaveBeenCalledWith({ clientMode: 'auto' }); }); it('shows visual selection indicator when an option is selected', () => { const stateWithSelection: WizardState = { ...defaultState, clientMode: 'technical', }; render(); // The selected card should have the check icon const checkIcons = document.querySelectorAll('.lucide-check'); expect(checkIcons.length).toBeGreaterThan(0); }); it('highlights selected option icon for auto mode', () => { const stateWithAuto: WizardState = { ...defaultState, clientMode: 'auto', }; render(); // Should have check mark for selected option const checkIcons = document.querySelectorAll('.lucide-check'); expect(checkIcons.length).toBeGreaterThan(0); }); }); describe('Accessibility', () => { it('each option has accessible aria-label', () => { render(); clientModeOptions.forEach((option) => { const button = screen.getByRole('button', { name: new RegExp(`${option.label}.*${option.description}`, 'i') }); expect(button).toBeInTheDocument(); }); }); it('icons have aria-hidden attribute', () => { render(); const hiddenIcons = document.querySelectorAll('[aria-hidden="true"]'); expect(hiddenIcons.length).toBeGreaterThan(0); }); it('CheckCircle2 icons in detail lists are hidden from assistive tech', () => { render(); // All lucide icons should have aria-hidden const allCheckCircles = document.querySelectorAll('.lucide-circle-check-big'); allCheckCircles.forEach((icon) => { expect(icon).toHaveAttribute('aria-hidden', 'true'); }); }); }); describe('Edge cases', () => { it('allows changing selection', async () => { const user = userEvent.setup(); const stateWithTechnical: WizardState = { ...defaultState, clientMode: 'technical', }; render(); const autoOption = screen.getByRole('button', { name: /auto mode.*help me figure/i }); await user.click(autoOption); expect(mockUpdateState).toHaveBeenCalledWith({ clientMode: 'auto' }); }); it('handles clicking already selected option', async () => { const user = userEvent.setup(); const stateWithTechnical: WizardState = { ...defaultState, clientMode: 'technical', }; render(); const technicalOption = screen.getByRole('button', { name: /technical mode.*detailed technical/i }); await user.click(technicalOption); // Should still call updateState expect(mockUpdateState).toHaveBeenCalledWith({ clientMode: 'technical' }); }); }); });