comparison .svn/pristine/ec/ec7c0d826b7228b3557fac4fa00ebff6a515cfda.svn-base @ 1464:261b3d9a4903 redmine-2.4

Update to Redmine 2.4 branch rev 12663
author Chris Cannam
date Tue, 14 Jan 2014 14:37:42 +0000
parents
children
comparison
equal deleted inserted replaced
1296:038ba2d95de8 1464:261b3d9a4903
1 # Redmine - project management software
2 # Copyright (C) 2006-2013 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.expand_path('../../test_helper', __FILE__)
19
20 class UserTest < ActiveSupport::TestCase
21 fixtures :users, :members, :projects, :roles, :member_roles, :auth_sources,
22 :trackers, :issue_statuses,
23 :projects_trackers,
24 :watchers,
25 :issue_categories, :enumerations, :issues,
26 :journals, :journal_details,
27 :groups_users,
28 :enabled_modules
29
30 def setup
31 @admin = User.find(1)
32 @jsmith = User.find(2)
33 @dlopper = User.find(3)
34 end
35
36 def test_sorted_scope_should_sort_user_by_display_name
37 assert_equal User.all.map(&:name).map(&:downcase).sort, User.sorted.all.map(&:name).map(&:downcase)
38 end
39
40 def test_generate
41 User.generate!(:firstname => 'Testing connection')
42 User.generate!(:firstname => 'Testing connection')
43 assert_equal 2, User.where(:firstname => 'Testing connection').count
44 end
45
46 def test_truth
47 assert_kind_of User, @jsmith
48 end
49
50 def test_mail_should_be_stripped
51 u = User.new
52 u.mail = " foo@bar.com "
53 assert_equal "foo@bar.com", u.mail
54 end
55
56 def test_mail_validation
57 u = User.new
58 u.mail = ''
59 assert !u.valid?
60 assert_include I18n.translate('activerecord.errors.messages.blank'), u.errors[:mail]
61 end
62
63 def test_login_length_validation
64 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
65 user.login = "x" * (User::LOGIN_LENGTH_LIMIT+1)
66 assert !user.valid?
67
68 user.login = "x" * (User::LOGIN_LENGTH_LIMIT)
69 assert user.valid?
70 assert user.save
71 end
72
73 def test_generate_password_should_respect_minimum_password_length
74 with_settings :password_min_length => 15 do
75 user = User.generate!(:generate_password => true)
76 assert user.password.length >= 15
77 end
78 end
79
80 def test_generate_password_should_not_generate_password_with_less_than_10_characters
81 with_settings :password_min_length => 4 do
82 user = User.generate!(:generate_password => true)
83 assert user.password.length >= 10
84 end
85 end
86
87 def test_generate_password_on_create_should_set_password
88 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
89 user.login = "newuser"
90 user.generate_password = true
91 assert user.save
92
93 password = user.password
94 assert user.check_password?(password)
95 end
96
97 def test_generate_password_on_update_should_update_password
98 user = User.find(2)
99 hash = user.hashed_password
100 user.generate_password = true
101 assert user.save
102
103 password = user.password
104 assert user.check_password?(password)
105 assert_not_equal hash, user.reload.hashed_password
106 end
107
108 def test_create
109 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
110
111 user.login = "jsmith"
112 user.password, user.password_confirmation = "password", "password"
113 # login uniqueness
114 assert !user.save
115 assert_equal 1, user.errors.count
116
117 user.login = "newuser"
118 user.password, user.password_confirmation = "password", "pass"
119 # password confirmation
120 assert !user.save
121 assert_equal 1, user.errors.count
122
123 user.password, user.password_confirmation = "password", "password"
124 assert user.save
125 end
126
127 def test_user_before_create_should_set_the_mail_notification_to_the_default_setting
128 @user1 = User.generate!
129 assert_equal 'only_my_events', @user1.mail_notification
130 with_settings :default_notification_option => 'all' do
131 @user2 = User.generate!
132 assert_equal 'all', @user2.mail_notification
133 end
134 end
135
136 def test_user_login_should_be_case_insensitive
137 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
138 u.login = 'newuser'
139 u.password, u.password_confirmation = "password", "password"
140 assert u.save
141 u = User.new(:firstname => "Similar", :lastname => "User", :mail => "similaruser@somenet.foo")
142 u.login = 'NewUser'
143 u.password, u.password_confirmation = "password", "password"
144 assert !u.save
145 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:login]
146 end
147
148 def test_mail_uniqueness_should_not_be_case_sensitive
149 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
150 u.login = 'newuser1'
151 u.password, u.password_confirmation = "password", "password"
152 assert u.save
153
154 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
155 u.login = 'newuser2'
156 u.password, u.password_confirmation = "password", "password"
157 assert !u.save
158 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:mail]
159 end
160
161 def test_update
162 assert_equal "admin", @admin.login
163 @admin.login = "john"
164 assert @admin.save, @admin.errors.full_messages.join("; ")
165 @admin.reload
166 assert_equal "john", @admin.login
167 end
168
169 def test_update_should_not_fail_for_legacy_user_with_different_case_logins
170 u1 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser1@somenet.foo")
171 u1.login = 'newuser1'
172 assert u1.save
173
174 u2 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser2@somenet.foo")
175 u2.login = 'newuser1'
176 assert u2.save(:validate => false)
177
178 user = User.find(u2.id)
179 user.firstname = "firstname"
180 assert user.save, "Save failed"
181 end
182
183 def test_destroy_should_delete_members_and_roles
184 members = Member.find_all_by_user_id(2)
185 ms = members.size
186 rs = members.collect(&:roles).flatten.size
187
188 assert_difference 'Member.count', - ms do
189 assert_difference 'MemberRole.count', - rs do
190 User.find(2).destroy
191 end
192 end
193
194 assert_nil User.find_by_id(2)
195 assert Member.find_all_by_user_id(2).empty?
196 end
197
198 def test_destroy_should_update_attachments
199 attachment = Attachment.create!(:container => Project.find(1),
200 :file => uploaded_test_file("testfile.txt", "text/plain"),
201 :author_id => 2)
202
203 User.find(2).destroy
204 assert_nil User.find_by_id(2)
205 assert_equal User.anonymous, attachment.reload.author
206 end
207
208 def test_destroy_should_update_comments
209 comment = Comment.create!(
210 :commented => News.create!(:project_id => 1, :author_id => 1, :title => 'foo', :description => 'foo'),
211 :author => User.find(2),
212 :comments => 'foo'
213 )
214
215 User.find(2).destroy
216 assert_nil User.find_by_id(2)
217 assert_equal User.anonymous, comment.reload.author
218 end
219
220 def test_destroy_should_update_issues
221 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
222
223 User.find(2).destroy
224 assert_nil User.find_by_id(2)
225 assert_equal User.anonymous, issue.reload.author
226 end
227
228 def test_destroy_should_unassign_issues
229 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
230
231 User.find(2).destroy
232 assert_nil User.find_by_id(2)
233 assert_nil issue.reload.assigned_to
234 end
235
236 def test_destroy_should_update_journals
237 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
238 issue.init_journal(User.find(2), "update")
239 issue.save!
240
241 User.find(2).destroy
242 assert_nil User.find_by_id(2)
243 assert_equal User.anonymous, issue.journals.first.reload.user
244 end
245
246 def test_destroy_should_update_journal_details_old_value
247 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
248 issue.init_journal(User.find(1), "update")
249 issue.assigned_to_id = nil
250 assert_difference 'JournalDetail.count' do
251 issue.save!
252 end
253 journal_detail = JournalDetail.first(:order => 'id DESC')
254 assert_equal '2', journal_detail.old_value
255
256 User.find(2).destroy
257 assert_nil User.find_by_id(2)
258 assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value
259 end
260
261 def test_destroy_should_update_journal_details_value
262 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
263 issue.init_journal(User.find(1), "update")
264 issue.assigned_to_id = 2
265 assert_difference 'JournalDetail.count' do
266 issue.save!
267 end
268 journal_detail = JournalDetail.first(:order => 'id DESC')
269 assert_equal '2', journal_detail.value
270
271 User.find(2).destroy
272 assert_nil User.find_by_id(2)
273 assert_equal User.anonymous.id.to_s, journal_detail.reload.value
274 end
275
276 def test_destroy_should_update_messages
277 board = Board.create!(:project_id => 1, :name => 'Board', :description => 'Board')
278 message = Message.create!(:board_id => board.id, :author_id => 2, :subject => 'foo', :content => 'foo')
279
280 User.find(2).destroy
281 assert_nil User.find_by_id(2)
282 assert_equal User.anonymous, message.reload.author
283 end
284
285 def test_destroy_should_update_news
286 news = News.create!(:project_id => 1, :author_id => 2, :title => 'foo', :description => 'foo')
287
288 User.find(2).destroy
289 assert_nil User.find_by_id(2)
290 assert_equal User.anonymous, news.reload.author
291 end
292
293 def test_destroy_should_delete_private_queries
294 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PRIVATE)
295 query.project_id = 1
296 query.user_id = 2
297 query.save!
298
299 User.find(2).destroy
300 assert_nil User.find_by_id(2)
301 assert_nil Query.find_by_id(query.id)
302 end
303
304 def test_destroy_should_update_public_queries
305 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PUBLIC)
306 query.project_id = 1
307 query.user_id = 2
308 query.save!
309
310 User.find(2).destroy
311 assert_nil User.find_by_id(2)
312 assert_equal User.anonymous, query.reload.user
313 end
314
315 def test_destroy_should_update_time_entries
316 entry = TimeEntry.new(:hours => '2', :spent_on => Date.today, :activity => TimeEntryActivity.create!(:name => 'foo'))
317 entry.project_id = 1
318 entry.user_id = 2
319 entry.save!
320
321 User.find(2).destroy
322 assert_nil User.find_by_id(2)
323 assert_equal User.anonymous, entry.reload.user
324 end
325
326 def test_destroy_should_delete_tokens
327 token = Token.create!(:user_id => 2, :value => 'foo')
328
329 User.find(2).destroy
330 assert_nil User.find_by_id(2)
331 assert_nil Token.find_by_id(token.id)
332 end
333
334 def test_destroy_should_delete_watchers
335 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
336 watcher = Watcher.create!(:user_id => 2, :watchable => issue)
337
338 User.find(2).destroy
339 assert_nil User.find_by_id(2)
340 assert_nil Watcher.find_by_id(watcher.id)
341 end
342
343 def test_destroy_should_update_wiki_contents
344 wiki_content = WikiContent.create!(
345 :text => 'foo',
346 :author_id => 2,
347 :page => WikiPage.create!(:title => 'Foo', :wiki => Wiki.create!(:project_id => 1, :start_page => 'Start'))
348 )
349 wiki_content.text = 'bar'
350 assert_difference 'WikiContent::Version.count' do
351 wiki_content.save!
352 end
353
354 User.find(2).destroy
355 assert_nil User.find_by_id(2)
356 assert_equal User.anonymous, wiki_content.reload.author
357 wiki_content.versions.each do |version|
358 assert_equal User.anonymous, version.reload.author
359 end
360 end
361
362 def test_destroy_should_nullify_issue_categories
363 category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo')
364
365 User.find(2).destroy
366 assert_nil User.find_by_id(2)
367 assert_nil category.reload.assigned_to_id
368 end
369
370 def test_destroy_should_nullify_changesets
371 changeset = Changeset.create!(
372 :repository => Repository::Subversion.create!(
373 :project_id => 1,
374 :url => 'file:///tmp',
375 :identifier => 'tmp'
376 ),
377 :revision => '12',
378 :committed_on => Time.now,
379 :committer => 'jsmith'
380 )
381 assert_equal 2, changeset.user_id
382
383 User.find(2).destroy
384 assert_nil User.find_by_id(2)
385 assert_nil changeset.reload.user_id
386 end
387
388 def test_anonymous_user_should_not_be_destroyable
389 assert_no_difference 'User.count' do
390 assert_equal false, User.anonymous.destroy
391 end
392 end
393
394 def test_validate_login_presence
395 @admin.login = ""
396 assert !@admin.save
397 assert_equal 1, @admin.errors.count
398 end
399
400 def test_validate_mail_notification_inclusion
401 u = User.new
402 u.mail_notification = 'foo'
403 u.save
404 assert_not_equal [], u.errors[:mail_notification]
405 end
406
407 def test_password
408 user = User.try_to_login("admin", "admin")
409 assert_kind_of User, user
410 assert_equal "admin", user.login
411 user.password = "hello123"
412 assert user.save
413
414 user = User.try_to_login("admin", "hello123")
415 assert_kind_of User, user
416 assert_equal "admin", user.login
417 end
418
419 def test_validate_password_length
420 with_settings :password_min_length => '100' do
421 user = User.new(:firstname => "new100", :lastname => "user100", :mail => "newuser100@somenet.foo")
422 user.login = "newuser100"
423 user.password, user.password_confirmation = "password100", "password100"
424 assert !user.save
425 assert_equal 1, user.errors.count
426 end
427 end
428
429 def test_name_format
430 assert_equal 'John S.', @jsmith.name(:firstname_lastinitial)
431 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
432 with_settings :user_format => :firstname_lastname do
433 assert_equal 'John Smith', @jsmith.reload.name
434 end
435 with_settings :user_format => :username do
436 assert_equal 'jsmith', @jsmith.reload.name
437 end
438 with_settings :user_format => :lastname do
439 assert_equal 'Smith', @jsmith.reload.name
440 end
441 end
442
443 def test_today_should_return_the_day_according_to_user_time_zone
444 preference = User.find(1).pref
445 date = Date.new(2012, 05, 15)
446 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
447 Date.stubs(:today).returns(date)
448 Time.stubs(:now).returns(time)
449
450 preference.update_attribute :time_zone, 'Baku' # UTC+4
451 assert_equal '2012-05-16', User.find(1).today.to_s
452
453 preference.update_attribute :time_zone, 'La Paz' # UTC-4
454 assert_equal '2012-05-15', User.find(1).today.to_s
455
456 preference.update_attribute :time_zone, ''
457 assert_equal '2012-05-15', User.find(1).today.to_s
458 end
459
460 def test_time_to_date_should_return_the_date_according_to_user_time_zone
461 preference = User.find(1).pref
462 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
463
464 preference.update_attribute :time_zone, 'Baku' # UTC+4
465 assert_equal '2012-05-16', User.find(1).time_to_date(time).to_s
466
467 preference.update_attribute :time_zone, 'La Paz' # UTC-4
468 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
469
470 preference.update_attribute :time_zone, ''
471 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
472 end
473
474 def test_fields_for_order_statement_should_return_fields_according_user_format_setting
475 with_settings :user_format => 'lastname_coma_firstname' do
476 assert_equal ['users.lastname', 'users.firstname', 'users.id'], User.fields_for_order_statement
477 end
478 end
479
480 def test_fields_for_order_statement_width_table_name_should_prepend_table_name
481 with_settings :user_format => 'lastname_firstname' do
482 assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'], User.fields_for_order_statement('authors')
483 end
484 end
485
486 def test_fields_for_order_statement_with_blank_format_should_return_default
487 with_settings :user_format => '' do
488 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
489 end
490 end
491
492 def test_fields_for_order_statement_with_invalid_format_should_return_default
493 with_settings :user_format => 'foo' do
494 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
495 end
496 end
497
498 test ".try_to_login with good credentials should return the user" do
499 user = User.try_to_login("admin", "admin")
500 assert_kind_of User, user
501 assert_equal "admin", user.login
502 end
503
504 test ".try_to_login with wrong credentials should return nil" do
505 assert_nil User.try_to_login("admin", "foo")
506 end
507
508 def test_try_to_login_with_locked_user_should_return_nil
509 @jsmith.status = User::STATUS_LOCKED
510 @jsmith.save!
511
512 user = User.try_to_login("jsmith", "jsmith")
513 assert_equal nil, user
514 end
515
516 def test_try_to_login_with_locked_user_and_not_active_only_should_return_user
517 @jsmith.status = User::STATUS_LOCKED
518 @jsmith.save!
519
520 user = User.try_to_login("jsmith", "jsmith", false)
521 assert_equal @jsmith, user
522 end
523
524 test ".try_to_login should fall-back to case-insensitive if user login is not found as-typed" do
525 user = User.try_to_login("AdMin", "admin")
526 assert_kind_of User, user
527 assert_equal "admin", user.login
528 end
529
530 test ".try_to_login should select the exact matching user first" do
531 case_sensitive_user = User.generate! do |user|
532 user.password = "admin123"
533 end
534 # bypass validations to make it appear like existing data
535 case_sensitive_user.update_attribute(:login, 'ADMIN')
536
537 user = User.try_to_login("ADMIN", "admin123")
538 assert_kind_of User, user
539 assert_equal "ADMIN", user.login
540 end
541
542 if ldap_configured?
543 context "#try_to_login using LDAP" do
544 context "with failed connection to the LDAP server" do
545 should "return nil" do
546 @auth_source = AuthSourceLdap.find(1)
547 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
548
549 assert_equal nil, User.try_to_login('edavis', 'wrong')
550 end
551 end
552
553 context "with an unsuccessful authentication" do
554 should "return nil" do
555 assert_equal nil, User.try_to_login('edavis', 'wrong')
556 end
557 end
558
559 context "binding with user's account" do
560 setup do
561 @auth_source = AuthSourceLdap.find(1)
562 @auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
563 @auth_source.account_password = ''
564 @auth_source.save!
565
566 @ldap_user = User.new(:mail => 'example1@redmine.org', :firstname => 'LDAP', :lastname => 'user', :auth_source_id => 1)
567 @ldap_user.login = 'example1'
568 @ldap_user.save!
569 end
570
571 context "with a successful authentication" do
572 should "return the user" do
573 assert_equal @ldap_user, User.try_to_login('example1', '123456')
574 end
575 end
576
577 context "with an unsuccessful authentication" do
578 should "return nil" do
579 assert_nil User.try_to_login('example1', '11111')
580 end
581 end
582 end
583
584 context "on the fly registration" do
585 setup do
586 @auth_source = AuthSourceLdap.find(1)
587 @auth_source.update_attribute :onthefly_register, true
588 end
589
590 context "with a successful authentication" do
591 should "create a new user account if it doesn't exist" do
592 assert_difference('User.count') do
593 user = User.try_to_login('edavis', '123456')
594 assert !user.admin?
595 end
596 end
597
598 should "retrieve existing user" do
599 user = User.try_to_login('edavis', '123456')
600 user.admin = true
601 user.save!
602
603 assert_no_difference('User.count') do
604 user = User.try_to_login('edavis', '123456')
605 assert user.admin?
606 end
607 end
608 end
609
610 context "binding with user's account" do
611 setup do
612 @auth_source = AuthSourceLdap.find(1)
613 @auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
614 @auth_source.account_password = ''
615 @auth_source.save!
616 end
617
618 context "with a successful authentication" do
619 should "create a new user account if it doesn't exist" do
620 assert_difference('User.count') do
621 user = User.try_to_login('example1', '123456')
622 assert_kind_of User, user
623 end
624 end
625 end
626
627 context "with an unsuccessful authentication" do
628 should "return nil" do
629 assert_nil User.try_to_login('example1', '11111')
630 end
631 end
632 end
633 end
634 end
635
636 else
637 puts "Skipping LDAP tests."
638 end
639
640 def test_create_anonymous
641 AnonymousUser.delete_all
642 anon = User.anonymous
643 assert !anon.new_record?
644 assert_kind_of AnonymousUser, anon
645 end
646
647 def test_ensure_single_anonymous_user
648 AnonymousUser.delete_all
649 anon1 = User.anonymous
650 assert !anon1.new_record?
651 assert_kind_of AnonymousUser, anon1
652 anon2 = AnonymousUser.create(
653 :lastname => 'Anonymous', :firstname => '',
654 :mail => '', :login => '', :status => 0)
655 assert_equal 1, anon2.errors.count
656 end
657
658 def test_rss_key
659 assert_nil @jsmith.rss_token
660 key = @jsmith.rss_key
661 assert_equal 40, key.length
662
663 @jsmith.reload
664 assert_equal key, @jsmith.rss_key
665 end
666
667 def test_rss_key_should_not_be_generated_twice
668 assert_difference 'Token.count', 1 do
669 key1 = @jsmith.rss_key
670 key2 = @jsmith.rss_key
671 assert_equal key1, key2
672 end
673 end
674
675 def test_api_key_should_not_be_generated_twice
676 assert_difference 'Token.count', 1 do
677 key1 = @jsmith.api_key
678 key2 = @jsmith.api_key
679 assert_equal key1, key2
680 end
681 end
682
683 test "#api_key should generate a new one if the user doesn't have one" do
684 user = User.generate!(:api_token => nil)
685 assert_nil user.api_token
686
687 key = user.api_key
688 assert_equal 40, key.length
689 user.reload
690 assert_equal key, user.api_key
691 end
692
693 test "#api_key should return the existing api token value" do
694 user = User.generate!
695 token = Token.create!(:action => 'api')
696 user.api_token = token
697 assert user.save
698
699 assert_equal token.value, user.api_key
700 end
701
702 test "#find_by_api_key should return nil if no matching key is found" do
703 assert_nil User.find_by_api_key('zzzzzzzzz')
704 end
705
706 test "#find_by_api_key should return nil if the key is found for an inactive user" do
707 user = User.generate!
708 user.status = User::STATUS_LOCKED
709 token = Token.create!(:action => 'api')
710 user.api_token = token
711 user.save
712
713 assert_nil User.find_by_api_key(token.value)
714 end
715
716 test "#find_by_api_key should return the user if the key is found for an active user" do
717 user = User.generate!
718 token = Token.create!(:action => 'api')
719 user.api_token = token
720 user.save
721
722 assert_equal user, User.find_by_api_key(token.value)
723 end
724
725 def test_default_admin_account_changed_should_return_false_if_account_was_not_changed
726 user = User.find_by_login("admin")
727 user.password = "admin"
728 assert user.save(:validate => false)
729
730 assert_equal false, User.default_admin_account_changed?
731 end
732
733 def test_default_admin_account_changed_should_return_true_if_password_was_changed
734 user = User.find_by_login("admin")
735 user.password = "newpassword"
736 user.save!
737
738 assert_equal true, User.default_admin_account_changed?
739 end
740
741 def test_default_admin_account_changed_should_return_true_if_account_is_disabled
742 user = User.find_by_login("admin")
743 user.password = "admin"
744 user.status = User::STATUS_LOCKED
745 assert user.save(:validate => false)
746
747 assert_equal true, User.default_admin_account_changed?
748 end
749
750 def test_default_admin_account_changed_should_return_true_if_account_does_not_exist
751 user = User.find_by_login("admin")
752 user.destroy
753
754 assert_equal true, User.default_admin_account_changed?
755 end
756
757 def test_membership_with_project_should_return_membership
758 project = Project.find(1)
759
760 membership = @jsmith.membership(project)
761 assert_kind_of Member, membership
762 assert_equal @jsmith, membership.user
763 assert_equal project, membership.project
764 end
765
766 def test_membership_with_project_id_should_return_membership
767 project = Project.find(1)
768
769 membership = @jsmith.membership(1)
770 assert_kind_of Member, membership
771 assert_equal @jsmith, membership.user
772 assert_equal project, membership.project
773 end
774
775 def test_membership_for_non_member_should_return_nil
776 project = Project.find(1)
777
778 user = User.generate!
779 membership = user.membership(1)
780 assert_nil membership
781 end
782
783 def test_roles_for_project
784 # user with a role
785 roles = @jsmith.roles_for_project(Project.find(1))
786 assert_kind_of Role, roles.first
787 assert_equal "Manager", roles.first.name
788
789 # user with no role
790 assert_nil @dlopper.roles_for_project(Project.find(2)).detect {|role| role.member?}
791 end
792
793 def test_projects_by_role_for_user_with_role
794 user = User.find(2)
795 assert_kind_of Hash, user.projects_by_role
796 assert_equal 2, user.projects_by_role.size
797 assert_equal [1,5], user.projects_by_role[Role.find(1)].collect(&:id).sort
798 assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort
799 end
800
801 def test_accessing_projects_by_role_with_no_projects_should_return_an_empty_array
802 user = User.find(2)
803 assert_equal [], user.projects_by_role[Role.find(3)]
804 # should not update the hash
805 assert_nil user.projects_by_role.values.detect(&:blank?)
806 end
807
808 def test_projects_by_role_for_user_with_no_role
809 user = User.generate!
810 assert_equal({}, user.projects_by_role)
811 end
812
813 def test_projects_by_role_for_anonymous
814 assert_equal({}, User.anonymous.projects_by_role)
815 end
816
817 def test_valid_notification_options
818 # without memberships
819 assert_equal 5, User.find(7).valid_notification_options.size
820 # with memberships
821 assert_equal 6, User.find(2).valid_notification_options.size
822 end
823
824 def test_valid_notification_options_class_method
825 assert_equal 5, User.valid_notification_options.size
826 assert_equal 5, User.valid_notification_options(User.find(7)).size
827 assert_equal 6, User.valid_notification_options(User.find(2)).size
828 end
829
830 def test_mail_notification_all
831 @jsmith.mail_notification = 'all'
832 @jsmith.notified_project_ids = []
833 @jsmith.save
834 @jsmith.reload
835 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
836 end
837
838 def test_mail_notification_selected
839 @jsmith.mail_notification = 'selected'
840 @jsmith.notified_project_ids = [1]
841 @jsmith.save
842 @jsmith.reload
843 assert Project.find(1).recipients.include?(@jsmith.mail)
844 end
845
846 def test_mail_notification_only_my_events
847 @jsmith.mail_notification = 'only_my_events'
848 @jsmith.notified_project_ids = []
849 @jsmith.save
850 @jsmith.reload
851 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
852 end
853
854 def test_comments_sorting_preference
855 assert !@jsmith.wants_comments_in_reverse_order?
856 @jsmith.pref.comments_sorting = 'asc'
857 assert !@jsmith.wants_comments_in_reverse_order?
858 @jsmith.pref.comments_sorting = 'desc'
859 assert @jsmith.wants_comments_in_reverse_order?
860 end
861
862 def test_find_by_mail_should_be_case_insensitive
863 u = User.find_by_mail('JSmith@somenet.foo')
864 assert_not_nil u
865 assert_equal 'jsmith@somenet.foo', u.mail
866 end
867
868 def test_random_password
869 u = User.new
870 u.random_password
871 assert !u.password.blank?
872 assert !u.password_confirmation.blank?
873 end
874
875 test "#change_password_allowed? should be allowed if no auth source is set" do
876 user = User.generate!
877 assert user.change_password_allowed?
878 end
879
880 test "#change_password_allowed? should delegate to the auth source" do
881 user = User.generate!
882
883 allowed_auth_source = AuthSource.generate!
884 def allowed_auth_source.allow_password_changes?; true; end
885
886 denied_auth_source = AuthSource.generate!
887 def denied_auth_source.allow_password_changes?; false; end
888
889 assert user.change_password_allowed?
890
891 user.auth_source = allowed_auth_source
892 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
893
894 user.auth_source = denied_auth_source
895 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
896 end
897
898 def test_own_account_deletable_should_be_true_with_unsubscrive_enabled
899 with_settings :unsubscribe => '1' do
900 assert_equal true, User.find(2).own_account_deletable?
901 end
902 end
903
904 def test_own_account_deletable_should_be_false_with_unsubscrive_disabled
905 with_settings :unsubscribe => '0' do
906 assert_equal false, User.find(2).own_account_deletable?
907 end
908 end
909
910 def test_own_account_deletable_should_be_false_for_a_single_admin
911 User.delete_all(["admin = ? AND id <> ?", true, 1])
912
913 with_settings :unsubscribe => '1' do
914 assert_equal false, User.find(1).own_account_deletable?
915 end
916 end
917
918 def test_own_account_deletable_should_be_true_for_an_admin_if_other_admin_exists
919 User.generate! do |user|
920 user.admin = true
921 end
922
923 with_settings :unsubscribe => '1' do
924 assert_equal true, User.find(1).own_account_deletable?
925 end
926 end
927
928 context "#allowed_to?" do
929 context "with a unique project" do
930 should "return false if project is archived" do
931 project = Project.find(1)
932 Project.any_instance.stubs(:status).returns(Project::STATUS_ARCHIVED)
933 assert_equal false, @admin.allowed_to?(:view_issues, Project.find(1))
934 end
935
936 should "return false for write action if project is closed" do
937 project = Project.find(1)
938 Project.any_instance.stubs(:status).returns(Project::STATUS_CLOSED)
939 assert_equal false, @admin.allowed_to?(:edit_project, Project.find(1))
940 end
941
942 should "return true for read action if project is closed" do
943 project = Project.find(1)
944 Project.any_instance.stubs(:status).returns(Project::STATUS_CLOSED)
945 assert_equal true, @admin.allowed_to?(:view_project, Project.find(1))
946 end
947
948 should "return false if related module is disabled" do
949 project = Project.find(1)
950 project.enabled_module_names = ["issue_tracking"]
951 assert_equal true, @admin.allowed_to?(:add_issues, project)
952 assert_equal false, @admin.allowed_to?(:view_wiki_pages, project)
953 end
954
955 should "authorize nearly everything for admin users" do
956 project = Project.find(1)
957 assert ! @admin.member_of?(project)
958 %w(edit_issues delete_issues manage_news add_documents manage_wiki).each do |p|
959 assert_equal true, @admin.allowed_to?(p.to_sym, project)
960 end
961 end
962
963 should "authorize normal users depending on their roles" do
964 project = Project.find(1)
965 assert_equal true, @jsmith.allowed_to?(:delete_messages, project) #Manager
966 assert_equal false, @dlopper.allowed_to?(:delete_messages, project) #Developper
967 end
968 end
969
970 context "with multiple projects" do
971 should "return false if array is empty" do
972 assert_equal false, @admin.allowed_to?(:view_project, [])
973 end
974
975 should "return true only if user has permission on all these projects" do
976 assert_equal true, @admin.allowed_to?(:view_project, Project.all)
977 assert_equal false, @dlopper.allowed_to?(:view_project, Project.all) #cannot see Project(2)
978 assert_equal true, @jsmith.allowed_to?(:edit_issues, @jsmith.projects) #Manager or Developer everywhere
979 assert_equal false, @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects) #Dev cannot delete_issue_watchers
980 end
981
982 should "behave correctly with arrays of 1 project" do
983 assert_equal false, User.anonymous.allowed_to?(:delete_issues, [Project.first])
984 end
985 end
986
987 context "with options[:global]" do
988 should "authorize if user has at least one role that has this permission" do
989 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
990 @anonymous = User.find(6)
991 assert_equal true, @jsmith.allowed_to?(:delete_issue_watchers, nil, :global => true)
992 assert_equal false, @dlopper2.allowed_to?(:delete_issue_watchers, nil, :global => true)
993 assert_equal true, @dlopper2.allowed_to?(:add_issues, nil, :global => true)
994 assert_equal false, @anonymous.allowed_to?(:add_issues, nil, :global => true)
995 assert_equal true, @anonymous.allowed_to?(:view_issues, nil, :global => true)
996 end
997 end
998 end
999
1000 context "User#notify_about?" do
1001 context "Issues" do
1002 setup do
1003 @project = Project.find(1)
1004 @author = User.generate!
1005 @assignee = User.generate!
1006 @issue = Issue.generate!(:project => @project, :assigned_to => @assignee, :author => @author)
1007 end
1008
1009 should "be true for a user with :all" do
1010 @author.update_attribute(:mail_notification, 'all')
1011 assert @author.notify_about?(@issue)
1012 end
1013
1014 should "be false for a user with :none" do
1015 @author.update_attribute(:mail_notification, 'none')
1016 assert ! @author.notify_about?(@issue)
1017 end
1018
1019 should "be false for a user with :only_my_events and isn't an author, creator, or assignee" do
1020 @user = User.generate!(:mail_notification => 'only_my_events')
1021 Member.create!(:user => @user, :project => @project, :role_ids => [1])
1022 assert ! @user.notify_about?(@issue)
1023 end
1024
1025 should "be true for a user with :only_my_events and is the author" do
1026 @author.update_attribute(:mail_notification, 'only_my_events')
1027 assert @author.notify_about?(@issue)
1028 end
1029
1030 should "be true for a user with :only_my_events and is the assignee" do
1031 @assignee.update_attribute(:mail_notification, 'only_my_events')
1032 assert @assignee.notify_about?(@issue)
1033 end
1034
1035 should "be true for a user with :only_assigned and is the assignee" do
1036 @assignee.update_attribute(:mail_notification, 'only_assigned')
1037 assert @assignee.notify_about?(@issue)
1038 end
1039
1040 should "be false for a user with :only_assigned and is not the assignee" do
1041 @author.update_attribute(:mail_notification, 'only_assigned')
1042 assert ! @author.notify_about?(@issue)
1043 end
1044
1045 should "be true for a user with :only_owner and is the author" do
1046 @author.update_attribute(:mail_notification, 'only_owner')
1047 assert @author.notify_about?(@issue)
1048 end
1049
1050 should "be false for a user with :only_owner and is not the author" do
1051 @assignee.update_attribute(:mail_notification, 'only_owner')
1052 assert ! @assignee.notify_about?(@issue)
1053 end
1054
1055 should "be true for a user with :selected and is the author" do
1056 @author.update_attribute(:mail_notification, 'selected')
1057 assert @author.notify_about?(@issue)
1058 end
1059
1060 should "be true for a user with :selected and is the assignee" do
1061 @assignee.update_attribute(:mail_notification, 'selected')
1062 assert @assignee.notify_about?(@issue)
1063 end
1064
1065 should "be false for a user with :selected and is not the author or assignee" do
1066 @user = User.generate!(:mail_notification => 'selected')
1067 Member.create!(:user => @user, :project => @project, :role_ids => [1])
1068 assert ! @user.notify_about?(@issue)
1069 end
1070 end
1071 end
1072
1073 def test_notify_about_news
1074 user = User.generate!
1075 news = News.new
1076
1077 User::MAIL_NOTIFICATION_OPTIONS.map(&:first).each do |option|
1078 user.mail_notification = option
1079 assert_equal (option != 'none'), user.notify_about?(news)
1080 end
1081 end
1082
1083 def test_salt_unsalted_passwords
1084 # Restore a user with an unsalted password
1085 user = User.find(1)
1086 user.salt = nil
1087 user.hashed_password = User.hash_password("unsalted")
1088 user.save!
1089
1090 User.salt_unsalted_passwords!
1091
1092 user.reload
1093 # Salt added
1094 assert !user.salt.blank?
1095 # Password still valid
1096 assert user.check_password?("unsalted")
1097 assert_equal user, User.try_to_login(user.login, "unsalted")
1098 end
1099
1100 if Object.const_defined?(:OpenID)
1101
1102 def test_setting_identity_url
1103 normalized_open_id_url = 'http://example.com/'
1104 u = User.new( :identity_url => 'http://example.com/' )
1105 assert_equal normalized_open_id_url, u.identity_url
1106 end
1107
1108 def test_setting_identity_url_without_trailing_slash
1109 normalized_open_id_url = 'http://example.com/'
1110 u = User.new( :identity_url => 'http://example.com' )
1111 assert_equal normalized_open_id_url, u.identity_url
1112 end
1113
1114 def test_setting_identity_url_without_protocol
1115 normalized_open_id_url = 'http://example.com/'
1116 u = User.new( :identity_url => 'example.com' )
1117 assert_equal normalized_open_id_url, u.identity_url
1118 end
1119
1120 def test_setting_blank_identity_url
1121 u = User.new( :identity_url => 'example.com' )
1122 u.identity_url = ''
1123 assert u.identity_url.blank?
1124 end
1125
1126 def test_setting_invalid_identity_url
1127 u = User.new( :identity_url => 'this is not an openid url' )
1128 assert u.identity_url.blank?
1129 end
1130
1131 else
1132 puts "Skipping openid tests."
1133 end
1134
1135 end