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

44 statements  

« prev     ^ index     » next       coverage.py v7.15.0, created at 2026-07-07 00:01 +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 dataclasses import dataclass 

8 

9from django import forms 

10 

11from benefits.core import models 

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

13from benefits.routes import routes 

14 

15 

16@dataclass 

17class EligibilityPolicy: 

18 details: str 

19 

20 

21class InPersonEligibilityForm(forms.Form): 

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

23 

24 action_url = routes.IN_PERSON_ELIGIBILITY 

25 id = "form-flow-selection" 

26 method = "POST" 

27 

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

29 

30 cancel_url = routes.ADMIN_INDEX 

31 

32 flow_field_error_message = "Choose an eligibility type" 

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

34 

35 eligibility_policies = { 

36 models.SystemName.COURTESY_CARD.value: EligibilityPolicy( 

37 details="I confirmed this rider’s identity using a government-issued ID and verified they possess an MST " 

38 "Courtesy Card." 

39 ), 

40 models.SystemName.MEDICARE.value: EligibilityPolicy( 

41 details="I confirmed this rider’s identity using a government-issued ID and verified they possess a valid " 

42 "Medicare card." 

43 ), 

44 models.SystemName.OLDER_ADULT.value: EligibilityPolicy( 

45 details="I confirmed this rider’s identity using a government-issued ID and verified they are age 65 or older." 

46 ), 

47 models.SystemName.REDUCED_FARE_MOBILITY_ID.value: EligibilityPolicy( 

48 details="I confirmed this rider’s identity using a government-issued ID and verified they possess an SBMTD " 

49 "Reduced Fare Mobility ID." 

50 ), 

51 models.SystemName.GCTD_CARD.value: EligibilityPolicy( 

52 details="I confirmed this rider’s identity using a government-issued ID and verified they possess a GCTD Reduced " 

53 " Fare ID." 

54 ), 

55 } 

56 

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

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

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

60 

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

62 flow_field = self.fields["flow"] 

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

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

65 

66 # dynamically add a BooleanField for each flow 

67 for flow in flows: 

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

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

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

71 label=self.get_policy_details(flow), 

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

73 ) 

74 field = self.fields[field_id] 

75 field.hide = True 

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

77 

78 self.use_custom_validity = True 

79 

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

81 policy = self.eligibility_policies.get(flow.system_name, None) 

82 return policy.details if policy else None 

83 

84 def clean(self): 

85 cleaned_data = super().clean() 

86 

87 flow_field_name = "flow" 

88 selected_flow = cleaned_data.get(flow_field_name) 

89 

90 if not selected_flow: 

91 self.add_error(flow_field_name, self.flow_field_error_message) 

92 else: 

93 verified_field_name = f"verified_{selected_flow}" 

94 verified = cleaned_data.get(verified_field_name) 

95 if not verified: 

96 self.add_error(verified_field_name, self.verified_field_error_message)