From e2487c412bc9adc4971500c7718eb27dc9bb9967 Mon Sep 17 00:00:00 2001 From: bsag Date: Sun, 26 Feb 2006 10:58:39 +0000 Subject: [PATCH] Fixed bugs introduced in [190] which broke signup and change password (#213). Also fixed user functional and unit tests to include new functionality. git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@191 a4c988fc-2ded-0310-b66e-134b36920a42 --- tracks/test/fixtures/users.yml | 8 +- .../test/functional/login_controller_test.rb | 132 +++++++++++++++--- .../test/functional/todo_controller_test.rb | 9 +- .../test/functional/user_controller_test.rb | 105 +++++++++++++- tracks/test/test_helper.rb | 15 +- tracks/test/unit/todo_test.rb | 4 +- tracks/test/unit/user_test.rb | 76 ++++++++-- 7 files changed, 298 insertions(+), 51 deletions(-) diff --git a/tracks/test/fixtures/users.yml b/tracks/test/fixtures/users.yml index a284f8db..25d1c7bb 100644 --- a/tracks/test/fixtures/users.yml +++ b/tracks/test/fixtures/users.yml @@ -2,15 +2,15 @@ admin_user: id: 1 login: admin - password: <%= Digest::SHA1.hexdigest("test-salt--abracadabra--") %> - word: <%= Digest::SHA1.hexdigest("adminSun Feb 19 14:42:45 GMT 20060.408173979260027") %> + password: <%= Digest::SHA1.hexdigest("#{SALT}--abracadabra--") %> + word: <%= Digest::SHA1.hexdigest("adminSat Feb 25 17:14:00 GMT 20060.236961325863376") %> is_admin: 1 preferences: "---\nstaleness_starts: \"7\"\ndate_format: \"%d/%m/%Y\"\nno_completed: \"5\"\nadmin_email: butshesagirl@rousette.org.uk\nweek_starts: \"1\"\ndue_style: \"0\"" other_user: id: 2 login: jane - password: <%= Digest::SHA1.hexdigest("test-salt--sesame--") %> - word: <%= Digest::SHA1.hexdigest("other_userSun Feb 19 14:42:45 GMT 20060.408173979260027") %> + password: <%= Digest::SHA1.hexdigest("#{SALT}--sesame--") %> + word: <%= Digest::SHA1.hexdigest("janeSun Feb 19 14:42:45 GMT 20060.408173979260027") %> is_admin: 0 preferences: "---\nstaleness_starts: \"7\"\ndate_format: \"%d/%m/%Y\"\nno_completed: \"5\"\nadmin_email: butshesagirl@rousette.org.uk\nweek_starts: \"1\"\ndue_style: \"0\"" diff --git a/tracks/test/functional/login_controller_test.rb b/tracks/test/functional/login_controller_test.rb index 1720c861..f298be2f 100644 --- a/tracks/test/functional/login_controller_test.rb +++ b/tracks/test/functional/login_controller_test.rb @@ -10,55 +10,141 @@ class LoginControllerTest < Test::Unit::TestCase def setup assert_equal "test", ENV['RAILS_ENV'] + assert_equal "change-me", SALT @controller = LoginController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end - def test_login_with_invalid_user - post :login, {:user_login => 'cracker', :user_password => 'secret'} + # ============================================ + # Login and logout + # ============================================ + + def test_invalid_login + post :login, {:user_login => 'cracker', :user_password => 'secret', :user_noexpiry => 'on'} assert_response :success - assert_template 'login/login' - assert_nil(session['user']) + + assert_session_has_no :user + assert_template "login" end def test_login_with_valid_admin_user - user = login('admin','abracadabra') - assert_equal "Login successful: session will expire after 1 hour of inactivity.", flash['notice'] - assert_redirected_to :controller => 'todo', :action => 'list' - assert_equal 'admin', user.login - assert_equal 1, user.is_admin + @request.session['return-to'] = "/bogus/location" + user = login('admin', 'abracadabra', 'on') + assert_equal user, @response.session['user'] + assert_equal user.login, "admin" + assert_equal user.is_admin, true + assert_equal "Login successful: session will not expire.", flash['notice'] + assert_redirect_url "http://#{@request.host}/bogus/location" end + def test_login_with_valid_standard_user - user = login('jane','sesame') + user = login('jane','sesame', 'off') + assert_equal user, @response.session['user'] + assert_equal user.login, "jane" + assert_equal user.is_admin, false assert_equal "Login successful: session will expire after 1 hour of inactivity.", flash['notice'] assert_redirected_to :controller => 'todo', :action => 'list' - assert_equal 'jane', user.login - assert_equal 0, user.is_admin end def test_logout - user = login('admin','abracadabra') + user = login('admin','abracadabra', 'on') get :logout assert_nil(session['user']) assert_redirected_to :controller => 'login', :action => 'login' end - # TODO: Not sure how to test whether the user is blocked if the admin user is - # not logged in. I tried setting the session[:user] cookie to nil first, - # but that generated an error. + # Test login with a bad password for existing user + # + def test_login_bad_password + post :login, {:user_login => 'jane', :user_password => 'wrong', :user_noexpiry => 'on'} + assert_session_has_no :user + assert_equal "Login unsuccessful", flash['warning'] + assert_success + end + + def test_login_bad_login + post :login, {:user_login => 'blah', :user_password => 'sesame', :user_noexpiry => 'on'} + assert_session_has_no :user + assert_equal "Login unsuccessful", flash['warning'] + assert_success + end + + # ============================================ + # Signup and creation of new users + # ============================================ + + # Test signup of a new user by admin + # Check that newly created user can log in # def test_create - post :signup, :user => {:login => 'newbie', - :password => 'newbiepass', - :password_confirmation => 'newbiepass'} - assert_equal "Signup successful", flash['notice'] + admin = login('admin', 'abracadabra', 'on') + assert_equal admin.is_admin, true + assert_equal admin, @response.session['user'] + newbie = create('newbie', 'newbiepass') + assert_equal "Signup successful for user newbie.", flash['notice'] + assert_redirected_to :controller => 'todo', :action => 'list' + assert_valid newbie + get :logout # logout the admin user + assert_equal newbie.login, "newbie" + assert_equal newbie.is_admin, false + assert_not_nil newbie.preferences # have user preferences been created? + user = login('newbie', 'newbiepass', 'on') # log in the new user assert_redirected_to :controller => 'todo', :action => 'list' - assert_not_nil(session['user']) - user = User.find(session['user'].id) assert_equal 'newbie', user.login - assert_equal 0, user.is_admin + assert_equal user.is_admin, false + num_users = User.find(:all) + assert_equal num_users.length, 3 end + + # Test whether signup of new users is denied to a non-admin user + # + def test_create_by_non_admin + non_admin = login('jane', 'sesame', 'on') + assert_equal non_admin.is_admin, false + assert_equal non_admin, @response.session['user'] + post :signup, :user => {:login => 'newbie2', :password => 'newbiepass2', :password_confirmation => 'newbiepass2'} + assert_template 'login/nosignup' + num_users = User.find(:all) + assert_equal num_users.length, 2 + end + + # ============================================ + # Test validations + # ============================================ + + def test_create_with_invalid_password + admin = login('admin', 'abracadabra', 'on') + assert_equal admin.is_admin, true + assert_equal admin, @response.session['user'] + post :create, :user => {:login => 'newbie', :password => '', :password_confirmation => ''} + num_users = User.find(:all) + assert_equal num_users.length, 2 + assert_redirected_to :controller => 'login', :action => 'signup' + end + + def test_create_with_invalid_user + admin = login('admin', 'abracadabra', 'on') + assert_equal admin.is_admin, true + assert_equal admin, @response.session['user'] + post :create, :user => {:login => 'n', :password => 'newbiepass', :password_confirmation => 'newbiepass'} + num_users = User.find(:all) + assert_equal num_users.length, 2 + assert_redirected_to :controller => 'login', :action => 'signup' + end + + # Test uniqueness of login + # + def test_validate_uniqueness_of_login + admin = login('admin', 'abracadabra', 'on') + assert_equal admin.is_admin, true + assert_equal admin, @response.session['user'] + post :create, :user => {:login => 'jane', :password => 'newbiepass', :password_confirmation => 'newbiepass'} + num_users = User.find(:all) + assert_equal num_users.length, 2 + assert_redirected_to :controller => 'login', :action => 'signup' + end + end diff --git a/tracks/test/functional/todo_controller_test.rb b/tracks/test/functional/todo_controller_test.rb index 39f8770d..4df85ecb 100644 --- a/tracks/test/functional/todo_controller_test.rb +++ b/tracks/test/functional/todo_controller_test.rb @@ -10,8 +10,11 @@ class TodoControllerTest < Test::Unit::TestCase @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new end - # Replace this with your real tests. - def test_truth - assert true + # Test whether unlogged in users are redirected to login + # + def test_get_index + get :index + assert_redirected_to :controller => 'login', :action => 'login' end + end diff --git a/tracks/test/functional/user_controller_test.rb b/tracks/test/functional/user_controller_test.rb index b97a404a..c98b812c 100644 --- a/tracks/test/functional/user_controller_test.rb +++ b/tracks/test/functional/user_controller_test.rb @@ -1,18 +1,117 @@ require File.dirname(__FILE__) + '/../test_helper' require 'user_controller' +require 'user' # Re-raise errors caught by the controller. class UserController; def rescue_action(e) raise e end; end class UserControllerTest < Test::Unit::TestCase + fixtures :users + def setup + assert_equal "test", ENV['RAILS_ENV'] + assert_equal "change-me", SALT + @admin_user = User.find(1) @controller = UserController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end - # Replace this with your real tests. - def test_truth - assert true + # Test index with and without login + # + def test_index + get :index # should fail because no login + assert_redirected_to :controller => 'login', :action => 'login' + @request.session['user'] = @admin_user # log in the admin user + get :index + assert_success end + + # Test admin with and without login + # + def test_admin + get :admin # should fail because no login + assert_redirected_to :controller => 'login', :action => 'login' + @request.session['user'] = @admin_user # log in the admin user + get :admin + assert_success + end + + def test_preferences + get :preferences # should fail because no login + assert_redirected_to :controller => 'login', :action => 'login' + @request.session['user'] = @admin_user # log in the admin user + get :preferences + assert_success + assert_equal assigns['page_title'], "TRACKS::Preferences" + assert_not_nil assigns['prefs'] + assert_equal assigns['prefs'].length, 6 + end + + def test_edit_preferences + get :edit_preferences # should fail because no login + assert_redirected_to :controller => 'login', :action => 'login' + @request.session['user'] = @admin_user # log in the admin user + get :edit_preferences + assert_success + assert_equal assigns['page_title'], "TRACKS::Edit Preferences" + assert_not_nil assigns['prefs'] + assert_equal assigns['prefs'].length, 6 + assert_template 'user/preference_edit_form' + end + + # Test updating of preferences + # FIXME seems to be difficult to test serialization of preferences using YAML + # + def test_update_preferences + @request.session['user'] = @admin_user # log in the admin user + @admin_user.preferences = post :update_preferences, :prefs => { :date_format => "%m-%d-%Y", :week_starts => "0", :no_completed => "10", :staleness_starts => "14", :due_style => "1", :admin_email => "my.email@domain.com" } + @prefs = @admin_user.preferences + assert_not_nil @prefs + assert_redirected_to :action => 'preferences' + end + + def test_change_password + get :change_password # should fail because no login + assert_redirected_to :controller => 'login', :action => 'login' + @request.session['user'] = @admin_user # log in the admin user + get :change_password + assert_success + assert_equal assigns['page_title'], "TRACKS::Change password" + assert_not_nil assigns['user'] + assert_equal assigns['user'], @admin_user + end + + def test_update_password_successful + post :update_password # should fail because no login + assert_redirected_to :controller => 'login', :action => 'login' + @request.session['user'] = @admin_user # log in the admin user + post :update_password, :updateuser => {:password => 'newpassword', :password_confirmation => 'newpassword'} + assert_redirected_to :controller => 'user', :action => 'preferences' + assert_equal @admin_user.password, Digest::SHA1.hexdigest("#{SALT}--newpassword--") + assert_equal flash['notice'], "Password updated." + end + + def test_update_password_no_confirmation + post :update_password # should fail because no login + assert_redirected_to :controller => 'login', :action => 'login' + @request.session['user'] = @admin_user # log in the admin user + post :update_password, :updateuser => {:password => 'newpassword', :password_confirmation => 'wrong'} + assert_redirected_to :controller => 'user', :action => 'change_password' + assert !@admin_user.save + assert_equal flash['warning'], 'There was a problem saving the password. Please retry.' + end + + def test_update_password_validation_errors + post :update_password # should fail because no login + assert_redirected_to :controller => 'login', :action => 'login' + @request.session['user'] = @admin_user # log in the admin user + post :update_password, :updateuser => {:password => 'ba', :password_confirmation => 'ba'} + assert_redirected_to :controller => 'user', :action => 'change_password' + assert !@admin_user.save + assert_equal 1, @admin_user.errors.count + assert_equal @admin_user.errors.on(:password), "is too short (min is 5 characters)" + assert_equal flash['warning'], 'There was a problem saving the password. Please retry.' + end + end diff --git a/tracks/test/test_helper.rb b/tracks/test/test_helper.rb index e20b90cc..3f1345e6 100644 --- a/tracks/test/test_helper.rb +++ b/tracks/test/test_helper.rb @@ -4,20 +4,27 @@ require 'test_help' class Test::Unit::TestCase # Turn off transactional fixtures if you're working with MyISAM tables in MySQL - self.use_transactional_fixtures = true + self.use_transactional_fixtures = false # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david) - self.use_instantiated_fixtures = false + self.use_instantiated_fixtures = true # Add more helper methods to be used by all tests here... # Logs in a user and returns the user object found in the session object # - def login(login,password) - post :login, {:user_login => login, :user_password => password} + def login(login,password,expiry) + post :login, {:user_login => login, :user_password => password, :user_noexpiry => expiry} assert_not_nil(session['user']) return User.find(session['user'].id) end + # Creates a new users with the login and password given + def create(login,password) + post :create, :user => {:login => login, :password => password, :password_confirmation => password} + return User.find_by_login(login) + end + + # Generates a random string of ascii characters (a-z, "1 0") # of a given length for testing assignment to fields # for validation purposes diff --git a/tracks/test/unit/todo_test.rb b/tracks/test/unit/todo_test.rb index 30bfb76f..1e0a4b70 100644 --- a/tracks/test/unit/todo_test.rb +++ b/tracks/test/unit/todo_test.rb @@ -18,7 +18,7 @@ class TodoTest < Test::Unit::TestCase assert_equal 2, @not_completed1.project_id assert_equal "Call Bill Gates to find out how much he makes per day", @not_completed1.description assert_nil @not_completed1.notes - assert_equal 0, @not_completed1.done + assert_equal false, @not_completed1.done assert_equal "2004-11-28 16:01:00", @not_completed1.created_at.strftime("%Y-%m-%d %H:%M:%S") assert_equal "2004-10-30", @not_completed1.due.strftime("%Y-%m-%d") assert_nil @not_completed1.completed @@ -27,7 +27,7 @@ class TodoTest < Test::Unit::TestCase def test_completed assert_kind_of Todo, @completed - assert_equal 1, @completed.done + assert_equal true, @completed.done assert_not_nil @completed.completed end diff --git a/tracks/test/unit/user_test.rb b/tracks/test/unit/user_test.rb index 37d241ac..63896175 100644 --- a/tracks/test/unit/user_test.rb +++ b/tracks/test/unit/user_test.rb @@ -4,18 +4,21 @@ class UserTest < Test::Unit::TestCase fixtures :users def setup + assert_equal "test", ENV['RAILS_ENV'] + assert_equal "change-me", SALT @admin_user = User.find(1) @other_user = User.find(2) end # Test an admin user model + # def test_admin assert_kind_of User, @admin_user assert_equal 1, @admin_user.id assert_equal "admin", @admin_user.login - assert_equal "#{Digest::SHA1.hexdigest("change-me--abracadabra--")}", @admin_user.password - assert_equal "#{Digest::SHA1.hexdigest("change-me--badger--")}", @admin_user.word - assert_equal 1, @admin_user.is_admin + assert_equal "#{Digest::SHA1.hexdigest("#{SALT}--abracadabra--")}", @admin_user.password + assert_not_nil @admin_user.word + assert_equal true, @admin_user.is_admin end # Test a non-admin user model @@ -23,13 +26,19 @@ class UserTest < Test::Unit::TestCase assert_kind_of User, @other_user assert_equal 2, @other_user.id assert_equal "jane", @other_user.login - assert_equal "#{Digest::SHA1.hexdigest("change-me--sesame--")}", @other_user.password - assert_equal "#{Digest::SHA1.hexdigest("change-me--mouse--")}", @other_user.word - assert_equal 0, @other_user.is_admin + assert_equal "#{Digest::SHA1.hexdigest("#{SALT}--sesame--")}", @other_user.password + assert_not_nil @other_user.word + assert_equal false, @other_user.is_admin end + # ============================================ + # Validations + # ============================================ + + # Test a password shorter than 5 characters + # def test_validate_short_password - assert_equal "#{Digest::SHA1.hexdigest("change-me--sesame--")}", @other_user.password + assert_equal "#{Digest::SHA1.hexdigest("#{SALT}--sesame--")}", @other_user.password @other_user.password = "four" assert !@other_user.save assert_equal 1, @other_user.errors.count @@ -37,26 +46,69 @@ class UserTest < Test::Unit::TestCase end # Test a password longer than 40 characters + # def test_validate_long_password - assert_equal "#{Digest::SHA1.hexdigest("change-me--sesame--")}", @other_user.password + assert_equal "#{Digest::SHA1.hexdigest("#{SALT}--sesame--")}", @other_user.password @other_user.password = generate_random_string(41) assert !@other_user.save assert_equal 1, @other_user.errors.count assert_equal "is too long (max is 40 characters)", @other_user.errors.on(:password) - end + end + # Test that correct length password is valid + # def test_validate_correct_length_password - assert_equal "#{Digest::SHA1.hexdigest("change-me--sesame--")}", @other_user.password + assert_equal "#{Digest::SHA1.hexdigest("#{SALT}--sesame--")}", @other_user.password @other_user.password = generate_random_string(6) assert @other_user.save end - # Test an invalid user with no password + # Test a missing password + # def test_validate_missing_password assert_equal 2, @other_user.id @other_user.password = "" assert !@other_user.save assert_equal 2, @other_user.errors.count - assert_equal ["can't be blank", "is too short (min is 5 characters)"], @other_user.errors.on(:password) + assert_equal ["is too short (min is 5 characters)", "can't be blank"], @other_user.errors.on(:password) end + + # Test a login shorter than 3 characters + # + def test_validate_short_login + assert_equal "jane", @other_user.login + @other_user.login = "ba" + assert !@other_user.save + assert_equal 1, @other_user.errors.count + assert_equal "is too short (min is 3 characters)", @other_user.errors.on(:login) + end + + # Test a login longer than 80 characters + # + def test_validate_long_login + assert_equal "jane", @other_user.login + @other_user.login = generate_random_string(81) + assert !@other_user.save + assert_equal 1, @other_user.errors.count + assert_equal "is too long (max is 80 characters)", @other_user.errors.on(:login) + end + + # Test that correct length login is valid + # + def test_validate_correct_length_login + assert_equal "jane", @other_user.login + @other_user.login = generate_random_string(6) + assert @other_user.save + end + + # Test a missing login + # + def test_validate_missing_login + assert_equal 2, @other_user.id + @other_user.login = "" + assert !@other_user.save + assert_equal 2, @other_user.errors.count + assert_equal ["is too short (min is 3 characters)", "can't be blank"], @other_user.errors.on(:login) + end + end