Coverage for benefits/urls.py: 72%
51 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-08 19:50 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-08 19:50 +0000
1"""
2benefits URL Configuration
4The `urlpatterns` list routes URLs to views. For more information please see:
5 https://docs.djangoproject.com/en/stable/topics/http/urls/
6"""
8import logging
9import re
11from django.conf import settings
12from django.contrib import admin
13from django.core.exceptions import BadRequest, PermissionDenied
14from django.http import Http404, HttpResponse
15from django.urls import include, path, re_path
16from django.views.static import serve
18from benefits.core.admin.views import (
19 BenefitsPasswordResetConfirmView,
20 BenefitsPasswordResetDoneView,
21 BenefitsPasswordResetView,
22)
23from benefits.views import BadRequestView, ForbiddenView, NotFoundView, server_error_handler
25logger = logging.getLogger(__name__)
27handler400 = BadRequestView.as_view()
28handler403 = ForbiddenView.as_view()
29handler404 = NotFoundView.as_view()
30handler500 = server_error_handler
32urlpatterns = [
33 path("", include("benefits.core.urls")),
34 path("eligibility/", include("benefits.eligibility.urls")),
35 path("enrollment/", include("benefits.enrollment.urls")),
36 path("i18n/", include("django.conf.urls.i18n")),
37 path("oauth/", include("benefits.oauth.urls")),
38 path("in_person/", include("benefits.in_person.urls")),
39 path("init/", include("benefits.enrollment_init.urls")),
40 path("littlepay/", include("benefits.enrollment_littlepay.urls")),
41 path("switchio/", include("benefits.enrollment_switchio.urls")),
42]
44# TODO: move this URL pattern back into the main block above
45# once MMW is going live
46if settings.RUNTIME_ENVIRONMENT() != settings.RUNTIME_ENVS.PROD: 46 ↛ 49line 46 didn't jump to line 49 because the condition on line 46 was always true
47 urlpatterns.append(path("metro-mobility-wallet/", include("benefits.metro_mobility_wallet.urls")))
49if settings.RUNTIME_ENVIRONMENT() == settings.RUNTIME_ENVS.LOCAL: 49 ↛ 88line 49 didn't jump to line 88 because the condition on line 49 was always true
50 # serve user-uploaded media files
51 #
52 # the helper function `django.conf.urls.static.static` mentioned in
53 # https://docs.djangoproject.com/en/stable/howto/static-files/#serving-files-uploaded-by-a-user-during-development
54 # only works when settings.DEBUG = True, so here we add the URL pattern ourselves so it works regardless of DEBUG.
55 prefix = settings.MEDIA_URL
56 urlpatterns.extend(
57 [re_path(r"^%s(?P<path>.*)$" % re.escape(prefix.lstrip("/")), serve, {"document_root": settings.MEDIA_ROOT})]
58 )
60 # based on
61 # https://docs.sentry.io/platforms/python/guides/django/#verify
62 def trigger_400(request):
63 raise BadRequest("Test 400")
65 def trigger_403(request):
66 raise PermissionDenied("Test 403")
68 def trigger_404(request):
69 raise Http404("Test 404")
71 def trigger_500(request):
72 raise Exception("Test 500")
74 def trigger_csrf(request):
75 if request.method == "POST":
76 return HttpResponse("Should not reach here")
77 return HttpResponse(
78 "<html><body><form method='post' action='/testcsrf/'>"
79 "<button type='submit'>Submit CSRF failure</button></form></body></html>"
80 )
82 urlpatterns.append(path("test400/", trigger_400))
83 urlpatterns.append(path("test403/", trigger_403))
84 urlpatterns.append(path("test404/", trigger_404))
85 urlpatterns.append(path("test500/", trigger_500))
86 urlpatterns.append(path("testcsrf/", trigger_csrf))
88if settings.DEBUG_TOOLBAR: 88 ↛ 89line 88 didn't jump to line 89 because the condition on line 88 was never true
89 from debug_toolbar.toolbar import debug_toolbar_urls
91 urlpatterns.extend(debug_toolbar_urls())
94if settings.RUNTIME_ENVIRONMENT() in (settings.RUNTIME_ENVS.LOCAL, settings.RUNTIME_ENVS.DEV): 94 ↛ 106line 94 didn't jump to line 106 because the condition on line 94 was always true
95 # simple route to read a pre-defined "secret"
96 # this "secret" does not contain sensitive information
97 # and is only configured in the dev environment for testing/debugging
99 def test_secret(request):
100 from benefits.secrets import get_secret_by_name
102 return HttpResponse(get_secret_by_name("testsecret"))
104 urlpatterns.append(path("testsecret/", test_secret))
106logger.debug("Register admin urls")
107password_reset_patterns = [
108 path(
109 "admin/password_reset/",
110 BenefitsPasswordResetView.as_view(extra_context={"site_header": admin.site.site_header}),
111 name="admin_password_reset",
112 ),
113 path(
114 "admin/password_reset/done/",
115 BenefitsPasswordResetDoneView.as_view(extra_context={"site_header": admin.site.site_header}),
116 name="password_reset_done",
117 ),
118 path(
119 "admin/password_reset/<uidb64>/<token>/",
120 BenefitsPasswordResetConfirmView.as_view(extra_context={"site_header": admin.site.site_header}),
121 name="password_reset_confirm",
122 ),
123]
124urlpatterns.extend(password_reset_patterns)
125urlpatterns.append(path("admin/", admin.site.urls))
126urlpatterns.append(path("google_sso/", include("django_google_sso.urls", namespace="django_google_sso")))