[#4922] handle invalid date ranges in date range input#5192
Conversation
* Fixed issue where tabbing into date range field and typing invalid data bypassed Litepicker validation * Updated DateRangeHelper to catch parsing errors and show flash notice instead of raising 500 * Added custom client-side check in Stimulus controller to catch bad input on blur * Introduced global isLitePickerActive flag in application.js so that custom date range controller can avoid alerting user if Litepicker is open
|
Note some system tests have been failing on CI (Ferrum unknown target exception), but all tests pass locally. |
|
Given how hard it is to recreate, I'm surprised how frequently we get them! (one or two a month) There's probably some one person who just does things this way. Thank you for sussing it out! It LGTM functionally (in a perfect world, we'd have the same behaviour no matter how they got there, but this will do IMO). Over to @dorner for technical wisdom, etc. |
dorner
left a comment
There was a problem hiding this comment.
One admin question, otherwise looks good to me.
Not sure what's going on with the system specs, but they seem to be failing consistently. We need a way to fix them if we want this merged.
| def filter_button(options = {}, data = {}) | ||
| _button_to( | ||
| { icon: "filter", type: "primary", text: "Filter", size: "md" }.merge(options), | ||
| { data: { test_id: "filter-button" }.merge(data) } |
There was a problem hiding this comment.
Was this added by accident? I don't see it used.
There was a problem hiding this comment.
This adds a data-test-id to the filter button which is used in the shared example system spec:
page.execute_script("document.querySelector('[data-test-id=\"filter-button\"]').click();")Normally would simply use the Capybara click method with text "Filter", but due to event handling required to reproduce this issue, had to use execute_script with querySelector. And there wasn't an easy way to select a button by its text. So this was to ensure that the test is clicking the correct button, in case there should be more buttons added to any of the pages in the future.
There was a problem hiding this comment.
Actually, after working through the CI failing tests, this is no longer needed, removed.
I've seen those kind of test failures on CI ( I even tried running the tests locally with the same seed that's failing on CI, in case there's a specific sequence of test execution that causes the failures: But still they pass locally. There have been some commits on |
|
Update on system tests: I temporarily commented out the new invalid date range tests, and then all the tests pass on CI: https://github.com/rubyforgood/human-essentials/actions/runs/15084551153 Will investigate... |
…gate CI failures" This reverts commit f8ccea2.
|
First failure is for the date range, so possibly something here is causing a cascade of failures: |
|
Just FYI -- we had 3 different people run into this this week. Still seems weird, but people who do a lot of data entry probably use tabs to move around more than I do. |
…ich include invalid date range testing
…hance to simulate invalid data getting to server
|
Still investigating CI test failures - unfortunately since it passes locally, need to commit a bunch of temp changes to the test to see how it fails on CI. Issue seems to be that JS runs overall slower on CI, and it's difficult to simulate exact user interaction in scenario that triggers server side validation. So when trying to simulate user submitting invalid data to server, when CI runs, the Continuing to investigate... |
…erver side validation
…nt side validation test
|
@dorner's call on that, methinks. |
|
@danielabar: Your PR |
…byforgood#5192) * [rubyforgood#4922] handle invalid date ranges in date range input * Fixed issue where tabbing into date range field and typing invalid data bypassed Litepicker validation * Updated DateRangeHelper to catch parsing errors and show flash notice instead of raising 500 * Added custom client-side check in Stimulus controller to catch bad input on blur * Introduced global isLitePickerActive flag in application.js so that custom date range controller can avoid alerting user if Litepicker is open * temporarily remove invalid date range system tests to investigate CI failures * Revert "temporarily remove invalid date range system tests to investigate CI failures" This reverts commit f8ccea2. * temp changes to investigate js timing failure for system tests on ci * remove attempt to focus tests for ci failure investigation * temp ci failure investigation - run only distribution system tests which include invalid date range testing * temp investigation for ci failure - try to get to failure quickly * investigate ci failure - attempt to submit form without js having a chance to simulate invalid data getting to server * temp ci investigation - focus only on server side validation test * more ci failure investigation - how far does it get before js alert popups up * experiment to temp disable custom js validation in test to simulate server side validation * now that server side validation test passes on ci, try also with client side validation test * try with all tests * cleanup CI test failure investigation code * remove unused data test id from filter button * document disable validation option for client side JS * consolidate all js execution in test * undo changes to rspec system workflow file
Resolves #4922
Description
Fixes the issue where under very specific circumstances, a user could enter invalid data into the date range input (used to filter many views like Donations, Purchases, etc.) and have that data submitted to the server. In this case, an error would be raised and result in 500 Server Error page.
It was difficult to reproduce because most of the time, Litepicker.js (library which is bound to the date range input) is active and has its own validation logic for date ranges, such that if something invalid is entered, it will not update the state of the input, which results in it going back to the default value when user blurs away, so their invalid data never sticks around.
But if user tabs into the date range field, then the Litepicker.js events are not registered. In this case, the user can type in whatever they want without Litepicker being aware of it. Then if user hits Enter, the invalid date range will be submitted to the server. Server side logic was raising an error in this case. This has been fixed to gracefully handle it with a flash notice. See
app/helpers/date_range_helper.rb.Also, if a user tabs or clicks away from the date range field (after having tabbed in and entered invalid data), then some new client side JS has been added to alert them. See
app/javascript/controllers/date_range_controller.jsType of change
How Has This Been Tested?
For automated testing, the shared example
spec/support/date_range_picker_shared_example.rbwas modified to add cases for server and client side error handling of invalid input. This is run by all system tests that cover filtering: Transfer management, Donations, Purchases, Requests, Distributions, Adjustment management.Quick way to focus on just these:
bundle exec rspec spec/system -e "when entering an invalid date range"For manual testing:
Repeat steps 1 - 3, but then instead of hitting Enter, click or tab away (you still need to tab in to the field though) - this time an alert displays.
In either case, you can click into the date range and fix the invalid date, then submit the form and it should work.
Screenshots