Files
dashboard-cpsp/utils/__tests__/dashboardInsightMetrics.test.ts
T

146 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest';
import {
buildDashboardInsightMetrics,
scopeDashboardInsightMetrics,
} from '../insightContextBuilders.ts';
import { getTargetWeightForAge } from '../weight.ts';
describe('buildDashboardInsightMetrics', () => {
it('builds latest scalars and day-indexed weight series with targets', () => {
const metrics = buildDashboardInsightMetrics({
kpis: [
{
age: 10,
fcr: 1.2,
eef: 180,
chicken_life: 9800,
chicken_life_percentage: 98,
iot_weight: 0,
mortality_total: 200,
harvest_total: 0,
harvest_weight_total: 0,
feed_total: 120,
},
{
age: 28,
fcr: 1.55,
eef: 260,
chicken_life: 9500,
chicken_life_percentage: 95,
iot_weight: 1400,
mortality_total: 500,
harvest_total: 100,
harvest_weight_total: 150_500, // grams
feed_total: 400,
},
],
weights: [
{ age: 10, average_weight: 280, doc_weight: 40, uniformity: 82.5 },
{ age: 28, average_weight: 1350, doc_weight: 40, uniformity: 78.1 },
],
currentDay: 30,
docInCount: 10000,
});
expect(metrics.hari_ke).toBe(28);
expect(metrics.fcr).toBe(1.55);
expect(metrics.eef).toBe(260);
expect(metrics.ayam_hidup_ekor).toBe(9400); // 9500 life − 100 harvest
expect(metrics.mortalitas_kumulatif_persen).toBe(5);
expect(metrics.bobot_avg_gram).toBe(1400);
expect(metrics.doc_in_ekor).toBe(10000);
expect(metrics.kematian_kumulatif_ekor).toBe(500);
expect(metrics.panen_kumulatif_ekor).toBe(100);
expect(metrics.tonase_panen_kg).toBe(150.5);
expect(metrics.uniformity_persen).toBe(78.1);
expect(metrics.pakan_kumulatif_karung).toBe(400);
expect(metrics.weightSeries).toHaveLength(2);
expect(metrics.weightSeries[0]).toEqual({
hari: 10,
actual: 280,
target: getTargetWeightForAge(10, 40),
});
expect(metrics.kpiSeries.map((row) => row.hari)).toEqual([10, 28]);
});
it('falls back to weight average when iot_weight is missing', () => {
const metrics = buildDashboardInsightMetrics({
kpis: [
{
age: 7,
fcr: 1.1,
eef: 100,
chicken_life: 9900,
chicken_life_percentage: 99,
iot_weight: 0,
},
],
weights: [{ age: 7, average_weight: 190, doc_weight: 40 }],
pakanKumulatifFallback: 55,
});
expect(metrics.bobot_avg_gram).toBe(190);
expect(metrics.pakan_kumulatif_karung).toBe(55);
});
});
describe('scopeDashboardInsightMetrics', () => {
const base = buildDashboardInsightMetrics({
kpis: [
{
age: 7,
fcr: 1.1,
eef: 90,
chicken_life: 9900,
chicken_life_percentage: 99,
iot_weight: 200,
mortality_total: 100,
harvest_total: 0,
harvest_weight_total: 0,
feed_total: 40,
},
{
age: 14,
fcr: 1.3,
eef: 150,
chicken_life: 9800,
chicken_life_percentage: 98,
iot_weight: 450,
mortality_total: 200,
harvest_total: 50,
harvest_weight_total: 80_000, // grams
feed_total: 90,
},
],
weights: [
{ age: 7, average_weight: 200, doc_weight: 40, uniformity: 85 },
{ age: 14, average_weight: 450, doc_weight: 40, uniformity: 80 },
{ age: 21, average_weight: 800, doc_weight: 40, uniformity: 75 },
],
docInCount: 10000,
});
it('filters weight series and uses exact-day KPI scalars', () => {
const scoped = scopeDashboardInsightMetrics(base, 7);
expect(scoped.hari_ke).toBe(7);
expect(scoped.fcr).toBe(1.1);
expect(scoped.bobot_avg_gram).toBe(200);
expect(scoped.doc_in_ekor).toBe(10000);
expect(scoped.kematian_kumulatif_ekor).toBe(100);
expect(scoped.pakan_kumulatif_karung).toBe(40);
expect(scoped.uniformity_persen).toBe(85);
expect(scoped.weightSeries.map((row) => row.hari)).toEqual([7]);
});
it('does not invent scalars for a day without KPI snapshot', () => {
const scoped = scopeDashboardInsightMetrics(base, 21);
expect(scoped.hari_ke).toBe(21);
expect(scoped.fcr).toBeNull();
expect(scoped.eef).toBeNull();
expect(scoped.bobot_avg_gram).toBe(800); // from weight series at day 21
expect(scoped.kematian_kumulatif_ekor).toBeNull();
expect(scoped.doc_in_ekor).toBe(10000); // cycle constant still shown
expect(scoped.weightSeries.map((row) => row.hari)).toEqual([7, 14, 21]);
});
});