Как проверить after_sign_in_path_for (ресурс)? - PullRequest
17 голосов
/ 12 июля 2011

Я установил аутентификацию и регистрацию в моем приложении Rails.Я использую after_sign_in_path_for() для настройки перенаправления, когда пользователь входит в систему на основе различных сценариев.

Что я спрашиваю, как проверить этот метод?Кажется, что его трудно изолировать, так как он вызывается Devise автоматически, когда пользователь входит в систему. Я хочу сделать что-то вроде этого:

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

, но это явно не тот способ, потому что я просто получаю ошибку:

 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>

Итак, как я могу проверить этот метод?

Ответы [ 5 ]

32 голосов
/ 12 июля 2011

Как ни странно, мне было интересно именно это сегодня.Вот что я придумал.Я создал анонимный подкласс ApplicationController.В этом анонимном подклассе я показал защищенные методы, которые я хотел протестировать, как публичные методы.Затем я проверил их напрямую.

describe ApplicationController do
  controller do
    def after_sign_in_path_for(resource)
        super resource
    end
  end

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

  describe "After sigin-in" do
    it "redirects to the /jobs page" do
        controller.after_sign_in_path_for(@user).should == jobs_path
    end
  end

end
4 голосов
/ 12 июля 2011

На аналогичную заметку - если вы хотите проверить перенаправление после регистрации, у вас есть два варианта.

Во-первых, вы можете следовать шаблону, аналогичному приведенному выше, и очень напрямую протестировать метод в RegistrationsController:

require 'spec_helper'

describe RegistrationsController do

  controller(RegistrationsController) do
    def after_sign_up_path_for(resource)
        super resource
    end
  end

  describe "After sign-up" do
    it "redirects to the /organizations/new page" do
        @user = FactoryGirl.build(:user)
        controller.after_sign_up_path_for(@user).should == new_organization_path
    end
  end
end

Или же вы можете использовать более подход для тестирования интеграции и выполнитьследующее:

require 'spec_helper'

describe RegistrationsController do

  describe "After successfully completing the sign-up form" do

    before do
        @request.env["devise.mapping"] = Devise.mappings[:user]
    end

    it "redirects to the new organization page" do
        post :create, :user => {"name" => "Test User", "email" => "test@example.com", "password" => "please"}
        response.should redirect_to(new_organization_path)
    end
  end
end
1 голос
/ 04 августа 2018

Я недавно нашел этот ответ в Google и подумал, что добавлю свое решение.Мне не понравился принятый ответ, потому что он проверял возвращаемое значение метода на контроллере приложения, а не проверял желаемое поведение приложения.

В итоге я просто протестировал вызов для создания новых сеансов,спецификация запроса.

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)

0 голосов
/ 20 сентября 2017

Для новичков я бы порекомендовал сделать так:

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
0 голосов
/ 16 августа 2012
context "without previous page" do
  before do
    Factory.create(:user, email: "junior@example.com", password: "123456", password_confirmation: "123456")
    request.env["devise.mapping"] = Devise.mappings[:user]
    post :create, user: { email: "junior@example.com", password: "123456" }
  end
end 

  it { response.should redirect_to(root_path) }
context "with previous page" do
  before do
    Factory.create(:user, email: "junior@example.com", password: "123456", password_confirmation: "123456")
    request.env["devise.mapping"] = Devise.mappings[:user]
    request.env['HTTP_REFERER'] = 'http://test.com/restaurants'
    post :create, user: { email: "junior@example.com", password: "123456" }
  end

  it { response.should redirect_to("http://test.com/restaurants") }
end
...