Forum: Ruby on Rails Routes and Testing Routes

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Steven H. (Guest)
on 2006-05-19 01:12
(Received via mailing list)
I love the routes feature for RoR...until now. I'm trying to write tests
to make sure my urls are correctly mapping to the routes I expect them
to map to. This is driving me nuts because I simply can't get any of my
tests to pass. I have thus concluded that routes must work differently
than I thought. If someone could possibly point me in the right
direction, I would really appreciate it....I will try to explain my
understanding of how routes work.

Here is my route:

[code]
map.download
'latform_filter/:software/:version/latform/:distribution_channel/:id',
    :controller => 'user/version',
    latform_filter => /all/,
    latform => /windows/linux/,
    :distribution_channel => /download/,
    :action => 'download',
    :id => /\d+/
[/code]

Ok, so the following url will map to this route:
http://mysite.com:3000/all/eudora/7.0.1/windows/download/5

Here's how I *think* the match is determined:

   1. Rails looks at the first portion of the url--"all"--and checks to
      see if it will be accepted by my route. It matches my regex
      constraint, so platform_filter => "all" is set.
   2. Rails inspects the next url item--"eudora"--checks to see if it
      matches my mapping constraint. There is no constraint, so it
      matches, sets :software => "eudora".
   3. Rails inspects the next url item--"7.0.1"--checks to see if it
      matches my mapping constraint. There is no constraint, so :version
      => "7.0.1" is set.
   4. Rails inspects the next url item--"windows"--checks to see if it
      matches my mapping constraint. It matches my regex constraint, so
      platform => "windows" is set.
   5. Rails inspects the next url item--"download"--checks to see if it
      matches my mapping constraint. It matches my regex constraint, so
      :distribution_channel => "download" is set.
   6. Rails inspects the last url item--"5"--checks to see if it matches
      my mapping constraint. It matches my regex constraint, so :id =>
      "download" is set.
   7. All the url portions mapped, so this route will be used.
   8. Rails looks at the :controller and the :action defined in this
      route and executes them, passing all the matchig url portions via
      the params hash. Ex: we can access the :software portion of the
      url like this--params[:software]

If any of the above steps do not match, the route is skipped, the keys
are cleared and the process is repeated with the next route.

So now I want to test my route with within the
User::VersionControllerTest class:

[code]
def test_route
url = "/all/eudora/7.0.1/windows|download/5"
opts = {:controller => 'user/version', latform_filter => "all",
:software => "eudora",
             :version => "7.0.1", latform => "windows",
             :distribution_channel => "download", :id => 5}

assert_recognizes(opts, url)     # Assertion fails!
end
[/code]

I really don't understand why this is failing, even the error message
doesn't make sense:

[code]
The recognized options <{"software"=>"eudora",
"platform"=>"windows",
"action"=>"download",
"platform_filter"=>"all",
"id"=>"5",
"controller"=>"user/version",
"version"=>"7.0.1",
"distribution_channel"=>"download"}> did not match
<{"software"=>"eudora",
"platform"=>"windows",
"platform_filter"=>"all",
"id"=>5,
"controller"=>"user/version",
"version"=>"7.0.1",
"distribution_channel"=>"download"}>
[/code]

The error message show identical options but says they don't match?

If anyone can shed some light on this, please do.

-Steven
Jean-François (Guest)
on 2006-05-19 01:59
(Received via mailing list)
Hello Steven,

> "platform_filter"=>"all",
> "id"=>5,
> "controller"=>"user/version",
> "version"=>"7.0.1",
> "distribution_channel"=>"download"}>
> [/code]
>
> The error message show identical options but says they don't match?

The two hashes are not the same because of  "action" => "download"
key/value pair. I guess you have to modify opts.

Hope it helps,

    -- Jean-François.
Steven H. (Guest)
on 2006-05-19 02:23
(Received via mailing list)
Thanks!

I've been staring at the computer screen way too long! :-P

However, hah, when I change "opts" I get:

def test_route
  url = "/all/#{sname}/#{vname}/#{platform_name}/download/5"
  opts = {:controller => 'user/version', :platform_filter => "all",
:software => sname,
              :version => vname, :platform => platform_name, :action =>
"download",
              :distribution_channel => "download", :id => 5}

  assert_recognizes(opts, url)
end

[ERROR]:
The recognized options <{"software"=>"matlab",
 "platform"=>"windows",
 "action"=>"download",
 "platform_filter"=>"all",
 "id"=>"5",
 "controller"=>"user/version",
 "version"=>"r2006a",
 "distribution_channel"=>"download"}> did not match
<{"software"=>"matlab",
 "platform"=>"windows",
 "platform_filter"=>"all",
 "action"=>"download",
 "id"=>5,
 "controller"=>"user/version",
 "version"=>"r2006a",
 "distribution_channel"=>"download"}>
Jean-François (Guest)
on 2006-05-19 02:39
(Received via mailing list)
Hello again Steven,

> I've been staring at the computer screen way too long! :-P

Yes, a pause for the eyes in not bad...

>   assert_recognizes(opts, url)
> end

Because 5 is different from "5" !

  -- Jean-François.
Steven H. (Guest)
on 2006-05-19 03:11
(Received via mailing list)
Even if I change it to a string the error is still occurs:

def test_route
  url = "/all/matlab/r2006a/windows/download/5"
  opts = {:controller => 'user/version', :platform_filter => "all",
              :software => "matlab", :version => "r2006a",
              :platform => "windows", :action => "download",
              :distribution_channel => "download", :id => "5"}

  assert_recognizes(opts, url)
end

[ERROR]:
The recognized options <{"software"=>"matlab",
 "platform"=>"windows",
 "action"=>"download",
 "platform_filter"=>"all",
 "id"=>"5",
 "controller"=>"user/version",
 "version"=>"r2006a",
 "distribution_channel"=>"download"}> did not match
<{"platform"=>"windows",
 "action"=>"download",
 "platform_filter"=>"all",
 "id"=>"5",
 "controller"=>"user/version",
 "distribution_channel"=>"download"}>


@michael_daines
No that's just a typo :-(
The actual platform regex is /windows|linux/
As far as the "ltform_filter" That was the emotions feature in my email
client striping off the :p
from :platform_filter.


-Steven
Jean-François (Guest)
on 2006-05-19 03:26
(Received via mailing list)
2006/5/19, Steven H. <removed_email_address@domain.invalid>:
>   assert_recognizes(opts, url)
>  "distribution_channel"=>"download"}> did not match <{"platform"=>"windows",
>  "action"=>"download",
>  "platform_filter"=>"all",
>  "id"=>"5",
>  "controller"=>"user/version",
>  "distribution_channel"=>"download"}>

Can you post your download route again, is the :software line
missing ?

   -- Jean-François.
Steven H. (Guest)
on 2006-05-19 03:48
(Received via mailing list)
Ok I finally got the test to pass.  I think what was throwing me was
that I had :id => 5
when it should have been :id => "5"  Then I kept frantically changing
the keys and not realize that
there literally wasn't a match.

def test_download_via_get_before_authentication()
    url = "/all/matlab/r2006a/windows/download/5"
    opts =     {:controller => "user/version", :platform_filter =>
"all",
                      :software => "matlab", :version => "r2006a",
:platform =>  "windows",
                      :distribution_channel => "download",
                      :action => 'download', :id => "5"}

     assert_recognizes(opts, url)
end

[OUTPUT]:
2 tests, 3 assertions, 0 failures, 0 errors


I do have a question though, do the hashes that I pass via the "opts"
argument have to include the total sum of the keys in my route?

if my route is:
  map.download
':platform_filter/:software/:version/:platform/:distribution_channel/:id',
    :controller => 'user/version',
    :platform_filter => /all/,
    :platform =>  /windows/,
    :distribution_channel => /download/,
    :action => 'download',
    :id => /\d+/

I can't just pass in {:platform_filter, :software, :version, :platform,
:distribution_channel, :id} like I can with redirect_to()
or url_for() ?  I would also need to include the :controller and :action
?

I guess the answer is yes since my test is now passing, but to me this
seem a bit unintuitive.  Anyway, thanks to everyone for the help and
patience.

-Steven
This topic is locked and can not be replied to.