RSPEC test index action with before_action filter

Robbo picture Robbo · Dec 30, 2014 · Viewed 10.1k times · Source

I have a before_action filter and want to test that the index action is only executed if the user is logged in. Simply put, i don't know how to do this. I'm using my own simple authentication and i know i could use CanCan or similar but for my own learning i'm doing it the hard way!

ApplicationController.rb

helper_method :logged_in
helper_method :current_user


def current_user

  @current_user ||= User.find_by_id(session[:current_user]) if session[:current_user]

end



def logged_in

  unless current_user
    redirect_to root_path
  end

end

ActivitiesController.rb

before_action :logged_in

def index
  @activities = Activity.all.where(user_id: @current_user)
end

Activities_Controller_spec.rb

require 'rails_helper'

RSpec.describe ActivitiesController, :type => :controller do

describe "GET index" do

  before(:each) do
    @activity = FactoryGirl.create(:activity)
    session[:current_user] = @activity.user_id
    @current_user = User.find_by_id(session[:current_user]) if session[:current_user]
  end

  it "shows all activities for signed in user" do
    get :index, {user_id: @activity.user_id}
    expect(response).to redirect_to user_activities_path

  end  

end


end

activities.rb(Factory)

FactoryGirl.define do

factory :activity do

association :user

  title { Faker::App.name }
  activity_begin { Faker::Date.forward(10) }
  activity_end { Faker::Date.forward(24) }

end  

end

I'm getting the following error:

Failure/Error: expect(response).to redirect_to user_activities_path
   Expected response to be a redirect to <http://test.host/users/1/activities> but was a redirect to <http://test.host/>.
   Expected "http://test.host/users/1/activities" to be === "http://test.host/".

Answer

gotva picture gotva · Dec 30, 2014

After long discussion I think tests should be smth like this (it is not tested :) )

require 'rails_helper'

RSpec.describe ActivitiesController, :type => :controller do

  describe "GET index" do

    before(:each) do
      @activity = FactoryGirl.create(:activity)
    end

    context 'when user is logged' do

      before(:each) do
        session[:current_user] = @activity.user_id
      end

      it "shows all activities for signed in user" do
        get :index, {user_id: @activity.user_id}
        expect(response).to be_success      
      end  
    end

    context 'when user is anonymous' do
      it "redirects user to root path" do
        get :index, {user_id: @activity.user_id}
        expect(response).to redirect_to root_path
      end  
    end

  end


end