package middleware import ( "testing" ) func TestPIIRedactor_RedactsEmail(t *testing.T) { redactor := NewDefaultPIIRedactor() text := "User test@example.com logged in" result := redactor.Redact(text) if result == text { t.Error("Email should have been redacted") } if result != "User [EMAIL_REDACTED] logged in" { t.Errorf("Unexpected result: %s", result) } } func TestPIIRedactor_RedactsIPv4(t *testing.T) { redactor := NewDefaultPIIRedactor() text := "Request from 192.168.1.100" result := redactor.Redact(text) if result == text { t.Error("IP should have been redacted") } if result != "Request from [IP_REDACTED]" { t.Errorf("Unexpected result: %s", result) } } func TestPIIRedactor_RedactsGermanPhone(t *testing.T) { redactor := NewDefaultPIIRedactor() tests := []struct { input string expected string }{ {"+49 30 12345678", "[PHONE_REDACTED]"}, {"0049 30 12345678", "[PHONE_REDACTED]"}, {"030 12345678", "[PHONE_REDACTED]"}, } for _, tt := range tests { result := redactor.Redact(tt.input) if result != tt.expected { t.Errorf("For input %q: expected %q, got %q", tt.input, tt.expected, result) } } } func TestPIIRedactor_RedactsMultiplePII(t *testing.T) { redactor := NewDefaultPIIRedactor() text := "User test@example.com from 10.0.0.1" result := redactor.Redact(text) if result != "User [EMAIL_REDACTED] from [IP_REDACTED]" { t.Errorf("Unexpected result: %s", result) } } func TestPIIRedactor_PreservesNonPIIText(t *testing.T) { redactor := NewDefaultPIIRedactor() text := "User logged in successfully" result := redactor.Redact(text) if result != text { t.Errorf("Text should be unchanged: got %s", result) } } func TestPIIRedactor_EmptyString(t *testing.T) { redactor := NewDefaultPIIRedactor() result := redactor.Redact("") if result != "" { t.Error("Empty string should remain empty") } } func TestContainsPII(t *testing.T) { redactor := NewDefaultPIIRedactor() tests := []struct { input string expected bool }{ {"test@example.com", true}, {"192.168.1.1", true}, {"+49 30 12345678", true}, {"Hello World", false}, {"", false}, } for _, tt := range tests { result := redactor.ContainsPII(tt.input) if result != tt.expected { t.Errorf("For input %q: expected %v, got %v", tt.input, tt.expected, result) } } } func TestFindPII(t *testing.T) { redactor := NewDefaultPIIRedactor() text := "Email: test@example.com, IP: 10.0.0.1" findings := redactor.FindPII(text) if len(findings) != 2 { t.Errorf("Expected 2 findings, got %d", len(findings)) } hasEmail := false hasIP := false for _, f := range findings { if f.Type == "email" { hasEmail = true } if f.Type == "ip_v4" { hasIP = true } } if !hasEmail { t.Error("Should have found email") } if !hasIP { t.Error("Should have found IP") } } func TestRedactPII_GlobalFunction(t *testing.T) { text := "User test@example.com logged in" result := RedactPII(text) if result == text { t.Error("Email should have been redacted") } } func TestContainsPIIDefault(t *testing.T) { if !ContainsPIIDefault("test@example.com") { t.Error("Should detect email as PII") } if ContainsPIIDefault("Hello World") { t.Error("Should not detect non-PII text") } } func TestRedactMap(t *testing.T) { data := map[string]interface{}{ "email": "test@example.com", "message": "Hello World", "nested": map[string]interface{}{ "ip": "192.168.1.1", }, } result := RedactMap(data) if result["email"] != "[EMAIL_REDACTED]" { t.Errorf("Email should be redacted: %v", result["email"]) } if result["message"] != "Hello World" { t.Errorf("Non-PII should be unchanged: %v", result["message"]) } nested := result["nested"].(map[string]interface{}) if nested["ip"] != "[IP_REDACTED]" { t.Errorf("Nested IP should be redacted: %v", nested["ip"]) } } func TestAllPIIPatterns(t *testing.T) { patterns := AllPIIPatterns() if len(patterns) == 0 { t.Error("Should have PII patterns") } // Check that we have the expected patterns expectedNames := []string{"email", "ip_v4", "ip_v6", "phone", "iban", "uuid", "name"} nameMap := make(map[string]bool) for _, p := range patterns { nameMap[p.Name] = true } for _, name := range expectedNames { if !nameMap[name] { t.Errorf("Missing expected pattern: %s", name) } } } func TestDefaultPIIPatterns(t *testing.T) { patterns := DefaultPIIPatterns() if len(patterns) != 4 { t.Errorf("Expected 4 default patterns, got %d", len(patterns)) } } func TestIBANRedaction(t *testing.T) { redactor := NewPIIRedactor(AllPIIPatterns()) text := "IBAN: DE89 3704 0044 0532 0130 00" result := redactor.Redact(text) if result == text { t.Error("IBAN should have been redacted") } } func TestUUIDRedaction(t *testing.T) { redactor := NewPIIRedactor(AllPIIPatterns()) text := "User ID: a0000000-0000-0000-0000-000000000001" result := redactor.Redact(text) if result == text { t.Error("UUID should have been redacted") } }