import React from 'react'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import DailyStatusForm from '../src/components/DailyStatusForm'; import * as client from '../src/api/client'; jest.mock('../src/api/client', () => ({ dailyStatusesApi: { create: jest.fn(), update: jest.fn(), }, })); const ANIMAL_ID = 'animal-001'; const onSuccess = jest.fn(); const onCancel = jest.fn(); beforeEach(() => jest.clearAllMocks()); describe('DailyStatusForm', () => { it('renders date field (required) and optional fields', () => { render(); expect(screen.getByLabelText(/date/i)).toBeInTheDocument(); expect(screen.getByLabelText(/vitals/i)).toBeInTheDocument(); expect(screen.getByLabelText(/treatment/i)).toBeInTheDocument(); expect(screen.getByLabelText(/notes/i)).toBeInTheDocument(); expect(screen.getByLabelText(/experiment description/i)).toBeInTheDocument(); }); it('pre-fills date with today by default', () => { render(); const today = new Date().toISOString().slice(0, 10); expect(screen.getByLabelText(/date/i)).toHaveValue(today); }); it('shows error when date is cleared', async () => { render(); const dateInput = screen.getByLabelText(/date/i); await userEvent.clear(dateInput); fireEvent.click(screen.getByRole('button', { name: /log status/i })); expect(await screen.findByRole('alert')).toHaveTextContent(/date is required/i); expect(client.dailyStatusesApi.create).not.toHaveBeenCalled(); }); it('calls create with correct payload including animal_id', async () => { const status = { id: 's-1', animal_id: ANIMAL_ID, date: '2024-06-01', vitals: 'HR 72' }; client.dailyStatusesApi.create.mockResolvedValue(status); render(); const dateInput = screen.getByLabelText(/date/i); await userEvent.clear(dateInput); await userEvent.type(dateInput, '2024-06-01'); await userEvent.type(screen.getByLabelText(/vitals/i), 'HR 72'); fireEvent.click(screen.getByRole('button', { name: /log status/i })); await waitFor(() => expect(client.dailyStatusesApi.create).toHaveBeenCalledWith( expect.objectContaining({ animal_id: ANIMAL_ID, vitals: 'HR 72' }) ) ); await waitFor(() => expect(onSuccess).toHaveBeenCalled()); }); it('shows "Save Changes" and pre-fills fields for existing status', () => { const existing = { id: 's-1', date: '2024-06-01T00:00:00.000Z', vitals: 'HR 72', treatment: 'Control', notes: 'Normal', experiment_description: 'Baseline', }; render( ); expect(screen.getByRole('button', { name: /save changes/i })).toBeInTheDocument(); expect(screen.getByDisplayValue('HR 72')).toBeInTheDocument(); }); it('calls onCancel when Cancel is clicked', () => { render(); fireEvent.click(screen.getByRole('button', { name: /cancel/i })); expect(onCancel).toHaveBeenCalled(); }); });