How to test after_sign_in_path_for(resource)?

Viewed 5047

I have devise authentication and registration set up on my Rails app. I'm using after_sign_in_path_for() to customise the redirect when the user signs in based on various scenarios.

What I'm asking is how to test this method? It seems hard to isolate since it is called automatically by Devise when the user signes in. I want to do something like this:

describe ApplicationController do
  describe "after_sign_in_path_for" do
    before :each do
      @user = Factory :user
      @listing = Factory :listing
      sign_in @user
    end

    describe "with listing_id on the session" do
      before :each do
        session[:listing_id] = @listing.id
      end

      describe "and a user in one team" do
        it "should save the listing from the session" do
          expect {
            ApplicationController.new.after_sign_in_path_for(@user)
          }.to change(ListingStore, :count).by(1)
        end

        it "should return the path to the users team page" do
          ApplicationController.new.after_sign_in_path_for(@user).should eq team_path(@user.team)
        end
      end
    end
  end
end

but that's obviously not the way to do it because I just get an error:

 Failure/Error: ApplicationController.new.after_sign_in_path_for(@user)
 RuntimeError:
   ActionController::Metal#session delegated to @_request.session, but @_request is nil: #<ApplicationController:0x00000104581c68 @_routes=nil, @_action_has_layout=true, @_view_context_class=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=nil, @_response=nil>

So, how can I test this method?

5 Answers

For the newcomers, I would recommend doing this way:

RSpec.describe ApplicationController, type: :controller do
  let(:user) { create :user }

  describe "After sing-in" do
    it "redirects to the /yourpath/ home page" do
      expect(subject.after_sign_in_path_for(user)).to eq(yourpath_root_path)
    end
  end
end

I found this answer through Google recently and thought I would add my solution. I didn't like the accepted answer because it was testing the return value of a method on the application controller vs testing the desired behavior of the app.

I ended up just testing the call to create a new sessions as a request spec.

RSpec.describe "Sessions", type: :request do
    it "redirects to the internal home page" do
        user = FactoryBot.create(:user, password: 'password 123', password_confirmation: 'password 123')
        post user_session_path, params: {user: {email: user.email, password: 'password 123'}}
        expect(response).to redirect_to(internal_home_index_path)
    end
end

(Rails 5, Devise 4, RSpec 3)

Related