This project is archived and is in readonly mode.
[PATCH] assert_recognizes does not support constraints
-
Ryan Bigg
- 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)
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
Here's a working (in this case, failing) patch.
-
Dim
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
Ok, this is my final go - I promise!
-
Dim
- Title changed from assert_recognizes does not support constraints to [PATCH] assert_recognizes does not support constraints
-
Brian Ploetz
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 endAnd 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:inblock 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:inrecognized_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:inblock 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
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
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") endFor 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 endThere 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
- State changed from incomplete to open
- Milestone set to 3.x
- Assigned user set to Andrew White
-
Repository
- State changed from open to resolved
(from [e9ae88af2038f4d29e437a937f2ce63ffd935d5f]) Fix assert_recognizes with block constraints [#5805 [PATCH] assert_recognizes does not support constraints state:resolved] https://github.com/rails/rails/commit/e9ae88af2038f4d29e437a937f2ce...
-
Repository
(from [385be358cfa80cedff113ba57338e83ca8ac2b52]) Fix assert_recognizes with block constraints [#5805 [PATCH] assert_recognizes does not support constraints state:resolved] https://github.com/rails/rails/commit/385be358cfa80cedff113ba57338e...
