Skip to content

Commit

Permalink
fix(models): invert clean, catch and rethrow ValidationError
Browse files Browse the repository at this point in the history
TransitAgency cleans all of its associated EnrollmentFlows, to ensure
that an agency doesn't go live with partially configured flows

since TransitAgency won't have fields from EnrollmentFlow,
any ValidationError that bubbles would raise a new error in Django Admin

instead, catch and rethrow a ValidationError indicating the problem flow
  • Loading branch information
thekaveman committed Nov 27, 2024
1 parent bfde2e5 commit 6f0ed51
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
8 changes: 6 additions & 2 deletions benefits/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ def clean(self):
template_errors = []

if self.active:
for flow in self.enrollment_flows.all():
try:
flow.clean()
except ValidationError:
raise ValidationError(f"Invalid EnrollmentFlow: {flow.label}")

message = "This field is required for active transit agencies."
needed = dict(
short_name=self.short_name,
Expand Down Expand Up @@ -625,8 +631,6 @@ def clean(self):
field_errors.update(reenrollment_error_template=ValidationError("Required when supports expiration is True."))

if self.transit_agency and self.transit_agency.active:
self.transit_agency.clean()

if self.claims_provider:
message = "Required for claims verification."
needed = dict(
Expand Down
12 changes: 12 additions & 0 deletions tests/pytest/core/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,18 @@ def test_TransitAgency_clean_templates(model_TransitAgency_inactive, template_at
model_TransitAgency_inactive.clean()


@pytest.mark.django_db
def test_TransitAgency_clean_dirty_flow(model_TransitAgency, model_EnrollmentFlow, model_ClaimsProvider):
# partially setup the EnrollmentFlow
# missing scope and claims
model_EnrollmentFlow.claims_provider = model_ClaimsProvider
model_EnrollmentFlow.transit_agency = model_TransitAgency

# clean the agency, and expect an invalid EnrollmentFlow error
with pytest.raises(ValidationError, match=f"Invalid EnrollmentFlow: {model_EnrollmentFlow.label}"):
model_TransitAgency.clean()


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

0 comments on commit 6f0ed51

Please sign in to comment.