- Add `AutoTableExportService` for dynamic Excel export button generation and visible row extraction. - Integrate auto-export initialization in `main.js` for legacy non-paginated tables. - Extend `PaginationDisplay.vue` with support for paginated Excel export. - Add export functionality to vehicle views and dependencies, including full-table export handling. - Add tests for `TableExcelExportService.js`, export workflows, and normalization logic. - Enhance localization with `download_excel` translation key.
67 lines
2.6 KiB
JavaScript
67 lines
2.6 KiB
JavaScript
import { existsSync, unlinkSync } from 'node:fs';
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
import {
|
|
collectExcelColumns,
|
|
createWorkbookFromRows,
|
|
ensureExcelFilename,
|
|
exportRowsToExcel,
|
|
normalizeExcelValue,
|
|
normalizeRowsForExcel,
|
|
sanitizeSheetName,
|
|
} from '@/services/TableExcelExportService.js';
|
|
|
|
describe('table excel export service normalization', () => {
|
|
it('normalizes primitive, null, date, object and array values deterministically', () => {
|
|
const date = new Date('2026-03-18T10:00:00.000Z');
|
|
|
|
expect(normalizeExcelValue(null)).toBe('');
|
|
expect(normalizeExcelValue(undefined)).toBe('');
|
|
expect(normalizeExcelValue(42)).toBe(42);
|
|
expect(normalizeExcelValue(true)).toBe(true);
|
|
expect(normalizeExcelValue(date)).toBe('2026-03-18T10:00:00.000Z');
|
|
expect(normalizeExcelValue({ a: 1 })).toBe('{"a":1}');
|
|
expect(normalizeExcelValue(['x', 2])).toBe('["x",2]');
|
|
});
|
|
|
|
it('keeps stable union-column order based on first-seen keys', () => {
|
|
const rows = [
|
|
{ customer: 'A', amount: 10 },
|
|
{ amount: 20, note: 'second' },
|
|
{ created_at: '2026-03-18', customer: 'B' },
|
|
];
|
|
|
|
expect(collectExcelColumns(rows)).toEqual(['customer', 'amount', 'note', 'created_at']);
|
|
expect(normalizeRowsForExcel(rows).columns).toEqual(['customer', 'amount', 'note', 'created_at']);
|
|
});
|
|
});
|
|
|
|
describe('table excel export service workbook generation', () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it('sanitizes sheet names and file names for xlsx output', () => {
|
|
expect(sanitizeSheetName('invoices:2026/03?*[]')).toBe('invoices_2026_03____');
|
|
expect(ensureExcelFilename('orders')).toBe('orders.xlsx');
|
|
expect(ensureExcelFilename('orders.xlsx')).toBe('orders.xlsx');
|
|
expect(ensureExcelFilename('bad<>name')).toBe('bad--name.xlsx');
|
|
});
|
|
|
|
it('creates workbook metadata with normalized rows and writes .xlsx files', () => {
|
|
const rows = [
|
|
{ id: 1, amount: 10 },
|
|
{ id: 2, amount: 20, tags: ['vip'] },
|
|
];
|
|
const workbookResult = createWorkbookFromRows(rows, { sheetName: 'Orders/Report' });
|
|
const filename = exportRowsToExcel(rows, { filename: 'orders-report', sheetName: 'Orders/Report' });
|
|
|
|
expect(workbookResult.sheetName).toBe('Orders_Report');
|
|
expect(workbookResult.columns).toEqual(['id', 'amount', 'tags']);
|
|
expect(workbookResult.rows[1].tags).toBe('["vip"]');
|
|
expect(workbookResult.workbook.SheetNames).toEqual(['Orders_Report']);
|
|
expect(filename).toBe('orders-report.xlsx');
|
|
expect(existsSync(filename)).toBe(true);
|
|
unlinkSync(filename);
|
|
});
|
|
});
|