comparison .svn/pristine/3f/3ff56ecaa90caa3fe6d5a6c1a603bc58a9ed2add.svn-base @ 1517:dffacf8a6908 redmine-2.5

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