Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested root route results in falsely passing specs #843

Closed
balexand opened this issue Nov 1, 2013 · 14 comments
Closed

Nested root route results in falsely passing specs #843

balexand opened this issue Nov 1, 2013 · 14 comments

Comments

@balexand
Copy link

balexand commented Nov 1, 2013

To reproduce, create an empty Rails 4.0.0 project and add to your Gemfile:

group :development, :test do
  gem 'rspec-rails', '2.14.0'
end

Then run bundle and rails generate rspec:install.

Scaffold a test model/controller with rails g scaffold post and bundle exec rake db:migrate RAILS_ENV=test. The routes file (excluding comments) looks like:

Rspecmadness::Application.routes.draw do
  resources :posts
end

Running the generated controller spec passes:

bundle exec rspec spec/controllers/posts_controller_spec.rb

Change the routes file to look like this:

Rspecmadness::Application.routes.draw do
  # resources :posts
end

and run the same controller spec. It now fails with errors saying "No route matches...". That's what we expect.

But then change the routes to look like:

Rspecmadness::Application.routes.draw do
  # resources :posts

  namespace :admin do
    root to: redirect("http://google.com/")
  end
end

Run the controller spec again. I'd expect to get a "No route matches..." error. But instead, the request is routed to PostsController as if the route existed.

In fact, in our app we noticed that after adding the nested root, all controller specs will route successfully, even if their corresponding routes are deleted.

@balexand
Copy link
Author

balexand commented Nov 1, 2013

It looks like this is a bug in Rails since the exception should be raised from ActionController::TestCase:

  1) PostsController GET new assigns a new post as @post
     Failure/Error: get :new, {}, valid_session
     ActionController::UrlGenerationError:
       No route matches {:controller=>"posts", :action=>"new"}
     # /Users/balexand/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/journey/formatter.rb:35:in `generate'
     # /Users/balexand/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/routing/route_set.rb:576:in `generate'
     # /Users/balexand/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/routing/route_set.rb:606:in `generate'
     # /Users/balexand/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/routing/route_set.rb:601:in `generate_extras'
     # /Users/balexand/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/routing/route_set.rb:597:in `extra_keys'
     # /Users/balexand/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_controller/test_case.rb:189:in `assign_parameters'
     # /Users/balexand/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_controller/test_case.rb:557:in `process'
     # /Users/balexand/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_controller/test_case.rb:64:in `process'
     # /Users/balexand/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_controller/test_case.rb:469:in `get'
     # ./spec/controllers/posts_controller_spec.rb:51:in `block (3 levels) in <top (required)>'
...

I've been able to reproduce the problem using the default Rails testing setup (no rspec). And it affects Rails 4.0.0, but not 4.0.1 which was just released today.

I guess we'll be upgrading. Sigh...

@balexand balexand closed this as completed Nov 1, 2013
@soulcutter
Copy link
Member

Thanks for tracking this down - definitely an interesting one!

@prusswan
Copy link

I'm getting a similar error but possibly for a completely different reason on Rails 4.0.2. Yet to find a way to rescue from the error in the test (which is NOT what I'm testing for)

 Failure/Error: get :index
     ActionController::UrlGenerationError:
       No route matches {:action=>"index", :controller=>"api/v1/availabilities"}
     # /home/prusswan/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.2/lib/action_dispatch/journey/formatter.rb:39:in `generate'
     # /home/prusswan/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.2/lib/action_dispatch/routing/route_set.rb:601:in `generate'
     # /home/prusswan/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.2/lib/action_dispatch/routing/route_set.rb:631:in `generate'
     # /home/prusswan/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.2/lib/action_dispatch/routing/route_set.rb:626:in `generate_extras'
     # /home/prusswan/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.2/lib/action_dispatch/routing/route_set.rb:622:in `extra_keys'
     # /home/prusswan/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.2/lib/action_controller/test_case.rb:189:in `assign_parameters'
     # /home/prusswan/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.2/lib/action_controller/test_case.rb:557:in `process'
     # /home/prusswan/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.2/lib/action_controller/test_case.rb:64:in `process'
     # /home/prusswan/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.2/lib/action_controller/test_case.rb:469:in `get'

@JonRowe
Copy link
Member

JonRowe commented Dec 17, 2013

I'd suggest you figure out why your route isn't matching... as you won't be able to proceed without a valid route.

@prusswan
Copy link

@JonRowe I know why the route is not matching (again this is not what I'm testing for), but it is disturbing that usual methods involving bypass_rescue and rescue_from does not seem to work for this exception

@JonRowe
Copy link
Member

JonRowe commented Dec 18, 2013

Not really, those are both Rails methods specific to controllers, if you never enter the scope of the controller they cover then they won't be triggered. If you want to actually rescue the exception in the test then use a Ruby rescue e.g.

begin
  get :index
rescue ActionController::UrlGenerationError:
  raise 'broken route'
end

@prusswan
Copy link

@JonRowe I have already tried that in ApplicationController, but it is not raised at that level, so this is something that is only triggered in Rails.env.test? I can rescue from it in the test, that is certainly not an issue, but I'm more interested in finding out why it is not entering my custom error handling code, and therefore could not be handled like other exceptions, at least on the controller level. I do have a route like the following:

 get "*path", to: "errors#catch_404"    # used for custom error handling

@JonRowe
Copy link
Member

JonRowe commented Dec 18, 2013

Rails handles routes "not found" differently in development, test and production.

@prusswan
Copy link

Okay I see now this is related to rails/journey#59 and it has been closed, is there anything that can be done to align the behavior in the specs?

@JonRowe
Copy link
Member

JonRowe commented Dec 18, 2013

Yes, as specified in that issue: you specify all of the parameters so the route resolves correctly.

@JonRowe
Copy link
Member

JonRowe commented Dec 18, 2013

Meaning, the behaviour of this is left to Rails, rspec-rails is an integration for Rails test helpers so they work in rspec, we don't tend to correct that behaviour, preferring it be handled upstream.

@prusswan
Copy link

@JonRowe noted, but I agree with what is mentioned in that issue:

It might appear elegant to disallow that, but it fails to reflect the behaviour of the production environment while exactly that should be the goal of the testing env.

Just throwing this out, maybe there can be a better solution

@JonRowe
Copy link
Member

JonRowe commented Dec 18, 2013

Feel free to discuss it with the Rails core team, our aim (with rspec-rails) is to reflect their behaviour.

@benjaminwood
Copy link

I know this is an old issue, but I came across this today and figured I could shed some light for other internet travelers.

I believe the core of the problem was first reported here: rails/rails#6459

First attempt to address the problem was here: rails/journey#47

And the actual fix was here: rails/rails@aba0a17

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants