95 lines
3.1 KiB
TypeScript
95 lines
3.1 KiB
TypeScript
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', '<unparsed-by-engine>', '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');
|
|
});
|
|
});
|