Skip to content

Commit

Permalink
Fix undefined method []= in tests
Browse files Browse the repository at this point in the history
I found an entry in the Devise README which gave notice of exactly this
error happening when the Warden middleware is initialized before the
session middleware.
The solution was to explicitly define the proper order in the test
environment.
See https://github.com/heartcombo/devise#testing and
heartcombo/devise#4696.
  • Loading branch information
KyleRAnderson committed Jan 19, 2021
1 parent 9a525dd commit 89fb9b3
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
19 changes: 9 additions & 10 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,23 @@ class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.1

# API Only application. This should remain at the top
config.api_only = false # FIXME revert to true one day when the tests start working again
# API Only application. This should remain near the top (below the load_defaults of course)
# See also https://guides.rubyonrails.org/api_app.html#changing-an-existing-application for
# some of what needs to be done for api_only apps.
config.api_only = true

# See: https://github.com/rails/rails/blob/3c9d7a268f325f5cc6ab1ab49aed6f52e4c4f631/guides/source/api_app.md#using-session-middlewares.
# Add cookie middleware (included by default in non api_only applications)
# See the relevant section of https://guides.rubyonrails.org/v6.1/configuring.html#rails-general-configuration
# This also configures session_options for use below
config.session_store :cookie_store, key: '_interslice_session'
config.session_store :cookie_store

# See: https://github.com/rails/rails/blob/3c9d7a268f325f5cc6ab1ab49aed6f52e4c4f631/guides/source/api_app.md#using-session-middlewares.
# Required for all session management (regardless of session_store)
config.middleware.use ActionDispatch::Cookies
# config.session_options[:secure] = Rails.env.production? # TODO make sure that asserting this config in production.rb works with the following line.
# Enable HTTPS-only session cookies in production
config.session_options[:secure] = Rails.env.production?
config.middleware.use config.session_store, config.session_options

# Add session middleware (included by default in non api_only applications)
config.middleware.use ActionDispatch::Session::CookieStore
# TODO not sure if it's helpful, from https://stackoverflow.com/a/61238872/7309070
config.middleware.insert_after(ActionDispatch::Cookies, ActionDispatch::Session::CookieStore)

# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
Expand Down
6 changes: 6 additions & 0 deletions config/environments/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,10 @@

# Annotate rendered view with file names.
# config.action_view.annotate_rendered_view_with_filenames = true

# Solution obtained from https://github.com/heartcombo/devise#testing
# See also https://github.com/heartcombo/devise/issues/4696
# This is required because of how API mode re-orders the initialization of certain middlewares
Rails.application.config.middleware.insert_before Warden::Manager, ActionDispatch::Cookies
Rails.application.config.middleware.insert_before Warden::Manager, ActionDispatch::Session::CookieStore
end
8 changes: 8 additions & 0 deletions learning.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ Links:
- [Issue on GitHub](https://github.com/rspec/rspec-rails/issues/2439).
- [Someone else with the same issue](https://github.com/egiurleo/fixture-file-upload-test/commit/e2524d11220bb8169b42aaa5235d214ba8a1dd56).

## `Undefined method []=` after setting `config.api_only = true`

I was having trouble in all tests that used the Devise session helpers `sign_in` after enabling api_only for the application.
After several days, I found [documentation on how to fix the issue](https://github.com/heartcombo/devise#testing), as well as
a [GitHub ticket write-up about it](https://github.com/heartcombo/devise/issues/4696).
The fix is just to re-order the insertion of middleware so that the `Warden::Manager` is inserted after
`ActionDispatch::Cookies` and `ActionDispatch::Session::CookieStore`.

# Various hard to find Rails topics

[What does respond_to do?](https://api.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to)

0 comments on commit 89fb9b3

Please sign in to comment.