61 lines
3.4 KiB
TypeScript
61 lines
3.4 KiB
TypeScript
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);
|
|
}
|
|
});
|