Skip to content

Commit

Permalink
feat(migration): enforce that in-person flows have an eligibility policy
Browse files Browse the repository at this point in the history
data migration handles removing "in_person" from flows that do not have
a policy in the `in_person.context.eligibility_index` dict.

`EnrollmentFlow.clean` handles enforcing this rule going forward when
creating or editing flows.
  • Loading branch information
angela-tran committed Feb 21, 2025
1 parent 87f9644 commit d27a53e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
23 changes: 23 additions & 0 deletions benefits/core/migrations/0036_in_person_enrollmentflows.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("core", "0035_enrollmentflow_system_name_choices"),
]

def migrate_in_person_flows(apps, schema_editor):
EnrollmentFlow = apps.get_model("core", "EnrollmentFlow")
for flow in EnrollmentFlow.objects.all():
in_person = "in_person" # value of EnrollmentMethods.IN_PERSON as of this migration
if in_person in flow.supported_enrollment_methods:
if flow.system_name not in [
"senior",
"medicare",
"courtesy_card",
]: # the keys in `in_person.context.eligibility_index` as of this migration
flow.supported_enrollment_methods.remove(in_person)
flow.save()

operations = [migrations.RunPython(migrate_in_person_flows)]
17 changes: 13 additions & 4 deletions benefits/core/models/enrollment.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def in_person_eligibility_context(self):
return in_person_context.eligibility_index[self.system_name].dict()

def clean(self):
template_errors = []
errors = []

if self.transit_agency:
templates = [
Expand All @@ -281,10 +281,19 @@ def clean(self):
# so just create directly for a missing template
for t in templates:
if not template_path(t):
template_errors.append(ValidationError(f"Template not found: {t}"))
errors.append(ValidationError(f"Template not found: {t}"))

if template_errors:
raise ValidationError(template_errors)
if EnrollmentMethods.IN_PERSON in self.supported_enrollment_methods:
try:
in_person_eligibility_context = self.in_person_eligibility_context
except KeyError:
in_person_eligibility_context = None

if not in_person_eligibility_context:
errors.append(ValidationError(f"In-person eligibility context not found for: {self.system_name}"))

if errors:
raise ValidationError(errors)

def eligibility_form_instance(self, *args, **kwargs):
"""Return an instance of this flow's EligibilityForm, or None."""
Expand Down
10 changes: 10 additions & 0 deletions tests/pytest/core/models/test_enrollment.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,16 @@ def test_EnrollmentFlow_clean_templates(model_EnrollmentFlow_with_scope_and_clai
model_EnrollmentFlow_with_scope_and_claim.clean()


@pytest.mark.django_db
def test_EnrollmentFlow_clean_in_person_eligibility_context_not_found(model_EnrollmentFlow):
model_EnrollmentFlow.system_name = "nonexistent_system_name"

with pytest.raises(
ValidationError, match=f"In-person eligibility context not found for: {model_EnrollmentFlow.system_name}"
):
model_EnrollmentFlow.clean()


@pytest.mark.django_db
def test_EnrollmentEvent_create(model_TransitAgency, model_EnrollmentFlow):
ts = timezone.now()
Expand Down

0 comments on commit d27a53e

Please sign in to comment.