"""Test that all expected routes are defined in the service_pages router. This catches missing routes (potential 404s) purely from code inspection. No database or server is needed. """ import pytest from app.routers.service_pages import router def get_registered_routes(): """Return set of (method, path) tuples from the service_pages router.""" routes = set() for route in router.routes: if hasattr(route, "methods") and hasattr(route, "path"): for method in route.methods: routes.add((method, route.path)) return routes # All routes that SHOULD be registered in service_pages.py EXPECTED_ROUTES = [ ("GET", "/service/users"), ("POST", "/service/users/create"), ("POST", "/service/users/edit"), ("POST", "/service/users/delete"), ("GET", "/service/customers"), ("POST", "/service/customers/create"), ("POST", "/service/customers/edit"), ("POST", "/service/customers/delete"), ("GET", "/service/objects"), ("POST", "/service/objects/create"), ("POST", "/service/objects/edit"), ("POST", "/service/objects/delete"), ("GET", "/service/assignments"), ("POST", "/service/assignments/create"), ("POST", "/service/assignments/unassign"), ("GET", "/service/sla"), ("POST", "/service/sla/create"), ("POST", "/service/sla/edit"), ("GET", "/service/ceo"), ("POST", "/service/ceo/calc"), ("POST", "/service/ceo/kpi"), ("GET", "/service/coefficients"), ("POST", "/service/coefficients/edit"), ("POST", "/service/coefficients/toggle"), ("POST", "/service/coefficients/create"), ("POST", "/service/coefficients/delete"), ("GET", "/service/coefficients/test"), ("GET", "/service/formulas"), ("GET", "/service/tasks"), ("POST", "/service/tasks/create"), ("POST", "/service/tasks/close"), ("GET", "/service/reports"), ("POST", "/service/reports/create"), ("GET", "/service/incidents"), ("POST", "/service/incidents/create"), ("POST", "/service/incidents/resolve"), ("GET", "/service/questionnaire"), ("GET", "/service/questionnaire/step/{step}"), ("POST", "/service/questionnaire/save/{step}"), ("GET", "/service/questionnaire-config"), ("POST", "/service/questionnaire-config/create"), ("POST", "/service/questionnaire-config/edit"), ("POST", "/service/questionnaire-config/toggle"), ("POST", "/service/questionnaire-config/delete"), ("GET", "/service/passports"), ("GET", "/service/checklist"), ("POST", "/service/checklist/complete"), ("GET", "/service/blog"), ("POST", "/service/blog/create"), ("POST", "/service/blog/edit"), ("POST", "/service/blog/delete"), ("GET", "/service/api/quick-menu"), ("GET", "/service/quick-menu"), ("POST", "/service/quick-menu/save"), ("GET", "/service/quick-menu/tech"), ("POST", "/service/quick-menu/tech-save"), ("GET", "/service/ideas"), ("POST", "/service/ideas/create"), ("POST", "/service/ideas/edit"), ("POST", "/service/ideas/status"), ("POST", "/service/ideas/delete"), ("GET", "/service/charts"), ("GET", "/service/api/charts/data"), ("GET", "/service/cases"), ("POST", "/service/cases/create"), ("POST", "/service/cases/edit"), ("POST", "/service/cases/delete"), ("GET", "/service/bot-settings"), ("GET", "/service/bot-settings/responses"), ("GET", "/service/bot-settings/features"), ("GET", "/service/bot-settings/categories"), ("GET", "/service/bot-settings/kb"), ("GET", "/service/bot-settings/conversations"), ("GET", "/service/bot-settings/users"), ("GET", "/service/bot-settings/test-runner"), ("GET", "/service/bot-settings/analytics"), ("GET", "/service/portal-settings"), ("GET", "/service/role-settings"), ("GET", "/service/api/role-permissions"), ("POST", "/service/api/role-permissions/save"), ("POST", "/service/api/role/switch"), ("POST", "/service/api/role/reset"), ("GET", "/service/api/bot/settings"), ("POST", "/service/api/bot/settings/save"), ("GET", "/service/api/bot/templates"), ("POST", "/service/api/bot/templates/save"), ("GET", "/service/api/bot/features"), ("POST", "/service/api/bot/features/toggle"), ("GET", "/service/api/bot/categories"), ("POST", "/service/api/bot/categories/create"), ("POST", "/service/api/bot/categories/edit"), ("POST", "/service/api/bot/categories/delete"), ("GET", "/service/api/bot/kb"), ("POST", "/service/api/bot/kb/create"), ("POST", "/service/api/bot/kb/edit"), ("POST", "/service/api/bot/kb/delete"), ("GET", "/service/api/bot/conversations"), ("GET", "/service/api/bot/users"), ("GET", "/service/api/bot/analytics"), ("POST", "/service/api/bot/test-run"), ("GET", "/service/api/bot/broadcast/recipients"), ("GET", "/service/api/bot/broadcast/history"), ("POST", "/service/api/bot/broadcast"), ] class TestRoutesDefined: def test_routes_exist(self): actual = get_registered_routes() missing = [] for method, path in EXPECTED_ROUTES: if (method, path) not in actual: missing.append(f"{method} {path}") assert not missing, f"Missing routes:\n" + "\n".join(missing) def test_no_unexpected_missing_links(self): """Every sidebar link should have a corresponding route.""" from app.main import app as main_app # Collect all GET routes from both main app and service_pages router all_destinations = set() for route in list(router.routes) + list(main_app.routes): if hasattr(route, "methods") and hasattr(route, "path") and "GET" in route.methods: all_destinations.add(route.path) sidebar_links = [ "/service/dashboard", "/service/charts", "/service/ceo", "/service/customers", "/service/objects", "/service/sla", "/service/questionnaire", "/service/passports", "/service/users", "/service/assignments", "/service/documents/", "/service/tasks", "/service/reports", "/service/incidents", "/service/checklist", "/service/documents/tech-access", "/service/bot-settings/analytics", "/service/bot-settings/users", "/service/bot-settings/conversations", "/service/blog", "/service/cases", "/service/questionnaire-config", "/service/formulas", "/service/bot-settings", "/service/portal-settings", "/service/role-settings", "/service/ideas", ] for link in sidebar_links: assert link in all_destinations, f"Sidebar link {link} has no GET route registered" class TestCoefficientsTestCalc: """The formula test POST route uses path parameter {formula_name}.""" def test_formula_test_route_pattern(self): actual = get_registered_routes() assert ("POST", "/service/coefficients/test/{formula_name}") in actual, \ "Missing POST route pattern for formula tests"