All checks were successful
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 40s
CI/CD / test-python-backend-compliance (push) Successful in 41s
CI/CD / test-python-document-crawler (push) Successful in 26s
CI/CD / test-python-dsms-gateway (push) Successful in 23s
CI/CD / validate-canonical-controls (push) Successful in 18s
CI/CD / deploy-hetzner (push) Successful in 2m26s
Eigenstaendig formulierte Security Controls mit unabhaengiger Taxonomie und Open-Source-Verankerung (OWASP, NIST, ENISA). Keine BSI-Nomenklatur. - Migration 044: 5 DB-Tabellen (frameworks, controls, sources, licenses, mappings) - 10 Seed Controls mit 39 Open-Source-Referenzen - License Gate: Quellen-Berechtigungspruefung (analysis/excerpt/embeddings/product) - Too-Close-Detektor: 5 Metriken (exact-phrase, token-overlap, ngram, embedding, LCS) - REST API: 8 Endpoints unter /v1/canonical/ - Go Loader mit Multi-Index (ID, domain, severity, framework) - Frontend: Control Library Browser + Provenance Wiki - CI/CD: validate-controls.py Job (schema, no-leak, open-anchors) - 67 Tests (8 Go + 59 Python), alle PASS - MkDocs Dokumentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
155 lines
4.0 KiB
Go
155 lines
4.0 KiB
Go
package ucca
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestLoadCanonicalControls_ValidFile(t *testing.T) {
|
|
idx, err := LoadCanonicalControls()
|
|
if err != nil {
|
|
t.Fatalf("Expected no error, got %v", err)
|
|
}
|
|
if idx == nil {
|
|
t.Fatal("Expected non-nil index")
|
|
}
|
|
if len(idx.AllControls) != 10 {
|
|
t.Errorf("Expected 10 controls, got %d", len(idx.AllControls))
|
|
}
|
|
}
|
|
|
|
func TestCanonicalControlIndex_GetControl(t *testing.T) {
|
|
idx, err := LoadCanonicalControls()
|
|
if err != nil {
|
|
t.Fatalf("Failed to load controls: %v", err)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
id string
|
|
expected bool
|
|
}{
|
|
{"existing control AUTH-001", "AUTH-001", true},
|
|
{"existing control NET-001", "NET-001", true},
|
|
{"lowercase lookup", "auth-001", true},
|
|
{"non-existing control", "FAKE-999", false},
|
|
{"empty id", "", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctrl, ok := idx.GetControl(tt.id)
|
|
if ok != tt.expected {
|
|
t.Errorf("GetControl(%q): expected found=%v, got found=%v", tt.id, tt.expected, ok)
|
|
}
|
|
if ok && ctrl.ControlID == "" {
|
|
t.Error("Control found but has empty ControlID")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCanonicalControlIndex_GetControlsByDomain(t *testing.T) {
|
|
idx, err := LoadCanonicalControls()
|
|
if err != nil {
|
|
t.Fatalf("Failed to load controls: %v", err)
|
|
}
|
|
|
|
authControls := idx.GetControlsByDomain("AUTH")
|
|
if len(authControls) != 2 {
|
|
t.Errorf("Expected 2 AUTH controls, got %d", len(authControls))
|
|
}
|
|
|
|
netControls := idx.GetControlsByDomain("NET")
|
|
if len(netControls) != 2 {
|
|
t.Errorf("Expected 2 NET controls, got %d", len(netControls))
|
|
}
|
|
|
|
emptyControls := idx.GetControlsByDomain("NOPE")
|
|
if len(emptyControls) != 0 {
|
|
t.Errorf("Expected 0 controls for unknown domain, got %d", len(emptyControls))
|
|
}
|
|
}
|
|
|
|
func TestCanonicalControlIndex_GetControlsBySeverity(t *testing.T) {
|
|
idx, err := LoadCanonicalControls()
|
|
if err != nil {
|
|
t.Fatalf("Failed to load controls: %v", err)
|
|
}
|
|
|
|
highControls := idx.GetControlsBySeverity("high")
|
|
if len(highControls) < 5 {
|
|
t.Errorf("Expected at least 5 high-severity controls, got %d", len(highControls))
|
|
}
|
|
|
|
criticalControls := idx.GetControlsBySeverity("critical")
|
|
if len(criticalControls) != 1 {
|
|
t.Errorf("Expected 1 critical control, got %d", len(criticalControls))
|
|
}
|
|
}
|
|
|
|
func TestCanonicalControlIndex_GetControlsByFramework(t *testing.T) {
|
|
idx, err := LoadCanonicalControls()
|
|
if err != nil {
|
|
t.Fatalf("Failed to load controls: %v", err)
|
|
}
|
|
|
|
owaspControls := idx.GetControlsByFramework("OWASP ASVS")
|
|
if len(owaspControls) == 0 {
|
|
t.Error("Expected at least 1 control anchored to OWASP ASVS")
|
|
}
|
|
|
|
nistControls := idx.GetControlsByFramework("NIST SP 800-53")
|
|
if len(nistControls) == 0 {
|
|
t.Error("Expected at least 1 control anchored to NIST SP 800-53")
|
|
}
|
|
}
|
|
|
|
func TestCanonicalControl_OpenAnchors(t *testing.T) {
|
|
idx, err := LoadCanonicalControls()
|
|
if err != nil {
|
|
t.Fatalf("Failed to load controls: %v", err)
|
|
}
|
|
|
|
for _, ctrl := range idx.AllControls {
|
|
if len(ctrl.OpenAnchors) == 0 {
|
|
t.Errorf("Control %s has no open anchors — every control must have at least 1", ctrl.ControlID)
|
|
}
|
|
for i, anchor := range ctrl.OpenAnchors {
|
|
if anchor.Framework == "" {
|
|
t.Errorf("Control %s: open_anchor[%d] has empty framework", ctrl.ControlID, i)
|
|
}
|
|
if anchor.URL == "" {
|
|
t.Errorf("Control %s: open_anchor[%d] has empty URL", ctrl.ControlID, i)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCanonicalControlIndex_ValidateControlID(t *testing.T) {
|
|
idx, err := LoadCanonicalControls()
|
|
if err != nil {
|
|
t.Fatalf("Failed to load controls: %v", err)
|
|
}
|
|
|
|
if !idx.ValidateControlID("AUTH-001") {
|
|
t.Error("Expected AUTH-001 to be valid")
|
|
}
|
|
if idx.ValidateControlID("FAKE-999") {
|
|
t.Error("Expected FAKE-999 to be invalid")
|
|
}
|
|
}
|
|
|
|
func TestCanonicalControlIndex_FrameworkMetadata(t *testing.T) {
|
|
idx, err := LoadCanonicalControls()
|
|
if err != nil {
|
|
t.Fatalf("Failed to load controls: %v", err)
|
|
}
|
|
|
|
if idx.Framework.ID != "bp_security_v1" {
|
|
t.Errorf("Expected framework ID 'bp_security_v1', got '%s'", idx.Framework.ID)
|
|
}
|
|
if len(idx.Domains) != 8 {
|
|
t.Errorf("Expected 8 domains, got %d", len(idx.Domains))
|
|
}
|
|
}
|