Assessor_2.0/tests/importers/importer.test.ts

62 lines
2.6 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { genericProfile } from '../../src/profiles/generic/generic-profile';
import { importFile } from '../../src/importers/importer';
import { ImportError } from '../../src/shared/errors';
import genericFixture from '../../fixtures/generic/findings.synthetic.csv?raw';
const options = { profiles: [genericProfile] };
describe('file importer', () => {
it('imports the persistent generic CSV fixture through the full pipeline', async () => {
const file = new File([genericFixture], 'findings.synthetic.csv', { type: 'text/csv', lastModified: 1234 });
const imported = await importFile(file, options);
expect(imported.profileId).toBe('generic');
expect(imported.scanTool).toBe('Tabular Data');
expect(imported.sheets[0].analysis.records).toHaveLength(2);
expect(imported.sheets[0].analysis.records[0].title).toBe('Synthetic weak policy');
});
it('falls back to Windows-1252 when UTF-8 decoding fails', async () => {
const prefix = new TextEncoder().encode('Title;Severity\nPr');
const suffix = new TextEncoder().encode('fung;High');
const bytes = new Uint8Array([...prefix, 0xfc, ...suffix]);
const file = new File([bytes], 'windows-1252.csv', { type: 'text/csv' });
const imported = await importFile(file, options);
expect(imported.sheets[0].rows[1][0]).toBe('Pr\u00fcfung');
});
it('rejects a file without any evaluable rows', async () => {
const file = new File(['\r\n\r\n'], 'empty.csv', { type: 'text/csv' });
await expect(importFile(file, options)).rejects.toThrow(ImportError);
await expect(importFile(file, options)).rejects.toThrow('Die Datei enth\u00e4lt keine auswertbaren Tabellen.');
});
it('imports a larger realistic CSV without losing rows', async () => {
const header = 'Title;Severity;Status;Asset';
const rows = Array.from({ length: 5000 }, (_, index) =>
`Synthetic finding ${index + 1};Medium;Open;asset-${index + 1}`
);
const file = new File([[header, ...rows].join('\n')], 'large.csv', { type: 'text/csv' });
const imported = await importFile(file, options);
expect(imported.sheets[0].analysis.records).toHaveLength(5000);
expect(imported.sheets[0].analysis.records[4999].title).toBe('Synthetic finding 5000');
});
it('rejects a truncated XLSX container', async () => {
const truncatedZip = new Uint8Array([0x50, 0x4b, 0x03, 0x04]);
const file = new File([truncatedZip], 'broken.xlsx', {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
await expect(importFile(file, options)).rejects.toThrow();
});
});