3
votes

I am trying to pass the test cases for pages 404 & 500. But I am having a lot of problems

1) Firstly I have a page 500.html.erb inside app/views/errors/ which is not getting called.
2) If I run the below test my system freeze and I need to restart my system
3) If I comment this line expect{get "/errors/foo"}.to raise_exception(ActionController::RoutingError). So in my controller Action name page 500 gets passed as params but still, my system get freeze

Can anyone help me to fix this issue

errors_spec.rb

 require "spec_helper"

    describe "Errors" do

      before do
        allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new("production"))
      end

      it "renders the 500 page" do
         get "/errors/500"
         expect(response.status).to eq(500)
      end

      it "renders the 404 page" do
        get "/errors/404"
        expect(response.status).to eq(404)
      end

      it "raises an exception if the page doesn't exist" do
        expect {get "/errors/foo"}.to raise_exception(ActionController::RoutingError)
      end
    end 

errors_controller.rb

class ErrorsController < ApplicationController
  skip_before_filter :authenticate_user!

  EXTERNAL_ERRORS = ['sso']
  VALID_ERRORS = ['404', '403', '500', 'maintenance'] + EXTERNAL_ERRORS

  def show
    status = external_error? ? 500 : 200
    render page , status: status
  end

  def blocked
  end

  private

  def page
    if VALID_ERRORS.include?(params[:id])
      params[:id]
    else
      raise(ActionController::RoutingError.new("/errors/#{params[:id]} not found"))
    end
  end

  def external_error?
    EXTERNAL_ERRORS.include?(params[:id])
  end
end
1
Is this a test-only issue, i.e. does it work when you open the URLs in a browser? - Stefan
It is working fine when I am trying to hit from browser - ankur
Can you open any other URLs in your tests without freezing the system, i.e. is the problem specific to the ErrorsController? - Stefan
Yes I can open other URL in errors_controller except 404 and 500 - ankur
@Stefan - Do you have any idea where am I doing wrong? - ankur

1 Answers

0
votes

In your code, you are setting status 200 when /errors/500 gets called.

  def show
    # external_error? returns false.
    status = external_error? ? 500 : 200
    render page , status: status # Status is 200.
  end

Use debuggers like pry or byebug to check status. There is not any problem in your test case. Try this.

class ErrorsController < ApplicationController
  skip_before_filter :authenticate_user!

  EXTERNAL_ERRORS = ['sso']
  VALID_ERRORS = ['404', '403', '500', 'maintenance'] + EXTERNAL_ERRORS

  def show
    status = error_500? ? 500 : 200
    render page , status: status
  end

  def blocked
  end

  private

  def page
    if VALID_ERRORS.include?(params[:id])
      params[:id]
    else
      raise(ActionController::RoutingError.new("/errors/#{params[:id]} not found"))
    end
  end

  def external_error?
    EXTERNAL_ERRORS.include?(params[:id])
  end

  def error_500?
    ['500'].include?(params[:id]) || external_error?
  end
end