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..
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('あ')
.