[rspec-users] Spec'ing redirect with arbitrary parameters

nicholas a. evans nick at ekenosen.net
Wed May 23 15:24:40 EDT 2007

On 5/22/07, Pat Maddox <pergesu at gmail.com> wrote:
> On 5/21/07, Brandon Keepers <bkeepers at gmail.com> wrote:
> > On May 21, 2007, at 5:09 PM, Pat Maddox wrote:
> > > I've got the following expectation:
> > >
> > > response.should redirect_to(:action => "new", :video_id => "1",
> > > :process_id => "2", :origin_id => "3")
> >
> > > that fails with this error message:
> > >
> > > expected redirect to {:video_id=>"1", :process_id=>"2",
> > > :origin_id=>"3", :action=>"new"}, got redirect to
> > > "http://test.host/videos/1/screenshot_selections/new?
> > > process_id=2&origin_id=3",
> > > which cannot be routed within this application (spec using the URL
> > > string if the redirection is to an external address)

Interesting.  I submitted the patch that changed around "should
redirect_to()" behavior a bit, and I confess, I haven't had the
opportunity to use it much with named resources much yet.  That was to
get around an intermittent bug when the URL contained parameters on
the query string (but in a somewhat random order, so a simple string
comparison would intermittently fail).

The current behavior of the redirect_to matcher, when expecting a
hash, is to convert that hash into a URL and then *back* into a hash
(to pick up any magic dust that Rails might sprinkle in along the
way).  It also has to convert the response.redirect_url into a hash,
in order to do the comparison (and pick up any routing magic).  But
Rails doesn't exactly make that easy for me.  ;-)

And it looks like my approach breaks with nested resources!  It seems
to work fine for the first level.  I was rather surprised to find that
the following will not work:


So, I don't have the time to look into it at the moment, but if
someone else knows how to get the correct hash from that URL path,
they could place that solution in line 48 of

> > It looks like you're using resources.  If that's the case, use named
> > routes:
> >
> > response.should redirect_to(resource_path(@video, @process, @origin))
> Cool, I changed it to
> response.should redirect_to(new_screenshot_selection_path(:video_id =>
> "1", :process_id => "2", :origin_id => "3"))
> and it works fine now.  Thanks for the tip.

Yeah... if you are using resources, you should be using the named
route anyway.  ;-)  But I wonder if the unordered hash issue will
still cause occasional heartache...

new_screenshot_selection_path(:video_id => "1", :process_id => "2",
:origin_id => "3")
could theoretically generate both of the following:

Yuck!  Maybe the right solution is to enforce a strictly alphabetical
ordering within Rails itself?    Or should any URL which is routable
within the app be converted to a hash for comparison?


More information about the rspec-users mailing list