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

42 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-02-13 19:35 +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 

8 

9from benefits.core import models 

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

11from benefits.routes import routes 

12 

13 

14class InPersonEligibilityForm(forms.Form): 

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

16 

17 action_url = routes.IN_PERSON_ELIGIBILITY 

18 id = "form-flow-selection" 

19 method = "POST" 

20 

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

22 

23 cancel_url = routes.ADMIN_INDEX 

24 

25 flow_field_error_message = "Choose an eligibility type" 

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

27 

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

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

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

31 

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

33 flow_field = self.fields["flow"] 

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

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

36 

37 # dynamically add a BooleanField for each flow 

38 for flow in flows: 

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

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

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

42 label=self.get_policy_details(flow), 

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

44 ) 

45 field = self.fields[field_id] 

46 field.hide = True 

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

48 

49 self.use_custom_validity = True 

50 

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

52 try: 

53 eligibility_context = flow.in_person_eligibility_context 

54 except KeyError: 

55 eligibility_context = None 

56 

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

58 

59 def clean(self): 

60 cleaned_data = super().clean() 

61 

62 flow_field_name = "flow" 

63 selected_flow = cleaned_data.get(flow_field_name) 

64 

65 if not selected_flow: 

66 self.add_error(flow_field_name, self.flow_field_error_message) 

67 else: 

68 verified_field_name = f"verified_{selected_flow}" 

69 verified = cleaned_data.get(verified_field_name) 

70 if not verified: 

71 self.add_error(verified_field_name, self.verified_field_error_message)