Search code examples
ruby-on-railsrspec-rails

In rspec request specs how to test the actual behavior of endpoints being called with non-ascii characters in the URL?


When writing a test for rspec that calls an endpoint that has a non-ascii character, the test throws InvalidURIError - this is expected because non-ascii characters are not valid in URIs.

However the same request made in postman or curl produces a ActiveController::RouterError.

# Assuming a controller called BooksController with a show action that takes :book_id as a parameter

describe BooksController do
  describe 'GET #show' do
    get :show, id: 'あ' # Will throw InvalidURIError - making the same request via curl or postman will produce 404 ActiveController::RouterError
 end
end

This discrepancy is because rspec under the hood at some point uses the URI library to parse the intended url. But this means that the error is thrown before any actual code is tested - making it a useless test - however the behavior of return a 404/RouterError is still behavior I'd like to test and document.

What options are available here? Have other people came across this before? Are there ways to write this test so it doesn't use URI? And is that even a good idea?

For the test I wrapped it in a block that changed Rails.application.env_config to have the values action_dispatch.show_exceptions true and action_dispatch.show_detailed_exceptions false - but this error continued to occur which is what led me to inspect the stacktrace in more detail and realize this was occuring within the test itself and not actual code within the application logic.

But I'm actually at a dead-end here, leaning toward this just not being something that can be tested within rspec. I feel like there should be a way to test this at a lower level, and I even tried using net/https although I ran into the issue that this made an actual web request and was therefore blocked by webmock, and it didn't seem like good test code either way..


Solution

  • It's the way default Rails test-helpers work: they have assumed that URLs are valid (already escaped).

    There is a number of issues in rspec-rails and rack-test about it. Example: https://github.com/rspec/rspec-rails/issues/2494

    In order to reproduce browser (or curl / postman) behaviour in your tests - ensure all your non-ascii symbols are escaped: CGI.escape('あ').