response_assertions.rb: TypeError: can't convert Hash into String

Hello,

I'm getting an error while testing my AWDWR2 application :

  1) Error: test_login(LoginControllerTest): TypeError: can't convert Hash into String     /home/foudil/src/ror/depot/vendor/rails/actionpack/lib/ action_controller/assertions/response_assertions.rb:115:in `=~'     /home/foudil/src/ror/depot/vendor/rails/actionpack/lib/ action_controller/assertions/response_assertions.rb:115:in `assert_redirected_to'     /home/foudil/src/ror/depot/vendor/rails/actionpack/lib/ action_controller/assertions/response_assertions.rb:114:in `collect'     /home/foudil/src/ror/depot/vendor/rails/actionpack/lib/ action_controller/assertions/response_assertions.rb:114:in `assert_redirected_to'     /home/foudil/src/ror/depot/vendor/rails/actionpack/lib/ action_controller/assertions.rb:54:in `clean_backtrace'     /home/foudil/src/ror/depot/vendor/rails/actionpack/lib/ action_controller/assertions/response_assertions.rb:54:in `assert_redirected_to'     ./test/functional/login_controller_test.rb:25:in `test_login'     /home/foudil/src/ror/depot/vendor/rails/activerecord/lib/../../ activesupport/lib/active_support/testing/default.rb:7:in `run'

in test/functional/login_controller_test.rb:

#...   def test_login     dave = users(:dave)     post :login, :name => dave.name, :password => 'secret'     assert_redirected_to :action => "index"     assert_equal dave.id, session[:user_id]   end #...

in response_assertions.rb:

      #... 112 rescue ActionController::RoutingError # routing failed us, so match the strings only. 113 msg = build_message(message, "expected a redirect to <?

, found one to <?>", options, @response.redirect_url)

114 url_regexp = %r{^(\w+://.*?(/|$|\?))(.*)$} 115 eurl, epath, url, path = [options, @response.redirect_url].collect do |url| 116 u, p = (url_regexp =~ url) ? [$1, $3] : [nil, url] 117 [u, (p.first == '/') ? p : '/' + p] 118 end.flatten       #...

The problem seems to be that the "option" variable is a hash, in my case : {:action => :login} and thus, it can not be matched against a regex

Is this a bug, or am I misusing something ?

Ruby version 1.8.6 Rails version 2.0.2

Ok I think I found it : the problem comes from the "post" instruction, not from "assert_redirect_to" !

I should have written :

    post :login, {}, { :name => dave.name, :password => 'secret' }

No. This was a wrong solution.

because the parameters are passed as session information (non-sense).

The original problem comes from ssl_requirement used in the login controller, which redirects to the same URI, but with ssl. Thus making the assert_redirected_to break down.

Which leads me to another question : how to test redirection to https://… in the functional tests ? :slight_smile:

Further information underneath :

#... class LoginController < ApplicationController

  layout "products"   before_filter :authorize, :except => :login   ssl_required :login, :add_user #...   def login     session[:user_id] = nil     if request.post?       user = User.authenticate(params[:name], params[:password])       if user         session[:user_id] = user.id         uri = session[:original_uri]         session[:original_uri] = nil         redirect_to(uri || { :action => "index" })       else         flash[:notice] = "Nom de l'utilisateur ou mot de passe incorrect"       end     end   end #...

@request.headers:

REQUEST_URI: /login/login?name=dave&password=secret SERVER_PORT: 80 REQUEST_METHOD: POST

@request.response:

Status: 302 Found X-Runtime: 0.00129 Location: https://test.host/login/login?name=dave&password=secret type: text/html; charset=utf-8 cookie: Cache-Control: no-cache Content-Length: 121

No. This was a wrong solution.

because the parameters are passed as session information (non-sense).

The original problem comes from ssl_requirement used in the login controller, which redirects to the same URI, but with ssl. Thus making the assert_redirected_to break down.

This seems vaguely familiar. IIRC, if the parameter passed to
redirect_to is a string, then the parameter passed to
assert_redirected_to also needs to be a string: rails knows how to
compare strings, it knows how to compare hashes, but it won't compare
a string to a hash for you.

Fred