import { describe, it, expect, vi } from 'vitest'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import CreateSourceCorpusModal from './CreateSourceCorpusModal.jsx'; describe('CreateSourceCorpusModal', () => { it('renders nothing when open is false', () => { const { container } = render( {}} onCancel={() => {}} />, ); expect(container.innerHTML).toBe(''); }); it('renders the modal with title when open', () => { render( {}} onCancel={() => {}} />); expect(screen.getByText('New Source Corpus')).toBeInTheDocument(); }); it('renders input and buttons', () => { render( {}} onCancel={() => {}} />); expect(screen.getByPlaceholderText('Enter source corpus name')).toBeInTheDocument(); expect(screen.getByText('Cancel')).toBeInTheDocument(); expect(screen.getByText('Create')).toBeInTheDocument(); }); it('disables Create button when input is empty', () => { render( {}} onCancel={() => {}} />); expect(screen.getByText('Create')).toBeDisabled(); }); it('enables Create button when input has text', async () => { const user = userEvent.setup(); render( {}} onCancel={() => {}} />); await user.type(screen.getByPlaceholderText('Enter source corpus name'), 'My SourceCorpus'); expect(screen.getByText('Create')).toBeEnabled(); }); it('calls onConfirm with trimmed name on submit', async () => { const user = userEvent.setup(); const onConfirm = vi.fn(); render( {}} />); await user.type(screen.getByPlaceholderText('Enter source corpus name'), ' Research Notes '); await user.click(screen.getByText('Create')); expect(onConfirm).toHaveBeenCalledWith('Research Notes'); }); it('calls onConfirm on Enter key', async () => { const user = userEvent.setup(); const onConfirm = vi.fn(); render( {}} />); await user.type(screen.getByPlaceholderText('Enter source corpus name'), 'Test{Enter}'); expect(onConfirm).toHaveBeenCalledWith('Test'); }); it('does not call onConfirm when input is only whitespace', async () => { const user = userEvent.setup(); const onConfirm = vi.fn(); render( {}} />); const input = screen.getByPlaceholderText('Enter source corpus name'); await user.type(input, ' '); await user.type(input, '{Enter}'); expect(onConfirm).not.toHaveBeenCalled(); }); it('calls onCancel when Cancel button is clicked', async () => { const user = userEvent.setup(); const onCancel = vi.fn(); render( {}} onCancel={onCancel} />); await user.click(screen.getByText('Cancel')); expect(onCancel).toHaveBeenCalledOnce(); }); it('resets input when reopened', async () => { const user = userEvent.setup(); const { rerender } = render( {}} onCancel={() => {}} />, ); await user.type(screen.getByPlaceholderText('Enter source corpus name'), 'Old name'); rerender( {}} onCancel={() => {}} />); rerender( {}} onCancel={() => {}} />); expect(screen.getByPlaceholderText('Enter source corpus name')).toHaveValue(''); }); it('auto-focuses the input when opened', async () => { render( {}} onCancel={() => {}} />); await waitFor(() => { expect(screen.getByPlaceholderText('Enter source corpus name')).toHaveFocus(); }, { timeout: 200 }); }); });