Skip to content

Ill-timed Rails ActionCable requests can prevent login_as from working in tests #182

@agraves

Description

@agraves

I recognize that this issue isn't purely a Warden issue -- there are Rails and Devise interactions. That said, this was hideously difficult to track down and I think Warden is best positioned to help users. I also have a fix in mind but wanted to discuss first.

Repro

Essentially, Rails ActionCable requests can exhibit exactly the same problem you guys ran into with #45 . My repro case looks like this:

  1. Write Capybara / Selenium test that loads a React app with a web browser
  2. login_as create(:user), scope: :user
  3. Unfortunately, an ActionCable connection triggers a call to /cable. This could be caused by anything from logging in in the middle of a test, system load, test pollution, phase of the moon, etc.
  4. My ActionCable setup looks at env['warden'].user, consuming the one-time data generated by login_as
  5. The next line of my test does something basic like visit '/my_profile and is, maddeningly, not logged in.

Pseudocode

So just to be clear, the test looks like this:

login_as create(:user), scope: :user
visit '/my_profile'

But because I'm using a headless browser to run a react app, sometimes an ActionCable request hits the db before the request for /my_profile. This is hideously difficult to debug because I doubt many users have any idea how login_as works under the hood. Especially because of the way ActionCable works and acquires sessions, it tends to be very intermittent. Even with the same db seed, I'd see 1-2 tests fail every 3-4 runs on a full suite.

Fixes

  1. We can just accept that some users are gonna get screwed by this and hope that they eventually figure out that they need to do what I did, which is just to call:

Warden::Test::WardenHelpers.asset_paths=%r(/(assets/|cable)}

in their test setup. We can add something big and angry to the docs.

  1. We could just adjust the default asset_paths to match /cable. It's tricky because rails doesn't stop you from mounting ActionCable on another path, but it would probably save most users from running into this issue. There's also precedent for it.

  2. We could be smarter about how Warden behaves. Specifically, we could try to figure out when we're inside ActionCable and prevent ourselves from consuming the on_next_request trigger. I don't know how this would be done and it might risk coupling Warden and Rails. If there's a clean way to do this, that seems like it would be best -- the fundamental problem is that on_next_request is silently failing to do its real job, which is applying the cookie -- but I don't know how we would go about it.

Conclusion

Anyways, let me know what you think. Happy to help you repro it or to try implementing one of the fixes.

Metadata

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