3

I wrote a small test to check redirecting and URL parameters. Strangely the test fails, even though the error message seems to indicate the result is actually correct:

Failure/Error: response.should redirect_to(movies_path(:sort => 'title'))

Expected response to be a redirect to 
<http://test.host/movies?sort=title> 
but was a redirect to 
<http://test.host/movies?ratings%5BG%5D=G&ratings%5BNC-17%5D=NC-17&ratings%5BPG%5D=PG&ratings%5BPG-13%5D=PG-13&ratings%5BR%5D=R&sort=title>

The URLs are identical (as they should be) and the expected parameter 'sort=title' is included in the parameters of the actual result. I believe this is a valid situation...

Acoording to http://api.rubyonrails.org/classes/ActionDispatch/Assertions/ResponseAssertions.html#method-i-assert_redirected_to: "This match can be partial, such that assert_redirected_to(controller: "weblog") will also match the redirection of redirect_to(controller: "weblog", action: "show") and so on."

SOLUTION: I was not able to get the proposal of the selected answer to work, but the reply was useful in explaining that the 'partial' match in the above link is somewhat misleading, and the code did not work as expected. So, I created a Hash with all the parameters received, and added them to the 'should redirect_to' test:

response.should redirect_to(movies_path(:sort => 'title', :ratings => rest))

where 'rest' is that hash.

Freedom_Ben
  • 11,247
  • 10
  • 69
  • 89
jcoppens
  • 5,306
  • 6
  • 27
  • 47

2 Answers2

3

The documentation is misleading. Internally, assert_redirected_to calls normalize_argument_to_redirection, which (when a hash is given as the argument) calls url_for before performing the comparison. Basically, a partial match will work only if the route has the default pattern :controller/:action/:id, and your asserted path is a hash with the controller or controller and action as keys.

bgates
  • 2,333
  • 1
  • 18
  • 12
  • I think I understand that. I could not find how to do suggestion "your asserted path is a hash with the controller or controller and action as keys", but I was able to extend the hash with the missing parameters. – jcoppens Aug 16 '13 at 23:21
  • 1
    To clarify, the only partial matches which would work are `:controller => 'movies'` or `:controller => 'movies', :action => 'index'`. I wouldn't be surprised if the documentation on that method predates the introduction of named routes like `movies_path`. – bgates Aug 17 '13 at 00:13
  • Appreciate the explanation, @bgates. I've tried those combinations, and some others, but didn't have any luck. I was somewhat pressed in time with other projects - even had a system break down in my wife's pharmacy. I'll again check later. As edited above, I did finf a solution. – jcoppens Aug 17 '13 at 04:22
2

You should put something like:

response.should redirect_to(movies_path(:sort => 'title', :ratings => "Ratings"))

It should be a complete path for the redirect.

Rodrigo Oliveira
  • 913
  • 5
  • 16
  • 1
    Hello Rodrigo. By 'complete path', do you mean all the parameters are really necessary? According to the rspec docs, even with an example, that partial matches are accepted. What if I cannot know the remaining url parameters, but must only check from one of them? – jcoppens Aug 16 '13 at 19:16
  • I think so. The path is different depending on parameters. – Rodrigo Oliveira Aug 16 '13 at 22:26