title: Capybara, Devise, CanCan and RSpec integration tests: valid sign in 302 redirects to example.com
body: <p>Update: see end of post for how the specs now work now that I have my specs in spec/requests instead of spec/controllers. Still wondering how to get a valid signed in user for integration tests with my controllers.</p>
  
  <p>I'm working with Devise and CanCan for the first time and am having difficulty doing the most basic of integration tests whereby I'm verifying that a logged in user is...well...logged in. I have read countless posts and answers dealing with Devise and RSpec integration tests (i.e. speeding them up by accessing the session directly via <a href="https://github.com/plataformatec/devise/wiki/How-To%3a-Test-with-Capybara" rel="nofollow noreferrer">https://github.com/plataformatec/devise/wiki/How-To%3a-Test-with-Capybara</a>, <a href="http://schneems.com/post/15948562424/speed-up-capybara-tests-with-devise" rel="nofollow noreferrer">http://schneems.com/post/15948562424/speed-up-capybara-tests-with-devise</a>, and <a href="https://stackoverflow.com/questions/13174592/capybara-rspec-and-devise-any-way-to-make-integration-tests-faster-by-circumve">Capybara, RSpec and Devise: any way to make integration tests faster by circumventing slow login and setting session directly?</a>, but I have been unable to even get a standard post working as expected and I'm baffled:</p>
  
  <ol>
  <li>Development environment works fine (can log in and get redirected to proper page, with navigation login link changed to logout, etc.).</li>
  <li>test.log indicates no problems until it does a 302 redirect to <a href="http://www.example.com" rel="nofollow noreferrer">http://www.example.com</a> instead of my root_path.</li>
  </ol>
  
  <p>By the plethora of users with similar issues with varying solutions, I'm obviously not the only one who has had this problem as various aspects of the session etc. are unavailable in different scenarios.</p>
  
  <p>Stripped down test:</p>
  
  <pre><code>subject { page }
  
  describe 'should be able to log in' do
    before do
      visit '/users/sign_in'
      user = FactoryGirl.create(:admin)
      #user.add_role :admin
      fill_in 'Username', with: user.username
      fill_in 'Password', with: user.password
      click_on 'Sign in'
    end
    it { should have_link 'Logout' }
  end
  ...
  </code></pre>
  
  <p>Relevant log.test output:</p>
  
  <pre><code> Started POST "/users/sign_in" for 127.0.0.1 at 2012-11-06 17:31:10 -0800
   Processing by Devise::SessionsController#create as HTML
   Parameters: {"utf8"=&gt;"✓", "user"=&gt;{"username"=&gt;"username1", "password"=&gt;"[FILTERED]",        "remember_me"=&gt;"0"}, "commit"=&gt;"Sign in"}
   [1m[36mUser Load (0.1ms)[0m  [1mSELECT "users".* FROM "users" WHERE "users"."username" =   'username1' LIMIT 1[0m
   [1m[35m (0.0ms)[0m  SAVEPOINT active_record_1
      [1m[36m (0.0ms)[0m  [1mRELEASE SAVEPOINT active_record_1[0m
   [1m[35m (0.0ms)[0m  SAVEPOINT active_record_1
   [1m[36m (0.1ms)[0m  [1mUPDATE "users" SET "last_sign_in_at" = '2012-11-07   01:31:10.722712', "current_sign_in_at" = '2012-11-07 01:31:10.722712', "last_sign_in_ip" =   '127.0.0.1', "current_sign_in_ip" = '127.0.0.1', "sign_in_count" = 1, "updated_at" = '2012-11-  07 01:31:10.723051' WHERE "users"."id" = 1[0m
   [1m[35m (0.0ms)[0m  RELEASE SAVEPOINT active_record_1
   Redirected to http://www.example.com/
   Completed 302 Found in 12ms (ActiveRecord: 0.0ms)
  </code></pre>
  
  <p>Stripped down routes.rb:</p>
  
  <pre><code>authenticated :user do
    root :to =&gt; 'home#index'
  end
  root :to =&gt; "home#index"
  devise_for :users
  resources :users
  </code></pre>
  
  <p>Stripped down Ability:</p>
  
  <p>class Ability
       include CanCan::Ability</p>
  
  <pre><code> def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.has_role? :admin
      can :manage, :all
    end
    ...
  </code></pre>
  
  <p>And to be thorough, the current Gemfile:</p>
  
  <pre><code>source 'https://rubygems.org'
  
  gem 'rails', '3.2.8'
  gem "bootstrap-sass", "~&gt; 2.1.0.1"
  gem 'faker', '1.1.2'
  gem 'will_paginate', '~&gt; 3.0.3'
  gem 'bootstrap-will_paginate', '~&gt; 0.0.9'
  gem 'jquery-rails'
  gem 'client_side_validations'
  gem 'thin'
  gem "devise", "~&gt; 2.1.2"
  gem "cancan", "~&gt; 1.6.8"
  gem "rolify", "~&gt; 3.2.0"
  gem "simple_form", "~&gt; 2.0.4"
  
  group :assets do
     gem 'sass-rails',   '~&gt; 3.2.3'
     gem 'coffee-rails', '~&gt; 3.2.1'
     gem 'uglifier', '&gt;= 1.0.3'
  end
  
  group :development, :test do
   gem 'sqlite3', '1.3.5'
   gem "rspec-rails", "~&gt; 2.11.4"
   gem 'guard-rspec', '1.2.1'
   #gem 'listen', github: 'guard/listen', branch: 'polling/double'
   gem 'guard-spork'
   gem 'guard-cucumber'
   gem 'spork', '0.9.2'
   gem "factory_girl_rails", "&gt;= 4.1.0"
  end
  
  group :development do
    gem 'annotate', '2.5.0'
    gem "quiet_assets", "&gt;= 1.0.1"
  end
  
   group :test do
    gem 'capybara', "&gt;= 1.1.2"
   gem "email_spec", "&gt;= 1.2.1"
   gem "cucumber-rails", "&gt;= 1.3.0", :require =&gt; false
   gem "database_cleaner", "&gt;= 0.9.1"
   gem "launchy", "&gt;= 2.1.2"
   gem 'rb-fsevent', '0.9.1', :require =&gt; false
   gem 'growl', '1.0.3'
   gem 'terminal-notifier-guard'
  end
  
  group :production do
      gem 'pg', '0.12.2'
   end
  </code></pre>
  
  <p>There's another user who had issues with this basic task, but it turned out it was simply a syntax error (see <a href="https://stackoverflow.com/questions/11320483/login-integration-test-with-rspec-devise">Login integration test with rspec/devise</a>) so I'm sure I'm just missing something very obvious.</p>
  
  <p>Update:</p>
  
  <p>You have got to be kidding me. After leaving it for a couple hours, it turns out I had this spec for some reason in spec/controllers, when simply switching it over to spec/requests made everything green. </p>
  
  <p>I quote:</p>
  
  <blockquote>
    <p>If you are using Rails, put your Capybara specs in spec/requests or
    spec/integration.</p>
  </blockquote>
  
  <p>Found at <a href="https://github.com/jnicklas/capybara#readme" rel="nofollow noreferrer">https://github.com/jnicklas/capybara#readme</a></p>
  
  <p>However, I'm still wondering how for future requirements I can do integration tests on my controllers that will need to have a logged in user.... for other non-Devise apps in the past, this has been as simple as something like the following:</p>
  
  <pre><code>describe SomeController do
  
    let(:user) { FactoryGirl.create(:user) }
  
    before { valid_sign_in user }
  
  ...
  </code></pre>
  
  <p>where my helper is simply </p>
  
  <pre><code>  def valid_sign_in(user)
      visit signin_path
      fill_in "Email", with: user.email
      fill_in "Password", with: user.password
      uncheck(:remember_me)
      click_button "Sign In"
  
      # Sign in when not using Capybara as well.
      cookies[:remember_token] = user.remember_token
    end
  </code></pre>