2
votes

I'm using devise + rspec + factory + shoulda and having trouble with my controller specs. I've read a bunch of articles and docs but couldn't figure out what the best way is to log_in the user and use that user instance.

Task is nested under user so index route is /users/:user_id/tasks and task belongs_to :assigner, class_name: "User" and belongs_to :executor, class_name: "User"

At the moment with following code both tests fail. What is the best approach for properly sign_in the user and use it in the controller tests?

The error message for the first one:

Failure/Error: expect(assigns(:tasks)).to eq([assigned_task, executed_task])

expected: [#<Task id: 1, assigner_id: 1, executor_id: 2, .....>, #<Task id: 2, assigner_id: 3, executor_id: 1, ......>]
        got: nil

(compared using ==)

The error for the second one:

Failure/Error: it { is_expected.to respond_with :ok }
   Expected response to be a 200, but was 302

tasks_controller_spec.rb

require "rails_helper"

describe TasksController do

  describe "when user is signed in" do

    describe "collections" do

      login_user
      let(:assigned_task) { create(:task, assigner: @user) }
      let(:executed_task) { create(:task, executor: @user) }
      let(:other_task) { create(:task) }

      context "GET index" do
        before do
          get :index, user_id: @user.id
        end

        it "assigns user's tasks" do
          expect(assigns(:tasks)).to eq([assigned_task, executed_task])
        end

        it { is_expected.to respond_with :ok }

      end

      context "GET incoming_tasks"
    end
  end 
end

controller_macros.rb

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

tasks controller

def index
  @tasks = Task.alltasks(current_user).uncompleted.includes(:executor, :assigner).order("deadline DESC").paginate(page: params[:page], per_page: Task.pagination_per_page)
end
1
please provide code for index action, also please encode login_user to before(;each/:all) block.Малъ Скрылевъ
Updated with index action. Isn't the login_user already in before block?Sean Magyar
I havent seen that loginuser is executed inside the before block of describeМалъ Скрылевъ
well you can use pry gem to debug app.... introduce it to action, and to spec code and look into the contextМалъ Скрылевъ
I checked @user and it is available in the it block, still code fails. The @user.current_sign_in_at = nil though. Does that matter?Sean Magyar

1 Answers

0
votes

Add following line in rails_helper.

config.include ControllerMacros, :type => :controller 

SEE this thread.

I am assuming this only fails in rspec. When you test in browser it works fine.