A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
229 lines
4.9 KiB
Go
229 lines
4.9 KiB
Go
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")
|
|
}
|
|
}
|