0
votes

I have had a look around but maybe I'm not looking in the right places. I am trying to find out how to test that a user cannot access a page whose controller has:

before_filter :authenticate_user!

Ideally I would like to capture the devise message at the same time:

"you need to sign in or sign up before continuing"

I have this so far

require 'spec_helper'

describe CampaignsController do

  it "should not allow a user be able to access without being authenticated" do
    get :index
    response.should redirect_to(new_user_session_path)
  end

end

At present I get the error

Failure/Error: response.should redirect_to(new_user_session_path)
Expected response to be a <redirect>, but was <200>

Campaigns Controller

class CampaignsController < ApplicationController
  before_filter :authenticate_user! 

def index
  @campaigns = Campaign.all
end
end

In my spec helper I am calling the following

# Include Devise Test Helpers
config.include Devise::TestHelpers, :type => :controller
config.extend ControllerMacros, :type => :controller

controller_macros.rb

module ControllerMacros

def login_user
  before(:each) do
    @request.env["devise.mapping"] = Devise.mappings[:user]
    user = FactoryGirl.create(:user)
    sign_in user
  end
end
end

I'm not calling the login_user method at this stage, so would the spec_helper call this?

How do I approach this correctly?

2
please post CampaignsController.Зелёный
Seems ok to me, could you make sure you didn't call sign_in method somewhere (in you spec_helper?). Could we also have the code of the ApplicationController ?ccyrille
updated, thinking now after your comments that you could be onto somethingRichlewis

2 Answers

2
votes

At first look it seems ok. The problem could be caused if you run your entire suite, and depending on the place you call login_user it could add the before(:each) to all tests.

I understand you want to minimise typing, but generally I prefer my tests to be a little more explicit: I want to see what is going on in the spec.

So how I generally write this kind of test:

describe HomeController do
  include Devise::TestHelpers

  context "when not signed in" do
    describe "GET 'index'" do
      it "redirects to sign in" do
        get 'index'
        response.should be_redirect
      end
    end
    describe "GET 'about'" do
      it "returns http success" do
        get 'about'
        response.should be_redirect
      end
    end
  end

  context "when signed in" do
    before do
      user = FactoryGirl.create(:user)
      sign_in(user)
    end
    describe 'GET :index' do
      it "returns http success" do
        get 'index'
        response.should be_success
      end
    end
    describe "GET 'about'" do
      it "returns http success" do
        get 'about'
        response.should be_success
      end
    end
  end
end

Yes, admitted: I am still fond of the old rspec syntax (using should), it reads much more natural to me.

0
votes

Please try

module ControllerMacros

  def login_user
    @request.env["devise.mapping"] = Devise.mappings[:user]
    user = FactoryGirl.create(:user)
    sign_in user
  end
end

in rspec file

require 'spec_helper'

describe CampaignsController do

  it 'for authenticate user' do
    before do
      login user
    end
  end

  it "should not allow a user be able to access without being authenticated" do
    get :index
    expect(response).to redirect_to(new_user_session_path)
  end