ruby-on-railsrubyrspectddrspec-rails

Testing with rspec .consider_all_requests_local = false


I'm using in my application_controller : .consider_all_requests_local like

  unless Rails.application.config.consider_all_requests_local
    rescue_from ActionController::InvalidCrossOriginRequest, :with => :render_404
  end

This return 404 if ActionController::InvalidCrossOriginRequest is raised. In local environnement it's not raised, it's good for debugging. For this part it's working. But I would like to test it with rspec.

I've tried something like

describe 'ActionController::InvalidCrossOriginRequest render 404' do
    before { Rails.application.config.consider_all_requests_local = false }
    controller do
      def index
        raise ActionController::InvalidCrossOriginRequest
      end
    end

    subject { xhr :get, :index, format: :js }

    its(:status) { is_expected.to eq 404 }
end

Two things. I probably not raise in the proper way. Locally the error occurs when mywebsite.com/editor/fckeditor.js is called. Didn't found a way to call a specific url.

Second problem, the before doesn't change the Rails.application.config.consider_all_requests_local state.

I get :

1) ApplicationController ActionController::InvalidCrossOriginRequest render 404 status
     Failure/Error: raise ActionController::InvalidCrossOriginRequest
     ActionController::InvalidCrossOriginRequest:
       ActionController::InvalidCrossOriginRequest

Solution

  • The issue looks to be caused by your unless check being performed at class load time. This means the very first time the class is loaded the value in the application config is checked and the rescue_from is either set or not set.

    At the most basic workaround, you would need to use load to cause that file to get re-read once the setting has been changed. However, as is, once the rescue_from is turned on, loading the file again won't cause it to turn off.

    The next alternative is to use rescue_from(with:) which delegates to a helper or the block form. You can use this helper to check the value and either handle the condition or not. However, considering this looks to be something you only want to do in a non-production environment, you could combine the two. Use the unless to verify that you are not in production, then use the with to check the config each time.

    Something like:

    class ApplicationController < ActionController::Base
      unless Rails.env.production?
        rescue_from ActionController::InvalidCrossOriginRequest do
          unless Rails.application.config.consider_all_requests_local
            render_404
          end
        end
      end
    end