update dashboard with a warning if the chicken counting accuracy result drop to less than 95%

This commit is contained in:
Alberto-Audrix committed 2026-09-07 15:40:31 +07:00
1 parent 155a24c7bd
commit 61fae64aa6
7 files changed
+479 -2

No files matched your search

@@ -0,0 +1,36 @@
import { render, screen } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import CountingAccuracyWarningBanner from '../CountingAccuracyWarningBanner.tsx';
import type { CountingAccuracyWarning } from '../../../utils/countingAccuracyWarning.ts';
const base: CountingAccuracyWarning = {
day: 2,
date: '2026-08-12',
iotCount: 900,
stockAkhir: 1000,
accuracy: 90,
ratioPercent: 90,
direction: 'under',
};
describe('CountingAccuracyWarningBanner', () => {
it('renders under-count manager checklist', () => {
render(<CountingAccuracyWarningBanner warning={base} />);
expect(screen.getByText(/IoT lebih rendah dari stock/i)).toBeInTheDocument();
expect(screen.getByText(/video kamera lengkap/i)).toBeInTheDocument();
expect(screen.getByText(/Hari 2/i)).toBeInTheDocument();
expect(screen.getByText(/90%/)).toBeInTheDocument();
});
it('renders over-count fraud / AI checklist', () => {
render(
<CountingAccuracyWarningBanner
warning={{ ...base, iotCount: 1060, stockAkhir: 1000, accuracy: 94.3, ratioPercent: 106, direction: 'over' }}
/>
);
expect(screen.getByText(/lebih tinggi dari stock manual/i)).toBeInTheDocument();
expect(screen.getByText(/fraud/i)).toBeInTheDocument();
expect(screen.getByText(/akurasi 94,3%/i)).toBeInTheDocument();
expect(screen.queryByText(/106%/)).not.toBeInTheDocument();
});
});
@@ -1,4 +1,4 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { fireEvent, render, screen, waitFor, within } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import DataManagementPage from '../DataManagementPage.tsx';
import { api } from '../../../services/apiClient.ts';
@@ -76,6 +76,7 @@ vi.mock('../../../utils/format.ts', async () => {
describe('DataManagementPage', () => {
beforeEach(() => {
vi.mocked(api.kpis.list).mockResolvedValue([]);
vi.mocked(api.countings.list).mockResolvedValue([]);
vi.mocked(api.countings.sync).mockResolvedValue({
upserted: 2,
@@ -123,4 +124,57 @@ describe('DataManagementPage', () => {
expect(api.countings.sync).toHaveBeenCalledWith({ cycle_id: 1 });
});
});
it('shows under-count IoT accuracy warning for the latest IoT day', async () => {
vi.mocked(api.kpis.list).mockResolvedValue([
{
id: 1,
cycle: 1,
kandang: 1,
flock_id: 1,
date: '2026-08-12',
age: 2,
mortality: 0,
mortality_total: 10,
feed: 0,
feed_total: 0,
harvest: 0,
harvest_total: 0,
harvest_weight: 0,
harvest_weight_total: 0,
chicken_life: 19990,
chicken_life_percentage: 99.95,
iot_weight: 0,
average_harvest_day: 0,
average_harvest_weight: 0,
fcr: 0,
eef: 0,
cc: 0,
cw: 0,
fs: 0,
manual: 0,
created_at: '',
updated_at: '',
},
]);
vi.mocked(api.countings.list).mockResolvedValue([
{
id: 1,
cycle: 1,
kandang: 1,
flock_id: 1,
date: '2026-08-12',
total_count: 18000,
mortality_count: 0,
created_at: '',
updated_at: '',
},
]);
render(<DataManagementPage onSettings={() => undefined} />);
const alert = await screen.findByRole('alert');
expect(within(alert).getByText(/IoT lebih rendah dari stock/i)).toBeInTheDocument();
expect(within(alert).getByText(/Hari 2/i)).toBeInTheDocument();
});
});