Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix unexpected issued_at behavior when date field empty. #4849

Conversation

coalest
Copy link
Collaborator

@coalest coalest commented Dec 12, 2024

Resolves #4313

Description

Previously we had two callbacks on these models with an issued_at field. These before_save and before_create callbacks set the value for issued_at to be based on created_at if issued_at was missing. This prevented records from being saved with no issue date. But it causes the unexpected behavior mentioned in the issue when creating or updating a donation/purchase/distribution with an empty issued_at field, silently changing the issued_at date to something potentially incorrect.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

Added new request and service specs.

Screenshots

These date times are still filled in automatically with default values like before. The difference is that if a user manually deletes the date, an error will be shown like our other validation errors.
image

@coalest coalest force-pushed the 4313-bug-you-can-enter-an-issued_at-date-without-a-time-hijinks-ensue branch from 30510be to 5507b87 Compare December 12, 2024 17:27
Previously before_save and before_create callbacks set the value for issued_at
created_at end of day if no datetime was provided. This prevented records being
saved with no issue date. But it caused unexpected behavior when creating or
updating a donation/purchase/distribution with an empty issued_at field,
silently changing the issued_at date to something potentially incorrect.
@coalest coalest force-pushed the 4313-bug-you-can-enter-an-issued_at-date-without-a-time-hijinks-ensue branch from 5507b87 to 9f306ac Compare December 12, 2024 17:30
def issued_at_cannot_be_before_2000
if issued_at.present? && issued_at < Date.new(2000, 1, 1)
errors.add(:issued_at, "Cannot be before 2000")
errors.add(:issued_at, "cannot be before 2000")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Purely cosmetic change.

Error message before: "Issue date Cannot be before 2000"
Error message after: "Issue date cannot be before 2000"

@coalest
Copy link
Collaborator Author

coalest commented Dec 12, 2024

Pushed another commit that seems unrelated, but is kinda related. If you edit a distribution and the validation fails, the partner dropdown gets messed up.

Screenshot from 2024-12-12 18-34-29

(Yes and No appear as only options instead of partner names)

@coalest coalest requested a review from dorner December 12, 2024 17:51
@cielf
Copy link
Collaborator

cielf commented Dec 12, 2024

Hey @coalest -- as a matter of course, I'd prefer if you kept the changes on a PR tight to the issue you have claimed on a go-forward basis. Thanks. (It just makes the testing simpler)

@cielf
Copy link
Collaborator

cielf commented Dec 13, 2024

Well, this prevents the issue, so LGTM. Over to @dorner. (though, noting that there are conficts to be resolved)

@coalest
Copy link
Collaborator Author

coalest commented Dec 13, 2024

Fixed the merge confict, so ready for review again

@cielf
Copy link
Collaborator

cielf commented Dec 14, 2024

Still LGTM

app/views/distributions/edit.html.erb Show resolved Hide resolved
@@ -18,6 +18,7 @@
organization_name: organization.id,
distribution: {
partner_id: partner.id,
issued_at: Date.yesterday,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need these specifications when you added it to the factory already?

Or should yesterday be the default?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I added values to the factories so creating these records will always have an issued_at field, but here these are parameters for a request. If I omit this parameter we are trying to create a distribution with no issued_at field which is now invalid after these changes.

When you go to create a new distribution (although same for purchase/donation), a default value for issued_at is displayed. I could add a default value for issued_at in the controller, but then we are in a similar place as before (someone emptying the field, clicking save, and unexpected behavior occurring).

If someone decides to empty the issue date field, I think it would be better to respond with a validation error and make them put in a date. But that's just an assumption on my part based on the issue description, so I can change if you think coercing missing issue dates into a default would be better.

The date yesterday is arbitrary here, it could be any valid date/time.

@@ -211,8 +211,9 @@
describe "POST #create" do
let!(:storage_location) { create(:storage_location, organization: organization) }
let!(:partner) { create(:partner, organization: organization) }
let(:issued_at) { Time.current }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ditto here - we shouldn't need to specify this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Same as above. These are params for the request. issued_at now must be present. Unless we decide to coerce blank values into a default date/time. But if we do I think we need to communicate that to the user somehow.

@coalest
Copy link
Collaborator Author

coalest commented Dec 16, 2024

@dorner By the way, is there any danger here in regards to event sourcing. Since this is a new validation that didn't exist for old events, is it possible that we might have past events with a nil value for issued_at, and trying to replay those events to build the current state would then trigger a validation error if validate is set to true?

@coalest coalest requested a review from dorner December 16, 2024 11:34
@coalest
Copy link
Collaborator Author

coalest commented Dec 16, 2024

@dorner Re-requesting a review. I didn't make any changes, just replied to your comments. Hopefully you have enough context now

@dorner
Copy link
Collaborator

dorner commented Dec 18, 2024

Thanks for the clarifications!

@dorner dorner merged commit 9811a97 into rubyforgood:main Dec 18, 2024
11 checks passed
Copy link
Contributor

@coalest: Your PR Fix unexpected issued_at behavior when date field empty. is part of today's Human Essentials production release: 2024.12.22.
Thank you very much for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] You can enter an issued_at date without a time. Hijinks ensue.
3 participants