@@ -21,6 +21,7 class IssueStatus < ActiveRecord::Base | |||||
21 | has_many :workflow_transitions_as_new_status, :class_name => 'WorkflowTransition', :foreign_key => "new_status_id" |
|
21 | has_many :workflow_transitions_as_new_status, :class_name => 'WorkflowTransition', :foreign_key => "new_status_id" | |
22 | acts_as_list |
|
22 | acts_as_list | |
23 |
|
23 | |||
|
24 | after_update :handle_is_closed_change | |||
24 | before_destroy :delete_workflow_rules |
|
25 | before_destroy :delete_workflow_rules | |
25 |
|
26 | |||
26 | validates_presence_of :name |
|
27 | validates_presence_of :name | |
@@ -89,6 +90,23 class IssueStatus < ActiveRecord::Base | |||||
89 |
|
90 | |||
90 | private |
|
91 | private | |
91 |
|
92 | |||
|
93 | # Updates issues closed_on attribute when an existing status is set as closed. | |||
|
94 | def handle_is_closed_change | |||
|
95 | if is_closed_changed? && is_closed == true | |||
|
96 | # First we update issues that have a journal for when the current status was set, | |||
|
97 | # a subselect is used to update all issues with a single query | |||
|
98 | subselect = "SELECT MAX(j.created_on) FROM #{Journal.table_name} j" + | |||
|
99 | " JOIN #{JournalDetail.table_name} d ON d.journal_id = j.id" + | |||
|
100 | " WHERE j.journalized_type = 'Issue' AND j.journalized_id = #{Issue.table_name}.id" + | |||
|
101 | " AND d.property = 'attr' AND d.prop_key = 'status_id' AND d.value = :status_id" | |||
|
102 | Issue.where(:status_id => id, :closed_on => nil).update_all(["closed_on = (#{subselect})", :status_id => id.to_s]) | |||
|
103 | ||||
|
104 | # Then we update issues that don't have a journal which means the | |||
|
105 | # current status was set on creation | |||
|
106 | Issue.where(:status_id => id, :closed_on => nil).update_all("closed_on = created_on") | |||
|
107 | end | |||
|
108 | end | |||
|
109 | ||||
92 | def check_integrity |
|
110 | def check_integrity | |
93 | if Issue.where(:status_id => id).any? |
|
111 | if Issue.where(:status_id => id).any? | |
94 | raise "This status is used by some issues" |
|
112 | raise "This status is used by some issues" |
@@ -96,4 +96,38 class IssueStatusTest < ActiveSupport::TestCase | |||||
96 | assert_not_nil status |
|
96 | assert_not_nil status | |
97 | assert_equal "Resolved", status.name |
|
97 | assert_equal "Resolved", status.name | |
98 | end |
|
98 | end | |
|
99 | ||||
|
100 | def test_setting_status_as_closed_should_set_closed_on_for_issues_without_status_journal | |||
|
101 | issue = Issue.generate!(:status_id => 1, :created_on => 2.days.ago) | |||
|
102 | assert_nil issue.closed_on | |||
|
103 | ||||
|
104 | issue.status.update! :is_closed => true | |||
|
105 | ||||
|
106 | issue.reload | |||
|
107 | assert issue.closed? | |||
|
108 | assert_equal issue.created_on, issue.closed_on | |||
|
109 | end | |||
|
110 | ||||
|
111 | def test_setting_status_as_closed_should_set_closed_on_for_issues_with_status_journal | |||
|
112 | issue = Issue.generate!(:status_id => 1, :created_on => 2.days.ago) | |||
|
113 | issue.init_journal(User.find(1)) | |||
|
114 | issue.status_id = 2 | |||
|
115 | issue.save! | |||
|
116 | ||||
|
117 | issue.status.update! :is_closed => true | |||
|
118 | ||||
|
119 | issue.reload | |||
|
120 | assert issue.closed? | |||
|
121 | assert_equal issue.journals.first.created_on, issue.closed_on | |||
|
122 | end | |||
|
123 | ||||
|
124 | def test_setting_status_as_closed_should_not_set_closed_on_for_issues_with_other_status | |||
|
125 | issue = Issue.generate!(:status_id => 2) | |||
|
126 | ||||
|
127 | IssueStatus.find(1).update! :is_closed => true | |||
|
128 | ||||
|
129 | issue.reload | |||
|
130 | assert !issue.closed? | |||
|
131 | assert_nil issue.closed_on | |||
|
132 | end | |||
99 | end |
|
133 | end |
General Comments 0
You need to be logged in to leave comments.
Login now