##// END OF EJS Templates
Merged r14417 from trunk to 3.1-stable....
Toshi MARUYAMA -
r14036:bcae2a41beb3
parent child
Show More
@@ -1,258 +1,260
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
2 # Copyright (C) 2006-2015 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.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class IssueSubtaskingTest < ActiveSupport::TestCase
20 class IssueSubtaskingTest < ActiveSupport::TestCase
21 fixtures :projects, :users, :roles, :members, :member_roles,
21 fixtures :projects, :users, :roles, :members, :member_roles,
22 :trackers, :projects_trackers,
22 :trackers, :projects_trackers,
23 :issue_statuses, :issue_categories, :enumerations,
23 :issue_statuses, :issue_categories, :enumerations,
24 :issues
24 :issues,
25 :enabled_modules,
26 :workflows
25
27
26 def test_leaf_planning_fields_should_be_editable
28 def test_leaf_planning_fields_should_be_editable
27 issue = Issue.generate!
29 issue = Issue.generate!
28 user = User.find(1)
30 user = User.find(1)
29 %w(priority_id done_ratio start_date due_date estimated_hours).each do |attribute|
31 %w(priority_id done_ratio start_date due_date estimated_hours).each do |attribute|
30 assert issue.safe_attribute?(attribute, user)
32 assert issue.safe_attribute?(attribute, user)
31 end
33 end
32 end
34 end
33
35
34 def test_parent_dates_should_be_read_only_with_parent_issue_dates_set_to_derived
36 def test_parent_dates_should_be_read_only_with_parent_issue_dates_set_to_derived
35 with_settings :parent_issue_dates => 'derived' do
37 with_settings :parent_issue_dates => 'derived' do
36 issue = Issue.generate_with_child!
38 issue = Issue.generate_with_child!
37 user = User.find(1)
39 user = User.find(1)
38 %w(start_date due_date).each do |attribute|
40 %w(start_date due_date).each do |attribute|
39 assert !issue.safe_attribute?(attribute, user)
41 assert !issue.safe_attribute?(attribute, user)
40 end
42 end
41 end
43 end
42 end
44 end
43
45
44 def test_parent_dates_should_be_lowest_start_and_highest_due_dates_with_parent_issue_dates_set_to_derived
46 def test_parent_dates_should_be_lowest_start_and_highest_due_dates_with_parent_issue_dates_set_to_derived
45 with_settings :parent_issue_dates => 'derived' do
47 with_settings :parent_issue_dates => 'derived' do
46 parent = Issue.generate!
48 parent = Issue.generate!
47 parent.generate_child!(:start_date => '2010-01-25', :due_date => '2010-02-15')
49 parent.generate_child!(:start_date => '2010-01-25', :due_date => '2010-02-15')
48 parent.generate_child!( :due_date => '2010-02-13')
50 parent.generate_child!( :due_date => '2010-02-13')
49 parent.generate_child!(:start_date => '2010-02-01', :due_date => '2010-02-22')
51 parent.generate_child!(:start_date => '2010-02-01', :due_date => '2010-02-22')
50 parent.reload
52 parent.reload
51 assert_equal Date.parse('2010-01-25'), parent.start_date
53 assert_equal Date.parse('2010-01-25'), parent.start_date
52 assert_equal Date.parse('2010-02-22'), parent.due_date
54 assert_equal Date.parse('2010-02-22'), parent.due_date
53 end
55 end
54 end
56 end
55
57
56 def test_reschuling_a_parent_should_reschedule_subtasks_with_parent_issue_dates_set_to_derived
58 def test_reschuling_a_parent_should_reschedule_subtasks_with_parent_issue_dates_set_to_derived
57 with_settings :parent_issue_dates => 'derived' do
59 with_settings :parent_issue_dates => 'derived' do
58 parent = Issue.generate!
60 parent = Issue.generate!
59 c1 = parent.generate_child!(:start_date => '2010-05-12', :due_date => '2010-05-18')
61 c1 = parent.generate_child!(:start_date => '2010-05-12', :due_date => '2010-05-18')
60 c2 = parent.generate_child!(:start_date => '2010-06-03', :due_date => '2010-06-10')
62 c2 = parent.generate_child!(:start_date => '2010-06-03', :due_date => '2010-06-10')
61 parent.reload.reschedule_on!(Date.parse('2010-06-02'))
63 parent.reload.reschedule_on!(Date.parse('2010-06-02'))
62 c1.reload
64 c1.reload
63 assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-08')], [c1.start_date, c1.due_date]
65 assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-08')], [c1.start_date, c1.due_date]
64 c2.reload
66 c2.reload
65 assert_equal [Date.parse('2010-06-03'), Date.parse('2010-06-10')], [c2.start_date, c2.due_date] # no change
67 assert_equal [Date.parse('2010-06-03'), Date.parse('2010-06-10')], [c2.start_date, c2.due_date] # no change
66 parent.reload
68 parent.reload
67 assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-10')], [parent.start_date, parent.due_date]
69 assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-10')], [parent.start_date, parent.due_date]
68 end
70 end
69 end
71 end
70
72
71 def test_parent_priority_should_be_read_only_with_parent_issue_priority_set_to_derived
73 def test_parent_priority_should_be_read_only_with_parent_issue_priority_set_to_derived
72 with_settings :parent_issue_priority => 'derived' do
74 with_settings :parent_issue_priority => 'derived' do
73 issue = Issue.generate_with_child!
75 issue = Issue.generate_with_child!
74 user = User.find(1)
76 user = User.find(1)
75 assert !issue.safe_attribute?('priority_id', user)
77 assert !issue.safe_attribute?('priority_id', user)
76 end
78 end
77 end
79 end
78
80
79 def test_parent_priority_should_be_the_highest_child_priority
81 def test_parent_priority_should_be_the_highest_child_priority
80 with_settings :parent_issue_priority => 'derived' do
82 with_settings :parent_issue_priority => 'derived' do
81 parent = Issue.generate!(:priority => IssuePriority.find_by_name('Normal'))
83 parent = Issue.generate!(:priority => IssuePriority.find_by_name('Normal'))
82 # Create children
84 # Create children
83 child1 = parent.generate_child!(:priority => IssuePriority.find_by_name('High'))
85 child1 = parent.generate_child!(:priority => IssuePriority.find_by_name('High'))
84 assert_equal 'High', parent.reload.priority.name
86 assert_equal 'High', parent.reload.priority.name
85 child2 = child1.generate_child!(:priority => IssuePriority.find_by_name('Immediate'))
87 child2 = child1.generate_child!(:priority => IssuePriority.find_by_name('Immediate'))
86 assert_equal 'Immediate', child1.reload.priority.name
88 assert_equal 'Immediate', child1.reload.priority.name
87 assert_equal 'Immediate', parent.reload.priority.name
89 assert_equal 'Immediate', parent.reload.priority.name
88 child3 = parent.generate_child!(:priority => IssuePriority.find_by_name('Low'))
90 child3 = parent.generate_child!(:priority => IssuePriority.find_by_name('Low'))
89 assert_equal 'Immediate', parent.reload.priority.name
91 assert_equal 'Immediate', parent.reload.priority.name
90 # Destroy a child
92 # Destroy a child
91 child1.destroy
93 child1.destroy
92 assert_equal 'Low', parent.reload.priority.name
94 assert_equal 'Low', parent.reload.priority.name
93 # Update a child
95 # Update a child
94 child3.reload.priority = IssuePriority.find_by_name('Normal')
96 child3.reload.priority = IssuePriority.find_by_name('Normal')
95 child3.save!
97 child3.save!
96 assert_equal 'Normal', parent.reload.priority.name
98 assert_equal 'Normal', parent.reload.priority.name
97 end
99 end
98 end
100 end
99
101
100 def test_parent_done_ratio_should_be_read_only_with_parent_issue_done_ratio_set_to_derived
102 def test_parent_done_ratio_should_be_read_only_with_parent_issue_done_ratio_set_to_derived
101 with_settings :parent_issue_done_ratio => 'derived' do
103 with_settings :parent_issue_done_ratio => 'derived' do
102 issue = Issue.generate_with_child!
104 issue = Issue.generate_with_child!
103 user = User.find(1)
105 user = User.find(1)
104 assert !issue.safe_attribute?('done_ratio', user)
106 assert !issue.safe_attribute?('done_ratio', user)
105 end
107 end
106 end
108 end
107
109
108 def test_parent_done_ratio_should_be_average_done_ratio_of_leaves
110 def test_parent_done_ratio_should_be_average_done_ratio_of_leaves
109 with_settings :parent_issue_done_ratio => 'derived' do
111 with_settings :parent_issue_done_ratio => 'derived' do
110 parent = Issue.generate!
112 parent = Issue.generate!
111 parent.generate_child!(:done_ratio => 20)
113 parent.generate_child!(:done_ratio => 20)
112 assert_equal 20, parent.reload.done_ratio
114 assert_equal 20, parent.reload.done_ratio
113 parent.generate_child!(:done_ratio => 70)
115 parent.generate_child!(:done_ratio => 70)
114 assert_equal 45, parent.reload.done_ratio
116 assert_equal 45, parent.reload.done_ratio
115
117
116 child = parent.generate_child!(:done_ratio => 0)
118 child = parent.generate_child!(:done_ratio => 0)
117 assert_equal 30, parent.reload.done_ratio
119 assert_equal 30, parent.reload.done_ratio
118
120
119 child.generate_child!(:done_ratio => 30)
121 child.generate_child!(:done_ratio => 30)
120 assert_equal 30, child.reload.done_ratio
122 assert_equal 30, child.reload.done_ratio
121 assert_equal 40, parent.reload.done_ratio
123 assert_equal 40, parent.reload.done_ratio
122 end
124 end
123 end
125 end
124
126
125 def test_parent_done_ratio_should_be_weighted_by_estimated_times_if_any
127 def test_parent_done_ratio_should_be_weighted_by_estimated_times_if_any
126 with_settings :parent_issue_done_ratio => 'derived' do
128 with_settings :parent_issue_done_ratio => 'derived' do
127 parent = Issue.generate!
129 parent = Issue.generate!
128 parent.generate_child!(:estimated_hours => 10, :done_ratio => 20)
130 parent.generate_child!(:estimated_hours => 10, :done_ratio => 20)
129 assert_equal 20, parent.reload.done_ratio
131 assert_equal 20, parent.reload.done_ratio
130 parent.generate_child!(:estimated_hours => 20, :done_ratio => 50)
132 parent.generate_child!(:estimated_hours => 20, :done_ratio => 50)
131 assert_equal (50 * 20 + 20 * 10) / 30, parent.reload.done_ratio
133 assert_equal (50 * 20 + 20 * 10) / 30, parent.reload.done_ratio
132 end
134 end
133 end
135 end
134
136
135 def test_parent_done_ratio_with_child_estimate_to_0_should_reach_100
137 def test_parent_done_ratio_with_child_estimate_to_0_should_reach_100
136 with_settings :parent_issue_done_ratio => 'derived' do
138 with_settings :parent_issue_done_ratio => 'derived' do
137 parent = Issue.generate!
139 parent = Issue.generate!
138 issue1 = parent.generate_child!
140 issue1 = parent.generate_child!
139 issue2 = parent.generate_child!(:estimated_hours => 0)
141 issue2 = parent.generate_child!(:estimated_hours => 0)
140 assert_equal 0, parent.reload.done_ratio
142 assert_equal 0, parent.reload.done_ratio
141 issue1.reload.close!
143 issue1.reload.close!
142 assert_equal 50, parent.reload.done_ratio
144 assert_equal 50, parent.reload.done_ratio
143 issue2.reload.close!
145 issue2.reload.close!
144 assert_equal 100, parent.reload.done_ratio
146 assert_equal 100, parent.reload.done_ratio
145 end
147 end
146 end
148 end
147
149
148 def test_done_ratio_of_parent_with_a_child_without_estimated_time_should_not_exceed_100
150 def test_done_ratio_of_parent_with_a_child_without_estimated_time_should_not_exceed_100
149 with_settings :parent_issue_done_ratio => 'derived' do
151 with_settings :parent_issue_done_ratio => 'derived' do
150 parent = Issue.generate!
152 parent = Issue.generate!
151 parent.generate_child!(:estimated_hours => 40)
153 parent.generate_child!(:estimated_hours => 40)
152 parent.generate_child!(:estimated_hours => 40)
154 parent.generate_child!(:estimated_hours => 40)
153 parent.generate_child!(:estimated_hours => 20)
155 parent.generate_child!(:estimated_hours => 20)
154 parent.generate_child!
156 parent.generate_child!
155 parent.reload.children.each(&:close!)
157 parent.reload.children.each(&:close!)
156 assert_equal 100, parent.reload.done_ratio
158 assert_equal 100, parent.reload.done_ratio
157 end
159 end
158 end
160 end
159
161
160 def test_done_ratio_of_parent_with_a_child_with_estimated_time_at_0_should_not_exceed_100
162 def test_done_ratio_of_parent_with_a_child_with_estimated_time_at_0_should_not_exceed_100
161 with_settings :parent_issue_done_ratio => 'derived' do
163 with_settings :parent_issue_done_ratio => 'derived' do
162 parent = Issue.generate!
164 parent = Issue.generate!
163 parent.generate_child!(:estimated_hours => 40)
165 parent.generate_child!(:estimated_hours => 40)
164 parent.generate_child!(:estimated_hours => 40)
166 parent.generate_child!(:estimated_hours => 40)
165 parent.generate_child!(:estimated_hours => 20)
167 parent.generate_child!(:estimated_hours => 20)
166 parent.generate_child!(:estimated_hours => 0)
168 parent.generate_child!(:estimated_hours => 0)
167 parent.reload.children.each(&:close!)
169 parent.reload.children.each(&:close!)
168 assert_equal 100, parent.reload.done_ratio
170 assert_equal 100, parent.reload.done_ratio
169 end
171 end
170 end
172 end
171
173
172 def test_changing_parent_should_update_previous_parent_done_ratio
174 def test_changing_parent_should_update_previous_parent_done_ratio
173 with_settings :parent_issue_done_ratio => 'derived' do
175 with_settings :parent_issue_done_ratio => 'derived' do
174 first_parent = Issue.generate!
176 first_parent = Issue.generate!
175 second_parent = Issue.generate!
177 second_parent = Issue.generate!
176 first_parent.generate_child!(:done_ratio => 40)
178 first_parent.generate_child!(:done_ratio => 40)
177 child = first_parent.generate_child!(:done_ratio => 20)
179 child = first_parent.generate_child!(:done_ratio => 20)
178 assert_equal 30, first_parent.reload.done_ratio
180 assert_equal 30, first_parent.reload.done_ratio
179 assert_equal 0, second_parent.reload.done_ratio
181 assert_equal 0, second_parent.reload.done_ratio
180 child.update_attributes(:parent_issue_id => second_parent.id)
182 child.update_attributes(:parent_issue_id => second_parent.id)
181 assert_equal 40, first_parent.reload.done_ratio
183 assert_equal 40, first_parent.reload.done_ratio
182 assert_equal 20, second_parent.reload.done_ratio
184 assert_equal 20, second_parent.reload.done_ratio
183 end
185 end
184 end
186 end
185
187
186 def test_parent_dates_should_be_editable_with_parent_issue_dates_set_to_independent
188 def test_parent_dates_should_be_editable_with_parent_issue_dates_set_to_independent
187 with_settings :parent_issue_dates => 'independent' do
189 with_settings :parent_issue_dates => 'independent' do
188 issue = Issue.generate_with_child!
190 issue = Issue.generate_with_child!
189 user = User.find(1)
191 user = User.find(1)
190 %w(start_date due_date).each do |attribute|
192 %w(start_date due_date).each do |attribute|
191 assert issue.safe_attribute?(attribute, user)
193 assert issue.safe_attribute?(attribute, user)
192 end
194 end
193 end
195 end
194 end
196 end
195
197
196 def test_parent_dates_should_not_be_updated_with_parent_issue_dates_set_to_independent
198 def test_parent_dates_should_not_be_updated_with_parent_issue_dates_set_to_independent
197 with_settings :parent_issue_dates => 'independent' do
199 with_settings :parent_issue_dates => 'independent' do
198 parent = Issue.generate!(:start_date => '2015-07-01', :due_date => '2015-08-01')
200 parent = Issue.generate!(:start_date => '2015-07-01', :due_date => '2015-08-01')
199 parent.generate_child!(:start_date => '2015-06-01', :due_date => '2015-09-01')
201 parent.generate_child!(:start_date => '2015-06-01', :due_date => '2015-09-01')
200 parent.reload
202 parent.reload
201 assert_equal Date.parse('2015-07-01'), parent.start_date
203 assert_equal Date.parse('2015-07-01'), parent.start_date
202 assert_equal Date.parse('2015-08-01'), parent.due_date
204 assert_equal Date.parse('2015-08-01'), parent.due_date
203 end
205 end
204 end
206 end
205
207
206 def test_reschuling_a_parent_should_not_reschedule_subtasks_with_parent_issue_dates_set_to_independent
208 def test_reschuling_a_parent_should_not_reschedule_subtasks_with_parent_issue_dates_set_to_independent
207 with_settings :parent_issue_dates => 'independent' do
209 with_settings :parent_issue_dates => 'independent' do
208 parent = Issue.generate!(:start_date => '2010-05-01', :due_date => '2010-05-20')
210 parent = Issue.generate!(:start_date => '2010-05-01', :due_date => '2010-05-20')
209 c1 = parent.generate_child!(:start_date => '2010-05-12', :due_date => '2010-05-18')
211 c1 = parent.generate_child!(:start_date => '2010-05-12', :due_date => '2010-05-18')
210 parent.reload.reschedule_on!(Date.parse('2010-06-01'))
212 parent.reload.reschedule_on!(Date.parse('2010-06-01'))
211 assert_equal Date.parse('2010-06-01'), parent.reload.start_date
213 assert_equal Date.parse('2010-06-01'), parent.reload.start_date
212 c1.reload
214 c1.reload
213 assert_equal [Date.parse('2010-05-12'), Date.parse('2010-05-18')], [c1.start_date, c1.due_date]
215 assert_equal [Date.parse('2010-05-12'), Date.parse('2010-05-18')], [c1.start_date, c1.due_date]
214 end
216 end
215 end
217 end
216
218
217 def test_parent_priority_should_be_editable_with_parent_issue_priority_set_to_independent
219 def test_parent_priority_should_be_editable_with_parent_issue_priority_set_to_independent
218 with_settings :parent_issue_priority => 'independent' do
220 with_settings :parent_issue_priority => 'independent' do
219 issue = Issue.generate_with_child!
221 issue = Issue.generate_with_child!
220 user = User.find(1)
222 user = User.find(1)
221 assert issue.safe_attribute?('priority_id', user)
223 assert issue.safe_attribute?('priority_id', user)
222 end
224 end
223 end
225 end
224
226
225 def test_parent_priority_should_not_be_updated_with_parent_issue_priority_set_to_independent
227 def test_parent_priority_should_not_be_updated_with_parent_issue_priority_set_to_independent
226 with_settings :parent_issue_priority => 'independent' do
228 with_settings :parent_issue_priority => 'independent' do
227 parent = Issue.generate!(:priority => IssuePriority.find_by_name('Normal'))
229 parent = Issue.generate!(:priority => IssuePriority.find_by_name('Normal'))
228 child1 = parent.generate_child!(:priority => IssuePriority.find_by_name('High'))
230 child1 = parent.generate_child!(:priority => IssuePriority.find_by_name('High'))
229 assert_equal 'Normal', parent.reload.priority.name
231 assert_equal 'Normal', parent.reload.priority.name
230 end
232 end
231 end
233 end
232
234
233 def test_parent_done_ratio_should_be_editable_with_parent_issue_done_ratio_set_to_independent
235 def test_parent_done_ratio_should_be_editable_with_parent_issue_done_ratio_set_to_independent
234 with_settings :parent_issue_done_ratio => 'independent' do
236 with_settings :parent_issue_done_ratio => 'independent' do
235 issue = Issue.generate_with_child!
237 issue = Issue.generate_with_child!
236 user = User.find(1)
238 user = User.find(1)
237 assert issue.safe_attribute?('done_ratio', user)
239 assert issue.safe_attribute?('done_ratio', user)
238 end
240 end
239 end
241 end
240
242
241 def test_parent_done_ratio_should_not_be_updated_with_parent_issue_done_ratio_set_to_independent
243 def test_parent_done_ratio_should_not_be_updated_with_parent_issue_done_ratio_set_to_independent
242 with_settings :parent_issue_done_ratio => 'independent' do
244 with_settings :parent_issue_done_ratio => 'independent' do
243 parent = Issue.generate!(:done_ratio => 0)
245 parent = Issue.generate!(:done_ratio => 0)
244 child1 = parent.generate_child!(:done_ratio => 10)
246 child1 = parent.generate_child!(:done_ratio => 10)
245 assert_equal 0, parent.reload.done_ratio
247 assert_equal 0, parent.reload.done_ratio
246 end
248 end
247 end
249 end
248
250
249 def test_parent_total_estimated_hours_should_be_sum_of_descendants
251 def test_parent_total_estimated_hours_should_be_sum_of_descendants
250 parent = Issue.generate!
252 parent = Issue.generate!
251 parent.generate_child!(:estimated_hours => nil)
253 parent.generate_child!(:estimated_hours => nil)
252 assert_equal 0, parent.reload.total_estimated_hours
254 assert_equal 0, parent.reload.total_estimated_hours
253 parent.generate_child!(:estimated_hours => 5)
255 parent.generate_child!(:estimated_hours => 5)
254 assert_equal 5, parent.reload.total_estimated_hours
256 assert_equal 5, parent.reload.total_estimated_hours
255 parent.generate_child!(:estimated_hours => 7)
257 parent.generate_child!(:estimated_hours => 7)
256 assert_equal 12, parent.reload.total_estimated_hours
258 assert_equal 12, parent.reload.total_estimated_hours
257 end
259 end
258 end
260 end
General Comments 0
You need to be logged in to leave comments. Login now