Coverage for benefits / core / views.py: 92%
93 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-22 19:08 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-22 19:08 +0000
1"""
2The core application: view definition for the root of the webapp.
3"""
5from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFound, HttpResponseServerError
6from django.template import loader
7from django.utils.decorators import method_decorator
8from django.views.generic import RedirectView, TemplateView, View
9from django.views.generic.edit import FormView
11from benefits.core.forms import ChooseAgencyForm
12from benefits.routes import routes
13from . import models, session
14from .middleware import pageview_decorator, index_or_agencyindex_origin_decorator, user_error
16TEMPLATE_BAD_REQUEST = "400.html"
17TEMPLATE_NOT_FOUND = "404.html"
18TEMPLATE_SERVER_ERROR = "500.html"
21class IndexView(FormView):
22 """View handler for the main entry page."""
24 template_name = "core/index.html"
25 form_class = ChooseAgencyForm
27 # this form cannot use an action_url because the redirect is determined
28 # *after* user interaction
29 def form_valid(self, form):
30 self.success_url = form.selected_transit_agency.eligibility_index_url
31 return super().form_valid(form)
33 @method_decorator(pageview_decorator)
34 def get(self, request, *args, **kwargs):
35 session.reset(request)
36 return super().get(request, *args, **kwargs)
39class AgencyIndexView(TemplateView):
40 """View handler for an agency entry page."""
42 template_name = "core/index--agency.html"
44 @method_decorator(pageview_decorator)
45 def get(self, request, *args, **kwargs):
46 agency = self.kwargs.get("agency")
47 session.reset(request)
48 session.update(request, agency=agency, origin=agency.index_url)
49 return super().get(request, *args, **kwargs)
51 def get_context_data(self, **kwargs):
52 context = super().get_context_data(**kwargs)
53 agency = self.kwargs.get("agency")
54 context |= agency.index_context
55 return context
58class AgencyCardView(RedirectView):
59 """View handler forwards the request to the agency's Agency Card (e.g. Eligibility API) flow, or returns a user error."""
61 pattern_name = routes.ELIGIBILITY_CONFIRM
63 @method_decorator(pageview_decorator)
64 def get(self, request, *args, **kwargs):
65 # keep a reference to the agency before removing from kwargs
66 # since the eventual reverse() lookup doesn't expect this key in the kwargs for routes.ELIGIBILITY_CONFIRM
67 # self.kwargs still contains the agency if needed
68 agency = kwargs.pop("agency")
69 session.reset(request)
70 session.update(request, agency=agency, origin=agency.index_url)
72 eligibility_api_flow = agency.enrollment_flows.exclude(api_request=None).order_by("id").last()
73 if eligibility_api_flow:
74 session.update(request, flow=eligibility_api_flow)
75 return super().get(request, *args, **kwargs)
76 else:
77 return user_error(request)
80class AgencyEligibilityIndexView(RedirectView):
81 """View handler forwards the request to the agency's Eligibility Index (e.g. flow selection) page."""
83 pattern_name = routes.ELIGIBILITY_INDEX
85 @method_decorator(pageview_decorator)
86 def get(self, request, *args, **kwargs):
87 # keep a reference to the agency before removing from kwargs
88 # since the eventual reverse() lookup doesn't expect this key in the kwargs for routes.ELIGIBILITY_INDEX
89 # self.kwargs still contains the agency if needed
90 agency = kwargs.pop("agency")
91 session.reset(request)
92 session.update(request, agency=agency, origin=agency.index_url)
93 return super().get(request, *args, **kwargs)
96class AgencyPublicKeyView(View):
97 """View handler returns an agency's public key as plain text."""
99 @method_decorator(pageview_decorator)
100 def get(self, request, *args, **kwargs):
101 agency = kwargs.get("agency")
102 return HttpResponse(agency.eligibility_api_public_key_data, content_type="text/plain")
105class HelpView(TemplateView):
106 """View handler for the help page."""
108 template_name = "core/help.html"
110 @method_decorator(pageview_decorator)
111 def get(self, request, *args, **kwargs):
112 return super().get(request, *args, **kwargs)
114 def get_context_data(self, **kwargs):
115 context = super().get_context_data(**kwargs)
117 if not session.active_agency(self.request):
118 choices = models.CardSchemes.CHOICES
119 context["all_card_schemes"] = [choices[card_scheme] for card_scheme in choices.keys()]
121 return context
124class LoggedOutView(TemplateView):
125 """View handler for the final log out confirmation message."""
127 template_name = "core/logged-out.html"
130@pageview_decorator
131@index_or_agencyindex_origin_decorator
132def bad_request(request, exception, template_name=TEMPLATE_BAD_REQUEST):
133 """View handler for HTTP 400 Bad Request responses."""
134 t = loader.get_template(template_name)
136 return HttpResponseBadRequest(t.render(request=request))
139@pageview_decorator
140@index_or_agencyindex_origin_decorator
141def csrf_failure(request, reason):
142 """
143 View handler for CSRF_FAILURE_VIEW with custom data.
144 """
145 t = loader.get_template(TEMPLATE_BAD_REQUEST)
147 return HttpResponseNotFound(t.render(request=request))
150@pageview_decorator
151@index_or_agencyindex_origin_decorator
152def page_not_found(request, exception, template_name=TEMPLATE_NOT_FOUND):
153 """View handler for HTTP 404 Not Found responses."""
154 t = loader.get_template(template_name)
156 return HttpResponseNotFound(t.render(request=request))
159@pageview_decorator
160@index_or_agencyindex_origin_decorator
161def server_error(request, template_name=TEMPLATE_SERVER_ERROR):
162 """View handler for HTTP 500 Server Error responses."""
163 t = loader.get_template(template_name)
165 return HttpResponseServerError(t.render(request=request))