RSpec InfiniteRedirectError при посещении root_path

Это с тестом характеристик водосвинки. У меня нет фильтров before_action в моем контроллере для корневой страницы, поэтому я полностью озадачен этим. У кого-нибудь еще была такая же проблема?

Строка, которая вызывает ошибку, просто

visit(root_path) 

Очень странно.

Кроме того, при запуске только этого теста он проходит успешно, но при запуске всего набора тестов происходит сбой с ошибкой InfiniteRedirectError.

user_and_role_spec.rb:

require 'rails_helper'
    
    def manually_create_user
        visit new_user_registration_path
        fill_in('user_first_name', :with => 'Test')
        fill_in('user_last_name', :with => 'User')
        fill_in('user_email', :with => '[email protected]')
        fill_in('user_password', :with => 'testuser')
        fill_in('user_password_confirmation', :with => 'testuser')
        click_button('Sign up')
    end

    def create_user_and_login_as(type)
        user = FactoryGirl.create(type)
        visit(new_user_session_path)
        fill_in('user_email', :with => user.email)
        fill_in('user_password', :with => user.password)
        click_button('Log in')
    end


describe 'with users and roles' do  

    context "if user is not an admin" do

        it "makes sure Login/Logout works" do
            visit(root_path)
            click_link("Sign up")
            fill_in('user_email', :with => "[email protected]")
            fill_in('user_first_name', :with => "Test")
            fill_in('user_last_name', :with => "User")
            fill_in('user_password', :with => "password")
            fill_in('user_password_confirmation', :with => "password")
            click_button "Sign up"
            expect(current_path).to eq(root_path)
            expect(page).to have_content('Welcome! You have signed up successfully.')
        end
    end
end

static_pages_controller.rb:

class StaticPagesController < ApplicationController
    before_action :an_admin?, only: [:admin]

  def home
    @testimonials = Testimonial.all
  end

  def admin
    @groups = Group.all

    @users = User.all

    @students = Student.all

    @teachers = Teacher.all
  end

  private

  def an_admin?
    unless signed_in? && (current_user.admin == true) 
      redirect_to root_path, notice: "You have to be a signed-in admin to view the admin page"
    end
  end

end

маршруты.rb:

Rails.application.routes.draw do

  resources :materials

  root 'static_pages#home'

  devise_for :users, :controllers => { registrations: 'registrations' }
  
  get 'admin' => 'static_pages#admin'

  resources :groups
  resources :users
  resources :students
  resources :teachers
  resources :testimonials
  post 'assign_to_group' => 'students#assign_to_group' # Could have been 'patch', but default in the controller method is 'post', so I left the method as default and changed this route to 'post'. Doesn't NEED to be patch.
  post 'remove_from_group' => 'students#remove_from_group'
  post 'unassign_teacher' => 'groups#unassign_teacher'
  post 'assign_as_student' => 'teachers#assign_as_student'
  post 'assign_as_teacher' => 'students#assign_as_teacher'
  post 'add_student' => 'groups#add_student'
  post 'remove_student_from_group' => 'groups#remove_student_from_group'
end

rails_helper.rb:

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
require 'database_cleaner'

require 'devise'

# Add additional requires below this line. Rails is not loaded until this point!

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
# Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
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"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = true

  # RSpec Rails can automatically mix in different behaviours to your tests
  # based on their file location, for example enabling you to call `get` and
  # `post` in specs under `spec/controllers`.
  #
  # You can disable this behaviour by removing the line below, and instead
  # explicitly tag your specs with their type, e.g.:
  #
  #     RSpec.describe UsersController, :type => :controller do
  #       # ...
  #     end
  #
  # The different available types are documented in the features, such as in
  # https://relishapp.com/rspec/rspec-rails/docs
  config.infer_spec_type_from_file_location!

  config.include Devise::TestHelpers, :type => :controller

  Capybara.register_driver :rack_test do |app|
    Capybara::RackTest::Driver.new(app, :respect_data_method => true, :redirect_limit => 20)
  end
  
end

spec_helper.rb:

RSpec.configure do |config|
  # rspec-expectations config goes here. You can use an alternate
  # assertion/expectation library such as wrong or the stdlib/minitest
  # assertions if you prefer.
  config.expect_with :rspec do |expectations|
    # This option will default to `true` in RSpec 4. It makes the `description`
    # and `failure_message` of custom matchers include text for helper methods
    # defined using `chain`, e.g.:
    #     be_bigger_than(2).and_smaller_than(4).description
    #     # => "be bigger than 2 and smaller than 4"
    # ...rather than:
    #     # => "be bigger than 2"
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  # rspec-mocks config goes here. You can use an alternate test double
  # library (such as bogus or mocha) by changing the `mock_with` option here.
  config.mock_with :rspec do |mocks|
    # Prevents you from mocking or stubbing a method that does not exist on
    # a real object. This is generally recommended, and will default to
    # `true` in RSpec 4.
    mocks.verify_partial_doubles = true
  end
end

тест.лог:

Started GET "/" for 127.0.0.1 at 2015-05-19 13:37:49 +0200
Processing by StaticPagesController#home as HTML
Redirected to http://www.example.com/
Filter chain halted as :an_admin? rendered or redirected
Completed 302 Found in 6ms (ActiveRecord: 0.0ms)
Started GET "/" for 127.0.0.1 at 2015-05-19 13:37:49 +0200
Processing by StaticPagesController#home as HTML
Redirected to http://www.example.com/
Filter chain halted as :an_admin? rendered or redirected
Completed 302 Found in 7ms (ActiveRecord: 0.0ms)
Started GET "/" for 127.0.0.1 at 2015-05-19 13:37:49 +0200
Processing by StaticPagesController#home as HTML
Redirected to http://www.example.com/
Filter chain halted as :an_admin? rendered or redirected

... и т. д. и т. д.

Для меня это говорит о том, что мое действие before_action в моем static_pages_controller сработало, но я не понимаю, почему это произошло, учитывая an_admin? код метода?

ОБНОВИТЬ:

Возможно, я приближаюсь к решению этого: static_controller_spec запускается перед user_and_role_spec при запуске полного набора тестов. Когда я отключаю static_controller_spec, тест user_and_role_spec выполняется без ошибок при выполнении всего набора тестов. Виновником кажется эта строка:

controller.class.skip_before_action :an_admin?

Эта строка находится в static_controller_spec:

require "rails_helper.rb"

describe StaticPagesController do



describe "GET #home" do
        it "renders the :home view" do
            get :home
            expect(response).to render_template :home
        end
    end

    describe "GET #admin" do
        it "renders the :admin view" do
            # This is line 14. The next line is intended to disable the :an_admin? before_action in the controller
            controller.class.skip_before_action :an_admin?
            get :admin 
            expect(response).to render_template :admin
            # The next line is intended to reverse line 15
            controller.class.before_action :an_admin?
        end

        it "requires user to be signed_in"

        it "requires user to be an admin"
    end

end

Я хотел отключить before_action для этого теста. Честно говоря, я не очень понимаю эту строку - это была прямая копия/вставка откуда-то. Кажется, это испортило мой тест user_and_role_spec, но я не понимаю, почему. Любые идеи?


person Yorkshireman    schedule 18.05.2015    source источник
comment
было бы полезно, если бы мы действительно могли видеть соответствующий код :) Не могли бы вы отредактировать свой вопрос и добавить его туда? (не пишите в комментариях, форматирование кода ужасное)   -  person Taryn East    schedule 18.05.2015


Ответы (2)


В вашем user_and_role_spec.rb у вас есть дополнительный end после закрытия конца def create_user_and_login_as(type). Вам нужно два end внизу спецификации, чтобы закрыть describe 'with users and roles' do и context "if user is not an admin" do.

В вашем route.rb вам нужно end внизу, чтобы закрыть Rails.application.routes.draw do

Я не уверен, что вы просто не вставили их, но это имеет значение в вашем приложении, и это имеет значение, когда вы публикуете код.

person Luis Menjivar    schedule 18.05.2015
comment
Исправил. Ошибка вставки. Впрочем, это не так уж и важно, так как очевидно, что приложение даже не запустится, не говоря уже об ошибке, которую я описал. - person Yorkshireman; 18.05.2015

РЕШЕНО:

Что касается обновления в моем исходном посте, я просто полностью удалил эти две строки controller.class в static_pages_controller_spec, и весь набор тестов проходит (слава богу!). Конечно, это заставляет меня задаться вопросом, почему у меня вообще были эти строки — я просто не могу вспомнить.

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

person Yorkshireman    schedule 19.05.2015