import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import DashboardManualInputForm from '../DashboardManualInputForm.tsx'; const { createMock, listMock } = vi.hoisted(() => ({ createMock: vi.fn(), listMock: vi.fn(), })); vi.mock('../../../services/apiClient.ts', () => ({ api: { manualInputs: { list: listMock, create: createMock, }, }, ApiError: class ApiError extends Error { status: number; constructor(status: number, message: string) { super(message); this.status = status; } }, errorMessage: (err: unknown) => (err instanceof Error ? err.message : 'Terjadi kesalahan'), })); describe('DashboardManualInputForm', () => { beforeEach(() => { listMock.mockReset(); createMock.mockReset(); listMock.mockResolvedValue([]); createMock.mockResolvedValue({ id: 1, cycle: 4, date: '2026-08-19', age_manual: 10, mortality_manual: 5, mortality_manual_total: 5, feed_in_manual: 8, feed_use_manual: 12, feed_out_manual: 3, feed_in_manual_total: 8, feed_use_manual_total: 12, feed_out_manual_total: 3, harvest_manual: 0, harvest_manual_total: 0, harvest_weight_manual: 0, harvest_weight_manual_total: 0, manual_weight: 320, }); }); it('lets the user save daily manual fields without totals, FCR, or EEF', async () => { render(); expect(await screen.findByRole('heading', { name: /Input manual/i })).toBeInTheDocument(); expect(screen.queryByLabelText(/FCR/i)).not.toBeInTheDocument(); expect(screen.queryByLabelText(/EEF/i)).not.toBeInTheDocument(); expect(screen.queryByLabelText(/rata-rata panen/i)).not.toBeInTheDocument(); fireEvent.change(screen.getByLabelText(/Umur/i), { target: { value: '10' } }); fireEvent.change(screen.getByLabelText(/Mortalitas/i), { target: { value: '5' } }); fireEvent.change(screen.getByLabelText(/Karung masuk/i), { target: { value: '8' } }); fireEvent.change(screen.getByLabelText(/Karung tuang/i), { target: { value: '12' } }); fireEvent.change(screen.getByLabelText(/Karung keluar/i), { target: { value: '3' } }); fireEvent.change(screen.getByLabelText(/Berat panen/i), { target: { value: '8.5' } }); expect(screen.getByLabelText(/Berat panen/i)).toHaveAttribute('step', '0.01'); fireEvent.click(screen.getByRole('button', { name: /Simpan/i })); await waitFor(() => expect(createMock).toHaveBeenCalledTimes(1)); const body = createMock.mock.calls[0]![0]; expect(body).toMatchObject({ cycle: 4, age_manual: 10, mortality_manual: 5, feed_in_manual: 8, feed_use_manual: 12, feed_out_manual: 3, harvest_weight_manual: 8500, }); expect(body).not.toHaveProperty('mortality_manual_total'); expect(body).not.toHaveProperty('fcr_manual'); expect(body).not.toHaveProperty('eef_manual'); }); });