0

I am running into an interesting challenge this weekend. I want to test the following 4 rescue statements. What do you feel is the best approach? I have been testing anonymous controllers, gets, and more but I am coming up blank. Is this even possible?

Rspec

# frozen_string_literal: true

require 'rails_helper'

RSpec.describe ApplicationController, type: :controller do
  it 'rescue record not found with 404' do

  end

  it 'rescue parameter missing with 400' do

  end

  it 'rescue routing error with 400' do

  end

  it 'rescue invalid authenticity token with 400' do

  end
end

Application Controller

# frozen_string_literal: true

class ApplicationController < ActionController::Base
  force_ssl if: :ssl_configured?

  rescue_from ActiveRecord::RecordNotFound, with: :render_404
  rescue_from ActionController::ParameterMissing, with: :render_400
  rescue_from ActionController::RoutingError, with: :render_404
  rescue_from ActionController::InvalidAuthenticityToken, with: :render_400

  include StatusCodes
  include JsonTester

  private

  def ssl_configured?
    AppUnsecure.settings[:ssl_configured]
  end
end
halfer
  • 19,824
  • 17
  • 99
  • 186
Chris Hough
  • 3,389
  • 3
  • 41
  • 80
  • the problem is with frozen_string_literal read this https://stackoverflow.com/questions/37799296/what-does-the-comment-frozen-string-literal-true-do – Aniket Tiwari Oct 28 '17 at 08:16
  • The first issue is that you cannot rescue `ActionController::RoutingError` from the controller. Its raised in the router before the request is passed to a controller. So a better approach altogether is to declare `config.exceptions_app = self.routes` and create custom errors via a separate controller. https://mattbrictson.com/dynamic-rails-error-pages – max Oct 28 '17 at 10:42
  • To test it you want to use a request spec that drives the full stack. – max Oct 28 '17 at 10:43
  • Hi Chris. [On this question](https://stackoverflow.com/q/46597848/472495), on 7th October, I asked whether you'd mind following the preferred format for titles, given that volunteer editors are repairing your lower-case tag-list titles, on an ad-hoc basis. It would be great to be able to save them some effort. Would you be able to write your questions using ordinary sentence case, with initial caps for proper nouns, and minus the home-made tags? We'd much appreciate it! – halfer Oct 29 '17 at 21:40

1 Answers1

2

As @max said, you can't test a routing error in this way since it is raised earlier in the stack than the controller.

However, as for the rest of your test cases, you can do that pretty easily:

RSpec.describe ApplicationController do
  controller do
    def test_record_not_found
      raise ActiveRecord::RecordNotFound
    end

    def test_parameter_missing
      raise ActionController::ParameterMissing, :test
    end

    def test_invalid_auth_token
      raise ActionController::InvalidAuthenticityToken
    end
  end

  before :each do
    routes.draw do
      get "test_record_not_found" => "anonymous#test_record_not_found"
      get "test_parameter_missing" => "anonymous#test_parameter_missing"
      get "test_invalid_auth_token" => "anonymous#test_invalid_auth_token"
    end
  end

  it "rescues record not found with 404" do
    get :test_record_not_found
    expect(response).to have_http_status(404)
  end

  it "rescues parameter missing with 400" do
    get :test_parameter_missing
    expect(response).to have_http_status(400)
  end

  it "rescues invalid auth token with 400" do
    get :test_invalid_auth_token
    expect(response).to have_http_status(400)
  end
end
Adam Lassek
  • 35,156
  • 14
  • 91
  • 107