Files
pixa/internal/middleware/middleware_internal_test.go
clawbot 2d805125ee
All checks were successful
check / check (push) Successful in 4s
chore: update golangci-lint to v2.12.2 with canonical config (#54)
Canonical v2-schema `.golangci.yml`, golangci-lint pins bumped to v2.12.2 in `Dockerfile` and `script/bootstrap`, and the tree brought to `0 issues.` under it.

Three behaviour deltas: `Cache.StoreVariant` takes a context (cancelled requests skip the accounting row, recovered by reconciliation); `MetadataStorage.Store` no longer leaks `.tmp-*.json` on Write/Close/Rename failure (dead-defer bug fix); the `signing_key` too-short error text gained a `value too short:` prefix.

Eviction-loop context cancellation deferred to #102.
2026-08-10 16:12:22 +02:00

96 lines
2.1 KiB
Go

package middleware
import (
"log/slog"
"net/http"
"net/http/httptest"
"testing"
"sneak.berlin/go/pixa/internal/config"
)
func TestSecurityHeaders(t *testing.T) {
t.Parallel()
// 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.NewRequestWithContext(t.Context(), 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) {
t.Parallel()
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) {
t.Parallel()
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.NewRequestWithContext(t.Context(), 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")
}
}