Coverage for benefits/core/mixins.py: 96%
40 statements
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-15 00:14 +0000
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-15 00:14 +0000
1import logging
3from django.conf import settings
5from benefits.core import analytics
7from . import recaptcha, session
8from .middleware import user_error
10logger = logging.getLogger(__name__)
13class AgencySessionRequiredMixin:
14 """Mixin intended for use with a class-based view as the first in the MRO.
16 Gets the active `TransitAgency` out of session and sets an attribute on `self`.
18 If the session is not configured with an agency, return a user error.
19 """
21 def dispatch(self, request, *args, **kwargs):
22 if session.active_agency(request):
23 self.agency = session.agency(request)
24 return super().dispatch(request, *args, **kwargs)
25 else:
26 logger.warning("Session not configured with an active agency")
27 return user_error(request)
30class EligibleSessionRequiredMixin:
31 """Mixin intended for use with a class-based view as the first in the MRO.
33 If the session is not marked as eligible (e.g. the user has verified their eligibility), return a user error.
34 """
36 def dispatch(self, request, *args, **kwargs):
37 if session.eligible(request):
38 return super().dispatch(request, *args, **kwargs)
39 else:
40 logger.warning("Session does not have verified eligibility")
41 return user_error(request)
44class FlowSessionRequiredMixin:
45 """Mixin intended for use with a class-based view as the first in the MRO.
47 Gets the current `EnrollmentFlow` out of session and sets an attribute on `self`.
49 If the session is not configured with a flow, return a user error.
50 """
52 def dispatch(self, request, *args, **kwargs):
53 flow = session.flow(request)
54 if flow:
55 self.flow = flow
56 return super().dispatch(request, *args, **kwargs)
57 else:
58 logger.warning("Session not configured with enrollment flow")
59 return user_error(request)
62class PageViewMixin:
63 """
64 Mixin sends an analytics event for page views.
65 """
67 def dispatch(self, request, *args, **kwargs):
68 event = analytics.ViewedPageEvent(request)
69 try:
70 analytics.send_event(event)
71 except Exception:
72 logger.warning(f"Failed to send event: {event}")
73 finally:
74 return super().dispatch(request, *args, **kwargs)
77class RecaptchaEnabledMixin:
78 """Mixin intended for use with a class-based view as the first in the MRO.
80 Configures the request with required reCAPTCHA settings."""
82 def dispatch(self, request, *args, **kwargs):
83 if settings.RECAPTCHA_ENABLED:
84 request.recaptcha = {
85 "data_field": recaptcha.DATA_FIELD,
86 "script_api": settings.RECAPTCHA_API_KEY_URL,
87 "site_key": settings.RECAPTCHA_SITE_KEY,
88 }
89 return super().dispatch(request, *args, **kwargs)