Skip to content

Devise in test environment: mapping.to.serialize_from_session gives error "wrong number of arguments (given 10, expected 2)" #5752

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

Open
dianedouglas-thrive opened this issue Jan 7, 2025 · 3 comments

Comments

@dianedouglas-thrive
Copy link

Environment

  • Ruby [3.3.6]
  • Rails [8.0.0]
  • Devise [4.9.4]

Current behavior

I just updated my app to rails 8 with the newest version of Devise and hotwire turbo. When running tests with Capybara/Rspec I'm seeing certain form submissions fail with a 500 error from inside of Devise. This behavior seems to be only in the test environment.

lib/devise.rb:496

  # A method used internally to complete the setup of warden manager after routes are loaded.
  # See lib/devise/rails/routes.rb - ActionDispatch::Routing::RouteSet#finalize_with_devise!
  def self.configure_warden! #:nodoc:
    @@warden_configured ||= begin
      warden_config.failure_app   = Devise::Delegator.new
      warden_config.default_scope = Devise.default_scope
      warden_config.intercept_401 = false

      Devise.mappings.each_value do |mapping|
        warden_config.scope_defaults mapping.name, strategies: mapping.strategies

        warden_config.serialize_into_session(mapping.name) do |record|
          mapping.to.serialize_into_session(record)
        end

        warden_config.serialize_from_session(mapping.name) do |args|
          mapping.to.serialize_from_session(*args)
        end
      end

      @@warden_config_blocks.map { |block| block.call Devise.warden_config }
      true
    end
  end

When mapping.to.serialize_from_session(*args) is called I get the error "wrong number of arguments (given 10, expected 2)".

I have not been able to find a pattern between tests that pass and tests that cause this behavior except that I can see the data is different.

On a passing test args looks like this:

[1] pry(#<Warden::SessionSerializer>)>  args
=> [[1], "$2a$04$yPg9CBmwVeIZc3VYqdmL3O"]

But on a failing test args looks like this:

[1] pry(#<Warden::SessionSerializer>)> args
=> {"id"=>27,
 "email"=>"[email protected]",
 "created_at"=>"2000-01-01T05:00:03.000Z",
 "updated_at"=>"2000-01-01T05:00:19.000Z",
 "client_id"=>18,
 "role"=>"coordinator",
 "authentication_token"=>"pxcFTApxeyCo1evMNd9X",
 "first_name"=>"User12",
 "last_name"=>"Name",
 "analytics_enabled"=>false}

What could be causing this? Looks like a hash composed of a full user record instead of just an id and token.

I understand there have been issues with Devise.mapping with the newest version of rails, I've tried adding in the recommended initializer file from here, but it had no effect:

#5728 (comment)

@aiomaster
Copy link

It seems that while the test is running, devise hasn't configured its warden stuff, yet.
That should be done while finalizing the route set:

Devise.configure_warden!

Obviously the patch from #5728 isn't enough to make it work in system tests.

If you want to use a quick workaround do something like that in your spec/spec_helper.rb:

RSpec.configure do |config|
  config.before(:each, type: :system) do
      Rails.application.try(:reload_routes_unless_loaded)
  end
end

@tomash
Copy link

tomash commented Feb 18, 2025

Also hurt by this.
What's funny is that when I run the entire test suite it's all green. But when I do rspec spec/controllers/ANYTHING, the first controller test fails with that deserialization exception.

The workaround in previous comment works:

  config.before(:each, type: :controller) do
      Rails.application.try(:reload_routes_unless_loaded)
  end

Rails 8.0.1, Devise 4.9.4, Ruby 3.4.1.

@benbonnet
Copy link

wow... spent hours troubleshooting that one.

indeed solves the issue.

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

No branches or pull requests

4 participants