package main import ( "net/http" "net/http/httptest" "testing" "git.dev.alexdunmow.com/block/pluginsdk/auth" "git.dev.alexdunmow.com/block/pluginsdk/plugin" "github.com/go-chi/chi/v5" "github.com/google/uuid" ) // TestRouterMatchesAbsolutePluginPaths pins the wasm routing contract: the // host forwards the FULL request path (/api/plugins/calcomblock/...) to the // guest with no prefix strip, so every route must be registered absolute. // Relative registrations 404 the plugin's entire HTTP surface at runtime — // exactly the regression that shipped in 2.0.0–2.0.2. func TestRouterMatchesAbsolutePluginPaths(t *testing.T) { router, ok := NewCalcomRouter(plugin.CoreServices{}).(chi.Routes) if !ok { t.Fatal("NewCalcomRouter no longer returns a chi router") } for _, tc := range []struct{ method, path string }{ {http.MethodGet, "/api/plugins/calcomblock/reset"}, {http.MethodGet, "/api/plugins/calcomblock/slots"}, {http.MethodGet, "/api/plugins/calcomblock/date-grid"}, {http.MethodPost, "/api/plugins/calcomblock/book"}, {http.MethodPost, "/api/plugins/calcomblock/cancel"}, {http.MethodGet, "/api/plugins/calcomblock/event-types"}, } { rctx := chi.NewRouteContext() if !router.Match(rctx, tc.method, tc.path) { t.Errorf("%s %s does not match any route — must be registered at the absolute plugin path", tc.method, tc.path) } } } // TestRouterRebuildsClaimsFromTrustedHeaders pins the wasm identity contract: // context does not cross the ABI, so the ONLY way requireAdmin can see the // caller is for the router to rebuild claims from the host-stamped // X-Bn-Verified-* headers (auth.TrustedHeaderMiddleware). 2.0.3 shipped // without it — every admin endpoint 401'd for real admins. A viewer-role // header must reach requireAdmin and be rejected 403 (claims seen), never // 401 (claims lost); no handler runs, so empty CoreServices is safe. func TestRouterRebuildsClaimsFromTrustedHeaders(t *testing.T) { router := NewCalcomRouter(plugin.CoreServices{}) req := httptest.NewRequest(http.MethodGet, "/api/plugins/calcomblock/settings", nil) req.Header.Set(auth.HeaderVerifiedUserID, uuid.NewString()) req.Header.Set(auth.HeaderVerifiedEmail, "viewer@example.test") req.Header.Set(auth.HeaderVerifiedRole, "viewer") rec := httptest.NewRecorder() router.ServeHTTP(rec, req) if rec.Code == http.StatusUnauthorized { t.Fatalf("viewer trusted headers yielded 401 — TrustedHeaderMiddleware is not mounted, claims never reach requireAdmin") } if rec.Code != http.StatusForbidden { t.Errorf("viewer trusted headers: expected 403 from requireAdmin, got %d (body %q)", rec.Code, rec.Body.String()) } }