import { render, screen, fireEvent, waitFor } from '@testing-library/react' import { describe, it, expect, vi } from 'vitest' import { BrowserRouter } from 'react-router-dom' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import EntitiesPage from '@/pages/EntitiesPage' import * as entitiesApi from '@/api/entitiesApi' vi.mock('@/api/entitiesApi') const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} ) const mockEntity = { id: 'entity-1', name: 'Test Entity', email: 'test@condado.com', jobTitle: 'Tester', personality: 'Formal', scheduleCron: '0 9 * * *', contextWindowDays: 3, active: true, createdAt: '2024-01-01T00:00:00', } describe('EntitiesPage', () => { it('should_renderEntityList_when_entitiesLoaded', async () => { vi.mocked(entitiesApi.getEntities).mockResolvedValue([mockEntity]) render(, { wrapper }) await waitFor(() => { expect(screen.getByText('Test Entity')).toBeInTheDocument() }) }) it('should_openCreateDialog_when_addButtonClicked', async () => { vi.mocked(entitiesApi.getEntities).mockResolvedValue([]) render(, { wrapper }) const addButton = screen.getByRole('button', { name: /add|create|new/i }) fireEvent.click(addButton) await waitFor(() => { expect(screen.getByRole('dialog')).toBeInTheDocument() expect(screen.queryByLabelText(/default email context window/i)).not.toBeInTheDocument() }) }) it('should_submitDefaultContextWindow_when_createEntitySubmitted', async () => { vi.mocked(entitiesApi.getEntities).mockResolvedValue([]) vi.mocked(entitiesApi.createEntity).mockResolvedValue(mockEntity) render(, { wrapper }) fireEvent.click(screen.getByRole('button', { name: /add|create|new/i })) await waitFor(() => { expect(screen.getByRole('dialog', { name: /create entity/i })).toBeInTheDocument() }) fireEvent.change(screen.getByLabelText(/entity name/i), { target: { value: 'Test Entity' } }) fireEvent.change(screen.getByLabelText(/sender email/i), { target: { value: 'test@condado.com' } }) fireEvent.change(screen.getByLabelText(/job title/i), { target: { value: 'Tester' } }) fireEvent.change(screen.getByLabelText(/personality notes/i), { target: { value: 'Formal' } }) fireEvent.click(screen.getByRole('button', { name: /create/i })) await waitFor(() => { expect(entitiesApi.createEntity).toHaveBeenCalled() expect(vi.mocked(entitiesApi.createEntity).mock.calls[0]?.[0]).toEqual({ name: 'Test Entity', email: 'test@condado.com', jobTitle: 'Tester', personality: 'Formal', contextWindowDays: 3, }) }) }) it('should_callDeleteApi_when_deleteConfirmed', async () => { vi.mocked(entitiesApi.getEntities).mockResolvedValue([mockEntity]) vi.mocked(entitiesApi.deleteEntity).mockResolvedValue(undefined) render(, { wrapper }) await waitFor(() => { expect(screen.getByText('Test Entity')).toBeInTheDocument() }) const deleteButton = screen.getByRole('button', { name: /delete|deactivate/i }) fireEvent.click(deleteButton) await waitFor(() => { expect(entitiesApi.deleteEntity).toHaveBeenCalledWith('entity-1') }) }) it('should_renderDetailLink_when_entitiesLoaded', async () => { vi.mocked(entitiesApi.getEntities).mockResolvedValue([mockEntity]) render(, { wrapper }) await waitFor(() => { expect(screen.getByRole('link', { name: /open details/i })).toHaveAttribute('href', '/entities/entity-1') }) }) })