/** * ComplexityStep Component Tests * * Tests for the project complexity selection step. */ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { ComplexityStep } from '@/components/projects/wizard/steps/ComplexityStep'; import { complexityOptions } from '@/components/projects/wizard/constants'; import type { WizardState } from '@/components/projects/wizard/types'; describe('ComplexityStep', () => { const defaultState: WizardState = { step: 2, projectName: 'Test Project', description: '', repoUrl: '', complexity: null, clientMode: null, autonomyLevel: null, }; const mockUpdateState = jest.fn(); beforeEach(() => { jest.clearAllMocks(); }); describe('Rendering', () => { it('renders the step title', () => { render(); expect(screen.getByText('Project Complexity')).toBeInTheDocument(); }); it('renders the description text', () => { render(); expect(screen.getByText(/how complex is your project/i)).toBeInTheDocument(); }); it('renders all complexity options', () => { render(); complexityOptions.forEach((option) => { expect(screen.getByText(option.label)).toBeInTheDocument(); expect(screen.getByText(option.description)).toBeInTheDocument(); }); }); it('renders scope information for each option', () => { render(); complexityOptions.forEach((option) => { expect(screen.getByText(option.scope)).toBeInTheDocument(); }); }); it('renders examples for each option', () => { render(); complexityOptions.forEach((option) => { expect(screen.getByText(option.examples)).toBeInTheDocument(); }); }); it('has accessible radiogroup role', () => { render(); expect( screen.getByRole('radiogroup', { name: /project complexity options/i }) ).toBeInTheDocument(); }); }); describe('Selection', () => { it('shows no selection initially', () => { render(); // No check icons should be visible const selectedIndicators = document.querySelectorAll('[data-selected="true"]'); expect(selectedIndicators.length).toBe(0); }); it('calls updateState when clicking a complexity option', async () => { const user = userEvent.setup(); render(); // Find and click the "Simple" option const simpleOption = screen.getByRole('button', { name: /simple.*small applications/i }); await user.click(simpleOption); expect(mockUpdateState).toHaveBeenCalledWith({ complexity: 'simple' }); }); it('calls updateState when selecting script complexity', async () => { const user = userEvent.setup(); render(); const scriptOption = screen.getByRole('button', { name: /script.*single-file/i }); await user.click(scriptOption); expect(mockUpdateState).toHaveBeenCalledWith({ complexity: 'script' }); }); it('calls updateState when selecting medium complexity', async () => { const user = userEvent.setup(); render(); const mediumOption = screen.getByRole('button', { name: /medium.*full applications/i }); await user.click(mediumOption); expect(mockUpdateState).toHaveBeenCalledWith({ complexity: 'medium' }); }); it('calls updateState when selecting complex complexity', async () => { const user = userEvent.setup(); render(); const complexOption = screen.getByRole('button', { name: /complex.*enterprise/i }); await user.click(complexOption); expect(mockUpdateState).toHaveBeenCalledWith({ complexity: 'complex' }); }); it('shows visual selection indicator when an option is selected', () => { const stateWithSelection: WizardState = { ...defaultState, complexity: 'simple', }; render(); // The selected card should have the check icon const checkIcons = document.querySelectorAll('.lucide-check'); expect(checkIcons.length).toBeGreaterThan(0); }); }); describe('Script Mode Hint', () => { it('does not show script mode hint when script is not selected', () => { render(); expect(screen.queryByText(/simplified flow/i)).not.toBeInTheDocument(); }); it('shows script mode hint when script complexity is selected', () => { const stateWithScript: WizardState = { ...defaultState, complexity: 'script', }; render(); expect(screen.getByText(/simplified flow/i)).toBeInTheDocument(); expect(screen.getByText(/skip to agent chat/i)).toBeInTheDocument(); }); it('does not show script mode hint for simple complexity', () => { const stateWithSimple: WizardState = { ...defaultState, complexity: 'simple', }; render(); expect(screen.queryByText(/simplified flow/i)).not.toBeInTheDocument(); }); }); describe('Accessibility', () => { it('each option has accessible aria-label', () => { render(); complexityOptions.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); }); }); });