All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 32s
CI / test-python-backend-compliance (push) Successful in 29s
CI / test-python-document-crawler (push) Successful in 20s
CI / test-python-dsms-gateway (push) Successful in 18s
- 9 Regulation-JSON-Dateien (DSGVO 80, AI Act 60, NIS2 40, BDSG 30, TTDSG 20, DSA 35, Data Act 25, EU-Maschinen 15, DORA 20) - Condition-Tree-Engine fuer automatische Pflichtenselektion (all_of/any_of, 80+ Field-Paths) - Generischer JSONRegulationModule-Loader mit YAML-Fallback - Bidirektionales TOM-Control-Mapping (291 Obligation→Control, 92 Control→Obligation) - Gap-Analyse-Engine (Compliance-%, Priority Actions, Domain Breakdown) - ScopeDecision→UnifiedFacts Bridge fuer Auto-Profiling - 4 neue API-Endpoints (assess-from-scope, tom-controls, gap-analysis, reverse-lookup) - Frontend: Auto-Profiling Button, Regulation-Filter Chips, TOM-Panel, Gap-Analyse-View - 18 Unit Tests (Condition Engine, v2 Loader, TOM Mapper) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
176 lines
5.0 KiB
Go
176 lines
5.0 KiB
Go
package ucca
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestTOMControlLoader(t *testing.T) {
|
|
index, err := LoadTOMControls()
|
|
if err != nil {
|
|
t.Skipf("TOM controls not found: %v", err)
|
|
}
|
|
|
|
if len(index.ByID) == 0 {
|
|
t.Error("expected controls indexed by ID")
|
|
}
|
|
if len(index.ByDomain) == 0 {
|
|
t.Error("expected controls indexed by domain")
|
|
}
|
|
t.Logf("Loaded %d TOM controls across %d domains", len(index.ByID), len(index.ByDomain))
|
|
|
|
// Check known control
|
|
ctrl, ok := index.GetControl("TOM.GOV.01")
|
|
if !ok || ctrl == nil {
|
|
t.Error("expected TOM.GOV.01 to exist")
|
|
} else if ctrl.Title == "" {
|
|
t.Error("expected TOM.GOV.01 to have a title")
|
|
}
|
|
|
|
// Check domain
|
|
govCtrls := index.GetControlsByDomain("GOV")
|
|
if len(govCtrls) == 0 {
|
|
t.Error("expected GOV domain to have controls")
|
|
}
|
|
|
|
// Validate known ID
|
|
if !index.ValidateControlID("TOM.GOV.01") {
|
|
t.Error("TOM.GOV.01 should be valid")
|
|
}
|
|
if index.ValidateControlID("TOM.FAKE.99") {
|
|
t.Error("TOM.FAKE.99 should be invalid")
|
|
}
|
|
}
|
|
|
|
func TestTOMObligationMapper_FromObligations(t *testing.T) {
|
|
index, err := LoadTOMControls()
|
|
if err != nil {
|
|
t.Skipf("TOM controls not found: %v", err)
|
|
}
|
|
|
|
// Create test obligations with tom_control_ids
|
|
obligations := []V2Obligation{
|
|
{
|
|
ID: "TEST-OBL-001",
|
|
TOMControlIDs: []string{"TOM.GOV.01", "TOM.GOV.02"},
|
|
Priority: "kritisch",
|
|
},
|
|
{
|
|
ID: "TEST-OBL-002",
|
|
TOMControlIDs: []string{"TOM.GOV.01", "TOM.CRYPTO.01"},
|
|
Priority: "hoch",
|
|
},
|
|
}
|
|
|
|
mapper := NewTOMObligationMapperFromObligations(index, obligations)
|
|
|
|
// Check obligation->control
|
|
controls := mapper.GetControlsForObligation("TEST-OBL-001")
|
|
if len(controls) != 2 {
|
|
t.Errorf("expected 2 controls for TEST-OBL-001, got %d", len(controls))
|
|
}
|
|
|
|
// Check control->obligation (reverse)
|
|
oblIDs := mapper.GetObligationsForControl("TOM.GOV.01")
|
|
if len(oblIDs) != 2 {
|
|
t.Errorf("expected 2 obligations for TOM.GOV.01, got %d", len(oblIDs))
|
|
}
|
|
|
|
// Check deduplicated requirements
|
|
frameworkObls := make([]Obligation, len(obligations))
|
|
for i, o := range obligations {
|
|
frameworkObls[i] = Obligation{
|
|
ID: o.ID,
|
|
Priority: ObligationPriority(o.Priority),
|
|
ExternalResources: o.TOMControlIDs,
|
|
}
|
|
}
|
|
reqs := mapper.DeriveControlsFromObligations(frameworkObls)
|
|
if len(reqs) == 0 {
|
|
t.Error("expected derived control requirements")
|
|
}
|
|
|
|
// GOV.01 should appear once but with 2 obligation references
|
|
for _, req := range reqs {
|
|
if req.Control != nil && req.Control.ID == "TOM.GOV.01" {
|
|
if req.RequiredByCount != 2 {
|
|
t.Errorf("expected TOM.GOV.01 required by 2, got %d", req.RequiredByCount)
|
|
}
|
|
if req.Priority != "kritisch" {
|
|
t.Errorf("expected highest priority 'kritisch', got '%s'", req.Priority)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
t.Error("TOM.GOV.01 not found in derived requirements")
|
|
}
|
|
|
|
func TestTOMGapAnalysis(t *testing.T) {
|
|
index, err := LoadTOMControls()
|
|
if err != nil {
|
|
t.Skipf("TOM controls not found: %v", err)
|
|
}
|
|
|
|
obligations := []V2Obligation{
|
|
{ID: "T-001", TOMControlIDs: []string{"TOM.GOV.01"}, Priority: "kritisch"},
|
|
{ID: "T-002", TOMControlIDs: []string{"TOM.GOV.01", "TOM.CRYPTO.01"}, Priority: "hoch"},
|
|
}
|
|
mapper := NewTOMObligationMapperFromObligations(index, obligations)
|
|
analyzer := NewTOMGapAnalyzer(mapper, index)
|
|
|
|
frameworkObls := []Obligation{
|
|
{ID: "T-001", Priority: "kritisch", ExternalResources: []string{"TOM.GOV.01"}},
|
|
{ID: "T-002", Priority: "hoch", ExternalResources: []string{"TOM.GOV.01", "TOM.CRYPTO.01"}},
|
|
}
|
|
|
|
result := analyzer.Analyze(&GapAnalysisRequest{
|
|
Obligations: frameworkObls,
|
|
ControlStatusMap: map[string]ControlStatus{
|
|
"TOM.GOV.01": ControlImplemented,
|
|
"TOM.CRYPTO.01": ControlNotImplemented,
|
|
},
|
|
})
|
|
|
|
if result.TotalControls != 2 {
|
|
t.Errorf("expected 2 total controls, got %d", result.TotalControls)
|
|
}
|
|
if result.ImplementedControls != 1 {
|
|
t.Errorf("expected 1 implemented, got %d", result.ImplementedControls)
|
|
}
|
|
if result.MissingControls != 1 {
|
|
t.Errorf("expected 1 missing, got %d", result.MissingControls)
|
|
}
|
|
if result.CompliancePercent != 50 {
|
|
t.Errorf("expected 50%% compliance, got %.1f%%", result.CompliancePercent)
|
|
}
|
|
if len(result.Gaps) != 1 {
|
|
t.Errorf("expected 1 gap, got %d", len(result.Gaps))
|
|
}
|
|
}
|
|
|
|
func TestTOMGapAnalysis_AllImplemented(t *testing.T) {
|
|
index, err := LoadTOMControls()
|
|
if err != nil {
|
|
t.Skipf("TOM controls not found: %v", err)
|
|
}
|
|
|
|
obligations := []V2Obligation{
|
|
{ID: "T-001", TOMControlIDs: []string{"TOM.GOV.01"}, Priority: "hoch"},
|
|
}
|
|
mapper := NewTOMObligationMapperFromObligations(index, obligations)
|
|
analyzer := NewTOMGapAnalyzer(mapper, index)
|
|
|
|
result := analyzer.Analyze(&GapAnalysisRequest{
|
|
Obligations: []Obligation{{ID: "T-001", Priority: "hoch", ExternalResources: []string{"TOM.GOV.01"}}},
|
|
ControlStatusMap: map[string]ControlStatus{
|
|
"TOM.GOV.01": ControlImplemented,
|
|
},
|
|
})
|
|
|
|
if result.CompliancePercent != 100 {
|
|
t.Errorf("expected 100%% compliance, got %.1f%%", result.CompliancePercent)
|
|
}
|
|
if len(result.Gaps) != 0 {
|
|
t.Errorf("expected 0 gaps, got %d", len(result.Gaps))
|
|
}
|
|
}
|