annotate test/unit/user_test.rb @ 1082:997f6d7738f7 bug_531

In repo controller entry action, show the page for the file even if it's binary (so user still has access to history etc links). This makes it possible to use the entry action as the default when a file is clicked on
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Thu, 22 Nov 2012 18:04:17 +0000
parents 5f33065ddc4b
children 433d4f72a19b
rev   line source
Chris@128 1 # Redmine - project management software
Chris@128 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
Chris@0 3 #
Chris@0 4 # This program is free software; you can redistribute it and/or
Chris@0 5 # modify it under the terms of the GNU General Public License
Chris@0 6 # as published by the Free Software Foundation; either version 2
Chris@0 7 # of the License, or (at your option) any later version.
Chris@909 8 #
Chris@0 9 # This program is distributed in the hope that it will be useful,
Chris@0 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 # GNU General Public License for more details.
Chris@909 13 #
Chris@0 14 # You should have received a copy of the GNU General Public License
Chris@0 15 # along with this program; if not, write to the Free Software
Chris@0 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 17
Chris@119 18 require File.expand_path('../../test_helper', __FILE__)
Chris@0 19
Chris@0 20 class UserTest < ActiveSupport::TestCase
Chris@909 21 fixtures :users, :members, :projects, :roles, :member_roles, :auth_sources,
Chris@909 22 :trackers, :issue_statuses,
Chris@909 23 :projects_trackers,
Chris@909 24 :watchers,
Chris@909 25 :issue_categories, :enumerations, :issues,
Chris@909 26 :journals, :journal_details,
Chris@909 27 :groups_users,
Chris@909 28 :enabled_modules,
Chris@909 29 :workflows
Chris@0 30
Chris@0 31 def setup
Chris@0 32 @admin = User.find(1)
Chris@0 33 @jsmith = User.find(2)
Chris@0 34 @dlopper = User.find(3)
Chris@0 35 end
Chris@0 36
Chris@0 37 test 'object_daddy creation' do
Chris@0 38 User.generate_with_protected!(:firstname => 'Testing connection')
Chris@0 39 User.generate_with_protected!(:firstname => 'Testing connection')
Chris@0 40 assert_equal 2, User.count(:all, :conditions => {:firstname => 'Testing connection'})
Chris@0 41 end
Chris@909 42
Chris@0 43 def test_truth
Chris@0 44 assert_kind_of User, @jsmith
Chris@0 45 end
Chris@909 46
Chris@1 47 def test_mail_should_be_stripped
Chris@1 48 u = User.new
Chris@1 49 u.mail = " foo@bar.com "
Chris@1 50 assert_equal "foo@bar.com", u.mail
Chris@1 51 end
Chris@0 52
Chris@909 53 def test_mail_validation
Chris@909 54 u = User.new
Chris@909 55 u.mail = ''
Chris@909 56 assert !u.valid?
Chris@909 57 assert_equal I18n.translate('activerecord.errors.messages.blank'), u.errors.on(:mail)
Chris@909 58 end
Chris@909 59
Chris@0 60 def test_create
Chris@0 61 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
Chris@909 62
Chris@0 63 user.login = "jsmith"
Chris@0 64 user.password, user.password_confirmation = "password", "password"
Chris@0 65 # login uniqueness
Chris@0 66 assert !user.save
Chris@0 67 assert_equal 1, user.errors.count
Chris@909 68
Chris@0 69 user.login = "newuser"
Chris@0 70 user.password, user.password_confirmation = "passwd", "password"
Chris@0 71 # password confirmation
Chris@0 72 assert !user.save
Chris@0 73 assert_equal 1, user.errors.count
Chris@0 74
Chris@0 75 user.password, user.password_confirmation = "password", "password"
Chris@0 76 assert user.save
Chris@0 77 end
chris@37 78
chris@37 79 context "User#before_create" do
chris@37 80 should "set the mail_notification to the default Setting" do
chris@37 81 @user1 = User.generate_with_protected!
chris@37 82 assert_equal 'only_my_events', @user1.mail_notification
chris@37 83
chris@37 84 with_settings :default_notification_option => 'all' do
chris@37 85 @user2 = User.generate_with_protected!
chris@37 86 assert_equal 'all', @user2.mail_notification
chris@37 87 end
chris@37 88 end
chris@37 89 end
Chris@909 90
Chris@0 91 context "User.login" do
Chris@0 92 should "be case-insensitive." do
Chris@0 93 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
Chris@0 94 u.login = 'newuser'
Chris@0 95 u.password, u.password_confirmation = "password", "password"
Chris@0 96 assert u.save
Chris@909 97
Chris@0 98 u = User.new(:firstname => "Similar", :lastname => "User", :mail => "similaruser@somenet.foo")
Chris@0 99 u.login = 'NewUser'
Chris@0 100 u.password, u.password_confirmation = "password", "password"
Chris@0 101 assert !u.save
Chris@0 102 assert_equal I18n.translate('activerecord.errors.messages.taken'), u.errors.on(:login)
Chris@0 103 end
Chris@0 104 end
Chris@0 105
Chris@0 106 def test_mail_uniqueness_should_not_be_case_sensitive
Chris@0 107 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
Chris@0 108 u.login = 'newuser1'
Chris@0 109 u.password, u.password_confirmation = "password", "password"
Chris@0 110 assert u.save
Chris@909 111
Chris@0 112 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
Chris@0 113 u.login = 'newuser2'
Chris@0 114 u.password, u.password_confirmation = "password", "password"
Chris@0 115 assert !u.save
Chris@0 116 assert_equal I18n.translate('activerecord.errors.messages.taken'), u.errors.on(:mail)
Chris@0 117 end
Chris@0 118
Chris@0 119 def test_update
Chris@0 120 assert_equal "admin", @admin.login
Chris@0 121 @admin.login = "john"
Chris@0 122 assert @admin.save, @admin.errors.full_messages.join("; ")
Chris@0 123 @admin.reload
Chris@0 124 assert_equal "john", @admin.login
Chris@0 125 end
Chris@909 126
Chris@128 127 def test_destroy_should_delete_members_and_roles
Chris@128 128 members = Member.find_all_by_user_id(2)
Chris@128 129 ms = members.size
Chris@128 130 rs = members.collect(&:roles).flatten.size
Chris@909 131
Chris@128 132 assert_difference 'Member.count', - ms do
Chris@128 133 assert_difference 'MemberRole.count', - rs do
Chris@128 134 User.find(2).destroy
Chris@128 135 end
Chris@128 136 end
Chris@909 137
Chris@128 138 assert_nil User.find_by_id(2)
Chris@128 139 assert Member.find_all_by_user_id(2).empty?
Chris@128 140 end
Chris@909 141
Chris@128 142 def test_destroy_should_update_attachments
Chris@128 143 attachment = Attachment.create!(:container => Project.find(1),
Chris@128 144 :file => uploaded_test_file("testfile.txt", "text/plain"),
Chris@128 145 :author_id => 2)
Chris@909 146
Chris@0 147 User.find(2).destroy
Chris@0 148 assert_nil User.find_by_id(2)
Chris@128 149 assert_equal User.anonymous, attachment.reload.author
Chris@128 150 end
Chris@909 151
Chris@128 152 def test_destroy_should_update_comments
Chris@128 153 comment = Comment.create!(
Chris@128 154 :commented => News.create!(:project_id => 1, :author_id => 1, :title => 'foo', :description => 'foo'),
Chris@128 155 :author => User.find(2),
Chris@128 156 :comments => 'foo'
Chris@128 157 )
Chris@909 158
Chris@128 159 User.find(2).destroy
Chris@128 160 assert_nil User.find_by_id(2)
Chris@128 161 assert_equal User.anonymous, comment.reload.author
Chris@128 162 end
Chris@909 163
Chris@128 164 def test_destroy_should_update_issues
Chris@128 165 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
Chris@909 166
Chris@128 167 User.find(2).destroy
Chris@128 168 assert_nil User.find_by_id(2)
Chris@128 169 assert_equal User.anonymous, issue.reload.author
Chris@128 170 end
Chris@909 171
Chris@128 172 def test_destroy_should_unassign_issues
Chris@128 173 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
Chris@909 174
Chris@128 175 User.find(2).destroy
Chris@128 176 assert_nil User.find_by_id(2)
Chris@128 177 assert_nil issue.reload.assigned_to
Chris@128 178 end
Chris@909 179
Chris@128 180 def test_destroy_should_update_journals
Chris@128 181 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
Chris@128 182 issue.init_journal(User.find(2), "update")
Chris@128 183 issue.save!
Chris@909 184
Chris@128 185 User.find(2).destroy
Chris@128 186 assert_nil User.find_by_id(2)
Chris@128 187 assert_equal User.anonymous, issue.journals.first.reload.user
Chris@128 188 end
Chris@909 189
Chris@128 190 def test_destroy_should_update_journal_details_old_value
Chris@128 191 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
Chris@128 192 issue.init_journal(User.find(1), "update")
Chris@128 193 issue.assigned_to_id = nil
Chris@128 194 assert_difference 'JournalDetail.count' do
Chris@128 195 issue.save!
Chris@128 196 end
Chris@128 197 journal_detail = JournalDetail.first(:order => 'id DESC')
Chris@128 198 assert_equal '2', journal_detail.old_value
Chris@909 199
Chris@128 200 User.find(2).destroy
Chris@128 201 assert_nil User.find_by_id(2)
Chris@128 202 assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value
Chris@128 203 end
Chris@909 204
Chris@128 205 def test_destroy_should_update_journal_details_value
Chris@128 206 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
Chris@128 207 issue.init_journal(User.find(1), "update")
Chris@128 208 issue.assigned_to_id = 2
Chris@128 209 assert_difference 'JournalDetail.count' do
Chris@128 210 issue.save!
Chris@128 211 end
Chris@128 212 journal_detail = JournalDetail.first(:order => 'id DESC')
Chris@128 213 assert_equal '2', journal_detail.value
Chris@909 214
Chris@128 215 User.find(2).destroy
Chris@128 216 assert_nil User.find_by_id(2)
Chris@128 217 assert_equal User.anonymous.id.to_s, journal_detail.reload.value
Chris@128 218 end
Chris@909 219
Chris@128 220 def test_destroy_should_update_messages
Chris@128 221 board = Board.create!(:project_id => 1, :name => 'Board', :description => 'Board')
Chris@128 222 message = Message.create!(:board_id => board.id, :author_id => 2, :subject => 'foo', :content => 'foo')
Chris@909 223
Chris@128 224 User.find(2).destroy
Chris@128 225 assert_nil User.find_by_id(2)
Chris@128 226 assert_equal User.anonymous, message.reload.author
Chris@128 227 end
Chris@909 228
Chris@128 229 def test_destroy_should_update_news
Chris@128 230 news = News.create!(:project_id => 1, :author_id => 2, :title => 'foo', :description => 'foo')
Chris@909 231
Chris@128 232 User.find(2).destroy
Chris@128 233 assert_nil User.find_by_id(2)
Chris@128 234 assert_equal User.anonymous, news.reload.author
Chris@128 235 end
Chris@909 236
Chris@128 237 def test_destroy_should_delete_private_queries
Chris@128 238 query = Query.new(:name => 'foo', :is_public => false)
Chris@128 239 query.project_id = 1
Chris@128 240 query.user_id = 2
Chris@128 241 query.save!
Chris@909 242
Chris@128 243 User.find(2).destroy
Chris@128 244 assert_nil User.find_by_id(2)
Chris@128 245 assert_nil Query.find_by_id(query.id)
Chris@128 246 end
Chris@909 247
Chris@128 248 def test_destroy_should_update_public_queries
Chris@128 249 query = Query.new(:name => 'foo', :is_public => true)
Chris@128 250 query.project_id = 1
Chris@128 251 query.user_id = 2
Chris@128 252 query.save!
Chris@909 253
Chris@128 254 User.find(2).destroy
Chris@128 255 assert_nil User.find_by_id(2)
Chris@128 256 assert_equal User.anonymous, query.reload.user
Chris@128 257 end
Chris@909 258
Chris@128 259 def test_destroy_should_update_time_entries
Chris@128 260 entry = TimeEntry.new(:hours => '2', :spent_on => Date.today, :activity => TimeEntryActivity.create!(:name => 'foo'))
Chris@128 261 entry.project_id = 1
Chris@128 262 entry.user_id = 2
Chris@128 263 entry.save!
Chris@909 264
Chris@128 265 User.find(2).destroy
Chris@128 266 assert_nil User.find_by_id(2)
Chris@128 267 assert_equal User.anonymous, entry.reload.user
Chris@128 268 end
Chris@909 269
Chris@128 270 def test_destroy_should_delete_tokens
Chris@128 271 token = Token.create!(:user_id => 2, :value => 'foo')
Chris@909 272
Chris@128 273 User.find(2).destroy
Chris@128 274 assert_nil User.find_by_id(2)
Chris@128 275 assert_nil Token.find_by_id(token.id)
Chris@128 276 end
Chris@909 277
Chris@128 278 def test_destroy_should_delete_watchers
Chris@128 279 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
Chris@128 280 watcher = Watcher.create!(:user_id => 2, :watchable => issue)
Chris@909 281
Chris@128 282 User.find(2).destroy
Chris@128 283 assert_nil User.find_by_id(2)
Chris@128 284 assert_nil Watcher.find_by_id(watcher.id)
Chris@128 285 end
Chris@909 286
Chris@128 287 def test_destroy_should_update_wiki_contents
Chris@128 288 wiki_content = WikiContent.create!(
Chris@128 289 :text => 'foo',
Chris@128 290 :author_id => 2,
Chris@128 291 :page => WikiPage.create!(:title => 'Foo', :wiki => Wiki.create!(:project_id => 1, :start_page => 'Start'))
Chris@128 292 )
Chris@128 293 wiki_content.text = 'bar'
Chris@128 294 assert_difference 'WikiContent::Version.count' do
Chris@128 295 wiki_content.save!
Chris@128 296 end
Chris@909 297
Chris@128 298 User.find(2).destroy
Chris@128 299 assert_nil User.find_by_id(2)
Chris@128 300 assert_equal User.anonymous, wiki_content.reload.author
Chris@128 301 wiki_content.versions.each do |version|
Chris@128 302 assert_equal User.anonymous, version.reload.author
Chris@128 303 end
Chris@128 304 end
Chris@909 305
Chris@128 306 def test_destroy_should_nullify_issue_categories
Chris@128 307 category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo')
Chris@909 308
Chris@128 309 User.find(2).destroy
Chris@128 310 assert_nil User.find_by_id(2)
Chris@128 311 assert_nil category.reload.assigned_to_id
Chris@128 312 end
Chris@909 313
Chris@128 314 def test_destroy_should_nullify_changesets
Chris@128 315 changeset = Changeset.create!(
Chris@128 316 :repository => Repository::Subversion.create!(
Chris@128 317 :project_id => 1,
Chris@128 318 :url => 'file:///var/svn'
Chris@128 319 ),
Chris@128 320 :revision => '12',
Chris@128 321 :committed_on => Time.now,
Chris@128 322 :committer => 'jsmith'
Chris@128 323 )
Chris@128 324 assert_equal 2, changeset.user_id
Chris@909 325
Chris@128 326 User.find(2).destroy
Chris@128 327 assert_nil User.find_by_id(2)
Chris@128 328 assert_nil changeset.reload.user_id
Chris@128 329 end
Chris@909 330
Chris@128 331 def test_anonymous_user_should_not_be_destroyable
Chris@128 332 assert_no_difference 'User.count' do
Chris@128 333 assert_equal false, User.anonymous.destroy
Chris@128 334 end
Chris@0 335 end
Chris@909 336
Chris@119 337 def test_validate_login_presence
Chris@0 338 @admin.login = ""
Chris@0 339 assert !@admin.save
Chris@0 340 assert_equal 1, @admin.errors.count
Chris@0 341 end
Chris@909 342
Chris@119 343 def test_validate_mail_notification_inclusion
Chris@119 344 u = User.new
Chris@119 345 u.mail_notification = 'foo'
Chris@119 346 u.save
Chris@909 347 assert_not_nil u.errors[:mail_notification]
Chris@119 348 end
Chris@909 349
Chris@0 350 context "User#try_to_login" do
Chris@0 351 should "fall-back to case-insensitive if user login is not found as-typed." do
Chris@0 352 user = User.try_to_login("AdMin", "admin")
Chris@0 353 assert_kind_of User, user
Chris@0 354 assert_equal "admin", user.login
Chris@0 355 end
Chris@0 356
Chris@0 357 should "select the exact matching user first" do
Chris@909 358 case_sensitive_user = User.generate_with_protected!(
Chris@909 359 :login => 'changed', :password => 'admin',
Chris@909 360 :password_confirmation => 'admin')
Chris@0 361 # bypass validations to make it appear like existing data
Chris@0 362 case_sensitive_user.update_attribute(:login, 'ADMIN')
Chris@0 363
Chris@0 364 user = User.try_to_login("ADMIN", "admin")
Chris@0 365 assert_kind_of User, user
Chris@0 366 assert_equal "ADMIN", user.login
Chris@0 367
Chris@0 368 end
Chris@0 369 end
Chris@0 370
Chris@0 371 def test_password
Chris@0 372 user = User.try_to_login("admin", "admin")
Chris@0 373 assert_kind_of User, user
Chris@0 374 assert_equal "admin", user.login
Chris@0 375 user.password = "hello"
Chris@0 376 assert user.save
Chris@909 377
Chris@0 378 user = User.try_to_login("admin", "hello")
Chris@0 379 assert_kind_of User, user
Chris@0 380 assert_equal "admin", user.login
Chris@0 381 end
Chris@909 382
Chris@909 383 def test_validate_password_length
Chris@909 384 with_settings :password_min_length => '100' do
Chris@909 385 user = User.new(:firstname => "new100", :lastname => "user100", :mail => "newuser100@somenet.foo")
Chris@909 386 user.login = "newuser100"
Chris@909 387 user.password, user.password_confirmation = "password100", "password100"
Chris@909 388 assert !user.save
Chris@909 389 assert_equal 1, user.errors.count
Chris@909 390 end
Chris@909 391 end
Chris@909 392
Chris@0 393 def test_name_format
Chris@0 394 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
Chris@0 395 Setting.user_format = :firstname_lastname
Chris@0 396 assert_equal 'John Smith', @jsmith.reload.name
Chris@0 397 Setting.user_format = :username
Chris@0 398 assert_equal 'jsmith', @jsmith.reload.name
Chris@0 399 end
Chris@0 400
Chris@909 401 def test_fields_for_order_statement_should_return_fields_according_user_format_setting
Chris@909 402 with_settings :user_format => 'lastname_coma_firstname' do
Chris@909 403 assert_equal ['users.lastname', 'users.firstname', 'users.id'], User.fields_for_order_statement
Chris@909 404 end
Chris@909 405 end
Chris@909 406
Chris@909 407 def test_fields_for_order_statement_width_table_name_should_prepend_table_name
Chris@909 408 with_settings :user_format => 'lastname_firstname' do
Chris@909 409 assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'], User.fields_for_order_statement('authors')
Chris@909 410 end
Chris@909 411 end
Chris@909 412
Chris@909 413 def test_fields_for_order_statement_with_blank_format_should_return_default
Chris@909 414 with_settings :user_format => '' do
Chris@909 415 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
Chris@909 416 end
Chris@909 417 end
Chris@909 418
Chris@909 419 def test_fields_for_order_statement_with_invalid_format_should_return_default
Chris@909 420 with_settings :user_format => 'foo' do
Chris@909 421 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
Chris@909 422 end
Chris@909 423 end
Chris@909 424
Chris@0 425 def test_lock
Chris@0 426 user = User.try_to_login("jsmith", "jsmith")
Chris@0 427 assert_equal @jsmith, user
Chris@909 428
Chris@0 429 @jsmith.status = User::STATUS_LOCKED
Chris@0 430 assert @jsmith.save
Chris@909 431
Chris@0 432 user = User.try_to_login("jsmith", "jsmith")
Chris@909 433 assert_equal nil, user
Chris@0 434 end
Chris@909 435
Chris@245 436 context ".try_to_login" do
Chris@245 437 context "with good credentials" do
Chris@245 438 should "return the user" do
Chris@245 439 user = User.try_to_login("admin", "admin")
Chris@245 440 assert_kind_of User, user
Chris@245 441 assert_equal "admin", user.login
Chris@245 442 end
Chris@245 443 end
Chris@909 444
Chris@245 445 context "with wrong credentials" do
Chris@245 446 should "return nil" do
Chris@245 447 assert_nil User.try_to_login("admin", "foo")
Chris@245 448 end
Chris@245 449 end
Chris@245 450 end
Chris@909 451
Chris@0 452 if ldap_configured?
Chris@0 453 context "#try_to_login using LDAP" do
Chris@0 454 context "with failed connection to the LDAP server" do
Chris@0 455 should "return nil" do
Chris@0 456 @auth_source = AuthSourceLdap.find(1)
Chris@0 457 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
Chris@909 458
Chris@0 459 assert_equal nil, User.try_to_login('edavis', 'wrong')
Chris@0 460 end
Chris@0 461 end
Chris@0 462
Chris@0 463 context "with an unsuccessful authentication" do
Chris@0 464 should "return nil" do
Chris@0 465 assert_equal nil, User.try_to_login('edavis', 'wrong')
Chris@0 466 end
Chris@0 467 end
Chris@909 468
Chris@0 469 context "on the fly registration" do
Chris@0 470 setup do
Chris@0 471 @auth_source = AuthSourceLdap.find(1)
Chris@0 472 end
Chris@0 473
Chris@0 474 context "with a successful authentication" do
Chris@0 475 should "create a new user account if it doesn't exist" do
Chris@0 476 assert_difference('User.count') do
Chris@0 477 user = User.try_to_login('edavis', '123456')
Chris@0 478 assert !user.admin?
Chris@0 479 end
Chris@0 480 end
Chris@909 481
Chris@0 482 should "retrieve existing user" do
Chris@0 483 user = User.try_to_login('edavis', '123456')
Chris@0 484 user.admin = true
Chris@0 485 user.save!
Chris@909 486
Chris@0 487 assert_no_difference('User.count') do
Chris@0 488 user = User.try_to_login('edavis', '123456')
Chris@0 489 assert user.admin?
Chris@0 490 end
Chris@0 491 end
Chris@0 492 end
Chris@0 493 end
Chris@0 494 end
Chris@0 495
Chris@0 496 else
Chris@0 497 puts "Skipping LDAP tests."
Chris@0 498 end
Chris@909 499
Chris@0 500 def test_create_anonymous
Chris@0 501 AnonymousUser.delete_all
Chris@0 502 anon = User.anonymous
Chris@0 503 assert !anon.new_record?
Chris@0 504 assert_kind_of AnonymousUser, anon
Chris@0 505 end
Chris@0 506
Chris@909 507 def test_ensure_single_anonymous_user
Chris@909 508 AnonymousUser.delete_all
Chris@909 509 anon1 = User.anonymous
Chris@909 510 assert !anon1.new_record?
Chris@909 511 assert_kind_of AnonymousUser, anon1
Chris@909 512 anon2 = AnonymousUser.create(
Chris@909 513 :lastname => 'Anonymous', :firstname => '',
Chris@909 514 :mail => '', :login => '', :status => 0)
Chris@909 515 assert_equal 1, anon2.errors.count
Chris@909 516 end
Chris@909 517
Chris@0 518 should_have_one :rss_token
Chris@0 519
Chris@0 520 def test_rss_key
Chris@0 521 assert_nil @jsmith.rss_token
Chris@0 522 key = @jsmith.rss_key
Chris@0 523 assert_equal 40, key.length
Chris@909 524
Chris@0 525 @jsmith.reload
Chris@0 526 assert_equal key, @jsmith.rss_key
Chris@0 527 end
Chris@0 528
Chris@909 529
Chris@0 530 should_have_one :api_token
Chris@0 531
Chris@0 532 context "User#api_key" do
Chris@0 533 should "generate a new one if the user doesn't have one" do
Chris@0 534 user = User.generate_with_protected!(:api_token => nil)
Chris@0 535 assert_nil user.api_token
Chris@0 536
Chris@0 537 key = user.api_key
Chris@0 538 assert_equal 40, key.length
Chris@0 539 user.reload
Chris@0 540 assert_equal key, user.api_key
Chris@0 541 end
Chris@0 542
Chris@0 543 should "return the existing api token value" do
Chris@0 544 user = User.generate_with_protected!
Chris@0 545 token = Token.generate!(:action => 'api')
Chris@0 546 user.api_token = token
Chris@0 547 assert user.save
Chris@909 548
Chris@0 549 assert_equal token.value, user.api_key
Chris@0 550 end
Chris@0 551 end
Chris@0 552
Chris@0 553 context "User#find_by_api_key" do
Chris@0 554 should "return nil if no matching key is found" do
Chris@0 555 assert_nil User.find_by_api_key('zzzzzzzzz')
Chris@0 556 end
Chris@0 557
Chris@0 558 should "return nil if the key is found for an inactive user" do
Chris@0 559 user = User.generate_with_protected!(:status => User::STATUS_LOCKED)
Chris@0 560 token = Token.generate!(:action => 'api')
Chris@0 561 user.api_token = token
Chris@0 562 user.save
Chris@0 563
Chris@0 564 assert_nil User.find_by_api_key(token.value)
Chris@0 565 end
Chris@0 566
Chris@0 567 should "return the user if the key is found for an active user" do
Chris@0 568 user = User.generate_with_protected!(:status => User::STATUS_ACTIVE)
Chris@0 569 token = Token.generate!(:action => 'api')
Chris@0 570 user.api_token = token
Chris@0 571 user.save
Chris@909 572
Chris@0 573 assert_equal user, User.find_by_api_key(token.value)
Chris@0 574 end
Chris@0 575 end
Chris@0 576
Chris@929 577 def test_default_admin_account_changed_should_return_false_if_account_was_not_changed
Chris@929 578 user = User.find_by_login("admin")
Chris@929 579 user.password = "admin"
Chris@929 580 user.save!
Chris@929 581
Chris@929 582 assert_equal false, User.default_admin_account_changed?
Chris@929 583 end
Chris@929 584
Chris@929 585 def test_default_admin_account_changed_should_return_true_if_password_was_changed
Chris@929 586 user = User.find_by_login("admin")
Chris@929 587 user.password = "newpassword"
Chris@929 588 user.save!
Chris@929 589
Chris@929 590 assert_equal true, User.default_admin_account_changed?
Chris@929 591 end
Chris@929 592
Chris@929 593 def test_default_admin_account_changed_should_return_true_if_account_is_disabled
Chris@929 594 user = User.find_by_login("admin")
Chris@929 595 user.password = "admin"
Chris@929 596 user.status = User::STATUS_LOCKED
Chris@929 597 user.save!
Chris@929 598
Chris@929 599 assert_equal true, User.default_admin_account_changed?
Chris@929 600 end
Chris@929 601
Chris@929 602 def test_default_admin_account_changed_should_return_true_if_account_does_not_exist
Chris@929 603 user = User.find_by_login("admin")
Chris@929 604 user.destroy
Chris@929 605
Chris@929 606 assert_equal true, User.default_admin_account_changed?
Chris@929 607 end
Chris@929 608
Chris@0 609 def test_roles_for_project
Chris@0 610 # user with a role
Chris@0 611 roles = @jsmith.roles_for_project(Project.find(1))
Chris@0 612 assert_kind_of Role, roles.first
Chris@0 613 assert_equal "Manager", roles.first.name
Chris@909 614
Chris@0 615 # user with no role
Chris@0 616 assert_nil @dlopper.roles_for_project(Project.find(2)).detect {|role| role.member?}
Chris@0 617 end
Chris@909 618
Chris@441 619 def test_projects_by_role_for_user_with_role
Chris@441 620 user = User.find(2)
Chris@441 621 assert_kind_of Hash, user.projects_by_role
Chris@441 622 assert_equal 2, user.projects_by_role.size
Chris@441 623 assert_equal [1,5], user.projects_by_role[Role.find(1)].collect(&:id).sort
Chris@441 624 assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort
Chris@441 625 end
Chris@909 626
Chris@441 627 def test_projects_by_role_for_user_with_no_role
Chris@441 628 user = User.generate!
Chris@441 629 assert_equal({}, user.projects_by_role)
Chris@441 630 end
Chris@909 631
Chris@441 632 def test_projects_by_role_for_anonymous
Chris@441 633 assert_equal({}, User.anonymous.projects_by_role)
Chris@441 634 end
Chris@441 635
Chris@128 636 def test_valid_notification_options
Chris@128 637 # without memberships
Chris@128 638 assert_equal 5, User.find(7).valid_notification_options.size
Chris@128 639 # with memberships
Chris@128 640 assert_equal 6, User.find(2).valid_notification_options.size
Chris@128 641 end
Chris@909 642
Chris@128 643 def test_valid_notification_options_class_method
Chris@128 644 assert_equal 5, User.valid_notification_options.size
Chris@128 645 assert_equal 5, User.valid_notification_options(User.find(7)).size
Chris@128 646 assert_equal 6, User.valid_notification_options(User.find(2)).size
Chris@128 647 end
Chris@909 648
Chris@0 649 def test_mail_notification_all
chris@37 650 @jsmith.mail_notification = 'all'
Chris@0 651 @jsmith.notified_project_ids = []
Chris@0 652 @jsmith.save
Chris@0 653 @jsmith.reload
Chris@0 654 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
Chris@0 655 end
Chris@909 656
Chris@0 657 def test_mail_notification_selected
chris@37 658 @jsmith.mail_notification = 'selected'
Chris@0 659 @jsmith.notified_project_ids = [1]
Chris@0 660 @jsmith.save
Chris@0 661 @jsmith.reload
Chris@0 662 assert Project.find(1).recipients.include?(@jsmith.mail)
Chris@0 663 end
Chris@909 664
chris@37 665 def test_mail_notification_only_my_events
chris@37 666 @jsmith.mail_notification = 'only_my_events'
Chris@0 667 @jsmith.notified_project_ids = []
Chris@0 668 @jsmith.save
Chris@0 669 @jsmith.reload
Chris@0 670 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
Chris@0 671 end
Chris@909 672
Chris@0 673 def test_comments_sorting_preference
Chris@0 674 assert !@jsmith.wants_comments_in_reverse_order?
Chris@0 675 @jsmith.pref.comments_sorting = 'asc'
Chris@0 676 assert !@jsmith.wants_comments_in_reverse_order?
Chris@0 677 @jsmith.pref.comments_sorting = 'desc'
Chris@0 678 assert @jsmith.wants_comments_in_reverse_order?
Chris@0 679 end
Chris@909 680
Chris@0 681 def test_find_by_mail_should_be_case_insensitive
Chris@0 682 u = User.find_by_mail('JSmith@somenet.foo')
Chris@0 683 assert_not_nil u
Chris@0 684 assert_equal 'jsmith@somenet.foo', u.mail
Chris@0 685 end
Chris@909 686
Chris@0 687 def test_random_password
Chris@0 688 u = User.new
Chris@0 689 u.random_password
Chris@0 690 assert !u.password.blank?
Chris@0 691 assert !u.password_confirmation.blank?
Chris@0 692 end
Chris@0 693
Chris@0 694 context "#change_password_allowed?" do
Chris@0 695 should "be allowed if no auth source is set" do
Chris@0 696 user = User.generate_with_protected!
Chris@0 697 assert user.change_password_allowed?
Chris@0 698 end
Chris@0 699
Chris@0 700 should "delegate to the auth source" do
Chris@0 701 user = User.generate_with_protected!
Chris@909 702
Chris@0 703 allowed_auth_source = AuthSource.generate!
Chris@0 704 def allowed_auth_source.allow_password_changes?; true; end
Chris@0 705
Chris@0 706 denied_auth_source = AuthSource.generate!
Chris@0 707 def denied_auth_source.allow_password_changes?; false; end
Chris@0 708
Chris@0 709 assert user.change_password_allowed?
Chris@0 710
Chris@0 711 user.auth_source = allowed_auth_source
Chris@0 712 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
Chris@0 713
Chris@0 714 user.auth_source = denied_auth_source
Chris@0 715 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
Chris@0 716 end
Chris@0 717
Chris@0 718 end
Chris@909 719
chris@22 720 context "#allowed_to?" do
chris@22 721 context "with a unique project" do
chris@22 722 should "return false if project is archived" do
chris@22 723 project = Project.find(1)
chris@22 724 Project.any_instance.stubs(:status).returns(Project::STATUS_ARCHIVED)
chris@22 725 assert ! @admin.allowed_to?(:view_issues, Project.find(1))
chris@22 726 end
Chris@909 727
chris@22 728 should "return false if related module is disabled" do
chris@22 729 project = Project.find(1)
chris@22 730 project.enabled_module_names = ["issue_tracking"]
chris@22 731 assert @admin.allowed_to?(:add_issues, project)
chris@22 732 assert ! @admin.allowed_to?(:view_wiki_pages, project)
chris@22 733 end
Chris@909 734
chris@22 735 should "authorize nearly everything for admin users" do
chris@22 736 project = Project.find(1)
chris@22 737 assert ! @admin.member_of?(project)
chris@22 738 %w(edit_issues delete_issues manage_news manage_documents manage_wiki).each do |p|
chris@22 739 assert @admin.allowed_to?(p.to_sym, project)
chris@22 740 end
chris@22 741 end
Chris@909 742
chris@22 743 should "authorize normal users depending on their roles" do
chris@22 744 project = Project.find(1)
chris@22 745 assert @jsmith.allowed_to?(:delete_messages, project) #Manager
chris@22 746 assert ! @dlopper.allowed_to?(:delete_messages, project) #Developper
chris@22 747 end
chris@22 748 end
chris@37 749
chris@37 750 context "with multiple projects" do
chris@37 751 should "return false if array is empty" do
chris@37 752 assert ! @admin.allowed_to?(:view_project, [])
chris@37 753 end
Chris@909 754
chris@37 755 should "return true only if user has permission on all these projects" do
chris@37 756 assert @admin.allowed_to?(:view_project, Project.all)
chris@37 757 assert ! @dlopper.allowed_to?(:view_project, Project.all) #cannot see Project(2)
chris@37 758 assert @jsmith.allowed_to?(:edit_issues, @jsmith.projects) #Manager or Developer everywhere
chris@37 759 assert ! @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects) #Dev cannot delete_issue_watchers
chris@37 760 end
Chris@909 761
chris@37 762 should "behave correctly with arrays of 1 project" do
chris@37 763 assert ! User.anonymous.allowed_to?(:delete_issues, [Project.first])
chris@37 764 end
chris@37 765 end
Chris@909 766
chris@22 767 context "with options[:global]" do
chris@22 768 should "authorize if user has at least one role that has this permission" do
chris@22 769 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
chris@22 770 @anonymous = User.find(6)
chris@22 771 assert @jsmith.allowed_to?(:delete_issue_watchers, nil, :global => true)
chris@22 772 assert ! @dlopper2.allowed_to?(:delete_issue_watchers, nil, :global => true)
chris@22 773 assert @dlopper2.allowed_to?(:add_issues, nil, :global => true)
chris@22 774 assert ! @anonymous.allowed_to?(:add_issues, nil, :global => true)
chris@22 775 assert @anonymous.allowed_to?(:view_issues, nil, :global => true)
chris@22 776 end
chris@22 777 end
chris@22 778 end
Chris@909 779
chris@37 780 context "User#notify_about?" do
chris@37 781 context "Issues" do
chris@37 782 setup do
chris@37 783 @project = Project.find(1)
chris@37 784 @author = User.generate_with_protected!
chris@37 785 @assignee = User.generate_with_protected!
chris@37 786 @issue = Issue.generate_for_project!(@project, :assigned_to => @assignee, :author => @author)
chris@37 787 end
chris@37 788
chris@37 789 should "be true for a user with :all" do
Chris@119 790 @author.update_attribute(:mail_notification, 'all')
chris@37 791 assert @author.notify_about?(@issue)
chris@37 792 end
Chris@909 793
chris@37 794 should "be false for a user with :none" do
Chris@119 795 @author.update_attribute(:mail_notification, 'none')
chris@37 796 assert ! @author.notify_about?(@issue)
chris@37 797 end
Chris@909 798
chris@37 799 should "be false for a user with :only_my_events and isn't an author, creator, or assignee" do
Chris@119 800 @user = User.generate_with_protected!(:mail_notification => 'only_my_events')
Chris@210 801 Member.create!(:user => @user, :project => @project, :role_ids => [1])
chris@37 802 assert ! @user.notify_about?(@issue)
chris@37 803 end
Chris@909 804
chris@37 805 should "be true for a user with :only_my_events and is the author" do
Chris@119 806 @author.update_attribute(:mail_notification, 'only_my_events')
chris@37 807 assert @author.notify_about?(@issue)
chris@37 808 end
Chris@909 809
chris@37 810 should "be true for a user with :only_my_events and is the assignee" do
Chris@119 811 @assignee.update_attribute(:mail_notification, 'only_my_events')
chris@37 812 assert @assignee.notify_about?(@issue)
chris@37 813 end
Chris@909 814
chris@37 815 should "be true for a user with :only_assigned and is the assignee" do
Chris@119 816 @assignee.update_attribute(:mail_notification, 'only_assigned')
chris@37 817 assert @assignee.notify_about?(@issue)
chris@37 818 end
Chris@909 819
chris@37 820 should "be false for a user with :only_assigned and is not the assignee" do
Chris@119 821 @author.update_attribute(:mail_notification, 'only_assigned')
chris@37 822 assert ! @author.notify_about?(@issue)
chris@37 823 end
Chris@909 824
chris@37 825 should "be true for a user with :only_owner and is the author" do
Chris@119 826 @author.update_attribute(:mail_notification, 'only_owner')
chris@37 827 assert @author.notify_about?(@issue)
chris@37 828 end
Chris@909 829
chris@37 830 should "be false for a user with :only_owner and is not the author" do
Chris@119 831 @assignee.update_attribute(:mail_notification, 'only_owner')
chris@37 832 assert ! @assignee.notify_about?(@issue)
chris@37 833 end
Chris@909 834
Chris@210 835 should "be true for a user with :selected and is the author" do
Chris@210 836 @author.update_attribute(:mail_notification, 'selected')
Chris@210 837 assert @author.notify_about?(@issue)
Chris@210 838 end
Chris@909 839
Chris@210 840 should "be true for a user with :selected and is the assignee" do
Chris@210 841 @assignee.update_attribute(:mail_notification, 'selected')
Chris@210 842 assert @assignee.notify_about?(@issue)
Chris@210 843 end
Chris@909 844
Chris@210 845 should "be false for a user with :selected and is not the author or assignee" do
Chris@210 846 @user = User.generate_with_protected!(:mail_notification => 'selected')
Chris@210 847 Member.create!(:user => @user, :project => @project, :role_ids => [1])
Chris@210 848 assert ! @user.notify_about?(@issue)
Chris@210 849 end
chris@37 850 end
chris@37 851
chris@37 852 context "other events" do
chris@37 853 should 'be added and tested'
chris@37 854 end
chris@37 855 end
Chris@245 856
Chris@245 857 def test_salt_unsalted_passwords
Chris@245 858 # Restore a user with an unsalted password
Chris@245 859 user = User.find(1)
Chris@245 860 user.salt = nil
Chris@245 861 user.hashed_password = User.hash_password("unsalted")
Chris@245 862 user.save!
Chris@909 863
Chris@245 864 User.salt_unsalted_passwords!
Chris@909 865
Chris@245 866 user.reload
Chris@245 867 # Salt added
Chris@245 868 assert !user.salt.blank?
Chris@245 869 # Password still valid
Chris@245 870 assert user.check_password?("unsalted")
Chris@245 871 assert_equal user, User.try_to_login(user.login, "unsalted")
Chris@245 872 end
Chris@909 873
Chris@0 874 if Object.const_defined?(:OpenID)
Chris@909 875
Chris@0 876 def test_setting_identity_url
Chris@0 877 normalized_open_id_url = 'http://example.com/'
Chris@0 878 u = User.new( :identity_url => 'http://example.com/' )
Chris@0 879 assert_equal normalized_open_id_url, u.identity_url
Chris@0 880 end
Chris@0 881
Chris@0 882 def test_setting_identity_url_without_trailing_slash
Chris@0 883 normalized_open_id_url = 'http://example.com/'
Chris@0 884 u = User.new( :identity_url => 'http://example.com' )
Chris@0 885 assert_equal normalized_open_id_url, u.identity_url
Chris@0 886 end
Chris@0 887
Chris@0 888 def test_setting_identity_url_without_protocol
Chris@0 889 normalized_open_id_url = 'http://example.com/'
Chris@0 890 u = User.new( :identity_url => 'example.com' )
Chris@0 891 assert_equal normalized_open_id_url, u.identity_url
Chris@0 892 end
Chris@909 893
Chris@0 894 def test_setting_blank_identity_url
Chris@0 895 u = User.new( :identity_url => 'example.com' )
Chris@0 896 u.identity_url = ''
Chris@0 897 assert u.identity_url.blank?
Chris@0 898 end
Chris@909 899
Chris@0 900 def test_setting_invalid_identity_url
Chris@0 901 u = User.new( :identity_url => 'this is not an openid url' )
Chris@0 902 assert u.identity_url.blank?
Chris@0 903 end
Chris@909 904
Chris@0 905 else
Chris@0 906 puts "Skipping openid tests."
Chris@0 907 end
Chris@0 908
Chris@0 909 end