package l7 import ( "net/http" "net/http/httptest" "testing" ) func TestPolicyMiddlewareNoPolicies(t *testing.T) { called := false next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { called = true w.WriteHeader(200) }) handler := PolicyMiddleware(nil, next) req := httptest.NewRequest("GET", "/", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if !called { t.Fatal("next handler was not called") } if w.Code != 200 { t.Fatalf("status = %d, want 200", w.Code) } } func TestPolicyBlockUserAgentMatch(t *testing.T) { next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }) policies := []PolicyRule{ {Type: "block_user_agent", Value: "BadBot"}, } handler := PolicyMiddleware(policies, next) req := httptest.NewRequest("GET", "/", nil) req.Header.Set("User-Agent", "Mozilla/5.0 BadBot/1.0") w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != 403 { t.Fatalf("status = %d, want 403", w.Code) } } func TestPolicyBlockUserAgentNoMatch(t *testing.T) { called := false next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { called = true w.WriteHeader(200) }) policies := []PolicyRule{ {Type: "block_user_agent", Value: "BadBot"}, } handler := PolicyMiddleware(policies, next) req := httptest.NewRequest("GET", "/", nil) req.Header.Set("User-Agent", "Mozilla/5.0 GoodBrowser/1.0") w := httptest.NewRecorder() handler.ServeHTTP(w, req) if !called { t.Fatal("next handler was not called") } if w.Code != 200 { t.Fatalf("status = %d, want 200", w.Code) } } func TestPolicyRequireHeaderPresent(t *testing.T) { called := false next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { called = true w.WriteHeader(200) }) policies := []PolicyRule{ {Type: "require_header", Value: "X-API-Key"}, } handler := PolicyMiddleware(policies, next) req := httptest.NewRequest("GET", "/", nil) req.Header.Set("X-API-Key", "secret") w := httptest.NewRecorder() handler.ServeHTTP(w, req) if !called { t.Fatal("next handler was not called") } if w.Code != 200 { t.Fatalf("status = %d, want 200", w.Code) } } func TestPolicyRequireHeaderAbsent(t *testing.T) { next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }) policies := []PolicyRule{ {Type: "require_header", Value: "X-API-Key"}, } handler := PolicyMiddleware(policies, next) req := httptest.NewRequest("GET", "/", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != 403 { t.Fatalf("status = %d, want 403", w.Code) } } func TestPolicyMultipleRules(t *testing.T) { next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }) policies := []PolicyRule{ {Type: "block_user_agent", Value: "BadBot"}, {Type: "require_header", Value: "X-Token"}, } handler := PolicyMiddleware(policies, next) // Blocked by UA even though header is present. req := httptest.NewRequest("GET", "/", nil) req.Header.Set("User-Agent", "BadBot/1.0") req.Header.Set("X-Token", "abc") w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != 403 { t.Fatalf("UA block: status = %d, want 403", w.Code) } // Good UA but missing header. req2 := httptest.NewRequest("GET", "/", nil) req2.Header.Set("User-Agent", "GoodBot/1.0") w2 := httptest.NewRecorder() handler.ServeHTTP(w2, req2) if w2.Code != 403 { t.Fatalf("missing header: status = %d, want 403", w2.Code) } // Good UA and header present — passes. req3 := httptest.NewRequest("GET", "/", nil) req3.Header.Set("User-Agent", "GoodBot/1.0") req3.Header.Set("X-Token", "abc") w3 := httptest.NewRecorder() handler.ServeHTTP(w3, req3) if w3.Code != 200 { t.Fatalf("pass: status = %d, want 200", w3.Code) } }