Mercurial > hg > soundsoftware-site
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 |