[rspec-devel] [ rspec-Bugs-6541 ] catch-22 using named routes

noreply at rubyforge.org noreply at rubyforge.org
Fri Jan 19 05:11:30 EST 2007


Bugs item #6541, was opened at 2006-11-07 08:39
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3149&aid=6541&group_id=797

Category: rails plugin
Group: None
Status: Open
Resolution: None
Priority: 3
Submitted By: Nobody (None)
Assigned to: Nobody (None)
Summary: catch-22 using named routes

Initial Comment:
The recommended way specify controller redirects is to use

  controller.should_redirect_to 'path or hash'

*before* calling the action.

However, you cannot use named routes (XXX_url) until the action has been called (it gives 'rewrite' undefined for nil when it tries to call an instance variable in the controller).  

Can the mock be improved sufficiently to allow named routes to work in advance of the action? 

One workaround is to instantiate an ActionController::Integration::Session and delegate the named routes to that.

----------------------------------------------------------------------

Comment By: Eric Peden (ericpeden)
Date: 2007-01-19 04:11

Message:
You know, the more I think about it, the more I wonder if named routes should only appear in integration tests and not at all in specs. I'd also wanted to be able to do things like:

  get docs_url
  controller.should_render :template => 'docs/index'

but it does feel like I'm crossing boundaries by bringing routing into the controller spec, since routing is what connects the public interface of my app (namly, the URLs) with the semi-backend (the controllers). But I really like RSpec's should_ syntax and don't want to have to go back to asserts in my integration tests. ;)

----------------------------------------------------------------------

Comment By: Eric Peden (ericpeden)
Date: 2007-01-19 03:56

Message:
I'm of the opinion that simply setting expectations post-action is insufficient. For example, I have a case where I simply want to verify that a named route points to the correct url. I'd like to simply do:

  docs_url.should == 'http://test.host/applicant/first-last/docs'

without having to make a dummy call to the controller.

I have a patch that I think fixes this problem. I extend ActionController::Base so that its @url variable is accessible and then initialize that in context_extra. This is what initialize_current_url does; I'm just doing it earlier. This allows named routes to be called at any point in the spec. I've added a spec to verify the new behavior, but I'm not sure if it runs properly. I get scores of errors when trying to run the specs for the rspec_for_rails plugin.

I don't appear to be able to attach files to this request. Should I submit the patch in the patch tracker and then link to it here?


----------------------------------------------------------------------

Comment By: David Chelimsky (dchelimsky)
Date: 2006-12-07 10:05

Message:
I'd say you should set your expectations post-action:

response.should_be_redirect
response.redirect_url.should == my_named_url

----------------------------------------------------------------------

Comment By: Brandon Keepers (brandon)
Date: 2006-12-07 09:28

Message:
Does anyone have any suggestions for a workaround for this? I tried sending :initialize_current_url to my controller in the setup and that doesn't seem to do anything.

----------------------------------------------------------------------

Comment By: Jerry West (jjw)
Date: 2006-11-07 15:37

Message:
PS: 

def redirect
  controller.url_for(response.redirected_to)
end 

# that's because named routes return the path. While should_redirect_to takes paths, response.redirected_to is a Hash.  Yes, I know, I know, I've just found out about should_have_redirected_to or whatever it is.  I'm still coming to grips with the new equality rules and latest functionality!


----------------------------------------------------------------------

Comment By: Jerry West (jjw)
Date: 2006-11-07 15:25

Message:
Sorry, failing spec as requested...

----------------------------------------------------------
require File.dirname(__FILE__) + '/../spec_helper'

# just so we have something to test
class TestController < ApplicationController
  def index
    render :text => 'testing'   # don't look for view
  end
end # probably redundant with 0.7?

context "All controllers (via ApplicationController)" do  
  controller_name :test
  
  specify 'should redirect to login if protected page sought and not logged in' do
    controller.should_redirect_to login_url
    get :index
    controller.should_not_be_logged_in
    redirect.should == login_url
  end
end

----------------------------------------------------------

spec -fs spec/controllers/application_controller_spec.rb
/home/jjw/work/northants/config/environment.rb:31: warning: already initialized constant RAILS_CONNECTION_ADAPTERS
Creating sqlite in memory database...

All controllers (via ApplicationController)
- should redirect to login if protected page sought and not logged in (FAILED - 1)

1)
NoMethodError in 'All controllers (via ApplicationController) should redirect to login if protected page sought and not logged in'
You have a nil object when you didn't expect it!
The error occured while evaluating nil.rewrite
generated/routing/named_routes/login.rb:2:in `login_url'
./spec/controllers/application_controller_spec.rb:17:in `should redirect to login if protected page sought and not logged in'

Finished in 0.004108 seconds

1 specification, 1 failure

---------------------------------------------------------

commenting out the offending 'should_redirect_to' shows that the code itself is fine and login_url valid after the call to get:-

All controllers (via ApplicationController)
- should redirect to login if protected page sought and not logged in

Finished in 0.006735 seconds

1 specification, 0 failures

----------------------------------------------------------

Examining the code for ActionController::Base shows that the nil value is an unset instance variable (@url).  There is a method 'initialize_current_url' (line 927) which passes @request and @params to UrlRewriter.new, if that's any help.  

----------------------------------------------------------------------

Comment By: Aslak Hellesøy (aslak_hellesoy)
Date: 2006-11-07 11:46

Message:
Could you please attach a failing spec as explained here?
http://rspec.rubyforge.org/contribute.html

----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3149&aid=6541&group_id=797


More information about the rspec-devel mailing list