import assert from 'node:assert/strict'; import test from 'node:test'; import ExcelJS from 'exceljs'; import { createFaultReportWorkbook, type FaultReport } from './report-export'; const now = new Date('2026-10-13T08:00:00Z'); async function saved(report: FaultReport) { const book = await createFaultReportWorkbook(report, undefined, now); const reopened = new ExcelJS.Workbook(); await reopened.xlsx.load(await book.xlsx.writeBuffer()); return reopened.worksheets[0]; } test('trend export preserves monthly range, real dates, cohort counts and weighted closure rate after serialization', async () => { const sheet = await saved({ kind: 'trend', data: { start: '2026-09-14', end: '2026-10-13', granularity: 'month', updatedAt: now.toISOString(), totals: { reported: 10, closed: 7, unclosed: 3 }, periods: [{ period: '2026-09', reported: 8, closed: 5, unclosed: 3 }, { period: '2026-10', reported: 2, closed: 2, unclosed: 0 }], } }); assert.match(String(sheet.getCell('A2').value), /2026-09-14 至 2026-10-13.*按月/); assert.equal((sheet.getCell('A10').value as Date).toISOString(), '2026-10-01T00:00:00.000Z'); assert.equal(sheet.getCell('A10').numFmt, 'yyyy-mm'); assert.equal(sheet.getCell('B11').value, 8); assert.equal(sheet.getCell('C11').value, 5); assert.equal(sheet.getCell('D11').value, 3); assert.deepEqual(sheet.getCell('B12').value, { formula: 'SUM(B10:B11)', result: 10 }); assert.deepEqual(sheet.getCell('E12').value, { formula: 'IFERROR(C12/B12,0)', result: .7 }); assert.equal(sheet.autoFilter, 'A9:E11'); assert.equal(sheet.views[0].state, 'frozen'); assert.equal(sheet.getCell('A9').fill.type, 'pattern'); }); test('weekly export keeps independent solved counts, descending dates and excludes receipt metrics', async () => { const sheet = await saved({ kind: 'weekly', data: { start: '2026-10-12', end: '2026-10-13', updatedAt: now.toISOString(), totals: { reported: 3, closed: 9, received: 99 }, days: [{ date: '2026-10-12', reported: 1, closed: 3, received: 90 }, { date: '2026-10-13', reported: 2, closed: 6, received: 9 }], } }); assert.deepEqual([1, 2, 3, 4].map(col => sheet.getCell(9, col).value), ['日期', '星期', '新增故障(单)', '解决故障(单)']); assert.equal((sheet.getCell('A10').value as Date).toISOString(), '2026-10-13T00:00:00.000Z'); assert.match(sheet.getCell('A10').numFmt, /今天/); assert.equal(sheet.getCell('B10').value, '周二'); assert.equal(sheet.getCell('D10').value, 6); assert.deepEqual(sheet.getCell('D12').value, { formula: 'SUM(D10:D11)', result: 9 }); assert.deepEqual(sheet.getCell('C6').value, { formula: 'SUM(D10:D11)', result: 9 }); assert.equal(sheet.columnCount, 4); }); test('zero-data trend exports valid guarded ratios and empty reports avoid inverted SUM ranges', async () => { for (const periods of [[], [{ period: '2026-10-13', reported: 0, closed: 0, unclosed: 0 }]]) { const sheet = await saved({ kind: 'trend', data: { start: '2026-10-13', end: '2026-10-13', granularity: 'day', updatedAt: now.toISOString(), totals: { reported: 0, closed: 0, unclosed: 0 }, periods, } }); const total = 10 + periods.length; assert.equal(sheet.getCell(`E${total}`).formula, `IFERROR(C${total}/B${total},0)`); assert.equal(sheet.getCell(`B${total}`).formula, periods.length ? 'SUM(B10:B10)' : '0'); assert.equal(sheet.getCell('A6').result, 0); } });