package main import ( "net/http/httptest" "strings" "testing" "time" ) func TestStrictJSON(t *testing.T) { type payload struct { Name string `json:"name"` } for _, test := range []struct { body string valid bool }{ {`{"name":"vps"}`, true}, {`{"name":"vps","secret":"leak"}`, false}, {`{"name":"vps"}{"name":"second"}`, false}, } { request := httptest.NewRequest("POST", "/", strings.NewReader(test.body)) writer := httptest.NewRecorder() var value payload err := decodeJSON(writer, request, &value) if (err == nil) != test.valid { t.Fatalf("body %q valid=%v err=%v", test.body, test.valid, err) } } } func TestLoginLimiterIsBounded(t *testing.T) { limiter := NewLoginLimiter(2, time.Minute) now := time.Now() if !limiter.Allow("ip", now) || !limiter.Allow("ip", now) { t.Fatal("initial attempts rejected") } if limiter.Allow("ip", now) { t.Fatal("limit not enforced") } if !limiter.Allow("ip", now.Add(time.Minute)) { t.Fatal("window did not reset") } limiter.maxKeys = 1 if limiter.Allow("second-ip", now) { t.Fatal("bounded limiter accepted an untracked key") } } func TestValidators(t *testing.T) { if !validSimpleName("nginx-http-auth") || validSimpleName("jail;shutdown") { t.Fatal("jail validation failed") } if !validServiceName("wg-quick@wg0") || validServiceName("nginx/restart") { t.Fatal("service validation failed") } } func TestPercent(t *testing.T) { if percent(25, 100) != 25 || percent(1, 0) != 0 { t.Fatal("invalid percentage") } } func TestRedactLogMessage(t *testing.T) { input := `Authorization: Bearer abc123 password="hunter2" token=xyz&safe=1` want := `Authorization: Bearer [REDACTED] password=[REDACTED] token=[REDACTED]&safe=1` if got := redactLogMessage(input); got != want { t.Fatalf("redaction mismatch: got %q want %q", got, want) } } func TestTruncateUTF8(t *testing.T) { if got := truncateUTF8("привет", 5); got != "пр" { t.Fatalf("unexpected UTF-8 truncation %q", got) } }