28

In the devise documentation they give tips on how you can have access to current_user when testing a controller:

https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-%28and-RSpec%29

However, what about when doing a feature test? I am trying to test a create method of one of my controllers, and in that controller is used the current_user variable.

The problem is that the macro suggested in devise uses the @request variable, and it is nil for a feature spec. What is a workaround?

EDIT:

This is what I have so far for my current spec:

feature 'As a user I manage the orders of the system' do
  scenario 'User is logged in ad an admin' do
    user = create(:user)
    order = create(:order, user: user)
    visit orders_path
    #Expectations
  end
end

The problem is that in my OrdersController I have a current_user.orders call, and since current_user is not defined, it will redirect me to /users/sign_in.

I have defined this under /spec/features/manage_orders.rb

kayatela
  • 394
  • 5
  • 21
Hommer Smith
  • 26,772
  • 56
  • 167
  • 296
  • I've used https://github.com/railsware/rack_session_access for something like that – Kimmo Lehto May 21 '14 at 21:13
  • 1
    Also, see http://blog.pixarea.com/2013/01/making-rspec-feature-specs-easy-with-devise and http://stackoverflow.com/questions/5865555/how-to-do-integration-testing-with-rspec-and-devise-cancan. – Jacob Brown May 21 '14 at 21:14
  • Maybe include the test code you are trying to write? You can just pretend that `current_user` is there, I think that will help a lot in clarifying your intentions. – Patrick Oscity May 21 '14 at 21:31
  • I am not logging the user because I don't know how to do that in a feature rspec test. – Hommer Smith May 21 '14 at 21:57

3 Answers3

35

from https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-%28and-RSpec%29

if i have understood you right, maybe you need to use

subject.current_user.email
#or
controller.current_user.email

for example :

describe OrdersController, :type => :controller do
  login_user

  describe "POST 'create'" do
     it "with valid parametres" do
        post 'create', title: 'example order', email: subject.current_user.email
     end
  end
end

controller_macros.rb :

module ControllerMacros
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user = FactoryGirl.create(:user)
      #user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the "confirmable" module
      sign_in user
    end
  end
end

Don't forget to include this into your spec_helper.rb :

config.include Devise::TestHelpers, type: :controller
config.extend ControllerMacros, type: :controller
RustemMazitov
  • 958
  • 1
  • 10
  • 15
2

Here's what I think you are looking for:

require 'spec_helper'
include Warden::Test::Helpers
Warden.test_mode!

feature 'As a user I manage the orders of the system' do
  scenario 'User is logged in ad an admin' do
    user = create(:user)
    login_as(user, scope: :user)
    order = create(:order, user: user)
    visit orders_path
    #Expectations
  end
end
Alec Rooney
  • 3,025
  • 2
  • 13
  • 11
  • 2
    This is the most correct answer so far as it is very close to the officially recommended way on the devise wiki for feature specs (not controller specs) https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara – Kris Khaira Apr 12 '18 at 08:52
2

you can define login_user as a method for the user to login as follows (put it in support folder):

def login_user
  Warden.test_mode!
  user = create(:user)
  login_as user, :scope => :user
  user.confirmed_at = Time.now
  user.confirm!
  user.save
  user
end

Then in the scenario say:

user = login_user
Hani Alsioufi
  • 167
  • 1
  • 10