Assessor_2.0/tests/features/severity-facet.test.ts

73 lines
2.9 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { makeSheet } from '../../src/importers/sheet-factory';
import { deriveDynamicFacets, matchesDynamicFacets } from '../../src/features/search-filter/dynamic-facets';
import { genericProfile } from '../../src/profiles/generic/generic-profile';
/**
* Synthetisch, aber in der Schreibweise absichtlich so uneinheitlich wie die
* echten Quellen: dieselbe Stufe erscheint als "info" und als "Informational",
* und die Gross-/Kleinschreibung wechselt je Werkzeug.
*/
const rows = [
['Title', 'Severity', 'Result'],
['Fund 1', 'Critical', 'Failed'],
['Fund 2', 'High', 'Failed'],
['Fund 3', 'high', 'Failed'],
['Fund 4', 'medium', 'Failed'],
['Fund 5', 'medium', 'Failed'],
['Fund 6', 'medium', 'Failed'],
['Fund 7', 'low', 'Failed'],
['Fund 8', 'info', 'Failed'],
['Fund 9', 'Informational', 'Failed'],
['Fund 10', 'Informational', 'Failed']
];
/**
* Ohne Dataset bleibt die Feldrolle unbestimmt - genau der Fall, der in der
* Projektaggregation eines Mandanten auftritt. Die Facette muss trotzdem als
* Severity-Skala erkannt werden, sonst greift die Zusammenfassung nie.
*/
function severityFacet() {
const sheet = makeSheet('blatt', rows, '', 'datei.csv');
const facets = deriveDynamicFacets(sheet, null, genericProfile, {});
const facet = facets.find(item => item.severityScale);
if (!facet) throw new Error('Schweregrad-Facette fehlt');
expect(facet.role).toBeUndefined();
return { sheet, facet };
}
describe('Schweregrad-Facette', () => {
it('ordnet nach fachlicher Rangfolge, nicht nach Haeufigkeit oder Alphabet', () => {
const { facet } = severityFacet();
expect(facet.values.map(value => value.value)).toEqual(['critical', 'high', 'medium', 'low', 'info']);
});
/**
* Regression: "info" und "Informational" standen als zwei Eintraege
* nebeneinander, obwohl sie dieselbe kanonische Stufe meinen.
*/
it('fasst abweichende Schreibweisen derselben Stufe zusammen', () => {
const { facet } = severityFacet();
const info = facet.values.filter(value => value.value === 'info');
expect(info).toHaveLength(1);
expect(info[0].count).toBe(3);
expect(facet.values.find(value => value.value === 'high')?.count).toBe(2);
});
it('zeigt je Stufe genau einen Anzeigenamen', () => {
const { facet } = severityFacet();
expect(facet.values.map(value => value.label)).toEqual(['Critical', 'High', 'Medium', 'Low', 'Info']);
});
it('filtert ueber die kanonische Stufe und trifft damit jede Schreibweise', () => {
const { sheet, facet } = severityFacet();
const selected = sheet.analysis.records.filter(record =>
matchesDynamicFacets(record, [facet], { [facet.id]: { values: ['info'] } }, {}));
expect(selected).toHaveLength(3);
const highs = sheet.analysis.records.filter(record =>
matchesDynamicFacets(record, [facet], { [facet.id]: { values: ['high'] } }, {}));
expect(highs).toHaveLength(2);
});
});