This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/website/__tests__/compliance/DependencyMap.test.tsx
BreakPilot Dev 19855efacc
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
feat: BreakPilot PWA - Full codebase (clean push without large binaries)
All services: admin-v2, studio-v2, website, ai-compliance-sdk,
consent-service, klausur-service, voice-service, and infrastructure.
Large PDFs and compiled binaries excluded via .gitignore.
2026-02-11 13:25:58 +01:00

312 lines
8.4 KiB
TypeScript

/**
* DependencyMap Component Tests
*
* Tests fuer die Control-Requirement Mapping Visualisierung
*/
import { describe, it, expect, vi } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import DependencyMap from '../../components/compliance/charts/DependencyMap'
// Mock-Daten
const mockRequirements = [
{
id: 'req-1',
article: 'Art. 32',
title: 'Sicherheit der Verarbeitung',
regulation_code: 'GDPR',
},
{
id: 'req-2',
article: 'Art. 9',
title: 'Risikomanagement',
regulation_code: 'AIACT',
},
{
id: 'req-3',
article: 'Art. 25',
title: 'Datenschutz durch Technikgestaltung',
regulation_code: 'GDPR',
},
]
const mockControls = [
{
id: 'ctrl-1',
control_id: 'PRIV-001',
title: 'Verarbeitungsverzeichnis',
domain: 'priv',
status: 'pass',
},
{
id: 'ctrl-2',
control_id: 'CRYPTO-001',
title: 'Verschluesselung',
domain: 'crypto',
status: 'pass',
},
{
id: 'ctrl-3',
control_id: 'AI-001',
title: 'KI-Risikobewertung',
domain: 'ai',
status: 'partial',
},
]
const mockMappings = [
{ requirement_id: 'req-1', control_id: 'PRIV-001', coverage_level: 'full' as const },
{ requirement_id: 'req-1', control_id: 'CRYPTO-001', coverage_level: 'partial' as const },
{ requirement_id: 'req-2', control_id: 'AI-001', coverage_level: 'full' as const },
{ requirement_id: 'req-3', control_id: 'PRIV-001', coverage_level: 'planned' as const },
]
describe('DependencyMap', () => {
it('should render the component with data', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
// Statistik-Header sollte sichtbar sein
expect(screen.getByText('Abdeckung')).toBeInTheDocument()
expect(screen.getByText('Vollstaendig')).toBeInTheDocument()
expect(screen.getByText('Teilweise')).toBeInTheDocument()
expect(screen.getByText('Geplant')).toBeInTheDocument()
})
it('should render empty state when no data', () => {
render(
<DependencyMap
requirements={[]}
controls={[]}
mappings={[]}
/>
)
expect(screen.getByText(/Keine Mappings vorhanden/i)).toBeInTheDocument()
})
it('should show correct coverage statistics', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
// 2 full, 1 partial, 1 planned
expect(screen.getByText('2')).toBeInTheDocument() // full mappings
expect(screen.getByText('1')).toBeInTheDocument() // partial/planned mappings
})
it('should display control IDs in matrix header', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
expect(screen.getByText('PRIV-001')).toBeInTheDocument()
expect(screen.getByText('CRYPTO-001')).toBeInTheDocument()
expect(screen.getByText('AI-001')).toBeInTheDocument()
})
it('should display requirement articles', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
expect(screen.getByText(/GDPR Art. 32/i)).toBeInTheDocument()
expect(screen.getByText(/AIACT Art. 9/i)).toBeInTheDocument()
})
it('should support German language', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
lang="de"
/>
)
expect(screen.getByText('Alle Verordnungen')).toBeInTheDocument()
expect(screen.getByText('Alle Domains')).toBeInTheDocument()
})
it('should support English language', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
lang="en"
/>
)
expect(screen.getByText('All Regulations')).toBeInTheDocument()
expect(screen.getByText('All Domains')).toBeInTheDocument()
expect(screen.getByText('Coverage')).toBeInTheDocument()
})
it('should call onControlClick when control is clicked', () => {
const onControlClick = vi.fn()
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
onControlClick={onControlClick}
/>
)
const controlHeader = screen.getByText('PRIV-001')
fireEvent.click(controlHeader)
expect(onControlClick).toHaveBeenCalledWith(mockControls[0])
})
it('should call onRequirementClick when requirement is clicked', () => {
const onRequirementClick = vi.fn()
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
onRequirementClick={onRequirementClick}
/>
)
// Finde den Requirement-Text
const reqElement = screen.getByText(/Sicherheit der Verarbeitung/i)
fireEvent.click(reqElement.closest('div[class*="cursor-pointer"]')!)
expect(onRequirementClick).toHaveBeenCalledWith(mockRequirements[0])
})
it('should filter by regulation', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
const regSelect = screen.getByDisplayValue('Alle Verordnungen')
fireEvent.change(regSelect, { target: { value: 'AIACT' } })
// Nur AIACT Requirements sollten sichtbar sein
expect(screen.queryByText(/GDPR Art. 32/i)).not.toBeInTheDocument()
expect(screen.getByText(/AIACT Art. 9/i)).toBeInTheDocument()
})
it('should filter by domain', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
const domainSelect = screen.getByDisplayValue('Alle Domains')
fireEvent.change(domainSelect, { target: { value: 'priv' } })
// Nur Privacy Controls sollten sichtbar sein
expect(screen.getByText('PRIV-001')).toBeInTheDocument()
expect(screen.queryByText('CRYPTO-001')).not.toBeInTheDocument()
})
it('should switch between matrix and connection view', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
// Standard ist Matrix-Ansicht
expect(screen.getByText('Matrix')).toBeInTheDocument()
// Wechsle zu Verbindungs-Ansicht
fireEvent.click(screen.getByText('Verbindungen'))
// Connection-View Text sollte erscheinen
expect(screen.getByText(/Waehlen Sie ein Control/i)).toBeInTheDocument()
})
it('should highlight connected items when control is selected', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
// Klicke auf einen Control
fireEvent.click(screen.getByText('PRIV-001'))
// Der Control sollte highlighted sein (bg-primary-100 Klasse)
const controlElement = screen.getByText('PRIV-001').closest('div')
expect(controlElement?.className).toContain('bg-primary-100')
})
it('should show legend with coverage levels', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
expect(screen.getByText('Vollstaendig abgedeckt')).toBeInTheDocument()
expect(screen.getByText('Teilweise abgedeckt')).toBeInTheDocument()
expect(screen.getByText('Geplant')).toBeInTheDocument()
})
it('should calculate coverage percentage correctly', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
// 3 von 3 Requirements haben mindestens ein Mapping = 100%
expect(screen.getByText('100.0%')).toBeInTheDocument()
})
it('should show control counts in connection view', () => {
render(
<DependencyMap
requirements={mockRequirements}
controls={mockControls}
mappings={mockMappings}
/>
)
// Wechsle zu Verbindungs-Ansicht
fireEvent.click(screen.getByText('Verbindungen'))
// PRIV-001 hat 2 Verbindungen
const privControl = screen.getAllByText('PRIV-001')[0].closest('button')
expect(privControl?.textContent).toContain('2')
})
})