70 lines
3.0 KiB
TypeScript
70 lines
3.0 KiB
TypeScript
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('<a href="https://example.org/nist">NIST-Leitfaden</a>');
|
|
expect(rows[1][1]).toBe('Klick');
|
|
expect(rows[1][1]).not.toContain('javascript');
|
|
});
|
|
});
|