Note that there are some explanatory texts on larger screens.

plurals
  1. PODevise+CanCan AccessDenied redirect differs between dev and test environments
    primarykey
    data
    text
    <p>I have a Rails 3.1 (RC5) app with Devise and CanCan. Both are configured well and working as expected except that when I run integration tests to ensure that AccessDenied is being redirected as desired, the redirect goes to Devise's sign in instead of the application root. I can verify in my test that the user is still logged in and can still access applicable parts of the app.</p> <p>The redirect is defined in this short controller, which the other restricted controllers inherit (instead of directly inheriting ApplicationController).</p> <pre><code>class AuthorizedController &lt; ApplicationController before_filter :authenticate_user! rescue_from CanCan::AccessDenied do |exception| redirect_to root_url, :alert =&gt; exception.message end end </code></pre> <p>The restricted controllers look like this:</p> <pre><code>class Admin::UsersController &lt; AuthorizedController load_and_authorize_resource def index @users = User.all.order('name') end ... end </code></pre> <p>I am using the default (ActionDispatch::IntegrationTest) integration test; the only additional testing gems I have are Capybara, Machinist, and Faker (no RSpec, Cucumber, etc.).</p> <p>My test looks like:</p> <pre><code>def test_user_permissions sign_in users(:user) get admin_users_path assert_response :redirect assert_redirected_to root_url end </code></pre> <p>The test fails with:</p> <pre><code>Expected response to be a redirect to &lt;http://www.example.com/&gt; but was a redirect to &lt;http://www.example.com/users/sign_in&gt; </code></pre> <p>When I test this by logging in as a restricted user in my dev environment, I am redirected to '/' as expected, but using the same type of user in the integration tests fails.</p> <p>In the integration tests, the user is not actually being logged out, although the redirect makes it look like that is happening. When I change the test to not test the redirection target and continue trying other URLs, the user is still logged in and the test passes.</p> <h2>Addendum &amp; Solution:</h2> <p>I originally did not include the sign_in method that held the key clue. Here it is:</p> <pre><code>module ActionController class IntegrationTest include Capybara::DSL def sign_in (user, password = 'Passw0rd') sign_out visit root_path fill_in 'Email', :with =&gt; user.email fill_in 'Password', :with =&gt; password click_button 'Sign in' signed_in? user end ... end end </code></pre> <p>I was mixing Capybara access methods (<code>visit</code>, <code>click_button</code>, etc.) in <code>sign_in</code> and vanilla integration test access methods (<code>get</code>, etc.) in the test. When I used Webrat (before Capybara) this mixing worked as I expected, but evidently Capybara's session state is handled separately, so access via the Capybara methods was authenticated, but access via the vanilla integration test methods was not.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload