Search code examples
ruby-on-railsrubyruby-on-rails-4rspecbefore-filter

RSPEC test index action with before_action filter


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/".

Solution

  • 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