package server import ( "net/http" "net/http/httptest" "strings" "testing" ) // fakeAuthMiddleware simulates auth.Config.Middleware for // newRouteAwareHandler tests, without standing up a real session manager: // a request carrying X-Fake-Authed is treated as authenticated and passed // through; everything else is redirected to /login (302), or answered 401 // with HX-Redirect for an HTMX request, matching the shape of the real // auth middleware's HTMX branch (auth.Config.Middleware) closely enough to // exercise newRouteAwareHandler's dispatch decision. func fakeAuthMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/login" || r.Header.Get("X-Fake-Authed") == "true" { next.ServeHTTP(w, r) return } if r.Header.Get("HX-Request") == "true" { w.Header().Set("HX-Redirect", "/login") w.WriteHeader(http.StatusUnauthorized) return } http.Redirect(w, r, "/login", http.StatusFound) }) } func newTestRouteAwareMux() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("login page")) }) mux.HandleFunc("GET /protected", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("protected content")) }) mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // Mirrors Start()'s own "/" handler: only the literal root is real, // anything else that reaches this point is a bug in the pre-check. if r.URL.Path != "/" { http.Error(w, "unexpected: routeAware should have intercepted this", http.StatusNotFound) return } w.Write([]byte("dashboard")) }) return mux } // TestNewRouteAwareHandler covers design.md Decision 4 / the error-pages // delta's route-existence-before-auth-redirect requirement: an anonymous // request for a path no route matches gets the styled 404 without ever // reaching the auth middleware (no session required, no IdP redirect); a // path that DOES match a real route keeps the ordinary auth-wrapped // dispatch, including the login redirect when the session is absent, and // authenticated behavior on both matched and unmatched paths is unchanged. func TestNewRouteAwareHandler(t *testing.T) { tests := []struct { name string path string authed bool hxRequest bool wantStatus int wantStyled404 bool // body contains the styled error.html page wantRedirect string wantBody string }{ { name: "anonymous unknown route gets styled 404, not a login redirect", path: "/no-such-page", authed: false, wantStatus: http.StatusNotFound, wantStyled404: true, }, { name: "anonymous real protected route still redirects to login", path: "/protected", authed: false, wantStatus: http.StatusFound, wantRedirect: "/login", }, { name: "authenticated unknown route still gets styled 404 (existing behavior stays)", path: "/no-such-page", authed: true, wantStatus: http.StatusNotFound, wantStyled404: true, }, { name: "authenticated real protected route reaches the real handler", path: "/protected", authed: true, wantStatus: http.StatusOK, wantBody: "protected content", }, { name: "HTMX request to an unknown route keeps the HX-aware plain-text 404", path: "/no-such-page", authed: false, hxRequest: true, wantStatus: http.StatusNotFound, wantStyled404: false, wantBody: "The page you requested does not exist.", }, { name: "HTMX request to a real protected route keeps the 10e HX-aware unauthorized response", path: "/protected", authed: false, hxRequest: true, wantStatus: http.StatusUnauthorized, }, } mux := newTestRouteAwareMux() tmpl := errorPageTemplates(t) handler := newRouteAwareHandler(mux, fakeAuthMiddleware, tmpl) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { req := httptest.NewRequest("GET", tt.path, nil) if tt.authed { req.Header.Set("X-Fake-Authed", "true") } if tt.hxRequest { req.Header.Set("HX-Request", "true") } rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != tt.wantStatus { t.Fatalf("status = %d, want %d (body: %s)", rec.Code, tt.wantStatus, rec.Body.String()) } if tt.wantRedirect != "" { if loc := rec.Header().Get("Location"); loc != tt.wantRedirect { t.Errorf("Location = %q, want %q", loc, tt.wantRedirect) } } body := rec.Body.String() if tt.wantStyled404 { for _, want := range []string{"404", "Not Found", "navbar-brand"} { if !strings.Contains(body, want) { t.Errorf("styled 404 body missing %q: %s", want, body) } } } if tt.wantBody != "" && strings.TrimSpace(body) != tt.wantBody { t.Errorf("body = %q, want %q", body, tt.wantBody) } }) } }