Capybara InfiniteRedirectError

时间:2017-04-19 02:06:17

标签: ruby-on-rails ruby-on-rails-4 rspec capybara bdd

无论是在浏览器中还是在运行rspec,我都会遇到相同的行为......如何解决此问题?

我尝试删除application_controller.rb中的before_filter :authenticate_user!,结果保持不变。失败的示例是spec / features / subdomain_feature_spec.rb

中的第一个示例
Failures:

1) subdomains redirects invalid accounts
 Failure/Error: visit root_url(subdomain: 'random-subdomain')

 Capybara::InfiniteRedirectError:
   redirected more than 5 times, check for infinite redirects.
 # /home/benny/.rvm/gems/ruby-2.3.3/gems/capybara-2.13.0/lib/capybara/rack_test/browser.rb:41:in `process_and_follow_redirects'
 # /home/benny/.rvm/gems/ruby-2.3.3/gems/capybara-2.13.0/lib/capybara/rack_test/browser.rb:22:in `visit'
 # /home/benny/.rvm/gems/ruby-2.3.3/gems/capybara-2.13.0/lib/capybara/rack_test/driver.rb:43:in `visit'
 # /home/benny/.rvm/gems/ruby-2.3.3/gems/capybara-2.13.0/lib/capybara/session.rb:254:in `visit'
 # /home/benny/.rvm/gems/ruby-2.3.3/gems/capybara-2.13.0/lib/capybara/dsl.rb:52:in `block (2 levels) in <module:DSL>'
 # ./spec/features/subdomain_feature_spec.rb:7:in `block (2 levels) in <top (required)>'

...

Failed examples:

rspec ./spec/features/subdomain_feature_spec.rb:6 # subdomains redirects invalid accounts

相关文件

  

规格/特征/ subdomain_feature_spec.rb

require 'rails_helper'

describe 'subdomains' do
  let!(:account) { create(:account_with_schema) }

  it 'redirects invalid accounts' do
    visit root_url(subdomain: 'random-subdomain')
    expect(page.current_url).to_not include('random-subdomain')
  end

  it 'allows valid accounts' do
    visit root_url(subdomain: account.subdomain)
    expect(page.current_url).to include(account.subdomain)
  end

  it 'forces user to login before accessing subdomain content' do
    visit root_url(subdomain: account.subdomain)
    expect(page).to have_content 'sign in or sign up before continuing'
  end
end
  

配置/ routes.rb中

class SubdomainPresent
  def self.matches?(request)
    request.subdomain.present?
  end
end

class SubdomainBlank
  def self.matches?(request)
    request.subdomain.blank?
  end
end

Rails.application.routes.draw do
  constraints(SubdomainPresent) do
    root 'projects#index', as: :subdomain_root
    devise_for :users
  end

  # only allow certain routes when there isn't a subdomain
  constraints(SubdomainBlank) do
    root 'welcome#index'
    resources :accounts, only: [:new, :create]
  end
end
  

控制器/ application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  before_filter :load_schema, :authenticate_user!

  private

  def load_schema
    Apartment::Tenant.switch!('public')
    return unless request.subdomain.present?

    account = Account.find_by(subdomain: request.subdomain)
    if account
      Apartment::Tenant.switch!(request.subdomain)
    else
      redirect_to root_url(subdomain: :false)
    end
  end

  def after_sign_out_path_for(resource_or_scope)
    new_user_session_path
  end
end
  

控制器/ welcome_controller.rb

class WelcomeController < ApplicationController
  skip_before_filter :authenticate_user!, only: :index

  def index
  end
end
  

规格/工厂/ accounts.rb

FactoryGirl.define do
  sequence(:subdomain) { |n| "subdomain#{n}" }

  factory :account do
    sequence(:subdomain) { |n| "subdomain#{n}" }
    association :owner, factory: :user

    factory :account_with_schema do
      after(:build) do |account|
        Apartment::Tenant.create(account.subdomain)
        Apartment::Tenant.switch!(account.subdomain)
      end
      after(:create) do |account|
        Apartment::Tenant.reset
      end
    end
  end
end
  

规格/ rails_helper.rb

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?

# Add additional requires below this line. Rails is not loaded until this point!
require 'spec_helper'
require 'rspec/rails'
require 'capybara/poltergeist'

Capybara.javascript_driver = :poltergeist

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.use_transactional_fixtures = false

  config.infer_spec_type_from_file_location!

  config.include FactoryGirl::Syntax::Methods

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
  # arbitrary gems may also be filtered via:
  # config.filter_gems_from_backtrace("gem name")
end

# Capybara.register_driver :poltergeist do |app|
#   Capybara::Poltergeist::Driver.new(app, options)
# end

1 个答案:

答案 0 :(得分:1)

Capybara rack_test驱动程序会忽略主机名,因此您无法使用它测试子域行为,您需要使用其中一个利用/模仿完整浏览器的驱动程序运行这些测试(selenium,poltergeist,水豚 - WebKit的)。

此外,你想使用Capybara have_current_path matcher而不是eq和`current_url'进行写和url /路径检查

expect(page).not_to have_current_path(/random-subdomain/, url: true)