Files

95 lines
2.5 KiB
Go

package auth
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
)
// injectUser returns a copy of r with the given user stored under userCtxKey.
// This mirrors what RequireUser does at runtime.
func injectUser(r *http.Request, u dbq.User) *http.Request {
ctx := context.WithValue(r.Context(), userCtxKey, u)
return r.WithContext(ctx)
}
func TestRequireAdmin_AdminPasses(t *testing.T) {
called := false
stub := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
called = true
w.WriteHeader(http.StatusOK)
})
h := RequireAdmin()(stub)
req := injectUser(
httptest.NewRequest(http.MethodGet, "/api/admin/test", nil),
dbq.User{IsAdmin: true},
)
w := httptest.NewRecorder()
h.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("status = %d, want 200", w.Code)
}
if !called {
t.Error("stub handler was not called for admin user")
}
}
func TestRequireAdmin_NonAdminReturns403(t *testing.T) {
stub := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
t.Fatal("stub handler must not be called for non-admin user")
})
h := RequireAdmin()(stub)
req := injectUser(
httptest.NewRequest(http.MethodGet, "/api/admin/test", nil),
dbq.User{IsAdmin: false},
)
w := httptest.NewRecorder()
h.ServeHTTP(w, req)
if w.Code != http.StatusForbidden {
t.Errorf("status = %d, want 403", w.Code)
}
body := w.Body.String()
if !strings.Contains(body, "not_authorized") {
t.Errorf("body %q does not contain %q", body, "not_authorized")
}
ct := w.Header().Get("Content-Type")
if !strings.HasPrefix(ct, "application/json") {
t.Errorf("Content-Type = %q, want application/json", ct)
}
}
func TestRequireAdmin_NoUserContextReturns500(t *testing.T) {
stub := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {
t.Fatal("stub handler must not be called when no user is in context")
})
h := RequireAdmin()(stub)
// Do NOT inject a user — simulate RequireUser being bypassed.
req := httptest.NewRequest(http.MethodGet, "/api/admin/test", nil)
w := httptest.NewRecorder()
h.ServeHTTP(w, req)
if w.Code != http.StatusInternalServerError {
t.Errorf("status = %d, want 500", w.Code)
}
body := w.Body.String()
if !strings.Contains(body, "internal_error") {
t.Errorf("body %q does not contain %q", body, "internal_error")
}
ct := w.Header().Get("Content-Type")
if !strings.HasPrefix(ct, "application/json") {
t.Errorf("Content-Type = %q, want application/json", ct)
}
}