import { describe, expect, it } from 'vitest'; import * as XLSX from 'xlsx'; import { importExcel } from '../../src/importers/excel-importer'; import { binarySource } from './import-source-fixtures'; describe('Excel importer', () => { it('reads a workbook locally and preserves sheet visibility metadata', async () => { const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, XLSX.utils.aoa_to_sheet([ ['Name', 'Severity', 'Weight'], ['Synthetic finding', 'High', 10] ]), 'Indicator Results'); workbook.Workbook = { Sheets: [{ name: 'Indicator Results', Hidden: 1 }] }; const bytes = XLSX.write(workbook, { type: 'array', bookType: 'xlsx' }); const imported = await importExcel(binarySource('synthetic.xlsx', new Uint8Array(bytes))); expect(imported.format).toBe('Excel'); expect(imported.sheets).toHaveLength(1); expect(imported.sheets[0].hidden).toBe(1); expect(imported.sheets[0].analysis.records[0].title).toBe('Synthetic finding'); }); it('returns no sheets for an empty workbook', async () => { const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, XLSX.utils.aoa_to_sheet([]), 'Empty'); const bytes = XLSX.write(workbook, { type: 'array', bookType: 'xlsx' }); const imported = await importExcel(binarySource('empty.xlsx', new Uint8Array(bytes))); expect(imported.sheets).toEqual([]); expect(imported.rawText).toBe(''); }); it('does not expose workbook formulas as imported cell content', async () => { const workbook = XLSX.utils.book_new(); const sheet = XLSX.utils.aoa_to_sheet([ ['Name', 'Calculated score'], ['Synthetic finding', 2] ]); sheet.B2 = { t: 'n', f: '1+1', v: 2 }; XLSX.utils.book_append_sheet(workbook, sheet, 'Findings'); const bytes = XLSX.write(workbook, { type: 'array', bookType: 'xlsx' }); const imported = await importExcel(binarySource('formula.xlsx', new Uint8Array(bytes))); expect(imported.sheets[0].rows[1]).toEqual(['Synthetic finding', '2']); expect(imported.rawText).not.toContain('1+1'); }); // Belegstellen liegen in Excel nicht im Zelltext, sondern als eigenes Ziel // der Zelle. Ohne Auswertung gingen sie beim Import verloren. it('carries a cell hyperlink into the value and drops unsafe schemes', async () => { const sheet = XLSX.utils.aoa_to_sheet([ ['Referenz', 'Boese'], ['NIST-Leitfaden', 'Klick'] ]); sheet.A2!.l = { Target: 'https://example.org/nist' }; sheet.B2!.l = { Target: 'javascript:alert(1)' }; const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, sheet, 'Indicators results'); const bytes = XLSX.write(workbook, { type: 'array', bookType: 'xlsx' }); const rows = (await importExcel(binarySource('links.xlsx', new Uint8Array(bytes)))).sheets[0].rows; expect(rows[1][0]).toBe('NIST-Leitfaden'); expect(rows[1][1]).toBe('Klick'); expect(rows[1][1]).not.toContain('javascript'); }); });