Files
dashboard/utils/__tests__/reportExcel.test.ts
T

163 lines
4.8 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import type { DashboardReportPayload } from '../../types/dashboardReport.ts';
import { buildReportWorkbook } from '../reportExcel.ts';
const snapshot: DashboardReportPayload = {
cycleId: 'CYCLE-JBW',
kandangId: 1,
kandangName: 'Kandang Atas',
area: 'Sukawarna',
upToDay: 2,
generatedAt: '2026-05-24T10:00:00.000Z',
counting: [
{
date: '2026-05-22',
day: 0,
countBefore: 100,
mortality: 0,
harvest: 0,
harvestWeight: null,
countAfter: 100,
iotCount: 95,
accuracy: 95,
},
],
weight: [
{
date: '2026-05-23',
day: 1,
avgManual: 1000,
avgIot: 900,
uniformity: 80,
difference: 100,
accuracy: 90,
},
],
feedIn: [{ date: '2026-05-22', manualIn: 10, iotIn: 10, accuracy: 100 }],
feedUse: [{ date: '2026-05-22', day: 0, manualUse: 4, iotUse: 4, accuracy: 100 }],
};
const emptySnapshot: DashboardReportPayload = {
...snapshot,
counting: [],
weight: [],
feedIn: [],
feedUse: [],
};
describe('buildReportWorkbook', () => {
it('creates four sheets with the specified names', async () => {
const workbook = await buildReportWorkbook(snapshot);
expect(workbook.worksheets.map((sheet) => sheet.name)).toEqual([
'Counting',
'Weight',
'Feed In',
'Feed Use',
]);
});
it('includes chicken age and mortality on Counting, and no chicken-age on Feed In', async () => {
const workbook = await buildReportWorkbook(snapshot);
const countingHeaders = workbook.getWorksheet('Counting')?.getRow(2).values ?? [];
const feedInHeaders = workbook.getWorksheet('Feed In')?.getRow(2).values ?? [];
expect(countingHeaders).toEqual(
expect.arrayContaining(['Umur (hari)', 'Mortalitas'])
);
expect(feedInHeaders).toEqual(expect.arrayContaining(['Tanggal', 'Manual masuk', 'IoT masuk']));
expect(feedInHeaders).not.toEqual(expect.arrayContaining(['Umur (hari)']));
});
it('writes header metadata matching upToDay and generatedAt', async () => {
const workbook = await buildReportWorkbook(snapshot);
const headerValues = workbook.getWorksheet('Counting')?.getRow(1).values ?? [];
const header = (Array.isArray(headerValues) ? headerValues : [])
.map((value) => (value == null ? '' : String(value)))
.filter(Boolean)
.join(' ');
expect(header).toContain('Kandang Atas');
expect(header).toContain('CYCLE-JBW');
expect(header).toContain('Hari ke-0 s/d ke-2');
expect(header).toContain('2026-05-24T10:00:00.000Z');
});
it('still produces a workbook when snapshot tables are empty (AE5)', async () => {
const workbook = await buildReportWorkbook(emptySnapshot);
expect(workbook.worksheets).toHaveLength(4);
expect(workbook.getWorksheet('Counting')?.rowCount).toBeGreaterThanOrEqual(2);
});
it('appends a Total row on each sheet', async () => {
const workbook = await buildReportWorkbook(snapshot);
const lastValues = (sheetName: string) => {
const sheet = workbook.getWorksheet(sheetName);
const values = sheet?.getRow(sheet.rowCount).values;
return (Array.isArray(values) ? values : []).filter((value) => value != null);
};
expect(lastValues('Counting')[0]).toBe('Total');
expect(lastValues('Weight')[0]).toBe('2026-05-23');
expect(lastValues('Feed In')).toEqual(['Total', 10, 10, '100.0%']);
expect(lastValues('Feed Use')).toEqual(['Total', '—', 4, 4, '100.0%']);
});
it('adds FCR and EEF sheets for an end-cycle snapshot', async () => {
const workbook = await buildReportWorkbook({
...snapshot,
reportType: 'end_cycle',
fcr: [
{
day: 0,
iotFcr: 1.234,
feedTotal: 10,
iotWeight: 45.5,
chickenLife: 10000,
harvestWeightTotal: 12000,
},
],
eef: [
{
day: 0,
iotEef: 310.456,
chickenLifePercentage: 99.5,
iotAverageHarvestBw: 45.5,
iotAverageDayWeight: 0.2,
iotFcr: 1.234,
},
],
});
expect(workbook.worksheets.map((sheet) => sheet.name)).toEqual([
'Counting',
'Weight',
'Feed In',
'Feed Use',
'FCR',
'EEF',
]);
const headerCells = (sheetName: string) => {
const values = workbook.getWorksheet(sheetName)?.getRow(2).values ?? [];
return (Array.isArray(values) ? values : []).filter((value) => value != null);
};
expect(headerCells('FCR')).toEqual([
'Umur',
'Total Pakan',
'Bobot IoT',
'Ayam Hidup',
'Total Bobot Panen',
'FCR',
]);
expect(headerCells('EEF')).toEqual([
'Umur',
'Persentase Ayam Hidup',
'BW Rata-rata Panen',
'Umur Rata-rata Panen',
'FCR',
'EEF',
]);
});
});