0a6e57ac02
2-Pass-Haiku-Klassifikation (konservativ + Re-Confirm jeder Nicht-unternehmen- Einstufung) der Review-Tier-Atome: wer muss die Pflicht erfuellen? - Migration 155: atom_classification.addressee (unternehmen/oeffentliche_stelle/ aufsichtsbefugnis/staat_eu/dritter/meta), additiv, kein CHECK. [migration-approved] - Service: addressee + applicable + is_gov pro Control; include_out_of_scope-Param (Default false -> out-of-scope advisory ausgeblendet, NIE geloescht); out_of_scope_count. Pure Helper addressee_applicable/addressee_is_gov (+ Tests). - Route: optionaler include_out_of_scope-Query (contract-safe, additiv). - Frontend: GOV-Chip (additiv) + "kein Kunden-Pruefaspekt"-Chip + 1-Klick-Toggle zum Einblenden der out-of-scope-Atome. Daten: 40.859 Adressat-Tags auf macmini geladen (81% applicable, 19% advisory, 3.146 GOV). Konservativ: NULL/Unklar = applicable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
121 lines
3.8 KiB
TypeScript
121 lines
3.8 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import {
|
|
licenseTierBadgeClass,
|
|
commercialBadgeClass,
|
|
groupUseCases,
|
|
provenanceLabel,
|
|
provenanceBadgeClass,
|
|
splitByTier,
|
|
severityBadgeClass,
|
|
addresseeLabel,
|
|
type UseCaseRow,
|
|
type ControlItem,
|
|
} from './_helpers'
|
|
|
|
const ctrl = (over: Partial<ControlItem>): ControlItem => ({
|
|
id: 'id',
|
|
title: 'T',
|
|
relevant: true,
|
|
tier: 'core',
|
|
source_type: 'derived',
|
|
applicable: true,
|
|
is_gov: false,
|
|
...over,
|
|
})
|
|
|
|
const uc = (over: Partial<UseCaseRow>): UseCaseRow => ({
|
|
key: 'x',
|
|
label: 'X',
|
|
group: 'security',
|
|
regulations: [],
|
|
verification_methods: [],
|
|
mapped_controls: 0,
|
|
atom_total: 0,
|
|
atom_relevant: 0,
|
|
...over,
|
|
})
|
|
|
|
describe('coverage helpers', () => {
|
|
it('license tier badge classes', () => {
|
|
expect(licenseTierBadgeClass(1)).toContain('green')
|
|
expect(licenseTierBadgeClass(2)).toContain('blue')
|
|
expect(licenseTierBadgeClass(3)).toContain('amber')
|
|
expect(licenseTierBadgeClass(null)).toContain('gray')
|
|
})
|
|
|
|
it('commercial-use badge classes', () => {
|
|
expect(commercialBadgeClass('allowed')).toContain('green')
|
|
expect(commercialBadgeClass('restricted')).toContain('amber')
|
|
expect(commercialBadgeClass('prohibited')).toContain('red')
|
|
expect(commercialBadgeClass(null)).toContain('gray')
|
|
})
|
|
|
|
it('groups use-cases in stable order and sorts by relevant desc', () => {
|
|
const groups = groupUseCases([
|
|
uc({ key: 'a', group: 'security', atom_relevant: 5 }),
|
|
uc({ key: 'b', group: 'security', atom_relevant: 15 }),
|
|
uc({ key: 'c', group: 'document', atom_relevant: 1 }),
|
|
])
|
|
expect(groups[0].group).toBe('document')
|
|
expect(groups[1].group).toBe('security')
|
|
expect(groups[1].rows[0].key).toBe('b')
|
|
expect(groups[1].rows[1].key).toBe('a')
|
|
})
|
|
|
|
it('appends unknown groups after the known order', () => {
|
|
const groups = groupUseCases([
|
|
uc({ key: 'z', group: 'mystery', atom_relevant: 9 }),
|
|
uc({ key: 'd', group: 'document', atom_relevant: 2 }),
|
|
])
|
|
expect(groups.map((g) => g.group)).toEqual(['document', 'mystery'])
|
|
})
|
|
|
|
it('provenance label: own library vs derived (with document + article)', () => {
|
|
expect(provenanceLabel(ctrl({ source_type: 'own_library' }))).toBe(
|
|
'Eigene Bibliothek',
|
|
)
|
|
expect(
|
|
provenanceLabel(
|
|
ctrl({ source_type: 'derived', source_regulation: 'DSGVO' }),
|
|
),
|
|
).toBe('Abgeleitet · DSGVO')
|
|
expect(
|
|
provenanceLabel(
|
|
ctrl({
|
|
source_type: 'derived',
|
|
source_regulation: 'DSGVO',
|
|
source_article: 'Art. 30',
|
|
}),
|
|
),
|
|
).toBe('Abgeleitet · DSGVO Art. 30')
|
|
// derived but no document known → graceful fallback
|
|
expect(provenanceLabel(ctrl({ source_type: 'derived' }))).toBe('Abgeleitet')
|
|
})
|
|
|
|
it('provenance + severity badge classes', () => {
|
|
expect(provenanceBadgeClass('own_library')).toContain('amber')
|
|
expect(provenanceBadgeClass('derived')).toContain('blue')
|
|
expect(severityBadgeClass('critical')).toContain('red')
|
|
expect(severityBadgeClass('high')).toContain('orange')
|
|
expect(severityBadgeClass(null)).toContain('gray')
|
|
})
|
|
|
|
it('addressee label maps keys to German labels', () => {
|
|
expect(addresseeLabel('oeffentliche_stelle')).toBe('Öffentliche Stelle')
|
|
expect(addresseeLabel('aufsichtsbefugnis')).toBe('Aufsichtsbehörde')
|
|
expect(addresseeLabel('staat_eu')).toBe('Mitgliedstaat/EU')
|
|
expect(addresseeLabel(null)).toBe('')
|
|
expect(addresseeLabel('unbekannt_neu')).toBe('unbekannt_neu')
|
|
})
|
|
|
|
it('splitByTier separates core (relevant) from review', () => {
|
|
const { core, review } = splitByTier([
|
|
ctrl({ id: 'a', relevant: true }),
|
|
ctrl({ id: 'b', relevant: false, tier: 'review' }),
|
|
ctrl({ id: 'c', relevant: true }),
|
|
])
|
|
expect(core.map((c) => c.id)).toEqual(['a', 'c'])
|
|
expect(review.map((c) => c.id)).toEqual(['b'])
|
|
})
|
|
})
|