import { describe, expect, it } from 'vitest'; import type { ImportSource } from '../../src/domain/import-source'; import { importSource } from '../../src/importers/engine'; import type { ImportRuntimeAdapters } from '../../src/importers/runtime-adapters'; import { genericProfile } from '../../src/profiles/generic/generic-profile'; function asciiSource(name: string, text: string, mediaType = 'text/plain'): ImportSource { return { metadata: { name, sizeBytes: text.length, lastModified: 1234, mediaType }, bytes: Uint8Array.from([...text].map(character => character.charCodeAt(0))) }; } const adapters: ImportRuntimeAdapters = { textDecoder: { decode(bytes) { return { text: String.fromCharCode(...bytes), encoding: 'test-ascii' }; } }, markup: { decodeHtml() { return { tables: [{ name: 'Injected HTML table', rows: [ ['Name', 'Severity'], ['Adapter finding', 'High'] ], attributes: { kind: 'test-adapter' }, cellSelectors: [ ['table tr:nth-child(1) th:nth-child(1)', 'table tr:nth-child(1) th:nth-child(2)'], ['table tr:nth-child(2) td:nth-child(1)', 'table tr:nth-child(2) td:nth-child(2)'] ] }], fallbackRows: [], removedContentCount: 0 }; }, decodeXml() { return { valid: true, rootName: 'report', rows: [{ path: 'report/title[1]', attributes: '', text: 'Adapter finding' }] }; } } }; const options = { profiles: [genericProfile] }; describe('platform-neutral import engine', () => { it('imports a plain byte source without a browser File object', async () => { const imported = await importSource( asciiSource('findings.csv', 'Name;Severity\nByte source finding;Medium', 'text/csv'), options, adapters ); expect(imported.fileName).toBe('findings.csv'); expect(imported.sheets[0].analysis.records[0].title).toBe('Byte source finding'); expect(imported.intermediate?.file.mediaType).toBe('text/csv'); expect(imported.intermediate?.file.encoding).toBe('test-ascii'); expect(imported.extraction).toMatchObject({ extractor: { id: 'generic-table-source-extractor' }, processing: { stage: 'extraction', status: 'complete' } }); expect(imported.mapping).toMatchObject({ extractor: { id: 'generic-table-source-extractor' }, mappingProfile: { kind: 'mapping-profile', id: 'generic', version: '1.0.0' }, processing: { stage: 'mapping', status: 'complete' } }); expect(imported.intermediate?.processing.at(-1)?.stage).toBe('mapping'); }); it('uses an injected markup adapter instead of accessing a DOM directly', async () => { const imported = await importSource( asciiSource('report.html', '', 'text/html'), options, adapters ); expect(imported.sheets[0].name).toBe('Injected HTML table'); expect(imported.sheets[0].analysis.records[0].title).toBe('Adapter finding'); expect(imported.intermediate?.tables[0].attributes.kind).toBe('test-adapter'); }); });