Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Refactor: field defaults, optional fields, templates #2471

Merged
merged 13 commits into from
Dec 2, 2024

Conversation

thekaveman
Copy link
Member

@thekaveman thekaveman commented Oct 22, 2024

This PR is another step along the way of making it easier and faster to configure new TransitAgency and EnrollmentFlow instances, while also ensuring a valid configuration for instances that are going live on the app.

Changes

TransitAgency

  • Make the slug field a Django SlugField to enforce the slugness; this field is now used to calculate template paths as well
  • Make all Eligibility API fields, Transit Processor API fields optional
  • Defaults for info fields e.g. long_name, phone from CST defaults
  • Calculate sane defaults for templates from the slug following our established pattern, e.g. core/index--{slug}.html and eligibility/index--{slug}.html
  • Retain ability to override templates if needed
  • Setting active=True and saving validates some fields (e.g. info fields, templates must exist, all associated flows must be valid)
  • Removes a field that was moved to EnrollmentFlow and no longer needed on TransitAgency

EnrollmentFlow

  • Make the system_name field a Django SlugField to enforce slugness; this field is now used to calculate template paths as well
  • Make all template fields optional
  • Calculate sane defaults for templates from the system_name or slug following our established pattern, e.g. eligibility/start--{system_name}.html and enrollment/success--{slug}.html
  • Remove the specific name of the agency card from templates, like courtesy-card
  • Calculate defaults specific to Agency Card flows establishing a new pattern, e.g. eligibility/start--{slug}-agency-card.html
  • Retain ability to override templates if needed
  • When the EnrollmentFlow has an active TransitAgency, saving validates that templates exist and that either claims verification or Eligibility API verification is configured correctly.

Reviewing

  1. Check out this branch locally
  2. Delete your database
  3. Run bin/reset_db.sh with default fixtures
  4. Launch the app
  5. Run through various flows, ensure no regressions
  6. # to the Admin
  7. Verify that new TransitAgency instances can be created with only the slug field provided
  8. Verify that saving an active TransitAgency requires certain info fields to have values
  9. Verify that saving an active TransitAgency requires templates to exist, and the defaults are calculated from the slug
  10. Verify that saving an active TransitAgency requires all of its associated EnrollmentFlows to be valid.
  11. Verify that saving an EnrollmentFlow with an active TransitAgency requires a valid claims or Eligibility API verification configuration.
  12. Verify that saving an EnrollmentFlow with an active TransitAgency requires templates to exist, and defaults are calculated from the system_name or TransitAgency.slug.

@github-actions github-actions bot added front-end HTML/CSS/JavaScript and Django templates back-end Django views, sessions, middleware, models, migrations etc. deployment-dev [auto] Changes that will trigger a deploy if merged to dev migrations [auto] Review for potential model changes/needed data migrations updates tests Related to automated testing (unit, UI, integration, etc.) and removed deployment-dev [auto] Changes that will trigger a deploy if merged to dev labels Oct 22, 2024
Copy link

github-actions bot commented Oct 22, 2024

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  benefits/core
  admin.py
  context_processors.py
  models.py
  benefits/enrollment
  views.py
Project Total  

This report was generated by python-coverage-comment-action

@thekaveman thekaveman added the deployment-dev [auto] Changes that will trigger a deploy if merged to dev label Oct 22, 2024
@thekaveman thekaveman self-assigned this Oct 22, 2024
@thekaveman thekaveman force-pushed the refactor/field-defaults branch from c14e109 to 8d1cd32 Compare October 29, 2024 15:11
@thekaveman thekaveman marked this pull request as ready for review October 29, 2024 15:11
@thekaveman thekaveman requested a review from a team as a code owner October 29, 2024 15:11
@thekaveman thekaveman marked this pull request as draft October 29, 2024 15:23
@thekaveman thekaveman force-pushed the refactor/field-defaults branch 2 times, most recently from a088943 to 54b2042 Compare October 29, 2024 15:30
@thekaveman thekaveman marked this pull request as ready for review October 29, 2024 15:40
@thekaveman thekaveman marked this pull request as draft October 29, 2024 18:22
@thekaveman thekaveman force-pushed the refactor/field-defaults branch 4 times, most recently from 56165d4 to 6012bff Compare November 6, 2024 00:44
@thekaveman thekaveman force-pushed the refactor/field-defaults branch 2 times, most recently from 321538f to 7759cc7 Compare November 12, 2024 23:16
@thekaveman thekaveman changed the base branch from main to feat/admin-agency-logos November 12, 2024 23:17
@lalver1 lalver1 force-pushed the feat/admin-agency-logos branch 5 times, most recently from 6f4337f to e255665 Compare November 14, 2024 21:52
Copy link
Member

@angela-tran angela-tran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of nice refactors in this PR @thekaveman!

I thought these were really great changes:

  • removing null=True for fields where it was not truly needed and default empty string worked just as well / is better
  • making more fields optional (basically allowing for saving an empty, inactive object that can be filled out later)
  • fixing things like group_id and label not allowing blank

I have two pieces of feedback:

  • a requested change for the default values for TransitAgency's info fields
  • a question on validation behavior

Let me know if you want to talk through any of these. Thanks!

benefits/core/models.py Outdated Show resolved Hide resolved
benefits/core/models.py Outdated Show resolved Hide resolved
benefits/core/models.py Show resolved Hide resolved
benefits/eligibility/verify.py Show resolved Hide resolved
benefits/core/models.py Show resolved Hide resolved
benefits/core/models.py Show resolved Hide resolved
@thekaveman thekaveman force-pushed the refactor/field-defaults branch from dfe4ab9 to 034bcaf Compare November 26, 2024 22:37
@thekaveman thekaveman force-pushed the refactor/field-defaults branch from 034bcaf to 6f0ed51 Compare November 27, 2024 02:06
@thekaveman
Copy link
Member Author

thekaveman commented Nov 27, 2024

Rebased with new commit a8c40bb to address @angela-tran's comments: #2471 (comment)

TransitAgency.clean() calls clean() on each of its EnrollmentFlow, catches any ValidationError, and rethrows with a message indicating an invalid flow.

This makes it less likely that an agency could go live with a misconfigured flow.

Thanks for continuing to push on this one Angela, I think this is definitely the better outcome.

Test this scenario

  1. Login to the Admin
  2. Create a TransitAgency with all fields necessary to be active=True, but don't make it active yet. Save.
  3. Create an EnrollmentFlow with only a claims_provider; select the TransitAgency from above. Save.
  4. Go back to the TransitAgency and check to make it active=True. Save.
  5. 💥

- compute template fields by default
- allow overriding templates
- compute some template fields by default
- allow overriding templates
further simplify template requirements for flows

rename agency card templates into standard naming pattern:

  {prefix}--{agency.slug}--agency-card.html

where {prefix} is e.g. eligibility/start or enrollment/success
when active=True, validate that:

- there are values for user-facing info fields like names, logos, phone, etc.
- transit processor is configured correctly, if any
- templates exist
when the flow's agency.active=True, validate that templates exist

consolidate other EnrollmentFlow.clean() tests
change default to empty string

these are stored as the empty string when blank=True
Django recommends against null=True on TextFields: https://docs.djangoproject.com/en/5.1/ref/models/fields/#null
keep track of all field and template errors separately

raise a ValidationError from either when present
this field is now captured on EnrollmentFlow with the other
Eligibility API fields
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
@thekaveman thekaveman force-pushed the refactor/field-defaults branch from 6f0ed51 to a8c40bb Compare November 27, 2024 02:12
@lalver1
Copy link
Member

lalver1 commented Dec 2, 2024

I really like these latest changes where TransitAgency.clean() calls clean() on each of its EnrollmentFlow 👍
One thing I'm wondering is, if we should remove and self.transit_agency.active from

if self.transit_agency and self.transit_agency.active:

so that the user can still see the particular validation errors when an EnrollmentFlow is being configured.

Following the testing steps, the validity of an EnrollmentFlow is only checked when setting a TransitAgency to active and attempting to save, and if there is an error, the message is only that the flow is invalid. So then we would go back to the flow, but we'd have no hint of what is invalid on the flow since the TransitAgency is inactive (because we were not allowed to activate it from the previous step) and the field and template validations are not ran because of the condition referenced above.

The only downside I guess of making this change is that if the EnrollmentFlow is associated with a TransitAgency, the user needs to have all the information for an EnrollmentFlow before being able to save it, regardless of the active status of the TransitAgency. But maybe this isn't too bad since if you can choose to not associate a TransitAgency with an EnrollmentFlow, and this would allow you to temporarily save an EnrollmentFlow that is not completely configured yet.

@thekaveman
Copy link
Member Author

Ahh @lalver1 that's a really good point!! 😭

Yes, I agree with you -- I'm going to update that commit one more time 🤞

whether or not the agency is marked as Active

since TransitAgency.clean() will call .clean() on each of its EnrollmentFlows
and raise a generic error, we want to be able to see the specific problem
on the EnrollmentFlow if any
@thekaveman
Copy link
Member Author

@lalver1 great suggestion! b48b7ac

@angela-tran
Copy link
Member

Agreed, great suggestion @lalver1! It makes the scenario described in #2471 (comment), where invalid flows are linked to transit agencies, pretty much impossible, which is great!

Copy link
Member

@angela-tran angela-tran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work on all this @thekaveman!

Copy link
Member

@lalver1 lalver1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great @thekaveman and @angela-tran!

@thekaveman thekaveman merged commit 8299355 into main Dec 2, 2024
14 checks passed
@thekaveman thekaveman deleted the refactor/field-defaults branch December 2, 2024 18:02
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
back-end Django views, sessions, middleware, models, migrations etc. deployment-dev [auto] Changes that will trigger a deploy if merged to dev front-end HTML/CSS/JavaScript and Django templates migrations [auto] Review for potential model changes/needed data migrations updates tests Related to automated testing (unit, UI, integration, etc.)
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants