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:inassert_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:inassert_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:inassert_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:inrun’

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

On 9 Apr 2008, at 16:20, foudfou wrote:

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