Coverage for benefits/in_person/forms.py: 100%

42 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-13 23:09 +0000

1""" 

2The in-person eligibility application: Form definition for the 

3in-person eligibility verification flow, in which a 

4transit agency employee manually verifies a rider's eligibility. 

5""" 

6 

7from django import forms 

8from benefits.routes import routes 

9from benefits.core import models 

10from benefits.enrollment.forms import CardTokenizeFailForm, CardTokenizeSuccessForm # noqa 

11 

12 

13class InPersonEligibilityForm(forms.Form): 

14 """Form to capture eligibility for in-person verification flow selection.""" 

15 

16 action_url = routes.IN_PERSON_ELIGIBILITY 

17 id = "form-flow-selection" 

18 method = "POST" 

19 

20 flow = forms.ChoiceField(label="Choose an eligibility type to qualify this rider.", widget=forms.widgets.RadioSelect) 

21 

22 cancel_url = routes.ADMIN_INDEX 

23 

24 flow_field_error_message = "Choose an eligibility type" 

25 verified_field_error_message = "Check the box to verify you have confirmed eligibility" 

26 

27 def __init__(self, agency: models.TransitAgency, *args, **kwargs): 

28 super().__init__(*args, **kwargs) 

29 flows = agency.enrollment_flows.filter(supported_enrollment_methods__contains=models.EnrollmentMethods.IN_PERSON) 

30 

31 self.classes = "in-person-eligibility-form" 

32 flow_field = self.fields["flow"] 

33 flow_field.choices = [(f.id, f.label) for f in flows] 

34 flow_field.widget.attrs.update({"data-custom-validity": self.flow_field_error_message}) 

35 

36 # dynamically add a BooleanField for each flow 

37 for flow in flows: 

38 field_id = f"verified_{flow.id}" 

39 self.fields[field_id] = forms.BooleanField( 

40 required=False, # `clean()` will handle requiring the specific field 

41 label=self.get_policy_details(flow), 

42 widget=forms.widgets.CheckboxInput(attrs={"class": "d-none"}), # start out hidden 

43 ) 

44 field = self.fields[field_id] 

45 field.hide = True 

46 field.widget.attrs.update({"data-custom-validity": self.verified_field_error_message}) 

47 

48 self.use_custom_validity = True 

49 

50 def get_policy_details(self, flow: models.EnrollmentFlow): 

51 try: 

52 eligibility_context = flow.in_person_eligibility_context 

53 except KeyError: 

54 eligibility_context = None 

55 

56 return eligibility_context["policy_details"] if eligibility_context else None 

57 

58 def clean(self): 

59 cleaned_data = super().clean() 

60 

61 flow_field_name = "flow" 

62 selected_flow = cleaned_data.get(flow_field_name) 

63 

64 if not selected_flow: 

65 self.add_error(flow_field_name, self.flow_field_error_message) 

66 else: 

67 verified_field_name = f"verified_{selected_flow}" 

68 verified = cleaned_data.get(verified_field_name) 

69 if not verified: 

70 self.add_error(verified_field_name, self.verified_field_error_message)