-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Rails 8: Make test helpers work with deferred routes #5695
base: main
Are you sure you want to change the base?
Conversation
Closing, as the original issue is not an issue any more. |
Reopening, as the issue reappeared on the latest Rails main. |
Sorry for the ping @gmcgibbon, mentioning you just in case you recommend a better fix. |
Ideally, we shouldn't need to load routes manually with the latest approach. There's no stacktrace in the issue. Please provide one and I'll see what I can do. |
Ok, I have updated the issue with the fullest backtrace I could produce. |
Here is my understanding of what the problem is. With deferred route drawing, routes are lazy loaded for Rails environments that have Basically by default for the test environment, whenever a route is visited, routes get lazy loaded. Devise's mappings aren't loaded when the test starts, they are only loaded when the test visits a route, because Devise's entry point is defined in the route files with devise_for or devise_scope. But in integration and controller tests you typically call the Devise This seems like a particular case that is very specific to Devise. I don't think many gems define their helper methods on route load. |
Yeah it is basically that devise/lib/devise/rails/routes.rb Line 243 in a259ff3
devise/lib/devise/test/controller_helpers.rb Lines 7 to 8 in a259ff3
I think it makes sense to move the mapping management to the route set, or to add a route load line to Line 35 in a259ff3
|
I think we need to consider both controller tests and integration tests because devise/lib/devise/test/integration_helpers.rb Lines 4 to 14 in a259ff3
And as shown in the attached issue, the test fails for an
This PR implements your second suggestion as a quick/easy fix Otherwise your first suggestion is to move the mapping management to the route set, but I am not familiar with this part and it seems like a more involved fix/refactor for Devise. But if this is the preferred way, it's all good if someone else wants to make a new PR. |
716543f
to
d809745
Compare
Update: I have changed this PR to use the public |
d809745
to
ff77889
Compare
I can't comment on the implementation, but as a datapoint - applying this patch locally fixed test our suite regressions after upgrading to rails 8.0.0.beta1 👍 |
|
Yes, the first call to
Maybe they need load paths after all. Global search results of |
I had to do the similar patch locally: ` def sign_out(resource_or_scope) Devise::Test::ControllerHelpers.prepend(DeviseHelpersPatch) |
@jeromedalbert thank you for the PR! Even though it makes sense to call Line 50 in 0f514f1
Devise.mappings directly (for any reason))
So I was thinking about something like https://github.com/heartcombo/devise/compare/lazy-routes-fix This approach covers all possible scenarios where |
@nashby Thanks for looking into this! Sounds good to me. I have tested your branch on a local Rails app and Devise test helpers like |
Fixes #5705.
Notes:
sign_in
andsign_out
controller and integration test helpers all callDevise::Mapping.find_scope!
, so that method seemed like a good place to lazy load routes if they were not already loaded.try
to keep backwards compatibility sincereload_routes_unless_loaded
only exists in Rails 8.