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

1import logging 

2 

3from django.conf import settings 

4 

5from benefits.core import analytics 

6 

7from . import recaptcha, session 

8from .middleware import user_error 

9 

10logger = logging.getLogger(__name__) 

11 

12 

13class AgencySessionRequiredMixin: 

14 """Mixin intended for use with a class-based view as the first in the MRO. 

15 

16 Gets the active `TransitAgency` out of session and sets an attribute on `self`. 

17 

18 If the session is not configured with an agency, return a user error. 

19 """ 

20 

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) 

28 

29 

30class EligibleSessionRequiredMixin: 

31 """Mixin intended for use with a class-based view as the first in the MRO. 

32 

33 If the session is not marked as eligible (e.g. the user has verified their eligibility), return a user error. 

34 """ 

35 

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) 

42 

43 

44class FlowSessionRequiredMixin: 

45 """Mixin intended for use with a class-based view as the first in the MRO. 

46 

47 Gets the current `EnrollmentFlow` out of session and sets an attribute on `self`. 

48 

49 If the session is not configured with a flow, return a user error. 

50 """ 

51 

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) 

60 

61 

62class PageViewMixin: 

63 """ 

64 Mixin sends an analytics event for page views. 

65 """ 

66 

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) 

75 

76 

77class RecaptchaEnabledMixin: 

78 """Mixin intended for use with a class-based view as the first in the MRO. 

79 

80 Configures the request with required reCAPTCHA settings.""" 

81 

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)