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

1""" 

2The core application: view definition for the root of the webapp. 

3""" 

4 

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 

10 

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 

15 

16TEMPLATE_BAD_REQUEST = "400.html" 

17TEMPLATE_NOT_FOUND = "404.html" 

18TEMPLATE_SERVER_ERROR = "500.html" 

19 

20 

21class IndexView(FormView): 

22 """View handler for the main entry page.""" 

23 

24 template_name = "core/index.html" 

25 form_class = ChooseAgencyForm 

26 

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) 

32 

33 @method_decorator(pageview_decorator) 

34 def get(self, request, *args, **kwargs): 

35 session.reset(request) 

36 return super().get(request, *args, **kwargs) 

37 

38 

39class AgencyIndexView(TemplateView): 

40 """View handler for an agency entry page.""" 

41 

42 template_name = "core/index--agency.html" 

43 

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) 

50 

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 

56 

57 

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.""" 

60 

61 pattern_name = routes.ELIGIBILITY_CONFIRM 

62 

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) 

71 

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) 

78 

79 

80class AgencyEligibilityIndexView(RedirectView): 

81 """View handler forwards the request to the agency's Eligibility Index (e.g. flow selection) page.""" 

82 

83 pattern_name = routes.ELIGIBILITY_INDEX 

84 

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) 

94 

95 

96class AgencyPublicKeyView(View): 

97 """View handler returns an agency's public key as plain text.""" 

98 

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") 

103 

104 

105class HelpView(TemplateView): 

106 """View handler for the help page.""" 

107 

108 template_name = "core/help.html" 

109 

110 @method_decorator(pageview_decorator) 

111 def get(self, request, *args, **kwargs): 

112 return super().get(request, *args, **kwargs) 

113 

114 def get_context_data(self, **kwargs): 

115 context = super().get_context_data(**kwargs) 

116 

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()] 

120 

121 return context 

122 

123 

124class LoggedOutView(TemplateView): 

125 """View handler for the final log out confirmation message.""" 

126 

127 template_name = "core/logged-out.html" 

128 

129 

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) 

135 

136 return HttpResponseBadRequest(t.render(request=request)) 

137 

138 

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) 

146 

147 return HttpResponseNotFound(t.render(request=request)) 

148 

149 

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) 

155 

156 return HttpResponseNotFound(t.render(request=request)) 

157 

158 

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) 

164 

165 return HttpResponseServerError(t.render(request=request))