comparison test/unit/issue_test.rb @ 1526:404aa68d4227

Merge from live branch
author Chris Cannam
date Thu, 11 Sep 2014 12:46:20 +0100
parents dffacf8a6908
children
comparison
equal deleted inserted replaced
1493:a5f2bdf3b486 1526:404aa68d4227
1 # Redmine - project management software 1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 # 3 #
4 # This program is free software; you can redistribute it and/or 4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License 5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2 6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version. 7 # of the License, or (at your option) any later version.
33 33
34 def teardown 34 def teardown
35 User.current = nil 35 User.current = nil
36 end 36 end
37 37
38 def test_initialize
39 issue = Issue.new
40
41 assert_nil issue.project_id
42 assert_nil issue.tracker_id
43 assert_nil issue.author_id
44 assert_nil issue.assigned_to_id
45 assert_nil issue.category_id
46
47 assert_equal IssueStatus.default, issue.status
48 assert_equal IssuePriority.default, issue.priority
49 end
50
38 def test_create 51 def test_create
39 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, 52 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
40 :status_id => 1, :priority => IssuePriority.all.first, 53 :status_id => 1, :priority => IssuePriority.all.first,
41 :subject => 'test_create', 54 :subject => 'test_create',
42 :description => 'IssueTest#test_create', :estimated_hours => '1:30') 55 :description => 'IssueTest#test_create', :estimated_hours => '1:30')
75 def test_due_date_lesser_than_start_date_should_not_validate 88 def test_due_date_lesser_than_start_date_should_not_validate
76 set_language_if_valid 'en' 89 set_language_if_valid 'en'
77 issue = Issue.new(:start_date => '2012-10-06', :due_date => '2012-10-02') 90 issue = Issue.new(:start_date => '2012-10-06', :due_date => '2012-10-02')
78 assert !issue.valid? 91 assert !issue.valid?
79 assert_include 'Due date must be greater than start date', issue.errors.full_messages 92 assert_include 'Due date must be greater than start date', issue.errors.full_messages
93 end
94
95 def test_start_date_lesser_than_soonest_start_should_not_validate_on_create
96 issue = Issue.generate(:start_date => '2013-06-04')
97 issue.stubs(:soonest_start).returns(Date.parse('2013-06-10'))
98 assert !issue.valid?
99 assert_include "Start date cannot be earlier than 06/10/2013 because of preceding issues", issue.errors.full_messages
100 end
101
102 def test_start_date_lesser_than_soonest_start_should_not_validate_on_update_if_changed
103 issue = Issue.generate!(:start_date => '2013-06-04')
104 issue.stubs(:soonest_start).returns(Date.parse('2013-06-10'))
105 issue.start_date = '2013-06-07'
106 assert !issue.valid?
107 assert_include "Start date cannot be earlier than 06/10/2013 because of preceding issues", issue.errors.full_messages
108 end
109
110 def test_start_date_lesser_than_soonest_start_should_validate_on_update_if_unchanged
111 issue = Issue.generate!(:start_date => '2013-06-04')
112 issue.stubs(:soonest_start).returns(Date.parse('2013-06-10'))
113 assert issue.valid?
114 end
115
116 def test_estimated_hours_should_be_validated
117 set_language_if_valid 'en'
118 ['-2'].each do |invalid|
119 issue = Issue.new(:estimated_hours => invalid)
120 assert !issue.valid?
121 assert_include 'Estimated time is invalid', issue.errors.full_messages
122 end
80 end 123 end
81 124
82 def test_create_with_required_custom_field 125 def test_create_with_required_custom_field
83 set_language_if_valid 'en' 126 set_language_if_valid 'en'
84 field = IssueCustomField.find_by_name('Database') 127 field = IssueCustomField.find_by_name('Database')
109 def test_create_with_group_assignment 152 def test_create_with_group_assignment
110 with_settings :issue_group_assignment => '1' do 153 with_settings :issue_group_assignment => '1' do
111 assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1, 154 assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
112 :subject => 'Group assignment', 155 :subject => 'Group assignment',
113 :assigned_to_id => 11).save 156 :assigned_to_id => 11).save
114 issue = Issue.first(:order => 'id DESC') 157 issue = Issue.order('id DESC').first
115 assert_kind_of Group, issue.assigned_to 158 assert_kind_of Group, issue.assigned_to
116 assert_equal Group.find(11), issue.assigned_to 159 assert_equal Group.find(11), issue.assigned_to
117 end 160 end
118 end 161 end
119 162
222 assert_visibility_match user, issues 265 assert_visibility_match user, issues
223 end 266 end
224 267
225 def test_visible_scope_for_member 268 def test_visible_scope_for_member
226 user = User.find(9) 269 user = User.find(9)
227 # User should see issues of projects for which he has view_issues permissions only 270 # User should see issues of projects for which user has view_issues permissions only
228 Role.non_member.remove_permission!(:view_issues) 271 Role.non_member.remove_permission!(:view_issues)
229 Member.create!(:principal => user, :project_id => 3, :role_ids => [2]) 272 Member.create!(:principal => user, :project_id => 3, :role_ids => [2])
230 issues = Issue.visible(user).all 273 issues = Issue.visible(user).all
231 assert issues.any? 274 assert issues.any?
232 assert_nil issues.detect {|issue| issue.project_id != 3} 275 assert_nil issues.detect {|issue| issue.project_id != 3}
237 def test_visible_scope_for_member_with_groups_should_return_assigned_issues 280 def test_visible_scope_for_member_with_groups_should_return_assigned_issues
238 user = User.find(8) 281 user = User.find(8)
239 assert user.groups.any? 282 assert user.groups.any?
240 Member.create!(:principal => user.groups.first, :project_id => 1, :role_ids => [2]) 283 Member.create!(:principal => user.groups.first, :project_id => 1, :role_ids => [2])
241 Role.non_member.remove_permission!(:view_issues) 284 Role.non_member.remove_permission!(:view_issues)
242 285
243 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, 286 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
244 :status_id => 1, :priority => IssuePriority.all.first, 287 :status_id => 1, :priority => IssuePriority.all.first,
245 :subject => 'Assignment test', 288 :subject => 'Assignment test',
246 :assigned_to => user.groups.first, 289 :assigned_to => user.groups.first,
247 :is_private => true) 290 :is_private => true)
248 291
249 Role.find(2).update_attribute :issues_visibility, 'default' 292 Role.find(2).update_attribute :issues_visibility, 'default'
250 issues = Issue.visible(User.find(8)).all 293 issues = Issue.visible(User.find(8)).all
251 assert issues.any? 294 assert issues.any?
252 assert issues.include?(issue) 295 assert issues.include?(issue)
253 296
254 Role.find(2).update_attribute :issues_visibility, 'own' 297 Role.find(2).update_attribute :issues_visibility, 'own'
255 issues = Issue.visible(User.find(8)).all 298 issues = Issue.visible(User.find(8)).all
256 assert issues.any? 299 assert issues.any?
257 assert issues.include?(issue) 300 assert issues.include?(issue)
258 end 301 end
261 user = User.find(1) 304 user = User.find(1)
262 user.members.each(&:destroy) 305 user.members.each(&:destroy)
263 assert user.projects.empty? 306 assert user.projects.empty?
264 issues = Issue.visible(user).all 307 issues = Issue.visible(user).all
265 assert issues.any? 308 assert issues.any?
266 # Admin should see issues on private projects that he does not belong to 309 # Admin should see issues on private projects that admin does not belong to
267 assert issues.detect {|issue| !issue.project.is_public?} 310 assert issues.detect {|issue| !issue.project.is_public?}
268 # Admin should see private issues of other users 311 # Admin should see private issues of other users
269 assert issues.detect {|issue| issue.is_private? && issue.author != user} 312 assert issues.detect {|issue| issue.is_private? && issue.author != user}
270 assert_visibility_match user, issues 313 assert_visibility_match user, issues
271 end 314 end
285 assert projects.size > 1 328 assert projects.size > 1
286 assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)} 329 assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)}
287 end 330 end
288 331
289 def test_visible_and_nested_set_scopes 332 def test_visible_and_nested_set_scopes
290 assert_equal 0, Issue.find(1).descendants.visible.all.size 333 user = User.generate!
334 parent = Issue.generate!(:assigned_to => user)
335 assert parent.visible?(user)
336 child1 = Issue.generate!(:parent_issue_id => parent.id, :assigned_to => user)
337 child2 = Issue.generate!(:parent_issue_id => parent.id, :assigned_to => user)
338 parent.reload
339 child1.reload
340 child2.reload
341 assert child1.visible?(user)
342 assert child2.visible?(user)
343 assert_equal 2, parent.descendants.count
344 assert_equal 2, parent.descendants.visible(user).count
345 # awesome_nested_set 2-1-stable branch has regression.
346 # https://github.com/collectiveidea/awesome_nested_set/commit/3d5ac746542b564f6586c2316180254b088bebb6
347 # ActiveRecord::StatementInvalid: SQLite3::SQLException: ambiguous column name: lft:
348 assert_equal 2, parent.descendants.collect{|i| i}.size
349 assert_equal 2, parent.descendants.visible(user).collect{|i| i}.size
291 end 350 end
292 351
293 def test_open_scope 352 def test_open_scope
294 issues = Issue.open.all 353 issues = Issue.open.all
295 assert_nil issues.detect(&:closed?) 354 assert_nil issues.detect(&:closed?)
296 end 355 end
297 356
298 def test_open_scope_with_arg 357 def test_open_scope_with_arg
299 issues = Issue.open(false).all 358 issues = Issue.open(false).all
300 assert_equal issues, issues.select(&:closed?) 359 assert_equal issues, issues.select(&:closed?)
360 end
361
362 def test_fixed_version_scope_with_a_version_should_return_its_fixed_issues
363 version = Version.find(2)
364 assert version.fixed_issues.any?
365 assert_equal version.fixed_issues.to_a.sort, Issue.fixed_version(version).to_a.sort
366 end
367
368 def test_fixed_version_scope_with_empty_array_should_return_no_result
369 assert_equal 0, Issue.fixed_version([]).count
301 end 370 end
302 371
303 def test_errors_full_messages_should_include_custom_fields_errors 372 def test_errors_full_messages_should_include_custom_fields_errors
304 field = IssueCustomField.find_by_name('Database') 373 field = IssueCustomField.find_by_name('Database')
305 374
400 issue = Issue.new(:project => Project.find(1)) 469 issue = Issue.new(:project => Project.find(1))
401 issue.attributes = attributes 470 issue.attributes = attributes
402 assert_equal 'MySQL', issue.custom_field_value(1) 471 assert_equal 'MySQL', issue.custom_field_value(1)
403 end 472 end
404 473
474 def test_reload_should_reload_custom_field_values
475 issue = Issue.generate!
476 issue.custom_field_values = {'2' => 'Foo'}
477 issue.save!
478
479 issue = Issue.order('id desc').first
480 assert_equal 'Foo', issue.custom_field_value(2)
481
482 issue.custom_field_values = {'2' => 'Bar'}
483 assert_equal 'Bar', issue.custom_field_value(2)
484
485 issue.reload
486 assert_equal 'Foo', issue.custom_field_value(2)
487 end
488
405 def test_should_update_issue_with_disabled_tracker 489 def test_should_update_issue_with_disabled_tracker
406 p = Project.find(1) 490 p = Project.find(1)
407 issue = Issue.find(1) 491 issue = Issue.find(1)
408 492
409 p.trackers.delete(issue.tracker) 493 p.trackers.delete(issue.tracker)
420 504
421 issue = Issue.find(1) 505 issue = Issue.find(1)
422 issue.tracker_id = 2 506 issue.tracker_id = 2
423 issue.subject = 'New subject' 507 issue.subject = 'New subject'
424 assert !issue.save 508 assert !issue.save
425 assert_not_nil issue.errors[:tracker_id] 509 assert_not_equal [], issue.errors[:tracker_id]
426 end 510 end
427 511
428 def test_category_based_assignment 512 def test_category_based_assignment
429 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, 513 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
430 :status_id => 1, :priority => IssuePriority.all.first, 514 :status_id => 1, :priority => IssuePriority.all.first,
439 :old_status_id => 1, :new_status_id => 2, 523 :old_status_id => 1, :new_status_id => 2,
440 :author => false, :assignee => false) 524 :author => false, :assignee => false)
441 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, 525 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
442 :old_status_id => 1, :new_status_id => 3, 526 :old_status_id => 1, :new_status_id => 3,
443 :author => true, :assignee => false) 527 :author => true, :assignee => false)
444 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, 528 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
445 :new_status_id => 4, :author => false, 529 :old_status_id => 1, :new_status_id => 4,
446 :assignee => true) 530 :author => false, :assignee => true)
447 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, 531 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
448 :old_status_id => 1, :new_status_id => 5, 532 :old_status_id => 1, :new_status_id => 5,
449 :author => true, :assignee => true) 533 :author => true, :assignee => true)
450 status = IssueStatus.find(1) 534 status = IssueStatus.find(1)
451 role = Role.find(1) 535 role = Role.find(1)
467 551
468 issue = Issue.generate!(:tracker => tracker, :status => status, 552 issue = Issue.generate!(:tracker => tracker, :status => status,
469 :project_id => 1, :author => user, 553 :project_id => 1, :author => user,
470 :assigned_to => user) 554 :assigned_to => user)
471 assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id) 555 assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
556
557 group = Group.generate!
558 group.users << user
559 issue = Issue.generate!(:tracker => tracker, :status => status,
560 :project_id => 1, :author => user,
561 :assigned_to => group)
562 assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
563 end
564
565 def test_new_statuses_allowed_to_should_consider_group_assignment
566 WorkflowTransition.delete_all
567 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
568 :old_status_id => 1, :new_status_id => 4,
569 :author => false, :assignee => true)
570 user = User.find(2)
571 group = Group.generate!
572 group.users << user
573
574 issue = Issue.generate!(:author_id => 1, :assigned_to => group)
575 assert_include 4, issue.new_statuses_allowed_to(user).map(&:id)
472 end 576 end
473 577
474 def test_new_statuses_allowed_to_should_return_all_transitions_for_admin 578 def test_new_statuses_allowed_to_should_return_all_transitions_for_admin
475 admin = User.find(1) 579 admin = User.find(1)
476 issue = Issue.find(1) 580 issue = Issue.find(1)
477 assert !admin.member_of?(issue.project) 581 assert !admin.member_of?(issue.project)
478 expected_statuses = [issue.status] + 582 expected_statuses = [issue.status] +
479 WorkflowTransition.find_all_by_old_status_id( 583 WorkflowTransition.where(:old_status_id => issue.status_id).
480 issue.status_id).map(&:new_status).uniq.sort 584 map(&:new_status).uniq.sort
481 assert_equal expected_statuses, issue.new_statuses_allowed_to(admin) 585 assert_equal expected_statuses, issue.new_statuses_allowed_to(admin)
482 end 586 end
483 587
484 def test_new_statuses_allowed_to_should_return_default_and_current_status_when_copying 588 def test_new_statuses_allowed_to_should_return_default_and_current_status_when_copying
485 issue = Issue.find(1).copy 589 issue = Issue.find(1).copy
600 values = issue.editable_custom_field_values(user) 704 values = issue.editable_custom_field_values(user)
601 assert values.detect {|value| value.custom_field == cf1} 705 assert values.detect {|value| value.custom_field == cf1}
602 assert values.detect {|value| value.custom_field == cf2} 706 assert values.detect {|value| value.custom_field == cf2}
603 end 707 end
604 708
709 def test_editable_custom_fields_should_return_custom_field_that_is_enabled_for_the_role_only
710 enabled_cf = IssueCustomField.generate!(:is_for_all => true, :tracker_ids => [1], :visible => false, :role_ids => [1,2])
711 disabled_cf = IssueCustomField.generate!(:is_for_all => true, :tracker_ids => [1], :visible => false, :role_ids => [2])
712 user = User.find(2)
713 issue = Issue.new(:project_id => 1, :tracker_id => 1)
714
715 assert_include enabled_cf, issue.editable_custom_fields(user)
716 assert_not_include disabled_cf, issue.editable_custom_fields(user)
717 end
718
605 def test_safe_attributes_should_accept_target_tracker_writable_fields 719 def test_safe_attributes_should_accept_target_tracker_writable_fields
606 WorkflowPermission.delete_all 720 WorkflowPermission.delete_all
607 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, 721 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1,
608 :role_id => 1, :field_name => 'due_date', 722 :role_id => 1, :field_name => 'due_date',
609 :rule => 'readonly') 723 :rule => 'readonly')
800 child_copy = copy.children.detect {|c| c.subject == 'Child1'} 914 child_copy = copy.children.detect {|c| c.subject == 'Child1'}
801 assert_equal %w(Child11), child_copy.children.map(&:subject).sort 915 assert_equal %w(Child11), child_copy.children.map(&:subject).sort
802 assert_equal copy.author, child_copy.author 916 assert_equal copy.author, child_copy.author
803 end 917 end
804 918
919 def test_copy_as_a_child_of_copied_issue_should_not_copy_itself
920 parent = Issue.generate!
921 child1 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 1')
922 child2 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 2')
923
924 copy = parent.reload.copy
925 copy.parent_issue_id = parent.id
926 copy.author = User.find(7)
927 assert_difference 'Issue.count', 3 do
928 assert copy.save
929 end
930 parent.reload
931 copy.reload
932 assert_equal parent, copy.parent
933 assert_equal 3, parent.children.count
934 assert_equal 5, parent.descendants.count
935 assert_equal 2, copy.children.count
936 assert_equal 2, copy.descendants.count
937 end
938
939 def test_copy_as_a_descendant_of_copied_issue_should_not_copy_itself
940 parent = Issue.generate!
941 child1 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 1')
942 child2 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 2')
943
944 copy = parent.reload.copy
945 copy.parent_issue_id = child1.id
946 copy.author = User.find(7)
947 assert_difference 'Issue.count', 3 do
948 assert copy.save
949 end
950 parent.reload
951 child1.reload
952 copy.reload
953 assert_equal child1, copy.parent
954 assert_equal 2, parent.children.count
955 assert_equal 5, parent.descendants.count
956 assert_equal 1, child1.children.count
957 assert_equal 3, child1.descendants.count
958 assert_equal 2, copy.children.count
959 assert_equal 2, copy.descendants.count
960 end
961
805 def test_copy_should_copy_subtasks_to_target_project 962 def test_copy_should_copy_subtasks_to_target_project
806 issue = Issue.generate_with_descendants! 963 issue = Issue.generate_with_descendants!
807 964
808 copy = issue.copy(:project_id => 3) 965 copy = issue.copy(:project_id => 3)
809 assert_difference 'Issue.count', 1+issue.descendants.count do 966 assert_difference 'Issue.count', 1+issue.descendants.count do
874 :relation_type => IssueRelation::TYPE_DUPLICATES) 1031 :relation_type => IssueRelation::TYPE_DUPLICATES)
875 1032
876 assert issue1.reload.duplicates.include?(issue2) 1033 assert issue1.reload.duplicates.include?(issue2)
877 1034
878 # Closing issue 1 1035 # Closing issue 1
879 issue1.init_journal(User.find(:first), "Closing issue1") 1036 issue1.init_journal(User.first, "Closing issue1")
880 issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true} 1037 issue1.status = IssueStatus.where(:is_closed => true).first
881 assert issue1.save 1038 assert issue1.save
882 # 2 and 3 should be also closed 1039 # 2 and 3 should be also closed
883 assert issue2.reload.closed? 1040 assert issue2.reload.closed?
884 assert issue3.reload.closed? 1041 assert issue3.reload.closed?
885 end 1042 end
893 :relation_type => IssueRelation::TYPE_DUPLICATES) 1050 :relation_type => IssueRelation::TYPE_DUPLICATES)
894 # 2 is a dup of 1 but 1 is not a duplicate of 2 1051 # 2 is a dup of 1 but 1 is not a duplicate of 2
895 assert !issue2.reload.duplicates.include?(issue1) 1052 assert !issue2.reload.duplicates.include?(issue1)
896 1053
897 # Closing issue 2 1054 # Closing issue 2
898 issue2.init_journal(User.find(:first), "Closing issue2") 1055 issue2.init_journal(User.first, "Closing issue2")
899 issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true} 1056 issue2.status = IssueStatus.where(:is_closed => true).first
900 assert issue2.save 1057 assert issue2.save
901 # 1 should not be also closed 1058 # 1 should not be also closed
902 assert !issue1.reload.closed? 1059 assert !issue1.reload.closed?
903 end 1060 end
904 1061
912 def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version 1069 def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
913 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, 1070 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
914 :status_id => 1, :fixed_version_id => 1, 1071 :status_id => 1, :fixed_version_id => 1,
915 :subject => 'New issue') 1072 :subject => 'New issue')
916 assert !issue.save 1073 assert !issue.save
917 assert_not_nil issue.errors[:fixed_version_id] 1074 assert_not_equal [], issue.errors[:fixed_version_id]
918 end 1075 end
919 1076
920 def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version 1077 def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
921 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, 1078 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
922 :status_id => 1, :fixed_version_id => 2, 1079 :status_id => 1, :fixed_version_id => 2,
923 :subject => 'New issue') 1080 :subject => 'New issue')
924 assert !issue.save 1081 assert !issue.save
925 assert_not_nil issue.errors[:fixed_version_id] 1082 assert_not_equal [], issue.errors[:fixed_version_id]
926 end 1083 end
927 1084
928 def test_should_be_able_to_assign_a_new_issue_to_an_open_version 1085 def test_should_be_able_to_assign_a_new_issue_to_an_open_version
929 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, 1086 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
930 :status_id => 1, :fixed_version_id => 3, 1087 :status_id => 1, :fixed_version_id => 3,
941 1098
942 def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version 1099 def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
943 issue = Issue.find(11) 1100 issue = Issue.find(11)
944 issue.status_id = 1 1101 issue.status_id = 1
945 assert !issue.save 1102 assert !issue.save
946 assert_not_nil issue.errors[:base] 1103 assert_not_equal [], issue.errors[:base]
947 end 1104 end
948 1105
949 def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version 1106 def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
950 issue = Issue.find(11) 1107 issue = Issue.find(11)
951 issue.status_id = 1 1108 issue.status_id = 1
970 assert_include 'Target version is not included in the list', issue.errors.full_messages 1127 assert_include 'Target version is not included in the list', issue.errors.full_messages
971 end 1128 end
972 1129
973 def test_should_keep_shared_version_when_changing_project 1130 def test_should_keep_shared_version_when_changing_project
974 Version.find(2).update_attribute :sharing, 'tree' 1131 Version.find(2).update_attribute :sharing, 'tree'
975 1132
976 issue = Issue.find(2) 1133 issue = Issue.find(2)
977 assert_equal 2, issue.fixed_version_id 1134 assert_equal 2, issue.fixed_version_id
978 issue.project_id = 3 1135 issue.project_id = 3
979 assert_equal 2, issue.fixed_version_id 1136 assert_equal 2, issue.fixed_version_id
980 assert issue.save 1137 assert issue.save
1108 assert_equal Tracker.find(2), copy.tracker 1265 assert_equal Tracker.find(2), copy.tracker
1109 # Custom field #2 is not associated with target tracker 1266 # Custom field #2 is not associated with target tracker
1110 assert_nil copy.custom_value_for(2) 1267 assert_nil copy.custom_value_for(2)
1111 end 1268 end
1112 1269
1113 context "#copy" do 1270 test "#copy should not create a journal" do
1114 setup do 1271 copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
1115 @issue = Issue.find(1) 1272 copy.save!
1116 end 1273 assert_equal 0, copy.reload.journals.size
1117 1274 end
1118 should "not create a journal" do 1275
1119 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3) 1276 test "#copy should allow assigned_to changes" do
1120 copy.save! 1277 copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
1121 assert_equal 0, copy.reload.journals.size 1278 assert_equal 3, copy.assigned_to_id
1122 end 1279 end
1123 1280
1124 should "allow assigned_to changes" do 1281 test "#copy should allow status changes" do
1125 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3) 1282 copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :status_id => 2)
1126 assert_equal 3, copy.assigned_to_id 1283 assert_equal 2, copy.status_id
1127 end 1284 end
1128 1285
1129 should "allow status changes" do 1286 test "#copy should allow start date changes" do
1130 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :status_id => 2) 1287 date = Date.today
1131 assert_equal 2, copy.status_id 1288 copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :start_date => date)
1132 end 1289 assert_equal date, copy.start_date
1133 1290 end
1134 should "allow start date changes" do 1291
1135 date = Date.today 1292 test "#copy should allow due date changes" do
1136 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date) 1293 date = Date.today
1137 assert_equal date, copy.start_date 1294 copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :due_date => date)
1138 end 1295 assert_equal date, copy.due_date
1139 1296 end
1140 should "allow due date changes" do 1297
1141 date = Date.today 1298 test "#copy should set current user as author" do
1142 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :due_date => date) 1299 User.current = User.find(9)
1143 assert_equal date, copy.due_date 1300 copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2)
1144 end 1301 assert_equal User.current, copy.author
1145 1302 end
1146 should "set current user as author" do 1303
1147 User.current = User.find(9) 1304 test "#copy should create a journal with notes" do
1148 copy = @issue.copy(:project_id => 3, :tracker_id => 2) 1305 date = Date.today
1149 assert_equal User.current, copy.author 1306 notes = "Notes added when copying"
1150 end 1307 copy = Issue.find(1).copy(:project_id => 3, :tracker_id => 2, :start_date => date)
1151 1308 copy.init_journal(User.current, notes)
1152 should "create a journal with notes" do 1309 copy.save!
1153 date = Date.today 1310
1154 notes = "Notes added when copying" 1311 assert_equal 1, copy.journals.size
1155 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date) 1312 journal = copy.journals.first
1156 copy.init_journal(User.current, notes) 1313 assert_equal 0, journal.details.size
1157 copy.save! 1314 assert_equal notes, journal.notes
1158
1159 assert_equal 1, copy.journals.size
1160 journal = copy.journals.first
1161 assert_equal 0, journal.details.size
1162 assert_equal notes, journal.notes
1163 end
1164 end 1315 end
1165 1316
1166 def test_valid_parent_project 1317 def test_valid_parent_project
1167 issue = Issue.find(1) 1318 issue = Issue.find(1)
1168 issue_in_same_project = Issue.find(2) 1319 issue_in_same_project = Issue.find(2)
1248 Issue.find(1).destroy 1399 Issue.find(1).destroy
1249 assert_nil Issue.find_by_id(1) 1400 assert_nil Issue.find_by_id(1)
1250 assert_nil TimeEntry.find_by_issue_id(1) 1401 assert_nil TimeEntry.find_by_issue_id(1)
1251 end 1402 end
1252 1403
1404 def test_destroy_should_delete_time_entries_custom_values
1405 issue = Issue.generate!
1406 time_entry = TimeEntry.generate!(:issue => issue, :custom_field_values => {10 => '1'})
1407
1408 assert_difference 'CustomValue.where(:customized_type => "TimeEntry").count', -1 do
1409 assert issue.destroy
1410 end
1411 end
1412
1253 def test_destroying_a_deleted_issue_should_not_raise_an_error 1413 def test_destroying_a_deleted_issue_should_not_raise_an_error
1254 issue = Issue.find(1) 1414 issue = Issue.find(1)
1255 Issue.find(1).destroy 1415 Issue.find(1).destroy
1256 1416
1257 assert_nothing_raised do 1417 assert_nothing_raised do
1368 issue2 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17') 1528 issue2 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
1369 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, 1529 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2,
1370 :relation_type => IssueRelation::TYPE_PRECEDES) 1530 :relation_type => IssueRelation::TYPE_PRECEDES)
1371 assert_equal Date.parse('2012-10-18'), issue2.reload.start_date 1531 assert_equal Date.parse('2012-10-18'), issue2.reload.start_date
1372 1532
1533 issue1.reload
1373 issue1.due_date = '2012-10-23' 1534 issue1.due_date = '2012-10-23'
1374 issue1.save! 1535 issue1.save!
1375 issue2.reload 1536 issue2.reload
1376 assert_equal Date.parse('2012-10-24'), issue2.start_date 1537 assert_equal Date.parse('2012-10-24'), issue2.start_date
1377 assert_equal Date.parse('2012-10-26'), issue2.due_date 1538 assert_equal Date.parse('2012-10-26'), issue2.due_date
1382 issue2 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17') 1543 issue2 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
1383 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, 1544 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2,
1384 :relation_type => IssueRelation::TYPE_PRECEDES) 1545 :relation_type => IssueRelation::TYPE_PRECEDES)
1385 assert_equal Date.parse('2012-10-18'), issue2.reload.start_date 1546 assert_equal Date.parse('2012-10-18'), issue2.reload.start_date
1386 1547
1548 issue1.reload
1387 issue1.start_date = '2012-09-17' 1549 issue1.start_date = '2012-09-17'
1388 issue1.due_date = '2012-09-18' 1550 issue1.due_date = '2012-09-18'
1389 issue1.save! 1551 issue1.save!
1390 issue2.reload 1552 issue2.reload
1391 assert_equal Date.parse('2012-09-19'), issue2.start_date 1553 assert_equal Date.parse('2012-09-19'), issue2.start_date
1400 :relation_type => IssueRelation::TYPE_PRECEDES) 1562 :relation_type => IssueRelation::TYPE_PRECEDES)
1401 IssueRelation.create!(:issue_from => issue3, :issue_to => issue2, 1563 IssueRelation.create!(:issue_from => issue3, :issue_to => issue2,
1402 :relation_type => IssueRelation::TYPE_PRECEDES) 1564 :relation_type => IssueRelation::TYPE_PRECEDES)
1403 assert_equal Date.parse('2012-10-18'), issue2.reload.start_date 1565 assert_equal Date.parse('2012-10-18'), issue2.reload.start_date
1404 1566
1567 issue1.reload
1405 issue1.start_date = '2012-09-17' 1568 issue1.start_date = '2012-09-17'
1406 issue1.due_date = '2012-09-18' 1569 issue1.due_date = '2012-09-18'
1407 issue1.save! 1570 issue1.save!
1408 issue2.reload 1571 issue2.reload
1409 # Issue 2 must start after Issue 3 1572 # Issue 2 must start after Issue 3
1423 end 1586 end
1424 assert_equal date, stale.reload.start_date 1587 assert_equal date, stale.reload.start_date
1425 end 1588 end
1426 end 1589 end
1427 1590
1591 def test_child_issue_should_consider_parent_soonest_start_on_create
1592 set_language_if_valid 'en'
1593 issue1 = Issue.generate!(:start_date => '2012-10-15', :due_date => '2012-10-17')
1594 issue2 = Issue.generate!(:start_date => '2012-10-18', :due_date => '2012-10-20')
1595 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2,
1596 :relation_type => IssueRelation::TYPE_PRECEDES)
1597 issue1.reload
1598 issue2.reload
1599 assert_equal Date.parse('2012-10-18'), issue2.start_date
1600
1601 child = Issue.new(:parent_issue_id => issue2.id, :start_date => '2012-10-16',
1602 :project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Child', :author_id => 1)
1603 assert !child.valid?
1604 assert_include 'Start date cannot be earlier than 10/18/2012 because of preceding issues', child.errors.full_messages
1605 assert_equal Date.parse('2012-10-18'), child.soonest_start
1606 child.start_date = '2012-10-18'
1607 assert child.save
1608 end
1609
1610 def test_setting_parent_to_a_dependent_issue_should_not_validate
1611 set_language_if_valid 'en'
1612 issue1 = Issue.generate!
1613 issue2 = Issue.generate!
1614 issue3 = Issue.generate!
1615 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
1616 IssueRelation.create!(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_PRECEDES)
1617 issue3.reload
1618 issue3.parent_issue_id = issue2.id
1619 assert !issue3.valid?
1620 assert_include 'Parent task is invalid', issue3.errors.full_messages
1621 end
1622
1623 def test_setting_parent_should_not_allow_circular_dependency
1624 set_language_if_valid 'en'
1625 issue1 = Issue.generate!
1626 issue2 = Issue.generate!
1627 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
1628 issue3 = Issue.generate!
1629 issue2.reload
1630 issue2.parent_issue_id = issue3.id
1631 issue2.save!
1632 issue4 = Issue.generate!
1633 IssueRelation.create!(:issue_from => issue3, :issue_to => issue4, :relation_type => IssueRelation::TYPE_PRECEDES)
1634 issue4.reload
1635 issue4.parent_issue_id = issue1.id
1636 assert !issue4.valid?
1637 assert_include 'Parent task is invalid', issue4.errors.full_messages
1638 end
1639
1428 def test_overdue 1640 def test_overdue
1429 assert Issue.new(:due_date => 1.day.ago.to_date).overdue? 1641 assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
1430 assert !Issue.new(:due_date => Date.today).overdue? 1642 assert !Issue.new(:due_date => Date.today).overdue?
1431 assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue? 1643 assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
1432 assert !Issue.new(:due_date => nil).overdue? 1644 assert !Issue.new(:due_date => nil).overdue?
1433 assert !Issue.new(:due_date => 1.day.ago.to_date, 1645 assert !Issue.new(:due_date => 1.day.ago.to_date,
1434 :status => IssueStatus.find(:first, 1646 :status => IssueStatus.where(:is_closed => true).first
1435 :conditions => {:is_closed => true})
1436 ).overdue? 1647 ).overdue?
1437 end 1648 end
1438 1649
1439 context "#behind_schedule?" do 1650 test "#behind_schedule? should be false if the issue has no start_date" do
1440 should "be false if the issue has no start_date" do 1651 assert !Issue.new(:start_date => nil,
1441 assert !Issue.new(:start_date => nil, 1652 :due_date => 1.day.from_now.to_date,
1442 :due_date => 1.day.from_now.to_date, 1653 :done_ratio => 0).behind_schedule?
1443 :done_ratio => 0).behind_schedule? 1654 end
1444 end 1655
1445 1656 test "#behind_schedule? should be false if the issue has no end_date" do
1446 should "be false if the issue has no end_date" do 1657 assert !Issue.new(:start_date => 1.day.from_now.to_date,
1447 assert !Issue.new(:start_date => 1.day.from_now.to_date, 1658 :due_date => nil,
1448 :due_date => nil, 1659 :done_ratio => 0).behind_schedule?
1449 :done_ratio => 0).behind_schedule? 1660 end
1450 end 1661
1451 1662 test "#behind_schedule? should be false if the issue has more done than it's calendar time" do
1452 should "be false if the issue has more done than it's calendar time" do 1663 assert !Issue.new(:start_date => 50.days.ago.to_date,
1453 assert !Issue.new(:start_date => 50.days.ago.to_date, 1664 :due_date => 50.days.from_now.to_date,
1454 :due_date => 50.days.from_now.to_date, 1665 :done_ratio => 90).behind_schedule?
1455 :done_ratio => 90).behind_schedule? 1666 end
1456 end 1667
1457 1668 test "#behind_schedule? should be true if the issue hasn't been started at all" do
1458 should "be true if the issue hasn't been started at all" do 1669 assert Issue.new(:start_date => 1.day.ago.to_date,
1459 assert Issue.new(:start_date => 1.day.ago.to_date, 1670 :due_date => 1.day.from_now.to_date,
1460 :due_date => 1.day.from_now.to_date, 1671 :done_ratio => 0).behind_schedule?
1461 :done_ratio => 0).behind_schedule? 1672 end
1462 end 1673
1463 1674 test "#behind_schedule? should be true if the issue has used more calendar time than it's done ratio" do
1464 should "be true if the issue has used more calendar time than it's done ratio" do 1675 assert Issue.new(:start_date => 100.days.ago.to_date,
1465 assert Issue.new(:start_date => 100.days.ago.to_date, 1676 :due_date => Date.today,
1466 :due_date => Date.today, 1677 :done_ratio => 90).behind_schedule?
1467 :done_ratio => 90).behind_schedule? 1678 end
1468 end 1679
1469 end 1680 test "#assignable_users should be Users" do
1470 1681 assert_kind_of User, Issue.find(1).assignable_users.first
1471 context "#assignable_users" do 1682 end
1472 should "be Users" do 1683
1473 assert_kind_of User, Issue.find(1).assignable_users.first 1684 test "#assignable_users should include the issue author" do
1474 end 1685 non_project_member = User.generate!
1475 1686 issue = Issue.generate!(:author => non_project_member)
1476 should "include the issue author" do 1687
1477 non_project_member = User.generate! 1688 assert issue.assignable_users.include?(non_project_member)
1478 issue = Issue.generate!(:author => non_project_member) 1689 end
1479 1690
1480 assert issue.assignable_users.include?(non_project_member) 1691 test "#assignable_users should include the current assignee" do
1481 end 1692 user = User.generate!
1482 1693 issue = Issue.generate!(:assigned_to => user)
1483 should "include the current assignee" do 1694 user.lock!
1484 user = User.generate! 1695
1485 issue = Issue.generate!(:assigned_to => user) 1696 assert Issue.find(issue.id).assignable_users.include?(user)
1486 user.lock! 1697 end
1487 1698
1488 assert Issue.find(issue.id).assignable_users.include?(user) 1699 test "#assignable_users should not show the issue author twice" do
1489 end 1700 assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
1490 1701 assert_equal 2, assignable_user_ids.length
1491 should "not show the issue author twice" do 1702
1492 assignable_user_ids = Issue.find(1).assignable_users.collect(&:id) 1703 assignable_user_ids.each do |user_id|
1493 assert_equal 2, assignable_user_ids.length 1704 assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length,
1494 1705 "User #{user_id} appears more or less than once"
1495 assignable_user_ids.each do |user_id| 1706 end
1496 assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length, 1707 end
1497 "User #{user_id} appears more or less than once" 1708
1498 end 1709 test "#assignable_users with issue_group_assignment should include groups" do
1499 end 1710 issue = Issue.new(:project => Project.find(2))
1500 1711
1501 context "with issue_group_assignment" do 1712 with_settings :issue_group_assignment => '1' do
1502 should "include groups" do 1713 assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
1503 issue = Issue.new(:project => Project.find(2)) 1714 assert issue.assignable_users.include?(Group.find(11))
1504 1715 end
1505 with_settings :issue_group_assignment => '1' do 1716 end
1506 assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort 1717
1507 assert issue.assignable_users.include?(Group.find(11)) 1718 test "#assignable_users without issue_group_assignment should not include groups" do
1508 end 1719 issue = Issue.new(:project => Project.find(2))
1509 end 1720
1510 end 1721 with_settings :issue_group_assignment => '0' do
1511 1722 assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
1512 context "without issue_group_assignment" do 1723 assert !issue.assignable_users.include?(Group.find(11))
1513 should "not include groups" do
1514 issue = Issue.new(:project => Project.find(2))
1515
1516 with_settings :issue_group_assignment => '0' do
1517 assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
1518 assert !issue.assignable_users.include?(Group.find(11))
1519 end
1520 end
1521 end 1724 end
1522 end 1725 end
1523 1726
1524 def test_create_should_send_email_notification 1727 def test_create_should_send_email_notification
1525 ActionMailer::Base.deliveries.clear 1728 ActionMailer::Base.deliveries.clear
1526 issue = Issue.new(:project_id => 1, :tracker_id => 1, 1729 issue = Issue.new(:project_id => 1, :tracker_id => 1,
1527 :author_id => 3, :status_id => 1, 1730 :author_id => 3, :status_id => 1,
1528 :priority => IssuePriority.all.first, 1731 :priority => IssuePriority.all.first,
1529 :subject => 'test_create', :estimated_hours => '1:30') 1732 :subject => 'test_create', :estimated_hours => '1:30')
1530 1733 with_settings :notified_events => %w(issue_added) do
1531 assert issue.save 1734 assert issue.save
1532 assert_equal 1, ActionMailer::Base.deliveries.size 1735 assert_equal 1, ActionMailer::Base.deliveries.size
1736 end
1737 end
1738
1739 def test_create_should_send_one_email_notification_with_both_settings
1740 ActionMailer::Base.deliveries.clear
1741 issue = Issue.new(:project_id => 1, :tracker_id => 1,
1742 :author_id => 3, :status_id => 1,
1743 :priority => IssuePriority.all.first,
1744 :subject => 'test_create', :estimated_hours => '1:30')
1745 with_settings :notified_events => %w(issue_added issue_updated) do
1746 assert issue.save
1747 assert_equal 1, ActionMailer::Base.deliveries.size
1748 end
1749 end
1750
1751 def test_create_should_not_send_email_notification_with_no_setting
1752 ActionMailer::Base.deliveries.clear
1753 issue = Issue.new(:project_id => 1, :tracker_id => 1,
1754 :author_id => 3, :status_id => 1,
1755 :priority => IssuePriority.all.first,
1756 :subject => 'test_create', :estimated_hours => '1:30')
1757 with_settings :notified_events => [] do
1758 assert issue.save
1759 assert_equal 0, ActionMailer::Base.deliveries.size
1760 end
1761 end
1762
1763 def test_update_should_notify_previous_assignee
1764 ActionMailer::Base.deliveries.clear
1765 user = User.find(3)
1766 user.members.update_all ["mail_notification = ?", false]
1767 user.update_attribute :mail_notification, 'only_assigned'
1768
1769 issue = Issue.find(2)
1770 issue.init_journal User.find(1)
1771 issue.assigned_to = nil
1772 issue.save!
1773 assert_include user.mail, ActionMailer::Base.deliveries.last.bcc
1533 end 1774 end
1534 1775
1535 def test_stale_issue_should_not_send_email_notification 1776 def test_stale_issue_should_not_send_email_notification
1536 ActionMailer::Base.deliveries.clear 1777 ActionMailer::Base.deliveries.clear
1537 issue = Issue.find(1) 1778 issue = Issue.find(1)
1538 stale = Issue.find(1) 1779 stale = Issue.find(1)
1539 1780
1540 issue.init_journal(User.find(1)) 1781 issue.init_journal(User.find(1))
1541 issue.subject = 'Subjet update' 1782 issue.subject = 'Subjet update'
1542 assert issue.save 1783 with_settings :notified_events => %w(issue_updated) do
1543 assert_equal 1, ActionMailer::Base.deliveries.size 1784 assert issue.save
1544 ActionMailer::Base.deliveries.clear 1785 assert_equal 1, ActionMailer::Base.deliveries.size
1545 1786 ActionMailer::Base.deliveries.clear
1546 stale.init_journal(User.find(1)) 1787
1547 stale.subject = 'Another subjet update' 1788 stale.init_journal(User.find(1))
1548 assert_raise ActiveRecord::StaleObjectError do 1789 stale.subject = 'Another subjet update'
1549 stale.save 1790 assert_raise ActiveRecord::StaleObjectError do
1550 end 1791 stale.save
1551 assert ActionMailer::Base.deliveries.empty? 1792 end
1793 assert ActionMailer::Base.deliveries.empty?
1794 end
1552 end 1795 end
1553 1796
1554 def test_journalized_description 1797 def test_journalized_description
1555 IssueCustomField.delete_all 1798 IssueCustomField.delete_all
1556 1799
1564 assert_difference 'JournalDetail.count', 1 do 1807 assert_difference 'JournalDetail.count', 1 do
1565 i.save! 1808 i.save!
1566 end 1809 end
1567 end 1810 end
1568 1811
1569 detail = JournalDetail.first(:order => 'id DESC') 1812 detail = JournalDetail.order('id DESC').first
1570 assert_equal i, detail.journal.journalized 1813 assert_equal i, detail.journal.journalized
1571 assert_equal 'attr', detail.property 1814 assert_equal 'attr', detail.property
1572 assert_equal 'description', detail.prop_key 1815 assert_equal 'description', detail.prop_key
1573 assert_equal old_description, detail.old_value 1816 assert_equal old_description, detail.old_value
1574 assert_equal new_description, detail.value 1817 assert_equal new_description, detail.value
1575 end 1818 end
1576 1819
1577 def test_blank_descriptions_should_not_be_journalized 1820 def test_blank_descriptions_should_not_be_journalized
1578 IssueCustomField.delete_all 1821 IssueCustomField.delete_all
1579 Issue.update_all("description = NULL", "id=1") 1822 Issue.where(:id => 1).update_all("description = NULL")
1580 1823
1581 i = Issue.find(1) 1824 i = Issue.find(1)
1582 i.init_journal(User.find(2)) 1825 i.init_journal(User.find(2))
1583 i.subject = "blank description" 1826 i.subject = "blank description"
1584 i.description = "\r\n" 1827 i.description = "\r\n"
1628 i = Issue.new(:description => "CR \r LF \n CRLF \r\n") 1871 i = Issue.new(:description => "CR \r LF \n CRLF \r\n")
1629 assert_equal "CR \r\n LF \r\n CRLF \r\n", i.description 1872 assert_equal "CR \r\n LF \r\n CRLF \r\n", i.description
1630 end 1873 end
1631 1874
1632 def test_saving_twice_should_not_duplicate_journal_details 1875 def test_saving_twice_should_not_duplicate_journal_details
1633 i = Issue.find(:first) 1876 i = Issue.first
1634 i.init_journal(User.find(2), 'Some notes') 1877 i.init_journal(User.find(2), 'Some notes')
1635 # initial changes 1878 # initial changes
1636 i.subject = 'New subject' 1879 i.subject = 'New subject'
1637 i.done_ratio = i.done_ratio + 10 1880 i.done_ratio = i.done_ratio + 10
1638 assert_difference 'Journal.count' do 1881 assert_difference 'Journal.count' do
1639 assert i.save 1882 assert i.save
1640 end 1883 end
1641 # 1 more change 1884 # 1 more change
1642 i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id]) 1885 i.priority = IssuePriority.where("id <> ?", i.priority_id).first
1643 assert_no_difference 'Journal.count' do 1886 assert_no_difference 'Journal.count' do
1644 assert_difference 'JournalDetail.count', 1 do 1887 assert_difference 'JournalDetail.count', 1 do
1645 i.save 1888 i.save
1646 end 1889 end
1647 end 1890 end
1666 :relation_type => IssueRelation::TYPE_PRECEDES) 1909 :relation_type => IssueRelation::TYPE_PRECEDES)
1667 1910
1668 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort 1911 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
1669 end 1912 end
1670 1913
1914 def test_all_dependent_issues_with_subtask
1915 IssueRelation.delete_all
1916
1917 project = Project.generate!(:name => "testproject")
1918
1919 parentIssue = Issue.generate!(:project => project)
1920 childIssue1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue.id)
1921 childIssue2 = Issue.generate!(:project => project, :parent_issue_id => parentIssue.id)
1922
1923 assert_equal [childIssue1.id, childIssue2.id].sort, parentIssue.all_dependent_issues.collect(&:id).uniq.sort
1924 end
1925
1926 def test_all_dependent_issues_does_not_include_self
1927 IssueRelation.delete_all
1928
1929 project = Project.generate!(:name => "testproject")
1930
1931 parentIssue = Issue.generate!(:project => project)
1932 childIssue = Issue.generate!(:project => project, :parent_issue_id => parentIssue.id)
1933
1934 assert_equal [childIssue.id], parentIssue.all_dependent_issues.collect(&:id)
1935 end
1936
1937 def test_all_dependent_issues_with_parenttask_and_sibling
1938 IssueRelation.delete_all
1939
1940 project = Project.generate!(:name => "testproject")
1941
1942 parentIssue = Issue.generate!(:project => project)
1943 childIssue1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue.id)
1944 childIssue2 = Issue.generate!(:project => project, :parent_issue_id => parentIssue.id)
1945
1946 assert_equal [parentIssue.id].sort, childIssue1.all_dependent_issues.collect(&:id)
1947 end
1948
1949 def test_all_dependent_issues_with_relation_to_leaf_in_other_tree
1950 IssueRelation.delete_all
1951
1952 project = Project.generate!(:name => "testproject")
1953
1954 parentIssue1 = Issue.generate!(:project => project)
1955 childIssue1_1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue1.id)
1956 childIssue1_2 = Issue.generate!(:project => project, :parent_issue_id => parentIssue1.id)
1957
1958 parentIssue2 = Issue.generate!(:project => project)
1959 childIssue2_1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue2.id)
1960 childIssue2_2 = Issue.generate!(:project => project, :parent_issue_id => parentIssue2.id)
1961
1962
1963 assert IssueRelation.create(:issue_from => parentIssue1,
1964 :issue_to => childIssue2_2,
1965 :relation_type => IssueRelation::TYPE_BLOCKS)
1966
1967 assert_equal [childIssue1_1.id, childIssue1_2.id, parentIssue2.id, childIssue2_2.id].sort,
1968 parentIssue1.all_dependent_issues.collect(&:id).uniq.sort
1969 end
1970
1971 def test_all_dependent_issues_with_relation_to_parent_in_other_tree
1972 IssueRelation.delete_all
1973
1974 project = Project.generate!(:name => "testproject")
1975
1976 parentIssue1 = Issue.generate!(:project => project)
1977 childIssue1_1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue1.id)
1978 childIssue1_2 = Issue.generate!(:project => project, :parent_issue_id => parentIssue1.id)
1979
1980 parentIssue2 = Issue.generate!(:project => project)
1981 childIssue2_1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue2.id)
1982 childIssue2_2 = Issue.generate!(:project => project, :parent_issue_id => parentIssue2.id)
1983
1984
1985 assert IssueRelation.create(:issue_from => parentIssue1,
1986 :issue_to => parentIssue2,
1987 :relation_type => IssueRelation::TYPE_BLOCKS)
1988
1989 assert_equal [childIssue1_1.id, childIssue1_2.id, parentIssue2.id, childIssue2_1.id, childIssue2_2.id].sort,
1990 parentIssue1.all_dependent_issues.collect(&:id).uniq.sort
1991 end
1992
1993 def test_all_dependent_issues_with_transitive_relation
1994 IssueRelation.delete_all
1995
1996 project = Project.generate!(:name => "testproject")
1997
1998 parentIssue1 = Issue.generate!(:project => project)
1999 childIssue1_1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue1.id)
2000
2001 parentIssue2 = Issue.generate!(:project => project)
2002 childIssue2_1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue2.id)
2003
2004 independentIssue = Issue.generate!(:project => project)
2005
2006 assert IssueRelation.create(:issue_from => parentIssue1,
2007 :issue_to => childIssue2_1,
2008 :relation_type => IssueRelation::TYPE_RELATES)
2009
2010 assert IssueRelation.create(:issue_from => childIssue2_1,
2011 :issue_to => independentIssue,
2012 :relation_type => IssueRelation::TYPE_RELATES)
2013
2014 assert_equal [childIssue1_1.id, parentIssue2.id, childIssue2_1.id, independentIssue.id].sort,
2015 parentIssue1.all_dependent_issues.collect(&:id).uniq.sort
2016 end
2017
2018 def test_all_dependent_issues_with_transitive_relation2
2019 IssueRelation.delete_all
2020
2021 project = Project.generate!(:name => "testproject")
2022
2023 parentIssue1 = Issue.generate!(:project => project)
2024 childIssue1_1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue1.id)
2025
2026 parentIssue2 = Issue.generate!(:project => project)
2027 childIssue2_1 = Issue.generate!(:project => project, :parent_issue_id => parentIssue2.id)
2028
2029 independentIssue = Issue.generate!(:project => project)
2030
2031 assert IssueRelation.create(:issue_from => parentIssue1,
2032 :issue_to => independentIssue,
2033 :relation_type => IssueRelation::TYPE_RELATES)
2034
2035 assert IssueRelation.create(:issue_from => independentIssue,
2036 :issue_to => childIssue2_1,
2037 :relation_type => IssueRelation::TYPE_RELATES)
2038
2039 assert_equal [childIssue1_1.id, parentIssue2.id, childIssue2_1.id, independentIssue.id].sort,
2040 parentIssue1.all_dependent_issues.collect(&:id).uniq.sort
2041
2042 end
2043
1671 def test_all_dependent_issues_with_persistent_circular_dependency 2044 def test_all_dependent_issues_with_persistent_circular_dependency
1672 IssueRelation.delete_all 2045 IssueRelation.delete_all
1673 assert IssueRelation.create!(:issue_from => Issue.find(1), 2046 assert IssueRelation.create!(:issue_from => Issue.find(1),
1674 :issue_to => Issue.find(2), 2047 :issue_to => Issue.find(2),
1675 :relation_type => IssueRelation::TYPE_PRECEDES) 2048 :relation_type => IssueRelation::TYPE_PRECEDES)
1678 :relation_type => IssueRelation::TYPE_PRECEDES) 2051 :relation_type => IssueRelation::TYPE_PRECEDES)
1679 2052
1680 r = IssueRelation.create!(:issue_from => Issue.find(3), 2053 r = IssueRelation.create!(:issue_from => Issue.find(3),
1681 :issue_to => Issue.find(7), 2054 :issue_to => Issue.find(7),
1682 :relation_type => IssueRelation::TYPE_PRECEDES) 2055 :relation_type => IssueRelation::TYPE_PRECEDES)
1683 IssueRelation.update_all("issue_to_id = 1", ["id = ?", r.id]) 2056 IssueRelation.where(["id = ?", r.id]).update_all("issue_to_id = 1")
1684 2057
1685 assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort 2058 assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort
1686 end 2059 end
1687 2060
1688 def test_all_dependent_issues_with_persistent_multiple_circular_dependencies 2061 def test_all_dependent_issues_with_persistent_multiple_circular_dependencies
1689 IssueRelation.delete_all 2062 IssueRelation.delete_all
1698 :relation_type => IssueRelation::TYPE_RELATES) 2071 :relation_type => IssueRelation::TYPE_RELATES)
1699 2072
1700 r = IssueRelation.create!(:issue_from => Issue.find(8), 2073 r = IssueRelation.create!(:issue_from => Issue.find(8),
1701 :issue_to => Issue.find(7), 2074 :issue_to => Issue.find(7),
1702 :relation_type => IssueRelation::TYPE_RELATES) 2075 :relation_type => IssueRelation::TYPE_RELATES)
1703 IssueRelation.update_all("issue_to_id = 2", ["id = ?", r.id]) 2076 IssueRelation.where(["id = ?", r.id]).update_all("issue_to_id = 2")
1704 2077
1705 r = IssueRelation.create!(:issue_from => Issue.find(3), 2078 r = IssueRelation.create!(:issue_from => Issue.find(3),
1706 :issue_to => Issue.find(7), 2079 :issue_to => Issue.find(7),
1707 :relation_type => IssueRelation::TYPE_RELATES) 2080 :relation_type => IssueRelation::TYPE_RELATES)
1708 IssueRelation.update_all("issue_to_id = 1", ["id = ?", r.id]) 2081 IssueRelation.where(["id = ?", r.id]).update_all("issue_to_id = 1")
1709 2082
1710 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort 2083 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
1711 end 2084 end
1712 2085
1713 context "#done_ratio" do 2086 test "#done_ratio should use the issue_status according to Setting.issue_done_ratio" do
1714 setup do 2087 @issue = Issue.find(1)
1715 @issue = Issue.find(1) 2088 @issue_status = IssueStatus.find(1)
1716 @issue_status = IssueStatus.find(1) 2089 @issue_status.update_attribute(:default_done_ratio, 50)
1717 @issue_status.update_attribute(:default_done_ratio, 50) 2090 @issue2 = Issue.find(2)
1718 @issue2 = Issue.find(2) 2091 @issue_status2 = IssueStatus.find(2)
1719 @issue_status2 = IssueStatus.find(2) 2092 @issue_status2.update_attribute(:default_done_ratio, 0)
1720 @issue_status2.update_attribute(:default_done_ratio, 0) 2093
1721 end 2094 with_settings :issue_done_ratio => 'issue_field' do
1722 2095 assert_equal 0, @issue.done_ratio
1723 teardown do 2096 assert_equal 30, @issue2.done_ratio
1724 Setting.issue_done_ratio = 'issue_field' 2097 end
1725 end 2098
1726 2099 with_settings :issue_done_ratio => 'issue_status' do
1727 context "with Setting.issue_done_ratio using the issue_field" do 2100 assert_equal 50, @issue.done_ratio
1728 setup do 2101 assert_equal 0, @issue2.done_ratio
1729 Setting.issue_done_ratio = 'issue_field' 2102 end
1730 end 2103 end
1731 2104
1732 should "read the issue's field" do 2105 test "#update_done_ratio_from_issue_status should update done_ratio according to Setting.issue_done_ratio" do
1733 assert_equal 0, @issue.done_ratio 2106 @issue = Issue.find(1)
1734 assert_equal 30, @issue2.done_ratio 2107 @issue_status = IssueStatus.find(1)
1735 end 2108 @issue_status.update_attribute(:default_done_ratio, 50)
1736 end 2109 @issue2 = Issue.find(2)
1737 2110 @issue_status2 = IssueStatus.find(2)
1738 context "with Setting.issue_done_ratio using the issue_status" do 2111 @issue_status2.update_attribute(:default_done_ratio, 0)
1739 setup do 2112
1740 Setting.issue_done_ratio = 'issue_status' 2113 with_settings :issue_done_ratio => 'issue_field' do
1741 end 2114 @issue.update_done_ratio_from_issue_status
1742 2115 @issue2.update_done_ratio_from_issue_status
1743 should "read the Issue Status's default done ratio" do 2116
1744 assert_equal 50, @issue.done_ratio 2117 assert_equal 0, @issue.read_attribute(:done_ratio)
1745 assert_equal 0, @issue2.done_ratio 2118 assert_equal 30, @issue2.read_attribute(:done_ratio)
1746 end 2119 end
1747 end 2120
1748 end 2121 with_settings :issue_done_ratio => 'issue_status' do
1749 2122 @issue.update_done_ratio_from_issue_status
1750 context "#update_done_ratio_from_issue_status" do 2123 @issue2.update_done_ratio_from_issue_status
1751 setup do 2124
1752 @issue = Issue.find(1) 2125 assert_equal 50, @issue.read_attribute(:done_ratio)
1753 @issue_status = IssueStatus.find(1) 2126 assert_equal 0, @issue2.read_attribute(:done_ratio)
1754 @issue_status.update_attribute(:default_done_ratio, 50)
1755 @issue2 = Issue.find(2)
1756 @issue_status2 = IssueStatus.find(2)
1757 @issue_status2.update_attribute(:default_done_ratio, 0)
1758 end
1759
1760 context "with Setting.issue_done_ratio using the issue_field" do
1761 setup do
1762 Setting.issue_done_ratio = 'issue_field'
1763 end
1764
1765 should "not change the issue" do
1766 @issue.update_done_ratio_from_issue_status
1767 @issue2.update_done_ratio_from_issue_status
1768
1769 assert_equal 0, @issue.read_attribute(:done_ratio)
1770 assert_equal 30, @issue2.read_attribute(:done_ratio)
1771 end
1772 end
1773
1774 context "with Setting.issue_done_ratio using the issue_status" do
1775 setup do
1776 Setting.issue_done_ratio = 'issue_status'
1777 end
1778
1779 should "change the issue's done ratio" do
1780 @issue.update_done_ratio_from_issue_status
1781 @issue2.update_done_ratio_from_issue_status
1782
1783 assert_equal 50, @issue.read_attribute(:done_ratio)
1784 assert_equal 0, @issue2.read_attribute(:done_ratio)
1785 end
1786 end 2127 end
1787 end 2128 end
1788 2129
1789 test "#by_tracker" do 2130 test "#by_tracker" do
1790 User.current = User.anonymous 2131 User.current = User.anonymous
1791 groups = Issue.by_tracker(Project.find(1)) 2132 groups = Issue.by_tracker(Project.find(1))
1792 assert_equal 3, groups.size 2133 assert_equal 3, groups.count
1793 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i} 2134 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1794 end 2135 end
1795 2136
1796 test "#by_version" do 2137 test "#by_version" do
1797 User.current = User.anonymous 2138 User.current = User.anonymous
1798 groups = Issue.by_version(Project.find(1)) 2139 groups = Issue.by_version(Project.find(1))
1799 assert_equal 3, groups.size 2140 assert_equal 3, groups.count
1800 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i} 2141 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1801 end 2142 end
1802 2143
1803 test "#by_priority" do 2144 test "#by_priority" do
1804 User.current = User.anonymous 2145 User.current = User.anonymous
1805 groups = Issue.by_priority(Project.find(1)) 2146 groups = Issue.by_priority(Project.find(1))
1806 assert_equal 4, groups.size 2147 assert_equal 4, groups.count
1807 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i} 2148 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1808 end 2149 end
1809 2150
1810 test "#by_category" do 2151 test "#by_category" do
1811 User.current = User.anonymous 2152 User.current = User.anonymous
1812 groups = Issue.by_category(Project.find(1)) 2153 groups = Issue.by_category(Project.find(1))
1813 assert_equal 2, groups.size 2154 assert_equal 2, groups.count
1814 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i} 2155 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1815 end 2156 end
1816 2157
1817 test "#by_assigned_to" do 2158 test "#by_assigned_to" do
1818 User.current = User.anonymous 2159 User.current = User.anonymous
1819 groups = Issue.by_assigned_to(Project.find(1)) 2160 groups = Issue.by_assigned_to(Project.find(1))
1820 assert_equal 2, groups.size 2161 assert_equal 2, groups.count
1821 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i} 2162 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1822 end 2163 end
1823 2164
1824 test "#by_author" do 2165 test "#by_author" do
1825 User.current = User.anonymous 2166 User.current = User.anonymous
1826 groups = Issue.by_author(Project.find(1)) 2167 groups = Issue.by_author(Project.find(1))
1827 assert_equal 4, groups.size 2168 assert_equal 4, groups.count
1828 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i} 2169 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1829 end 2170 end
1830 2171
1831 test "#by_subproject" do 2172 test "#by_subproject" do
1832 User.current = User.anonymous 2173 User.current = User.anonymous
1833 groups = Issue.by_subproject(Project.find(1)) 2174 groups = Issue.by_subproject(Project.find(1))
1834 # Private descendant not visible 2175 # Private descendant not visible
1835 assert_equal 1, groups.size 2176 assert_equal 1, groups.count
1836 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i} 2177 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1837 end 2178 end
1838 2179
1839 def test_recently_updated_scope 2180 def test_recently_updated_scope
1840 #should return the last updated issue 2181 #should return the last updated issue
1853 issue.project = Project.find(2) 2194 issue.project = Project.find(2)
1854 assert issue.save 2195 assert issue.save
1855 assert_equal before, Issue.on_active_project.length 2196 assert_equal before, Issue.on_active_project.length
1856 end 2197 end
1857 2198
1858 context "Issue#recipients" do 2199 test "Issue#recipients should include project recipients" do
1859 setup do 2200 issue = Issue.generate!
1860 @project = Project.find(1) 2201 assert issue.project.recipients.present?
1861 @author = User.generate! 2202 issue.project.recipients.each do |project_recipient|
1862 @assignee = User.generate! 2203 assert issue.recipients.include?(project_recipient)
1863 @issue = Issue.generate!(:project => @project, :assigned_to => @assignee, :author => @author) 2204 end
1864 end 2205 end
1865 2206
1866 should "include project recipients" do 2207 test "Issue#recipients should include the author if the author is active" do
1867 assert @project.recipients.present? 2208 issue = Issue.generate!(:author => User.generate!)
1868 @project.recipients.each do |project_recipient| 2209 assert issue.author, "No author set for Issue"
1869 assert @issue.recipients.include?(project_recipient) 2210 assert issue.recipients.include?(issue.author.mail)
1870 end 2211 end
1871 end 2212
1872 2213 test "Issue#recipients should include the assigned to user if the assigned to user is active" do
1873 should "include the author if the author is active" do 2214 issue = Issue.generate!(:assigned_to => User.generate!)
1874 assert @issue.author, "No author set for Issue" 2215 assert issue.assigned_to, "No assigned_to set for Issue"
1875 assert @issue.recipients.include?(@issue.author.mail) 2216 assert issue.recipients.include?(issue.assigned_to.mail)
1876 end 2217 end
1877 2218
1878 should "include the assigned to user if the assigned to user is active" do 2219 test "Issue#recipients should not include users who opt out of all email" do
1879 assert @issue.assigned_to, "No assigned_to set for Issue" 2220 issue = Issue.generate!(:author => User.generate!)
1880 assert @issue.recipients.include?(@issue.assigned_to.mail) 2221 issue.author.update_attribute(:mail_notification, :none)
1881 end 2222 assert !issue.recipients.include?(issue.author.mail)
1882 2223 end
1883 should "not include users who opt out of all email" do 2224
1884 @author.update_attribute(:mail_notification, :none) 2225 test "Issue#recipients should not include the issue author if they are only notified of assigned issues" do
1885 2226 issue = Issue.generate!(:author => User.generate!)
1886 assert !@issue.recipients.include?(@issue.author.mail) 2227 issue.author.update_attribute(:mail_notification, :only_assigned)
1887 end 2228 assert !issue.recipients.include?(issue.author.mail)
1888 2229 end
1889 should "not include the issue author if they are only notified of assigned issues" do 2230
1890 @author.update_attribute(:mail_notification, :only_assigned) 2231 test "Issue#recipients should not include the assigned user if they are only notified of owned issues" do
1891 2232 issue = Issue.generate!(:assigned_to => User.generate!)
1892 assert !@issue.recipients.include?(@issue.author.mail) 2233 issue.assigned_to.update_attribute(:mail_notification, :only_owner)
1893 end 2234 assert !issue.recipients.include?(issue.assigned_to.mail)
1894
1895 should "not include the assigned user if they are only notified of owned issues" do
1896 @assignee.update_attribute(:mail_notification, :only_owner)
1897
1898 assert !@issue.recipients.include?(@issue.assigned_to.mail)
1899 end
1900 end 2235 end
1901 2236
1902 def test_last_journal_id_with_journals_should_return_the_journal_id 2237 def test_last_journal_id_with_journals_should_return_the_journal_id
1903 assert_equal 2, Issue.find(1).last_journal_id 2238 assert_equal 2, Issue.find(1).last_journal_id
1904 end 2239 end
1912 assert_equal [], Issue.find(1).journals_after('2') 2247 assert_equal [], Issue.find(1).journals_after('2')
1913 end 2248 end
1914 2249
1915 def test_journals_after_with_blank_arg_should_return_all_journals 2250 def test_journals_after_with_blank_arg_should_return_all_journals
1916 assert_equal [Journal.find(1), Journal.find(2)], Issue.find(1).journals_after('') 2251 assert_equal [Journal.find(1), Journal.find(2)], Issue.find(1).journals_after('')
2252 end
2253
2254 def test_css_classes_should_include_tracker
2255 issue = Issue.new(:tracker => Tracker.find(2))
2256 classes = issue.css_classes.split(' ')
2257 assert_include 'tracker-2', classes
1917 end 2258 end
1918 2259
1919 def test_css_classes_should_include_priority 2260 def test_css_classes_should_include_priority
1920 issue = Issue.new(:priority => IssuePriority.find(8)) 2261 issue = Issue.new(:priority => IssuePriority.find(8))
1921 classes = issue.css_classes.split(' ') 2262 classes = issue.css_classes.split(' ')
1922 assert_include 'priority-8', classes 2263 assert_include 'priority-8', classes
1923 assert_include 'priority-highest', classes 2264 assert_include 'priority-highest', classes
2265 end
2266
2267 def test_css_classes_should_include_user_and_group_assignment
2268 project = Project.first
2269 user = User.generate!
2270 group = Group.generate!
2271 Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
2272 group.users << user
2273 assert user.member_of?(project)
2274 issue1 = Issue.generate(:assigned_to_id => group.id)
2275 assert_include 'assigned-to-my-group', issue1.css_classes(user)
2276 assert_not_include 'assigned-to-me', issue1.css_classes(user)
2277 issue2 = Issue.generate(:assigned_to_id => user.id)
2278 assert_not_include 'assigned-to-my-group', issue2.css_classes(user)
2279 assert_include 'assigned-to-me', issue2.css_classes(user)
1924 end 2280 end
1925 2281
1926 def test_save_attachments_with_hash_should_save_attachments_in_keys_order 2282 def test_save_attachments_with_hash_should_save_attachments_in_keys_order
1927 set_tmp_attachments_directory 2283 set_tmp_attachments_directory
1928 issue = Issue.generate! 2284 issue = Issue.generate!
1934 issue.attach_saved_attachments 2290 issue.attach_saved_attachments
1935 2291
1936 assert_equal 3, issue.reload.attachments.count 2292 assert_equal 3, issue.reload.attachments.count
1937 assert_equal %w(upload foo bar), issue.attachments.map(&:filename) 2293 assert_equal %w(upload foo bar), issue.attachments.map(&:filename)
1938 end 2294 end
2295
2296 def test_closed_on_should_be_nil_when_creating_an_open_issue
2297 issue = Issue.generate!(:status_id => 1).reload
2298 assert !issue.closed?
2299 assert_nil issue.closed_on
2300 end
2301
2302 def test_closed_on_should_be_set_when_creating_a_closed_issue
2303 issue = Issue.generate!(:status_id => 5).reload
2304 assert issue.closed?
2305 assert_not_nil issue.closed_on
2306 assert_equal issue.updated_on, issue.closed_on
2307 assert_equal issue.created_on, issue.closed_on
2308 end
2309
2310 def test_closed_on_should_be_nil_when_updating_an_open_issue
2311 issue = Issue.find(1)
2312 issue.subject = 'Not closed yet'
2313 issue.save!
2314 issue.reload
2315 assert_nil issue.closed_on
2316 end
2317
2318 def test_closed_on_should_be_set_when_closing_an_open_issue
2319 issue = Issue.find(1)
2320 issue.subject = 'Now closed'
2321 issue.status_id = 5
2322 issue.save!
2323 issue.reload
2324 assert_not_nil issue.closed_on
2325 assert_equal issue.updated_on, issue.closed_on
2326 end
2327
2328 def test_closed_on_should_not_be_updated_when_updating_a_closed_issue
2329 issue = Issue.open(false).first
2330 was_closed_on = issue.closed_on
2331 assert_not_nil was_closed_on
2332 issue.subject = 'Updating a closed issue'
2333 issue.save!
2334 issue.reload
2335 assert_equal was_closed_on, issue.closed_on
2336 end
2337
2338 def test_closed_on_should_be_preserved_when_reopening_a_closed_issue
2339 issue = Issue.open(false).first
2340 was_closed_on = issue.closed_on
2341 assert_not_nil was_closed_on
2342 issue.subject = 'Reopening a closed issue'
2343 issue.status_id = 1
2344 issue.save!
2345 issue.reload
2346 assert !issue.closed?
2347 assert_equal was_closed_on, issue.closed_on
2348 end
2349
2350 def test_status_was_should_return_nil_for_new_issue
2351 issue = Issue.new
2352 assert_nil issue.status_was
2353 end
2354
2355 def test_status_was_should_return_status_before_change
2356 issue = Issue.find(1)
2357 issue.status = IssueStatus.find(2)
2358 assert_equal IssueStatus.find(1), issue.status_was
2359 end
2360
2361 def test_status_was_should_be_reset_on_save
2362 issue = Issue.find(1)
2363 issue.status = IssueStatus.find(2)
2364 assert_equal IssueStatus.find(1), issue.status_was
2365 assert issue.save!
2366 assert_equal IssueStatus.find(2), issue.status_was
2367 end
1939 end 2368 end