Search code examples
ruby-on-railsrspecruby-on-rails-5rspec-rails

Rspec not processing param on get request


I am upgrading a legacy project to rails 5.0 and now one of the tests is failing. The test is as follows:

describe "tag searching" do
    before (:each) do
      @admin = FactoryGirl.create(:admin)
      stub_authenticate_client(@admin)
    end

    it "doesnt break a badly formatted tag search" do
      get :search, params: {search: {tags: "a"}}
      expect(assigns(:tags)).to_not be_nil
      expect(assigns(:reports)).to_not be_nil
    end

    it "doesnt break with a search with no tag params" do
      get :search, params: {search: {}}
      expect(assigns(:tags)).to_not be_nil
      expect(assigns(:reports)).to_not be_nil
    end
  end

The error occurs in the second test, the search with no tag params. In my controller I call params[:search][:tags] and I get

Failure/Error: if params[:search][:tags].nil?

     NoMethodError:
       undefined method `[]' for nil:NilClass

It seems that search param is not passing through, but it works with the first test.

The controller:

def search
    search_params = params['search']
    @reports = Report.includes([Report::TAG_CATEGORIES.keys].flatten)
                     .paginate(:page => params['page'],
                               :per_page => 50)

    tags = extract_tags_from_params(search_params['tags']) # ERROR HERE
    tags.each do |category, search_values|
      @reports = @reports.tagged_with(search_values, match: :all, on: category) if !search_values.blank?
    end

    @reports = @reports.where(#some queries related to search param)
    @tags = Report.flattened_tags
    render 'index'
end

  def search_params
    params.permit(search: {})
  end

Any thoughts?


Solution

  • The spec is failing due to the fact that RSpec automatically omits empty parameters.

    There is a pretty simple workaround for this case:

    it "doesnt break with a search with no tag params" do
      get :search, params: {search: { foo: ''}}
      expect(assigns(:tags)).to_not be_nil
      expect(assigns(:reports)).to_not be_nil
    end
    

    But the fact that you´re getting a NoMethodError should be telling you that your controller action is broken and should either bail early if the search param is not present (use params.require(:search)) or you should be using the safe navigation operator, .fetch or .try to avoid a NoMethodError.

    A missing param should not result in a 500 Internal Server Error.