package httpapi import ( "context" "net/http" "net/http/httptest" "testing" "github.com/alexedwards/scs/v2" "github.com/descrybe/descrybe-v2/apps/api/internal/auth" "github.com/descrybe/descrybe-v2/apps/api/internal/config" "github.com/google/uuid" ) func TestHandleAdminReadinessNilPool(t *testing.T) { t.Parallel() s := &Server{} req := httptest.NewRequest(http.MethodGet, "/api/admin/readiness", nil) rec := httptest.NewRecorder() s.handleAdminReadiness(rec, req) if rec.Code != http.StatusServiceUnavailable { t.Fatalf("status=%d want 503 body=%s", rec.Code, rec.Body.String()) } } // TestRouterAdminReadinessMounted locks the P1-15 SPA contract: after session + // platform-admin gates, GET /api/admin/readiness must reach the handler (503 with // nil pool), not chi 404. Unauthed probes alone cannot prove the mount — any // /api/admin/* returns 401 from RequireSession whether or not /readiness exists. func TestRouterAdminReadinessMounted(t *testing.T) { t.Parallel() sm := scs.New() sm.Cookie.Name = "descrybe_session" uid := uuid.MustParse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa") s := &Server{ Config: config.Config{ CSRFCookieName: "descrybe_csrf", WebOrigin: "http://localhost:5173", }, Sessions: sm, Auth: &auth.Service{}, testPlatformAdmin: func(_ context.Context, got uuid.UUID) (bool, error) { return got == uid, nil }, } var token string seed := LoadSession(sm)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { sm.Put(r.Context(), auth.SessionUserIDKey, uid.String()) w.WriteHeader(http.StatusNoContent) })) seedRec := httptest.NewRecorder() seed.ServeHTTP(seedRec, httptest.NewRequest(http.MethodGet, "/seed", nil)) for _, c := range seedRec.Result().Cookies() { if c.Name == sm.Cookie.Name { token = c.Value } } if token == "" { t.Fatal("expected session cookie from seed request") } h := s.Router() unauth := httptest.NewRecorder() h.ServeHTTP(unauth, httptest.NewRequest(http.MethodGet, "/api/admin/readiness", nil)) if unauth.Code != http.StatusUnauthorized { t.Fatalf("unauth status=%d want 401 body=%s", unauth.Code, unauth.Body.String()) } mounted := httptest.NewRecorder() req := httptest.NewRequest(http.MethodGet, "/api/admin/readiness", nil) req.AddCookie(&http.Cookie{Name: sm.Cookie.Name, Value: token}) h.ServeHTTP(mounted, req) if mounted.Code == http.StatusNotFound { t.Fatalf("readiness not mounted: status=404 body=%s", mounted.Body.String()) } if mounted.Code != http.StatusServiceUnavailable { t.Fatalf("mounted status=%d want 503 (nil pool) body=%s", mounted.Code, mounted.Body.String()) } missing := httptest.NewRecorder() missReq := httptest.NewRequest(http.MethodGet, "/api/admin/does-not-exist", nil) missReq.AddCookie(&http.Cookie{Name: sm.Cookie.Name, Value: token}) h.ServeHTTP(missing, missReq) if missing.Code != http.StatusNotFound { t.Fatalf("unknown admin path status=%d want 404 body=%s", missing.Code, missing.Body.String()) } }