This project is archived and is in readonly mode.

#3263 ✓invalid
Giuseppe Bertini

Failing functional test of a named route

Reported by Giuseppe Bertini | September 26th, 2009 @ 05:41 PM

Given the following named route:

map.accept_invitation '/accept_invitation/:id', :controller => "invitations", :action => "accept", :method => "get"

and the following controller:

class InvitationsController < ApplicationController
  def accept
  end
end

This test will fail:

class InvitationsControllerTest < ActionController::TestCase
  test "the post accept invitation should be successful" do
    get :accept, :id => "1"
    assert_response :success
  end
end

...with the following error:

ActionController::RoutingError: No route matches
{:controller=>"invitations", :action=>"accept", :id=>"1"}

while the app does not complain upon receiving the request:

http://localhost:3000/accept_invitation/3

I have posted a dummy app to reproduce the problem at

git://github.com/giuseb/spec_named_route.git

--Giuseppe

Comments and changes to this ticket

  • sr.iniv.t

    sr.iniv.t September 26th, 2009 @ 07:57 PM

    Giuseppe, can you please specify the rails version you're on?

    Seems to work for me on 2.3.3:

    ts > rails -v
    Rails 2.3.3
    
    ts > cat config/routes.rb 
    ActionController::Routing::Routes.draw do |map|
      map.accept_invitation '/accept_invitation/:id', :controller => "invitations", :action => "accept", :method => "get"
      map.connect ':controller/:action/:id'
    end
    
    ts > cat app/controllers/invitations_controller.rb 
    class InvitationsController < ApplicationController
      def accept; end
    end
    
    ts > cat test/functional/invitations_controller_test.rb 
    require 'test_helper'
    
    class InvitationsControllerTest < ActionController::TestCase
      test "the post accept invitation should be successful" do
        get :accept, :id => "1"
        assert_response :success
      end
    end
    
    ts > ruby -Itest test/functional/invitations_controller_test.rb 
    Loaded suite test/functional/invitations_controller_test
    Started
    .
    Finished in 0.082477 seconds.
    
    1 tests, 1 assertions, 0 failures, 0 errors
    
  • Giuseppe Bertini

    Giuseppe Bertini September 26th, 2009 @ 10:24 PM

    Hi, I am on rails 2.3.4.

    I believe that the reason your test passes is that, after the named route in question, you have the catch-all route (:controller/:action/:id). What happens if you remove the latter?

    Cheers,
    Giuseppe

  • CancelProfileIsBroken

    CancelProfileIsBroken September 27th, 2009 @ 11:30 AM

    • Tag changed from functional, routing, test to bugmash, functional, routing, test
  • John Trupiano

    John Trupiano September 27th, 2009 @ 04:13 PM

    verified, when removing the default routes this error does indeed occur.

    It's noteworthy that removing :method => 'get' from the route eliminates the problem.

  • Elad Meidar

    Elad Meidar September 27th, 2009 @ 08:10 PM

    +1 verified.

    it might have something to do with the use of accept as a method name? maybe get :accept is confusing for some reason...

  • Elad Meidar

    Elad Meidar September 27th, 2009 @ 08:19 PM

    No it's not.... i tried a different action name and it still failed... possibly this has something to do with the catch-all route that may be required.

  • Gaius Centus Novus

    Gaius Centus Novus September 27th, 2009 @ 10:41 PM

    Does the view app/views/invitations/accept.html.erb exist? Your empty definition of accept implicitly renders this view (or the more general app/views/inivitations/accept.erb). If that doesn't exist, you'll get a 404.

  • Gaius Centus Novus

    Gaius Centus Novus September 27th, 2009 @ 10:42 PM

    Also, you don't mean :method => :get, you mean :conditions => { :method => :get }.

  • Matías Flores

    Matías Flores September 28th, 2009 @ 05:13 AM

    I verified the behavior you described on 2-3-stable, but I'm not sure this is a bug.
    I agree with Gaius, correct syntax is :conditions => {:method => :get}, not just :method => 'get'

  • Giuseppe Bertini

    Giuseppe Bertini September 28th, 2009 @ 06:28 AM

    Suppose you have the following two named routes (along with controller actions and .erb templates):

    ActionController::Routing::Routes.draw do |map|
      map.accept_invitation '/accept_invitation/:id', :controller => "invitations", :action => "accept", :conditions => {:method => "get"}
      map.view_invitation '/view_invitation/:id',   :controller => "invitations", :action => "view",   :method => "get"
    end
    

    and the following two test:

    test "the get accept invitation should be successful" do
      get :accept, :id => "1"
      assert_response :success
    end
    test "the get view invitation should be successful" do
      get :view, :id => "1"
      assert_response :success
    end
    

    The first passes, while the second returns an error, seemingly supporting Gaius and Matías.
    However, if you stick the following 2 URLs in your browser:

    http://localhost:3000/accept_invitation/1
    http://localhost:3000/view_invitation/1

    ...then the FORMER request fails, while the latter succeeds.

  • Giuseppe Bertini

    Giuseppe Bertini September 28th, 2009 @ 08:24 AM

    Which leads to the following proposal.

    • The testing framework simply enforces the proper :conditions => {:method => :get} syntax, so there's no problem there.
    • It's really the routing that behaves funny.

    Reasonable?

  • Pablo Calderon

    Pablo Calderon October 27th, 2009 @ 06:21 PM

    I have run into the same problem with restful routes. Something as simple as the following will fail in testing.

    routes.rb
    map.resources :products
    
    products_controller_test.rb
    test "should get index" do
      get :index
      assert_response :success
    end
    
    Whatever format the testing framework requires you would think that the generated routes will be correct. This must be a bug, surely resource routes are meant to be testable in functional tests.
    
  • Prem Sichanugrist (sikachu)

    Prem Sichanugrist (sikachu) January 25th, 2010 @ 01:51 PM

    • State changed from “new” to “invalid”
    1. If you put :method => "get" in your route, and not :conditions => {:method => :get}, you just made typos there
    • You should specify :method as symbol
    • If you don't put it in :conditions, path will be recognized as :requirement => {:method => "get}. So no way the test will pass.

    However, somehow the :method will be included in the params[] when you request via browser. So in the post number 12 you will be able to visit view_invitation_path.

    I don't think this is really a problem. You just need to use :conditions => {:method => :get}, and your problem will go away

  • csnk

    csnk May 18th, 2011 @ 08:24 AM

    • Importance changed from “” to “”

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages