This project is archived and is in readonly mode.
[PATCH] assert_recognizes does not support constraints
Reported by ms (at budstikka) | October 14th, 2010 @ 12:27 PM | in 3.x
In a Rails 3.0.0 app with a HomeController and an #index action:
# routes.rb
class FooConstraint
def self.matches?(request)
false # Ensures routes with this constrains should _never_ match
end
end
Constraints::Application.routes.draw do
constraints FooConstraint do
root :to => 'home#index'
end
end
# home_controller_test.rb
require 'test_helper'
class HomeControllerTest < ActionController::TestCase
test "should route to home" do
assert_recognizes({ :controller => "home", :action => "index" }, "/")
end
end
This test should fail, as it does when I try to hit / in my web browser ('No route matches "/"').
It seems the code in FooConstrains.matches? is never run.
Comments and changes to this ticket
-
Ryan Bigg October 14th, 2010 @ 12:33 PM
- State changed from new to incomplete
- Importance changed from to Low
Please attach a failing test case to this ticket as per the Contributing to Rails guide that can be found at http://guides.rubyonrails.org.
-
ms (at budstikka) October 15th, 2010 @ 11:41 AM
I haven't been able to make a failing test case, as there is no assert_not_recognizes method. The test case in the attached patch should fail, but it does not. I couln't find any test for the routing assert_* methods themselves. I'd be happy to write more correct tests with a little guidance.
The main point here is that assert_recognizes does not seem to restrict the routes when the tests are run in the way the constraints do when the code is run in the app and accessed from a web browser.
-
Dim November 8th, 2010 @ 01:37 PM
Apologies, please ignore the last post. Here's an even better patch (not sure if it's the best way to validate constraints though).
-
Dim November 11th, 2010 @ 03:49 PM
- Title changed from assert_recognizes does not support constraints to [PATCH] assert_recognizes does not support constraints
-
Brian Ploetz December 13th, 2010 @ 05:42 PM
Actually, I seem to be able to test some constraints, but not others. Section 3.9 of the Routing guide says:
3.9 Request-Based Constraints
You can also constrain a route based on any method on the Request object that returns a String.
I'm able to test a constraint on :format, but not on :protocol. For example:
# config/routes.rb ProtocolBug::Application.routes.draw do scope :constraints => { :format => /(json|xml)/ } do match '/foos.(:format)' => 'foos#index', :via => :get end end # app/controllers/foos_controller.rb class FoosController < ApplicationController # GET /foos?... def index render :nothing => true end end # test/functional/foos_controller_test.rb require 'test_helper' class FoosControllerTest < ActionController::TestCase test "should route to index" do assert_recognizes({ :controller => "foos", :action => "index", :format => "xml" }, "/foos.xml") end test "should fail to route to index" do assert_recognizes({ :controller => "foos", :action => "index", :format => "bogus" }, "/foos.bogus") end end
And when I run the functional tests the test with the bogus format fails (as MS notes above, there's no "assert_not_recognized", so I'm just letting it fail here for you to see that the routing constraint is working correctly).
[bploetz:~/workspace/protocol_bug]> rake test:functionals
Started
E.
Finished in 0.027135 seconds.
1) Error: test_should_fail_to_route_to_index(FoosControllerTest): ActionController::RoutingError: No route matches "/foos.bogus" /Users/bploetz/.rvm/gems/ruby-1.9.2-p0@server/gems/actionpack-3.0.3/lib/action_dispatch/routing/route_set.rb:523:in
recognize_path'
/Users/bploetz/.rvm/gems/ruby-1.9.2-p0@server/gems/actionpack-3.0.3/lib/action_dispatch/testing/assertions/routing.rb:211:in
recognized_request_for'
/Users/bploetz/.rvm/gems/ruby-1.9.2-p0@server/gems/actionpack-3.0.3/lib/action_dispatch/testing/assertions/routing.rb:44:in
assert_recognizes' test/functional/foos_controller_test.rb:8:in
block in <class:FoosControllerTest>'2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
However, if I add a constraint on :protocol => "https://", it does not honor it in the test.
# config/routes.rb ProtocolBug::Application.routes.draw do scope :constraints => { :protocol => "https://" } do match '/foos' => 'foos#index', :via => :get end end # test/functional/foos_controller_test.rb require 'test_helper' class FoosControllerTest < ActionController::TestCase test "should route to index" do assert_recognizes({ :controller => "foos", :action => "index", :protocol => "https://" }, "/foos") end end
[bploetz:~/workspace/protocol_bug]> rake test:functionals
Started
E
Finished in 0.007458 seconds.
1) Error: test_should_route_to_index(FoosControllerTest):
ActionController::RoutingError: No route matches "/foos"
/Users/bploetz/.rvm/gems/ruby-1.9.2-p0@server/gems/actionpack-3.0.3/lib/action_dispatch/routing/route_set.rb:523:inrecognize_path' /Users/bploetz/.rvm/gems/ruby-1.9.2-p0@server/gems/actionpack-3.0.3/lib/action_dispatch/testing/assertions/routing.rb:211:in
recognized_request_for' /Users/bploetz/.rvm/gems/ruby-1.9.2-p0@server/gems/actionpack-3.0.3/lib/action_dispatch/testing/assertions/routing.rb:44:inassert_recognizes' test/functional/foos_controller_test.rb:4:in
block in <class:FoosControllerTest>'1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
And the protocol constraint seems to be correct according to rake routes:
[bploetz:~/workspace/protocol_bug]> rake routes
foos GET /foos(.:format) {:protocol=>"https://", :controller=>"foos", :action=>"index"}
I don't know if this is a different issue than this one, but figured I'd point it out.
-
Steve Schwartz February 12th, 2011 @ 08:38 PM
What is the status of this ticket? I am also encountering this problem, in that the routing constraint works fine, but the specs fail when they should be passing. I'd like to help fix it if the patch still needs work.
-
Andrew White February 13th, 2011 @ 04:40 PM
In terms of testing a constraint against a protocol you have to pass a full url to assert_recognizes, e.g:
test "should route to index when using https" do assert_recognizes({ :controller => "foos", :action => "index" }, "https://test.host/foos") end
For testing that a route fails to recognize then wrap the assert_recognizes in an assert_raises, e.g.:
test "should not route to index when using http" do assert_raises(ActionController::RoutingError) do assert_recognizes({ :controller => "foos", :action => "index" }, "http://test.host/foos") end end
There is an issue with class based constraints as the recognize_path method in ActionDispatch::Routing::RouteSet bypasses the constraints app. However I think I can fix that with a bit of refactoring of ActionDispatch::Routing::Mapper::Constraints so that I can check a constraint without doing a call.
Be aware though this is a functional test method - if there's a dependency in your class based constraint that needs the full application running then you're best off using an integration test, RSpec request spec or Cucumber feature for checking the constraint is working.
-
Andrew White February 13th, 2011 @ 04:48 PM
- State changed from incomplete to open
- Milestone set to 3.x
- Assigned user set to Andrew White
-
Repository February 13th, 2011 @ 11:41 PM
- State changed from open to resolved
(from [e9ae88af2038f4d29e437a937f2ce63ffd935d5f]) Fix assert_recognizes with block constraints [#5805 state:resolved] https://github.com/rails/rails/commit/e9ae88af2038f4d29e437a937f2ce...
-
Repository February 13th, 2011 @ 11:41 PM
(from [385be358cfa80cedff113ba57338e83ca8ac2b52]) Fix assert_recognizes with block constraints [#5805 state:resolved] https://github.com/rails/rails/commit/385be358cfa80cedff113ba57338e...
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>
People watching this ticket
Attachments
Referenced by
- 5805 [PATCH] assert_recognizes does not support constraints (from [e9ae88af2038f4d29e437a937f2ce63ffd935d5f]) Fix ass...
- 5805 [PATCH] assert_recognizes does not support constraints (from [385be358cfa80cedff113ba57338e83ca8ac2b52]) Fix ass...