import React from 'react'; import { vi, describe, it, expect } from 'vitest'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { Formik, Form } from 'formik'; import { SelectInput } from './select-input.component'; /** * Helper to render SelectInput component with Formik. */ function renderSelectInput( props: { name?: string; label?: string; options?: string[]; required?: boolean; } = {}, initialValues: Record = {}, ) { const defaultProps = { name: 'select', label: 'Select', options: ['A Option', 'B Option'], required: false, ...props, }; return render( {}}>
, ); } describe('SelectInput component', () => { describe('Rendering', () => { it('renders the select input', async () => { renderSelectInput({ required: true }); const select = await screen.findByRole('combobox', { name: /select/i }); expect(select).toBeInTheDocument(); }); it('shows required label when field is required', async () => { renderSelectInput({ required: true }); const select = await screen.findByRole('combobox', { name: /^select$/i }); expect(select).toBeInTheDocument(); expect(screen.queryByRole('combobox', { name: /select \(optional\)/i })).not.toBeInTheDocument(); }); it('shows optional label when field is not required', async () => { renderSelectInput({ required: false }); const select = await screen.findByRole('combobox', { name: /select \(optional\)/i }); expect(select).toBeInTheDocument(); }); it('renders all provided options', async () => { renderSelectInput({ options: ['Option 1', 'Option 2', 'Option 3'], required: true }); await screen.findByRole('combobox'); expect(screen.getByText('Option 1')).toBeInTheDocument(); expect(screen.getByText('Option 2')).toBeInTheDocument(); expect(screen.getByText('Option 3')).toBeInTheDocument(); }); }); describe('User interaction', () => { it('allows user to select an option', async () => { const user = userEvent.setup(); renderSelectInput({ required: true }); const select = await screen.findByRole('combobox', { name: /^select$/i }); await user.selectOptions(select, 'A Option'); await waitFor(() => { expect(select).toHaveValue('A Option'); }); }); it('updates form values when user selects an option', async () => { const user = userEvent.setup(); let formValues: Record = {}; render( {}}> {({ values }) => { formValues = values as Record; return (
); }}
, ); const select = await screen.findByRole('combobox'); await user.selectOptions(select, 'B Option'); await waitFor(() => { expect(formValues.select).toBe('B Option'); }); }); it('allows user to switch between options', async () => { const user = userEvent.setup(); renderSelectInput({ required: true }); const select = await screen.findByRole('combobox', { name: /^select$/i }); await user.selectOptions(select, 'A Option'); await waitFor(() => { expect(select).toHaveValue('A Option'); }); await user.selectOptions(select, 'B Option'); await waitFor(() => { expect(select).toHaveValue('B Option'); }); }); }); });