Add failing tests for security headers middleware
Tests for X-Content-Type-Options, X-Frame-Options, Referrer-Policy, X-XSS-Protection headers on responses.
This commit is contained in:
@@ -133,3 +133,13 @@ func (s *Middleware) MetricsAuth() func(http.Handler) http.Handler {
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// SecurityHeaders returns a middleware that adds security headers to responses.
|
||||
func (s *Middleware) SecurityHeaders() func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: implement security headers
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
89
internal/middleware/middleware_test.go
Normal file
89
internal/middleware/middleware_test.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"sneak.berlin/go/pixa/internal/config"
|
||||
)
|
||||
|
||||
func TestSecurityHeaders(t *testing.T) {
|
||||
// Create middleware instance
|
||||
cfg := &config.Config{}
|
||||
mw := &Middleware{
|
||||
log: slog.Default(),
|
||||
config: cfg,
|
||||
}
|
||||
|
||||
// Create a test handler
|
||||
testHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
// Wrap with security headers middleware
|
||||
handler := mw.SecurityHeaders()(testHandler)
|
||||
|
||||
// Make a test request
|
||||
req := httptest.NewRequest(http.MethodGet, "/test", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
// Check security headers
|
||||
tests := []struct {
|
||||
header string
|
||||
want string
|
||||
}{
|
||||
{"X-Content-Type-Options", "nosniff"},
|
||||
{"X-Frame-Options", "DENY"},
|
||||
{"Referrer-Policy", "strict-origin-when-cross-origin"},
|
||||
{"X-XSS-Protection", "0"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.header, func(t *testing.T) {
|
||||
got := rec.Header().Get(tt.header)
|
||||
if got != tt.want {
|
||||
t.Errorf("%s = %q, want %q", tt.header, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecurityHeaders_PreservesExistingHeaders(t *testing.T) {
|
||||
cfg := &config.Config{}
|
||||
mw := &Middleware{
|
||||
log: slog.Default(),
|
||||
config: cfg,
|
||||
}
|
||||
|
||||
// Handler that sets its own headers
|
||||
testHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("X-Custom-Header", "custom-value")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
handler := mw.SecurityHeaders()(testHandler)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/test", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
// Security headers should be present
|
||||
if rec.Header().Get("X-Content-Type-Options") != "nosniff" {
|
||||
t.Error("X-Content-Type-Options not set")
|
||||
}
|
||||
|
||||
// Custom headers should still be there
|
||||
if rec.Header().Get("X-Custom-Header") != "custom-value" {
|
||||
t.Error("Custom header was overwritten")
|
||||
}
|
||||
|
||||
if rec.Header().Get("Content-Type") != "application/json" {
|
||||
t.Error("Content-Type was overwritten")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user