RSpec testing redirect to URL with GET params

parameters, response, rspec, ruby, ruby-on-rails

Solution

From the documentation, the expected redirect path can match a regex:

expect(response).to redirect_to %r(\Ahttp://example.com)

To verify the redirect location's query string seems a little bit more convoluted. You have access to the response's location, so you should be able to do this:

response.location
# => http://example.com?foo=1&bar=2&baz=3

You should be able to extract the querystring params like this:

redirect_params = Rack::Utils.parse_query(URI.parse(response.location).query)
# => {"foo"=>"1", "bar"=>"2", "baz"=>"3"}

And from that it should be straightforward to verify that the redirect params are correct:

expect(redirect_params).to eq("foo" => "1", "baz" => "3", "bar" => "2")
# => true

If you have to do this sort of logic more than once though, it would definitely be convenient to wrap it all up into a custom rspec matcher.

Problem

Let's say I have a `FoosController` with a `redirect_to_baz` method. ``` class FoosController < ApplicationController def redirect_to_baz redirect_to 'http://example.com/?foo=1&bar=2&baz=3' end end ``` I'm testing this with `spec/controllers/foos_controller_spec.rb`: ``` require 'spec_helper' describe FoosController, :type => :controller do describe "GET redirect_to_baz" do it "redirects to example.com with params" do get :redirect_to_baz expect(response).to redirect_to "http://example.com/?foo=1&bar=2&baz=3" end end end ``` It works. However, if someone swaps the query string parameters (e.g. `http://example.com/?bar=2&baz=3&foo=1`), the test fails. What's the right way of testing this? I would like to do something like: ``` expect(response).to redirect_to("http://example.com/", params: { foo: 1, bar: 2, baz: 3 }) ``` I looked at the documentation and I tried searching for `response.parameters`, but I didn't find anything like that. Even `Hash#to_query` doesn't seem to solve this problem. Any help would be greatly appreciated.

Original source