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>
138 lines
3.6 KiB
Go
138 lines
3.6 KiB
Go
package ucca
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestLoadV2Manifest(t *testing.T) {
|
|
manifest, err := LoadV2Manifest()
|
|
if err != nil {
|
|
t.Skipf("v2 manifest not found (expected in CI): %v", err)
|
|
}
|
|
|
|
if manifest.SchemaVersion != "2.0" {
|
|
t.Errorf("expected schema_version 2.0, got %s", manifest.SchemaVersion)
|
|
}
|
|
if len(manifest.Regulations) == 0 {
|
|
t.Error("expected at least one regulation in manifest")
|
|
}
|
|
|
|
// Check known regulations
|
|
regIDs := make(map[string]bool)
|
|
for _, r := range manifest.Regulations {
|
|
regIDs[r.ID] = true
|
|
}
|
|
for _, expected := range []string{"dsgvo", "ai_act", "nis2"} {
|
|
if !regIDs[expected] {
|
|
t.Errorf("expected regulation %s in manifest", expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLoadV2RegulationFile_DSGVO(t *testing.T) {
|
|
basePath := getV2BasePath()
|
|
if _, err := os.Stat(basePath + "/dsgvo_v2.json"); os.IsNotExist(err) {
|
|
t.Skip("dsgvo_v2.json not found")
|
|
}
|
|
|
|
data, err := LoadV2RegulationFile("dsgvo_v2.json")
|
|
if err != nil {
|
|
t.Fatalf("failed to load dsgvo_v2.json: %v", err)
|
|
}
|
|
|
|
if data.Regulation != "dsgvo" {
|
|
t.Errorf("expected regulation dsgvo, got %s", data.Regulation)
|
|
}
|
|
if len(data.Obligations) < 11 {
|
|
t.Errorf("expected at least 11 DSGVO obligations (existing), got %d", len(data.Obligations))
|
|
}
|
|
|
|
// Verify first obligation preserves existing ID
|
|
if data.Obligations[0].ID != "DSGVO-OBL-001" {
|
|
t.Errorf("expected first obligation DSGVO-OBL-001, got %s", data.Obligations[0].ID)
|
|
}
|
|
|
|
// Verify v2 fields are present
|
|
obl := data.Obligations[0]
|
|
if obl.ValidFrom == "" {
|
|
t.Error("expected valid_from on first obligation")
|
|
}
|
|
if len(obl.TOMControlIDs) == 0 {
|
|
t.Error("expected tom_control_ids on first obligation")
|
|
}
|
|
}
|
|
|
|
func TestLoadV2RegulationFile_AIAct(t *testing.T) {
|
|
basePath := getV2BasePath()
|
|
if _, err := os.Stat(basePath + "/ai_act_v2.json"); os.IsNotExist(err) {
|
|
t.Skip("ai_act_v2.json not found")
|
|
}
|
|
|
|
data, err := LoadV2RegulationFile("ai_act_v2.json")
|
|
if err != nil {
|
|
t.Fatalf("failed to load: %v", err)
|
|
}
|
|
|
|
if len(data.Obligations) < 15 {
|
|
t.Errorf("expected at least 15 AI Act obligations (existing), got %d", len(data.Obligations))
|
|
}
|
|
}
|
|
|
|
func TestLoadV2RegulationFile_NIS2(t *testing.T) {
|
|
basePath := getV2BasePath()
|
|
if _, err := os.Stat(basePath + "/nis2_v2.json"); os.IsNotExist(err) {
|
|
t.Skip("nis2_v2.json not found")
|
|
}
|
|
|
|
data, err := LoadV2RegulationFile("nis2_v2.json")
|
|
if err != nil {
|
|
t.Fatalf("failed to load: %v", err)
|
|
}
|
|
|
|
if len(data.Obligations) < 14 {
|
|
t.Errorf("expected at least 14 NIS2 obligations (existing), got %d", len(data.Obligations))
|
|
}
|
|
}
|
|
|
|
func TestLoadAllV2Regulations(t *testing.T) {
|
|
regs, err := LoadAllV2Regulations()
|
|
if err != nil {
|
|
t.Skipf("v2 regulations not found: %v", err)
|
|
}
|
|
|
|
if len(regs) < 3 {
|
|
t.Errorf("expected at least 3 loaded regulations, got %d", len(regs))
|
|
}
|
|
|
|
totalObl := 0
|
|
for _, r := range regs {
|
|
totalObl += len(r.Obligations)
|
|
}
|
|
if totalObl < 40 {
|
|
t.Errorf("expected at least 40 total obligations, got %d", totalObl)
|
|
}
|
|
t.Logf("Loaded %d regulations with %d total obligations", len(regs), totalObl)
|
|
}
|
|
|
|
func TestLoadV2TOMMapping(t *testing.T) {
|
|
basePath := getV2BasePath()
|
|
if _, err := os.Stat(basePath + "/_tom_mapping.json"); os.IsNotExist(err) {
|
|
t.Skip("_tom_mapping.json not found")
|
|
}
|
|
|
|
mapping, err := LoadV2TOMMapping()
|
|
if err != nil {
|
|
t.Fatalf("failed to load TOM mapping: %v", err)
|
|
}
|
|
|
|
if len(mapping.ObligationToControl) == 0 {
|
|
t.Error("expected obligation_to_control mappings")
|
|
}
|
|
if len(mapping.ControlToObligation) == 0 {
|
|
t.Error("expected control_to_obligation mappings")
|
|
}
|
|
t.Logf("TOM mapping: %d obligation->control, %d control->obligation",
|
|
len(mapping.ObligationToControl), len(mapping.ControlToObligation))
|
|
}
|