require File.dirname(__FILE__) + '/../test_helper' require 'user_controller' require 'user_notify' # Raise errors beyond the default web-based presentation class UserController; def rescue_action(e) raise e end; end class UserControllerTest < Test::Unit::TestCase self.use_transactional_fixtures = false fixtures :parties, :users, :groups, :groups_users, :periods, :tasks, :estimates, :works def setup @controller = UserController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @request.host = "localhost" ActionMailer::Base.inject_one_error = false ActionMailer::Base.deliveries = [] end def test_login__valid_login__redirects_as_specified @request.session[:detours] ||= [] @request.session[:detours] << {:controller => 'bogus', :action => :location} post :login, :user => { :login => "tesla", :password => "atest" } assert_logged_in users(:tesla) assert_response :redirect assert_equal "http://#{@request.host}/bogus/location", @response.redirect_url end def test_login__valid_login__shows_welcome_as_default post :login, :user => { :login => "tesla", :password => "atest" } assert_logged_in users(:tesla) assert_response :redirect assert_equal @controller.url_for(:controller => 'backlogs', :action => :index), @response.redirect_url end def test_login__wrong_password post :login, :user => { :login => "tesla", :password => "wrong password" } assert_not_logged_in assert_template 'login' assert_contains "Login failed", flash['message'] end def test_login__wrong_login post :login, :user => { :login => "wrong login", :password => "atest" } assert_not_logged_in assert_template 'login' assert_contains "Login failed", flash['message'] end def test_login__deleted_user_cant_login post :login, :user => { :login => "deleted_tesla", :password => "atest" } assert_not_logged_in assert_template 'login' assert_contains "Login failed", flash['message'] end def test_signup post_signup :login => "newuser", :password => "password", :password_confirmation => "password", :email => "newemail@example.com" assert_not_logged_in assert_redirected_to_login assert_equal 1, ActionMailer::Base.deliveries.size mail = ActionMailer::Base.deliveries[0] assert_equal "newemail@example.com", mail.to_addrs[0].to_s assert_match /login:\s+\w+\n/, mail.encoded assert_match /password:\s+\w+\n/, mail.encoded user = User.find_by_email("newemail@example.com") assert_match /user\[id\]=#{user.id}/, mail.encoded assert_match /key=#{user.security_token}/, mail.encoded assert !user.verified end def test_signup__raises_delivery_errors ActionMailer::Base.inject_one_error = true post_signup :login => "newtesla", :password => "newpassword", :password_confirmation => "newpassword", :email => "newtesla@example.com" assert_not_logged_in assert_equal 0, ActionMailer::Base.deliveries.size assert_contains "confirmation email not sent", flash['message'] end def test_signup__mismatched_passwords post :signup, :user => { :login => "newtesla", :password => "newpassword", :password_confirmation => "wrong", :email => 'test@example.com' } user = assigns(:user) assert_equal 1, user.errors.size assert_not_nil user.errors['password'] end def test_signup__bad_login post_signup :login => "yo", :password => "newpassword", :password_confirmation => "newpassword", :email => 'test@example.com' user = assigns(:user) assert_equal 1, user.errors.size assert_not_nil user.errors['login'] end def test_welcome user = users(:unverified_user) get :welcome, :user=> { :id => user.id }, :key => user.security_token user.reload assert user.verified assert_logged_in( user ) end def test_welcome__fails_if_expired_token user = users(:unverified_user) Clock.advance_by_days 2 # now past verification deadline get :welcome, :user=> { :id => user.id }, :key => user.security_token user.reload assert !user.verified assert_not_logged_in end def test_welcome__fails_if_bad_token user = users(:unverified_user) Clock.time = Time.now # now before deadline, but with bad token get :welcome, :user=> { :id => user.id }, :key => "boguskey" user.reload assert !user.verified assert_not_logged_in end def test_edit tesla = users(:tesla) set_logged_in tesla post :edit, :user => { :first_name => "Bob", :form => "edit" } tesla.reload assert_equal "Bob", tesla.first_name end def test_delete user = users(:deletable_user) set_logged_in user post :edit, "user" => { "form" => "delete" } user.reload assert user.deleted assert_not_logged_in end def test_change_password user = users(:tesla) set_logged_in user post :change_password, :user => { :password => "changed_password", :password_onfirmation => "changed_password" } assert_equal 1, ActionMailer::Base.deliveries.size mail = ActionMailer::Base.deliveries[0] assert_equal "tesla@example.com", mail.to_addrs[0].to_s assert_match /login:\s+\w+\n/, mail.encoded assert_match /password:\s+\w+\n/, mail.encoded assert_equal user, User.authenticate(user.login, 'changed_password') end def test_change_password__confirms_password set_logged_in users(:tesla) post :change_password, :user => { :password => "bad", :password_confirmation => "bad" } user = assigns(:user) assert_equal 0, user.errors.size # assert_nil user.errors('password') assert_response :success assert_equal 1, ActionMailer::Base.deliveries.size end def test_change_password__succeeds_despite_delivery_errors set_logged_in users(:tesla) ActionMailer::Base.inject_one_error = true post :change_password, :user => { :password => "changed_password", :password_confirmation => "changed_password" } assert_equal 0, ActionMailer::Base.deliveries.size assert_equal users(:tesla), User.authenticate(users(:tesla).login, 'changed_password') end def test_forgot_password__when_logged_in_redirects_to_change_password user = users(:tesla) set_logged_in user post :forgot_password, :user => { :email => user.email } assert_equal 0, ActionMailer::Base.deliveries.size assert_response :redirect assert_equal @controller.url_for(:action => "change_password"), @response.redirect_url end def test_forgot_password__requires_valid_email_address post :forgot_password, :user => { :email => "" } assert_equal 0, ActionMailer::Base.deliveries.size assert_match /Please enter a valid email address./, @response.body end def test_forgot_password__ignores_unknown_email_address post :forgot_password, :user => { :email => "unknown_email@example.com" } assert_equal 0, ActionMailer::Base.deliveries.size end def test_forgot_password__reports_delivery_error ActionMailer::Base.inject_one_error = true post :forgot_password, :user => { :email => users(:tesla).email } assert_equal 0, ActionMailer::Base.deliveries.size assert_match /Your password could not be emailed/, @response.body end def test_invalid_login post :login, :user => { :login => "tesla", :password => "not_correct" } assert_not_logged_in assert_response :success assert_template 'login' end def test_logout set_logged_in users(:tesla) cookies['autologin'] = {:value => 'tesla'} get :logout assert_not_logged_in assert_nil cookies[:autologin] end def test_login_with_autologin post :login, :user => { :login => "tesla", :password => "atest", :autologin => '1' } assert_logged_in users(:tesla) assert_response :redirect assert_equal @controller.url_for(:controller => 'backlogs', :action => :index), @response.redirect_url assert_cookie :autologin, :value => 'tesla' end def test_autologin @request.cookies['autologin'] = CGI::Cookie.new('autologin', {:value => ['no_password_user'], :expires =>30.days.from_now}) get :welcome assert_logged_in users(:no_password_user) assert_response :ok end private # TODO (uwe): This method should be removed # It is here only because ClassTableInheritanceInRails broke reading fixtures by name def users(login) User.find(:first, :conditions => "login = '#{login.to_s}'") end def set_logged_in( user ) @request.session[:user_id] = user.id end def assert_logged_in( user ) assert_equal user.id, @request.session[:user_id] assert_equal user, Thread.current[:user] end def assert_not_logged_in assert_nil @request.session[:user_id] assert_nil assigns(:current_user) end def assert_redirected_to_login assert_equal @controller.url_for(:action => "login"), @response.redirect_url end def post_signup( user_params ) post :signup, "user" => user_params end def assert_password_validation_fails user = assigns(:user) assert_equal 1, user.errors.size assert_not_nil user.errors['password'] assert_response :success assert_equal 0, ActionMailer::Base.deliveries.size end def assert_contains( target, container ) assert !container.nil?, %Q( Failed to find "#{target}" in nil String ) assert container.include?(target) end end