package missionmatch import ( "net/http" "strings" "testing" "github.com/go-chi/chi/v5" "github.com/missionworkforce/missionmatch/internal/modules/commandcenter" "github.com/missionworkforce/missionmatch/internal/modules/matching" ) // TestNamespaceExposesMissionRoutes proves the missionMATCH namespace mounts the command center // rollups, the Candidates Intelligence View, the who can support read, and the shared pickers over the // shared core, and NOT the slate or screen WRITES (those belong to slateMATCH and screenMATCH). It // walks the registered routes, so it needs no database or session. func TestNamespaceExposesMissionRoutes(t *testing.T) { h := NewHandler( matching.NewHandler(matching.NewService(nil, nil, nil)), commandcenter.NewHandler(commandcenter.NewService(nil)), ) r := chi.NewRouter() r.Route("/missionmatch", h.Routes) routes := map[string]bool{} if err := chi.Walk(r, func(method, route string, _ http.Handler, _ ...func(http.Handler) http.Handler) error { routes[method+" "+route] = true return nil }); err != nil { t.Fatalf("walk: %v", err) } want := []string{ "GET /missionmatch/command-center", "POST /missionmatch/command-center/upcoming/{recordID}/adopt", "GET /missionmatch/candidates/intelligence", "GET /missionmatch/requirements/{requirementID}/support", "GET /missionmatch/candidates", "GET /missionmatch/requirements", } for _, w := range want { if !routes[w] { t.Errorf("missionMATCH namespace missing route %q", w) } } // missionMATCH is read only over the workforce; it must not expose a slate generate or a screen POST. for route := range routes { if strings.Contains(route, "/slates/generate") || strings.Contains(route, "POST /missionmatch/screen") { t.Errorf("missionMATCH namespace must not expose a write surface, found %q", route) } } }