95 lines
2.5 KiB
Go
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)
|
|
}
|
|
}
|