import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom'; import { PersonalDetailsStep } from '../PersonalDetailsStep'; import { EMPTY_FORM_DATA } from './helpers'; describe('PersonalDetailsStep', () => { const defaultProps: { formData: typeof EMPTY_FORM_DATA; errors: Record; updateField: jest.Mock; } = { formData: EMPTY_FORM_DATA, errors: {}, updateField: jest.fn() }; it('should render section header', () => { const { getByText } = render(); expect(getByText('Your details')).toBeInTheDocument(); }); it('should render all 4 fields', () => { const { getByLabelText } = render( ); expect(getByLabelText(/First Name/)).toBeInTheDocument(); expect(getByLabelText(/Last Name/)).toBeInTheDocument(); expect(getByLabelText(/Telephone Number/)).toBeInTheDocument(); expect(getByLabelText(/Email Address/)).toBeInTheDocument(); }); it('should call updateField when typing in first name', () => { const updateField = jest.fn(); const { getByLabelText } = render( ); fireEvent.change(getByLabelText(/First Name/), { target: { value: 'Jane' } }); expect(updateField).toHaveBeenCalledWith('firstName', 'Jane'); }); it('should display errors for fields', () => { const errors = { firstName: 'Please enter your first name', email: 'Please enter a valid email address' }; const { getByText } = render( ); expect(getByText('Please enter your first name')).toBeInTheDocument(); expect(getByText('Please enter a valid email address')).toBeInTheDocument(); }); it('should render email field with email type', () => { const { getByLabelText } = render( ); expect(getByLabelText(/Email Address/)).toHaveAttribute('type', 'email'); }); it('should render telephone field with tel type', () => { const { getByLabelText } = render( ); expect(getByLabelText(/Telephone Number/)).toHaveAttribute('type', 'tel'); }); it('should render contact preference checkboxes', () => { const { getByLabelText } = render( ); expect(getByLabelText('Telephone')).toBeInTheDocument(); expect(getByLabelText('Email')).toBeInTheDocument(); }); it('should render appointment checkboxes', () => { const { getByLabelText } = render( ); expect(getByLabelText('Video call')).toBeInTheDocument(); expect(getByLabelText('Telephone call')).toBeInTheDocument(); }); it('should toggle contactByTelephone on click', () => { const updateField = jest.fn(); const { getByLabelText } = render( ); fireEvent.click(getByLabelText('Telephone')); expect(updateField).toHaveBeenCalledWith('contactByTelephone', true); }); it('should not show date/time fields when no appointment selected', () => { const { queryByLabelText } = render( ); expect(queryByLabelText('Your preferred date')).not.toBeInTheDocument(); expect(queryByLabelText('Your preferred time')).not.toBeInTheDocument(); }); it('should show date/time fields when video call is selected', () => { const formData = { ...EMPTY_FORM_DATA, appointmentVideoCall: true }; const { getByLabelText, getByText } = render( ); expect(getByLabelText('Your preferred date')).toBeInTheDocument(); expect(getByText('Your preferred time')).toBeInTheDocument(); }); it('should apply checked class to contactByTelephone wrapper when checked', () => { const formData = { ...EMPTY_FORM_DATA, contactByTelephone: true }; const { getByLabelText } = render( ); const checkbox = getByLabelText('Telephone'); expect(checkbox.closest('.checked')).not.toBeNull(); }); it('should call updateField when preferred date changes', () => { const updateField = jest.fn(); const formData = { ...EMPTY_FORM_DATA, appointmentVideoCall: true }; const { getByLabelText } = render( ); fireEvent.change(getByLabelText('Your preferred date'), { target: { value: '2026-07-15' } }); expect(updateField).toHaveBeenCalledWith('preferredDate', '2026-07-15'); }); it('should call updateField with combined time when hour is changed', () => { const updateField = jest.fn(); const formData = { ...EMPTY_FORM_DATA, appointmentVideoCall: true, preferredTime: '10:30' }; const { getByRole } = render( ); fireEvent.click(document.getElementById('eq-preferredHour') as HTMLElement); fireEvent.click(getByRole('option', { name: '09' })); expect(updateField).toHaveBeenCalledWith('preferredTime', '09:30'); }); it('should call updateField with combined time when minute is changed', () => { const updateField = jest.fn(); const formData = { ...EMPTY_FORM_DATA, appointmentVideoCall: true, preferredTime: '10:00' }; const { getAllByRole } = render( ); fireEvent.click(document.getElementById( 'eq-preferredMinute' ) as HTMLElement); fireEvent.click(getAllByRole('option', { name: '30' })[0]); expect(updateField).toHaveBeenCalledWith('preferredTime', '10:30'); }); });