Coverage for benefits / urls.py: 75%

46 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-02-13 19:35 +0000

1""" 

2benefits URL Configuration 

3 

4The `urlpatterns` list routes URLs to views. For more information please see: 

5 https://docs.djangoproject.com/en/5.0/topics/http/urls/ 

6""" 

7 

8import logging 

9import re 

10 

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 

17 

18from benefits.core.admin.views import ( 

19 BenefitsPasswordResetConfirmView, 

20 BenefitsPasswordResetDoneView, 

21 BenefitsPasswordResetView, 

22) 

23from benefits.views import BadRequestView, ForbiddenView, NotFoundView, server_error_handler 

24 

25logger = logging.getLogger(__name__) 

26 

27handler400 = BadRequestView.as_view() 

28handler403 = ForbiddenView.as_view() 

29handler404 = NotFoundView.as_view() 

30handler500 = server_error_handler 

31 

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("littlepay/", include("benefits.enrollment_littlepay.urls")), 

40 path("switchio/", include("benefits.enrollment_switchio.urls")), 

41] 

42 

43if settings.RUNTIME_ENVIRONMENT() == settings.RUNTIME_ENVS.LOCAL: 43 ↛ 82line 43 didn't jump to line 82 because the condition on line 43 was always true

44 # serve user-uploaded media files 

45 # 

46 # the helper function `django.conf.urls.static.static` mentioned in 

47 # https://docs.djangoproject.com/en/5.1/howto/static-files/#serving-files-uploaded-by-a-user-during-development 

48 # only works when settings.DEBUG = True, so here we add the URL pattern ourselves so it works regardless of DEBUG. 

49 prefix = settings.MEDIA_URL 

50 urlpatterns.extend( 

51 [re_path(r"^%s(?P<path>.*)$" % re.escape(prefix.lstrip("/")), serve, {"document_root": settings.MEDIA_ROOT})] 

52 ) 

53 

54 # based on 

55 # https://docs.sentry.io/platforms/python/guides/django/#verify 

56 def trigger_400(request): 

57 raise BadRequest("Test 400") 

58 

59 def trigger_403(request): 

60 raise PermissionDenied("Test 403") 

61 

62 def trigger_404(request): 

63 raise Http404("Test 404") 

64 

65 def trigger_500(request): 

66 raise Exception("Test 500") 

67 

68 def trigger_csrf(request): 

69 if request.method == "POST": 

70 return HttpResponse("Should not reach here") 

71 return HttpResponse( 

72 "<html><body><form method='post' action='/testcsrf/'>" 

73 "<button type='submit'>Submit CSRF failure</button></form></body></html>" 

74 ) 

75 

76 urlpatterns.append(path("test400/", trigger_400)) 

77 urlpatterns.append(path("test403/", trigger_403)) 

78 urlpatterns.append(path("test404/", trigger_404)) 

79 urlpatterns.append(path("test500/", trigger_500)) 

80 urlpatterns.append(path("testcsrf/", trigger_csrf)) 

81 

82if settings.RUNTIME_ENVIRONMENT() in (settings.RUNTIME_ENVS.LOCAL, settings.RUNTIME_ENVS.DEV): 82 ↛ 94line 82 didn't jump to line 94 because the condition on line 82 was always true

83 # simple route to read a pre-defined "secret" 

84 # this "secret" does not contain sensitive information 

85 # and is only configured in the dev environment for testing/debugging 

86 

87 def test_secret(request): 

88 from benefits.secrets import get_secret_by_name 

89 

90 return HttpResponse(get_secret_by_name("testsecret")) 

91 

92 urlpatterns.append(path("testsecret/", test_secret)) 

93 

94logger.debug("Register admin urls") 

95password_reset_patterns = [ 

96 path( 

97 "admin/password_reset/", 

98 BenefitsPasswordResetView.as_view(extra_context={"site_header": admin.site.site_header}), 

99 name="admin_password_reset", 

100 ), 

101 path( 

102 "admin/password_reset/done/", 

103 BenefitsPasswordResetDoneView.as_view(extra_context={"site_header": admin.site.site_header}), 

104 name="password_reset_done", 

105 ), 

106 path( 

107 "admin/password_reset/<uidb64>/<token>/", 

108 BenefitsPasswordResetConfirmView.as_view(extra_context={"site_header": admin.site.site_header}), 

109 name="password_reset_confirm", 

110 ), 

111] 

112urlpatterns.extend(password_reset_patterns) 

113urlpatterns.append(path("admin/", admin.site.urls)) 

114urlpatterns.append(path("google_sso/", include("django_google_sso.urls", namespace="django_google_sso")))