将RSpec中的页面重定向到其他页面

时间:2015-11-23 12:11:45

标签: ruby-on-rails rspec devise rspec-rails

我正在使用Devise gem进行身份验证,我也指定了

before_filter :authenticate_contact! 

在我的ApplicationController中。因此,用户在访问应用程序之前需要login。如果他错误地键入url而没有登录,它将要求用户进行身份验证,一旦登录它将重定向到他给定的url而不是仪表板,我已经使用了以下代码

def after_sign_in_path_for(resource)
    flash[:notice] = "Welcome #{current_contact.first_name} #{current_contact.last_name}, #{current_contact.company.genre}."
    session[:announcements] = true
    sign_in_url = new_contact_session_url
    if request.referer == sign_in_url
      super
    else
      stored_location_for(resource) || request.referer || root_path
    end
  end

这很好用。我的下一步是写一个RSpec规范:

在我的spec / controller / application_controller_spec.rb

require 'spec_helper'

describe ApplicationController do
  controller do
    def after_sign_in_path_for(resource)
      sign_in_url = new_contact_session_url
      if request.referer == sign_in_url
        super
      else
        stored_location_for(resource) || request.referer || root_path
      end
    end
  end

  before (:each) do
    @user = FactoryGirl.create(:contact_owner, email: 'owner@test.com')
  end

  describe "After sigin-in" do
    it "redirects to the root path" do
      controller.after_sign_in_path_for(@user).should == root_path
    end
  end

end

这个规范正在通过,它是第一个场景,即用户来到应用程序登录并获取root_path。但是我在测试第二个条件时遇到困难,如果用户在没有身份验证的情况下键入url,它将要求进行身份验证,并且在登录后,它应该重定向到他的路径而不是root_path

describe CompaniesController do
    before do 
      @user = FactoryGirl.create(:contact_owner, email: "test@test.com")
    end
    context "when logged in redirect to path" do
      before { sign_out @user }
      after { sign_in @user } #after this how can i proceed, here user is trying companies/index without login. once he logs in it should redirect_to(companies_path)
      it { get :index }
    end
  end

1 个答案:

答案 0 :(得分:1)

RSpec中的beforeafter块用于设置和拆除示例:

describe FooController do
  before { do_something } # runs before the nested describe
  describe "GET #index" do
    before { get :index } # runs after do_something
    after { clean_up } # runs after each example
    it "renders the correct template" do
      expect(response).to render_template(:index)
    end 
  end
end

这与TDD中的setupteardown步骤相同。这里的关键点是你不能在after阻止之后继续。它不应该用于构造示例,而只是用于拆除任何可能会延迟的灯具或任何东西,例如会话数据或重置缓存等。

afterspec_helper.rb之外很少使用rails_helper.rb块。使用database_cleanerthe test helpers for your auth system等工具提供一个干净的平板,您将几乎不需要在个别示例后进行清理。

集成测试。

控制器规格适用于低级别测试,可让您快速测试控制器如何响应不同的输入。它们使用几个抽象速度来表示它们不会触及整个堆栈,例如路由和视图渲染。

要测试身份验证系统,您很可能需要feature spec

关键区别在于功能规范从实际用户的角度测试应用程序,您在应用程序中单击您的方式并对用户所呈现的内容写下期望:

# spec/features/authentication_spec.rb
require 'rails_helper'
RSpec.feature "Authentication" do

  let(:user) { FactoryGirl.create(:user) }

  scenario "when a user attemps to access a resource that requires authentication" do
    visit some_path
    expect(page).to have_content 'Please sign in'
  end

  scenario "when a user signs in with correct details" do
    visit root_path
    click_link 'Sign In'
    fill_in 'Email', with: user.email
    fill_in 'Password', with: user.password
    click_button 'Sign In'
    expect(page).to have_content "Welcome #{user.email}!"
  end
end