Files
breakpilot-compliance/ai-compliance-sdk/internal/training/escalation_test.go
Benjamin Admin 4f6bc8f6f6
Some checks failed
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) Failing after 37s
CI/CD / test-python-backend-compliance (push) Successful in 39s
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 12s
CI/CD / Deploy (push) Has been skipped
feat(training+controls): interactive video pipeline, training blocks, control generator, CE libraries
Interactive Training Videos (CP-TRAIN):
- DB migration 022: training_checkpoints + checkpoint_progress tables
- NarratorScript generation via Anthropic (AI Teacher persona, German)
- TTS batch synthesis + interactive video pipeline (slides + checkpoint slides + FFmpeg)
- 4 new API endpoints: generate-interactive, interactive-manifest, checkpoint submit, checkpoint progress
- InteractiveVideoPlayer component (HTML5 Video, quiz overlay, seek protection, progress tracking)
- Learner portal integration with automatic completion on all checkpoints passed
- 30 new tests (handler validation + grading logic + manifest/progress + seek protection)

Training Blocks:
- Block generator, block store, block config CRUD + preview/generate endpoints
- Migration 021: training_blocks schema

Control Generator + Canonical Library:
- Control generator routes + service enhancements
- Canonical control library helpers, sidebar entry
- Citation backfill service + tests
- CE libraries data (hazard, protection, evidence, lifecycle, components)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 21:41:48 +01:00

160 lines
4.5 KiB
Go

package training
import (
"testing"
)
// =============================================================================
// Escalation Threshold Tests
// =============================================================================
func TestEscalationThresholds_Values(t *testing.T) {
tests := []struct {
name string
threshold int
expected int
}{
{"L1 is 7 days", EscalationThresholdL1, 7},
{"L2 is 14 days", EscalationThresholdL2, 14},
{"L3 is 30 days", EscalationThresholdL3, 30},
{"L4 is 45 days", EscalationThresholdL4, 45},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.threshold != tt.expected {
t.Errorf("Expected %d, got %d", tt.expected, tt.threshold)
}
})
}
}
func TestEscalationThresholds_Ascending(t *testing.T) {
if EscalationThresholdL1 >= EscalationThresholdL2 {
t.Errorf("L1 (%d) should be < L2 (%d)", EscalationThresholdL1, EscalationThresholdL2)
}
if EscalationThresholdL2 >= EscalationThresholdL3 {
t.Errorf("L2 (%d) should be < L3 (%d)", EscalationThresholdL2, EscalationThresholdL3)
}
if EscalationThresholdL3 >= EscalationThresholdL4 {
t.Errorf("L3 (%d) should be < L4 (%d)", EscalationThresholdL3, EscalationThresholdL4)
}
}
// =============================================================================
// Escalation Label Tests
// =============================================================================
func TestEscalationLabels_AllLevelsPresent(t *testing.T) {
expectedLevels := []int{0, 1, 2, 3, 4}
for _, level := range expectedLevels {
label, ok := EscalationLabels[level]
if !ok {
t.Errorf("Missing label for escalation level %d", level)
}
if label == "" {
t.Errorf("Empty label for escalation level %d", level)
}
}
}
func TestEscalationLabels_Level0_NoEscalation(t *testing.T) {
label := EscalationLabels[0]
if label != "Keine Eskalation" {
t.Errorf("Expected 'Keine Eskalation', got '%s'", label)
}
}
func TestEscalationLabels_Level4_ComplianceOfficer(t *testing.T) {
label := EscalationLabels[4]
if label != "Benachrichtigung Compliance Officer" {
t.Errorf("Expected 'Benachrichtigung Compliance Officer', got '%s'", label)
}
}
func TestEscalationLabels_NoExtraLevels(t *testing.T) {
if len(EscalationLabels) != 5 {
t.Errorf("Expected exactly 5 escalation levels (0-4), got %d", len(EscalationLabels))
}
}
func TestEscalationLabels_LevelContent(t *testing.T) {
tests := []struct {
level int
contains string
}{
{1, "Mitarbeiter"},
{2, "Teamleitung"},
{3, "Management"},
{4, "Compliance Officer"},
}
for _, tt := range tests {
t.Run(EscalationLabels[tt.level], func(t *testing.T) {
label := EscalationLabels[tt.level]
if label == "" {
t.Fatalf("Label for level %d is empty", tt.level)
}
found := false
for i := 0; i <= len(label)-len(tt.contains); i++ {
if label[i:i+len(tt.contains)] == tt.contains {
found = true
break
}
}
if !found {
t.Errorf("Label '%s' should contain '%s'", label, tt.contains)
}
})
}
}
// =============================================================================
// Role Constants and Labels Tests
// =============================================================================
func TestRoleLabels_AllRolesHaveLabels(t *testing.T) {
roles := []string{RoleR1, RoleR2, RoleR3, RoleR4, RoleR5, RoleR6, RoleR7, RoleR8, RoleR9, RoleR10}
for _, role := range roles {
label, ok := RoleLabels[role]
if !ok {
t.Errorf("Missing label for role %s", role)
}
if label == "" {
t.Errorf("Empty label for role %s", role)
}
}
}
func TestNIS2RoleMapping_AllRolesMapped(t *testing.T) {
roles := []string{RoleR1, RoleR2, RoleR3, RoleR4, RoleR5, RoleR6, RoleR7, RoleR8, RoleR9, RoleR10}
for _, role := range roles {
nis2Level, ok := NIS2RoleMapping[role]
if !ok {
t.Errorf("Missing NIS2 mapping for role %s", role)
}
if nis2Level == "" {
t.Errorf("Empty NIS2 level for role %s", role)
}
}
}
func TestTargetAudienceRoleMapping_AllAudiencesPresent(t *testing.T) {
audiences := []string{"enterprise", "authority", "provider", "all"}
for _, aud := range audiences {
roles, ok := TargetAudienceRoleMapping[aud]
if !ok {
t.Errorf("Missing audience mapping for '%s'", aud)
}
if len(roles) == 0 {
t.Errorf("Empty roles for audience '%s'", aud)
}
}
}
func TestTargetAudienceRoleMapping_AllContainsAllRoles(t *testing.T) {
allRoles := TargetAudienceRoleMapping["all"]
if len(allRoles) != 10 {
t.Errorf("Expected 'all' audience to map to 10 roles, got %d", len(allRoles))
}
}