import { render, screen, waitFor, fireEvent } from '@testing-library/react' import { describe, it, expect, vi } from 'vitest' import { MemoryRouter, Route, Routes } from 'react-router-dom' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import EntityDetailPage from '@/pages/EntityDetailPage' import * as entitiesApi from '@/api/entitiesApi' import * as tasksApi from '@/api/tasksApi' vi.mock('@/api/entitiesApi') vi.mock('@/api/tasksApi') const wrapper = ({ children }: { children: React.ReactNode }) => ( ) describe('EntityDetailPage', () => { it('should_renderEntityAndTasks_when_pageLoads', async () => { vi.mocked(entitiesApi.getEntity).mockResolvedValue({ id: 'entity-1', name: 'Entity A', email: 'a@a.com', jobTitle: 'Ops', personality: 'Formal', scheduleCron: '0 9 * * 1', contextWindowDays: 3, active: true, createdAt: '', }) vi.mocked(tasksApi.getTasksByEntity).mockResolvedValue([ { id: 'task-1', entityId: 'entity-1', name: 'Weekly Check-in', prompt: 'Summarize jokes', scheduleCron: '0 9 * * 1', emailLookback: 'last_week', createdAt: '2026-03-26T10:00:00Z', }, ]) render(, { wrapper }) await waitFor(() => { expect(screen.getByText(/Entity A/i)).toBeInTheDocument() expect(screen.getByText(/Weekly Check-in/i)).toBeInTheDocument() expect(screen.getByText(/Last week/i)).toBeInTheDocument() }) }) it('should_generatePreviewAndCreateTask_when_formSubmitted', async () => { vi.mocked(entitiesApi.getEntity).mockResolvedValue({ id: 'entity-1', name: 'Entity A', email: 'a@a.com', jobTitle: 'Ops', personality: 'Formal', scheduleCron: '0 9 * * 1', contextWindowDays: 3, active: true, createdAt: '', }) vi.mocked(tasksApi.getTasksByEntity).mockResolvedValue([]) vi.mocked(tasksApi.generateTaskPreview).mockResolvedValue('SUBJECT: Preview\nBODY:\nFormal nonsense') vi.mocked(tasksApi.createTask).mockResolvedValue({ id: 'task-2', entityId: 'entity-1', name: 'Morning Blast', prompt: 'Talk about coffee', scheduleCron: '0 8 * * 1-5', emailLookback: 'last_week', createdAt: '2026-03-26T10:00:00Z', }) render(, { wrapper }) await screen.findByRole('button', { name: /new task/i }) fireEvent.click(screen.getByRole('button', { name: /new task/i })) fireEvent.change(screen.getByLabelText(/task name/i), { target: { value: 'Morning Blast' } }) fireEvent.change(screen.getByLabelText(/task prompt/i), { target: { value: 'Talk about coffee' } }) fireEvent.change(screen.getByLabelText(/task schedule/i), { target: { value: '0 8 * * 1-5' } }) fireEvent.click(screen.getByRole('button', { name: /generate test message/i })) await waitFor(() => { expect(tasksApi.generateTaskPreview).toHaveBeenCalledWith( expect.objectContaining({ entityId: 'entity-1', name: 'Morning Blast', prompt: 'Talk about coffee', scheduleCron: '0 8 * * 1-5', emailLookback: 'last_week', }) ) expect(screen.getByText(/Formal nonsense/i)).toBeInTheDocument() }) fireEvent.click(screen.getByRole('button', { name: /create task/i })) await waitFor(() => { expect(tasksApi.createTask).toHaveBeenCalledWith( expect.objectContaining({ entityId: 'entity-1', name: 'Morning Blast', prompt: 'Talk about coffee', scheduleCron: '0 8 * * 1-5', emailLookback: 'last_week', }) ) }) }) })