Topic: Testing a LoginForm (Partial) respectively LoginController

Hello together,

sorry for my last Post. My whole Text was gone. But here is a second try.

I would Test a Login in my (of course) Rails Application. With a "real" Client everything works fine. In any case of submitting the Partial (_login), the Controller redirects me to somwhere (of course not really "somewhere"). Even if i enterd no Username/Password and even if i enterd a wrong Password. But in my Test the redirection doesnt work. I get a HTTP Code 200:

Loaded suite /Users/project/test/functional/login_controller_test
Started
F 
Finished in 0.962905 seconds.

  1) Failure:
test_login:20
Expected response to be a <:redirect>, but was <200>

1 tests, 1 assertions, 1 failures, 0 errors

But, i think its better to show my Code. I hope i have selected the relevant parts:

login_controller_test.rb:

require File.dirname(__FILE__) + '/../test_helper'

class LoginController;
  def rescue_action(e)
    raise e
  end
end

class LoginControllerTest < ActionController::TestCase
  fixtures :companycontacts
  def setup
    @controller = LoginController.new
    @request = ActionController::TestRequest.new
    @response = ActionController::TestResponse.new
  end  
  def test_login
    user = companycontacts(:one)
    #debugger
    post :_login, :post => {:customer => {:emailaddress => user.emailaddress, :password => user.password}} 
    assert_redirected_to :controller => "company", :action => "index"
    assert_equal(user.id, session[:companycontact_id])
  end
end

login_controller.erb

class LoginController < ApplicationController
  def login
    if params[:customer]
      @customer = Companycontact.new(params[:customer])
      logged_in_user = @customer.try_to_login
      if logged_in_user
        session[:companycontact_id] = logged_in_user.id
        redirect_to(:controller => "company")
      else
        @admin = Admin.new(params[:customer])
        logged_in_user = @admin.try_to_login
        if logged_in_user
          session[:admin_id] = logged_in_user.id
          redirect_to(:controller => "admin", :action => "list_admins")
        else
          redirect_to(:controller => "broker", :action => "index")
          flash[:notice] = "E-Mail Adresse oder Passwort falsch. Bitte versuchen Sie es erneut."
        end
      end
    else
      redirect_to(:controller => "broker", :action => "index")
      flash[:notice] = "E-Mail Adresse oder Passwort falsch. Bitte versuchen Sie es erneut."
    end
  end
  def logout
    session[:companycontact_id] = nil
    session[:admin_id] = nil
    redirect_to(:controller => "broker")
  end
end

As you can see, i use one controller for two People.

_login.html.erb

<% form_tag :controller => "login", :action => "login" do -%>
<div id="login_form">
  <% if flash[:notice] -%>
    <div id="notice"><%= flash[:notice] %></div>
  <% end -%>
  <table class="login_table" cellpadding="3px">
  <tr>
    <td>E-Mail</td>
    <td><%= text_field("customer", "emailaddress", :size => 15) %></td>
  </tr>
  <tr>
    <td>Passwort:</td>
    <td><%= password_field("customer", "password", :size => 15) %></td>
  </tr>
  <tr>
    <td></td>
    <td><%= submit_tag "Login" %></td>
  </tr>
</table>
</div>
<br/>
<% end -%>

The only thing which seems to be different from the "real" test to the Test-Test is the number of Parameters in the POST:

real-Test:

Processing LoginController#login (for 127.0.0.1 at 2010-06-06 23:13:01) [POST]
  Parameters: {"commit"=>"Login", "authenticity_token"=>"6Kxxx/kDk=", "customer"=>{"emailaddress"=>"", "password"=>""}}
  Companycontact Load (1.4ms)   SELECT * FROM "companycontacts" WHERE (emailaddress = '' and password = 'dxxx-sha1hash-9') LIMIT 1
  Admins Load (1.1ms)   SELECT * FROM "admins" WHERE (emailaddress = '' and password = 'dxxx-sha1hash-9') LIMIT 1
Redirected to http://localhost:3000/
Completed in 73ms (DB: 3) | 302 Found [http://localhost/login/login]

test-test, test.log:

Unable to load zeug, underlying cause no such file to load -- zeug 

 /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:158:in `require'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:265:in `require_or_load'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:224:in `depend_on'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:136:in `require_dependency'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/fixtures.rb:853:in `try_to_load_dependency'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/fixtures.rb:868:in `require_fixture_classes'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/fixtures.rb:865:in `each'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/fixtures.rb:865:in `require_fixture_classes'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/fixtures.rb:848:in `fixtures'
/Users/project/test/functional/../test_helper.rb:35
/Users/project/test/functional/login_controller_test.rb:1:in `require'
/Users/project/test/functional/login_controller_test.rb:1
  Companycontact Load (11.3ms)   SELECT * FROM "companycontacts" WHERE ("companycontacts"."id" = 1) 


Processing LoginController#_login (for 0.0.0.0 at 2010-06-06 23:59:36) [POST]
  Parameters: {"post"=>{"customer"=>{"emailaddress"=>"myaatest@mail.de", "password"=>"8-xxxSHA1-HASHxxx6"}}}
Rendering template within layouts/application
Rendering login/_login
Rendered login/_login (207.4ms)
Completed in 464ms (View: 456, DB: 24) | 200 OK [http://test.host/login/_login?post%5Bcustomer%5D%5Bemailaddress%5D=myaatest%40mail.de&post%5Bcustomer%5D%5Bpassword%5D=SHA1-HASH]

Could someone explain me whats iam doing wrong? Is it because of the missing authenticity_token or "commit" in the tests POST?

btw. the first Error Message in the Test is another Table in my Database called "Zeug". I dont know why hes warning to this, but i think thats not the Point, isnt it?

Thanks a lot.

Regards,
Jens

Last edited by Havoc][ (2010-06-07 16:13:10)

Re: Testing a LoginForm (Partial) respectively LoginController

Okay, i found the Problem. Thanks to DerGuteMoritz on freenode#rubyonrails-de.

The Thing was:

post :_login, :post => {:customer => {:emailaddress => user.emailaddress, :password => user.password}} 

... in my login_controller_test.erb.

Its working with:

post :login, :customer => {:emailaddress => user.emailaddress, :password => user.password}

First i tried this, it was not working. I get a error message like "view not found" or something. But now, everything is fine. Dont know what i done wrong the first time i tested it.

Thanks for the Help :-).

Regards,
Jens