Skip to content

sign_in IntegrationHelper produces errors when trying to load a session #4696

Closed
@RocketPuppy

Description

Rails 5 API mode, devise cookie auth works just fine in the actual application, meaning all middleware and initializers are set up properly.

I have an ApiController that looks like this:

class ApiController < ActionController::API
end

And all my controllers inherit from it. I have multiple user scopes. The integration test helpers are set up according to the documentation:

# test/test_helper.rb

class ActionDispatch::IntegrationTest
  include Devise::Test::IntegrationHelpers
end

In a test:

class FooControllerTest < ActionDispatch::IntegrationTest
  test "should be successful" do
    sign_in CustomUser.first
    get foo_url, xhr: true, as: :json

    assert(@response.successful?) # fail
  end
end

In the response body I get this error message, implying things are failing even before they get to my controllers.

> undefined method `[]=' for nil:NilClass

actionpack (5.1.4) lib/action_dispatch/request/session.rb, line 217
-------------------------------------------------------------------


  212             load! unless loaded?
  213           end
  214
  215           def load!
  216             id, session = @by.load_session @req
> 217             options[:id] = id
  218             @delegate.replace(stringify_keys(session))
  219             @loaded = true
  220           end
  221
  222           def stringify_keys(other)


App backtrace
-------------

 - actionpack (5.1.4) lib/action_dispatch/request/session.rb:217:in `load!'
 - actionpack (5.1.4) lib/action_dispatch/request/session.rb:212:in `load_for_write!'
 - actionpack (5.1.4) lib/action_dispatch/request/session.rb:197:in `merge!'
 - actionpack (5.1.4) lib/action_dispatch/request/session.rb:17:in `create'
 - actionpack (5.1.4) lib/action_dispatch/middleware/session/abstract_store.rb:71:in `prepare_session'
 - rack (2.0.3) lib/rack/session/abstract/id.rb:231:in `context'
 - rack (2.0.3) lib/rack/session/abstract/id.rb:226:in `call'
 - actionpack (5.1.4) lib/action_dispatch/middleware/cookies.rb:613:in `call'
 - warden (1.2.7) lib/warden/manager.rb:36:in `block in call'
 - warden (1.2.7) lib/warden/manager.rb:35:in `catch'
 - warden (1.2.7) lib/warden/manager.rb:35:in `call'
 - rack (2.0.3) lib/rack/etag.rb:25:in `call'
 - rack (2.0.3) lib/rack/conditional_get.rb:25:in `call'
 - rack (2.0.3) lib/rack/head.rb:12:in `call'
 - actionpack (5.1.4) lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
 - activesupport (5.1.4) lib/active_support/callbacks.rb:97:in `run_callbacks'
 - actionpack (5.1.4) lib/action_dispatch/middleware/callbacks.rb:24:in `call'
 - better_errors (2.3.0) lib/better_errors/middleware.rb:84:in `protected_app_call'
 - better_errors (2.3.0) lib/better_errors/middleware.rb:79:in `better_errors_call'
 - better_errors (2.3.0) lib/better_errors/middleware.rb:57:in `call'
 - actionpack (5.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
 - actionpack (5.1.4) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
 - railties (5.1.4) lib/rails/rack/logger.rb:36:in `call_app'
 - railties (5.1.4) lib/rails/rack/logger.rb:24:in `block in call'
 - activesupport (5.1.4) lib/active_support/tagged_logging.rb:69:in `block in tagged'
 - activesupport (5.1.4) lib/active_support/tagged_logging.rb:26:in `tagged'
 - activesupport (5.1.4) lib/active_support/tagged_logging.rb:69:in `tagged'
 - railties (5.1.4) lib/rails/rack/logger.rb:24:in `call'
 - actionpack (5.1.4) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
 - actionpack (5.1.4) lib/action_dispatch/middleware/request_id.rb:25:in `call'
 - rack (2.0.3) lib/rack/runtime.rb:22:in `call'
 - activesupport (5.1.4) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
 - actionpack (5.1.4) lib/action_dispatch/middleware/executor.rb:12:in `call'
 - actionpack (5.1.4) lib/action_dispatch/middleware/static.rb:125:in `call'
 - rack (2.0.3) lib/rack/sendfile.rb:111:in `call'
 - rack-cors (1.0.2) lib/rack/cors.rb:97:in `call'
 - railties (5.1.4) lib/rails/engine.rb:522:in `call'
 - rack-test (0.7.0) lib/rack/mock_session.rb:30:in `request'
 - rack-test (0.7.0) lib/rack/test.rb:249:in `process_request'
 - rack-test (0.7.0) lib/rack/test.rb:125:in `request'
 - actionpack (5.1.4) lib/action_dispatch/testing/integration.rb:261:in `process'
 - actionpack (5.1.4) lib/action_dispatch/testing/integration.rb:16:in `get'
 - actionpack (5.1.4) lib/action_dispatch/testing/integration.rb:348:in `block (2 levels) in <module:Runner>'

I did some inspection of some of that code and there are a few things that seemed out of place to me.

  1. ActionDispatch::Request:Session.create includes a previous session.
def self.create(store, req, default_options)
  session_was = find req
  session     = Request::Session.new(store, req)
  session.merge! session_was if session_was

  set(req, session)
  Options.set(req, Request::Session::Options.new(store, default_options))
  session
end

If I break here I see that session_was is set, and it is attempted to merge! into the new session. This is where load! is eventually called on the new session. As an experiment I tried forcing session_was to nil. This caused the test to succeed! I imagine because it didn't try to merge in the old session, but was the old session even necessary?

  1. The newly created session in point 1 fails at load! because it doesn't have a rack.session.options header. I'm not sure why this is, but it is added in the Options.set line.

  2. If I remove the sign_in call in the test, I get to my controller code successfully.

On the whole this feels like some sort of user error on my part, but I can't seem to figure out just what the problem might be.

Activity

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

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions