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?
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.