##// END OF EJS Templates
Test for #14798....
Jean-Philippe Lang -
r11902:ae7304dd005a
parent child
Show More
@@ -1,358 +1,369
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2013 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class IssueNestedSetTest < ActiveSupport::TestCase
21 21 fixtures :projects, :users, :roles,
22 22 :trackers, :projects_trackers,
23 23 :issue_statuses, :issue_categories, :issue_relations,
24 24 :enumerations,
25 25 :issues
26 26
27 27 def test_create_root_issue
28 28 issue1 = Issue.generate!
29 29 issue2 = Issue.generate!
30 30 issue1.reload
31 31 issue2.reload
32 32
33 33 assert_equal [issue1.id, nil, 1, 2], [issue1.root_id, issue1.parent_id, issue1.lft, issue1.rgt]
34 34 assert_equal [issue2.id, nil, 1, 2], [issue2.root_id, issue2.parent_id, issue2.lft, issue2.rgt]
35 35 end
36 36
37 37 def test_create_child_issue
38 38 parent = Issue.generate!
39 39 child = Issue.generate!(:parent_issue_id => parent.id)
40 40 parent.reload
41 41 child.reload
42 42
43 43 assert_equal [parent.id, nil, 1, 4], [parent.root_id, parent.parent_id, parent.lft, parent.rgt]
44 44 assert_equal [parent.id, parent.id, 2, 3], [child.root_id, child.parent_id, child.lft, child.rgt]
45 45 end
46 46
47 47 def test_creating_a_child_in_a_subproject_should_validate
48 48 issue = Issue.generate!
49 49 child = Issue.new(:project_id => 3, :tracker_id => 2, :author_id => 1,
50 50 :subject => 'child', :parent_issue_id => issue.id)
51 51 assert_save child
52 52 assert_equal issue, child.reload.parent
53 53 end
54 54
55 55 def test_creating_a_child_in_an_invalid_project_should_not_validate
56 56 issue = Issue.generate!
57 57 child = Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
58 58 :subject => 'child', :parent_issue_id => issue.id)
59 59 assert !child.save
60 60 assert_not_equal [], child.errors[:parent_issue_id]
61 61 end
62 62
63 63 def test_move_a_root_to_child
64 64 parent1 = Issue.generate!
65 65 parent2 = Issue.generate!
66 66 child = Issue.generate!(:parent_issue_id => parent1.id)
67 67
68 68 parent2.parent_issue_id = parent1.id
69 69 parent2.save!
70 70 child.reload
71 71 parent1.reload
72 72 parent2.reload
73 73
74 74 assert_equal [parent1.id, 1, 6], [parent1.root_id, parent1.lft, parent1.rgt]
75 75 assert_equal [parent1.id, 4, 5], [parent2.root_id, parent2.lft, parent2.rgt]
76 76 assert_equal [parent1.id, 2, 3], [child.root_id, child.lft, child.rgt]
77 77 end
78 78
79 79 def test_move_a_child_to_root
80 80 parent1 = Issue.generate!
81 81 parent2 = Issue.generate!
82 82 child = Issue.generate!(:parent_issue_id => parent1.id)
83 83
84 84 child.parent_issue_id = nil
85 85 child.save!
86 86 child.reload
87 87 parent1.reload
88 88 parent2.reload
89 89
90 90 assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt]
91 91 assert_equal [parent2.id, 1, 2], [parent2.root_id, parent2.lft, parent2.rgt]
92 92 assert_equal [child.id, 1, 2], [child.root_id, child.lft, child.rgt]
93 93 end
94 94
95 95 def test_move_a_child_to_another_issue
96 96 parent1 = Issue.generate!
97 97 parent2 = Issue.generate!
98 98 child = Issue.generate!(:parent_issue_id => parent1.id)
99 99
100 100 child.parent_issue_id = parent2.id
101 101 child.save!
102 102 child.reload
103 103 parent1.reload
104 104 parent2.reload
105 105
106 106 assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt]
107 107 assert_equal [parent2.id, 1, 4], [parent2.root_id, parent2.lft, parent2.rgt]
108 108 assert_equal [parent2.id, 2, 3], [child.root_id, child.lft, child.rgt]
109 109 end
110 110
111 111 def test_move_a_child_with_descendants_to_another_issue
112 112 parent1 = Issue.generate!
113 113 parent2 = Issue.generate!
114 114 child = Issue.generate!(:parent_issue_id => parent1.id)
115 115 grandchild = Issue.generate!(:parent_issue_id => child.id)
116 116
117 117 parent1.reload
118 118 parent2.reload
119 119 child.reload
120 120 grandchild.reload
121 121
122 122 assert_equal [parent1.id, 1, 6], [parent1.root_id, parent1.lft, parent1.rgt]
123 123 assert_equal [parent2.id, 1, 2], [parent2.root_id, parent2.lft, parent2.rgt]
124 124 assert_equal [parent1.id, 2, 5], [child.root_id, child.lft, child.rgt]
125 125 assert_equal [parent1.id, 3, 4], [grandchild.root_id, grandchild.lft, grandchild.rgt]
126 126
127 127 child.reload.parent_issue_id = parent2.id
128 128 child.save!
129 129 child.reload
130 130 grandchild.reload
131 131 parent1.reload
132 132 parent2.reload
133 133
134 134 assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt]
135 135 assert_equal [parent2.id, 1, 6], [parent2.root_id, parent2.lft, parent2.rgt]
136 136 assert_equal [parent2.id, 2, 5], [child.root_id, child.lft, child.rgt]
137 137 assert_equal [parent2.id, 3, 4], [grandchild.root_id, grandchild.lft, grandchild.rgt]
138 138 end
139 139
140 140 def test_move_a_child_with_descendants_to_another_project
141 141 parent1 = Issue.generate!
142 142 child = Issue.generate!(:parent_issue_id => parent1.id)
143 143 grandchild = Issue.generate!(:parent_issue_id => child.id)
144 144
145 145 child.reload
146 146 child.project = Project.find(2)
147 147 assert child.save
148 148 child.reload
149 149 grandchild.reload
150 150 parent1.reload
151 151
152 152 assert_equal [1, parent1.id, 1, 2], [parent1.project_id, parent1.root_id, parent1.lft, parent1.rgt]
153 153 assert_equal [2, child.id, 1, 4], [child.project_id, child.root_id, child.lft, child.rgt]
154 154 assert_equal [2, child.id, 2, 3], [grandchild.project_id, grandchild.root_id, grandchild.lft, grandchild.rgt]
155 155 end
156 156
157 157 def test_moving_an_issue_to_a_descendant_should_not_validate
158 158 parent1 = Issue.generate!
159 159 parent2 = Issue.generate!
160 160 child = Issue.generate!(:parent_issue_id => parent1.id)
161 161 grandchild = Issue.generate!(:parent_issue_id => child.id)
162 162
163 163 child.reload
164 164 child.parent_issue_id = grandchild.id
165 165 assert !child.save
166 166 assert_not_equal [], child.errors[:parent_issue_id]
167 167 end
168 168
169 169 def test_destroy_should_destroy_children
170 170 issue1 = Issue.generate!
171 171 issue2 = Issue.generate!
172 172 issue3 = Issue.generate!(:parent_issue_id => issue2.id)
173 173 issue4 = Issue.generate!(:parent_issue_id => issue1.id)
174 174
175 175 issue3.init_journal(User.find(2))
176 176 issue3.subject = 'child with journal'
177 177 issue3.save!
178 178
179 179 assert_difference 'Issue.count', -2 do
180 180 assert_difference 'Journal.count', -1 do
181 181 assert_difference 'JournalDetail.count', -1 do
182 182 Issue.find(issue2.id).destroy
183 183 end
184 184 end
185 185 end
186 186
187 187 issue1.reload
188 188 issue4.reload
189 189 assert !Issue.exists?(issue2.id)
190 190 assert !Issue.exists?(issue3.id)
191 191 assert_equal [issue1.id, 1, 4], [issue1.root_id, issue1.lft, issue1.rgt]
192 192 assert_equal [issue1.id, 2, 3], [issue4.root_id, issue4.lft, issue4.rgt]
193 193 end
194 194
195 195 def test_destroy_child_should_update_parent
196 196 issue = Issue.generate!
197 197 child1 = Issue.generate!(:parent_issue_id => issue.id)
198 198 child2 = Issue.generate!(:parent_issue_id => issue.id)
199 199
200 200 issue.reload
201 201 assert_equal [issue.id, 1, 6], [issue.root_id, issue.lft, issue.rgt]
202 202
203 203 child2.reload.destroy
204 204
205 205 issue.reload
206 206 assert_equal [issue.id, 1, 4], [issue.root_id, issue.lft, issue.rgt]
207 207 end
208 208
209 209 def test_destroy_parent_issue_updated_during_children_destroy
210 210 parent = Issue.generate!
211 211 Issue.generate!(:start_date => Date.today, :parent_issue_id => parent.id)
212 212 Issue.generate!(:start_date => 2.days.from_now, :parent_issue_id => parent.id)
213 213
214 214 assert_difference 'Issue.count', -3 do
215 215 Issue.find(parent.id).destroy
216 216 end
217 217 end
218 218
219 219 def test_destroy_child_issue_with_children
220 220 root = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'root')
221 221 child = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => root.id)
222 222 leaf = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'leaf', :parent_issue_id => child.id)
223 223 leaf.init_journal(User.find(2))
224 224 leaf.subject = 'leaf with journal'
225 225 leaf.save!
226 226
227 227 assert_difference 'Issue.count', -2 do
228 228 assert_difference 'Journal.count', -1 do
229 229 assert_difference 'JournalDetail.count', -1 do
230 230 Issue.find(child.id).destroy
231 231 end
232 232 end
233 233 end
234 234
235 235 root = Issue.find(root.id)
236 236 assert root.leaf?, "Root issue is not a leaf (lft: #{root.lft}, rgt: #{root.rgt})"
237 237 end
238 238
239 239 def test_destroy_issue_with_grand_child
240 240 parent = Issue.generate!
241 241 issue = Issue.generate!(:parent_issue_id => parent.id)
242 242 child = Issue.generate!(:parent_issue_id => issue.id)
243 243 grandchild1 = Issue.generate!(:parent_issue_id => child.id)
244 244 grandchild2 = Issue.generate!(:parent_issue_id => child.id)
245 245
246 246 assert_difference 'Issue.count', -4 do
247 247 Issue.find(issue.id).destroy
248 248 parent.reload
249 249 assert_equal [1, 2], [parent.lft, parent.rgt]
250 250 end
251 251 end
252 252
253 253 def test_parent_priority_should_be_the_highest_child_priority
254 254 parent = Issue.generate!(:priority => IssuePriority.find_by_name('Normal'))
255 255 # Create children
256 256 child1 = Issue.generate!(:priority => IssuePriority.find_by_name('High'), :parent_issue_id => parent.id)
257 257 assert_equal 'High', parent.reload.priority.name
258 258 child2 = Issue.generate!(:priority => IssuePriority.find_by_name('Immediate'), :parent_issue_id => child1.id)
259 259 assert_equal 'Immediate', child1.reload.priority.name
260 260 assert_equal 'Immediate', parent.reload.priority.name
261 261 child3 = Issue.generate!(:priority => IssuePriority.find_by_name('Low'), :parent_issue_id => parent.id)
262 262 assert_equal 'Immediate', parent.reload.priority.name
263 263 # Destroy a child
264 264 child1.destroy
265 265 assert_equal 'Low', parent.reload.priority.name
266 266 # Update a child
267 267 child3.reload.priority = IssuePriority.find_by_name('Normal')
268 268 child3.save!
269 269 assert_equal 'Normal', parent.reload.priority.name
270 270 end
271 271
272 272 def test_parent_dates_should_be_lowest_start_and_highest_due_dates
273 273 parent = Issue.generate!
274 274 Issue.generate!(:start_date => '2010-01-25', :due_date => '2010-02-15', :parent_issue_id => parent.id)
275 275 Issue.generate!( :due_date => '2010-02-13', :parent_issue_id => parent.id)
276 276 Issue.generate!(:start_date => '2010-02-01', :due_date => '2010-02-22', :parent_issue_id => parent.id)
277 277 parent.reload
278 278 assert_equal Date.parse('2010-01-25'), parent.start_date
279 279 assert_equal Date.parse('2010-02-22'), parent.due_date
280 280 end
281 281
282 282 def test_parent_done_ratio_should_be_average_done_ratio_of_leaves
283 283 parent = Issue.generate!
284 284 Issue.generate!(:done_ratio => 20, :parent_issue_id => parent.id)
285 285 assert_equal 20, parent.reload.done_ratio
286 286 Issue.generate!(:done_ratio => 70, :parent_issue_id => parent.id)
287 287 assert_equal 45, parent.reload.done_ratio
288 288
289 289 child = Issue.generate!(:done_ratio => 0, :parent_issue_id => parent.id)
290 290 assert_equal 30, parent.reload.done_ratio
291 291
292 292 Issue.generate!(:done_ratio => 30, :parent_issue_id => child.id)
293 293 assert_equal 30, child.reload.done_ratio
294 294 assert_equal 40, parent.reload.done_ratio
295 295 end
296 296
297 297 def test_parent_done_ratio_should_be_weighted_by_estimated_times_if_any
298 298 parent = Issue.generate!
299 299 Issue.generate!(:estimated_hours => 10, :done_ratio => 20, :parent_issue_id => parent.id)
300 300 assert_equal 20, parent.reload.done_ratio
301 301 Issue.generate!(:estimated_hours => 20, :done_ratio => 50, :parent_issue_id => parent.id)
302 302 assert_equal (50 * 20 + 20 * 10) / 30, parent.reload.done_ratio
303 303 end
304 304
305 def test_parent_done_ratio_with_child_estimate_to_0_should_reach_100
306 parent = Issue.generate!
307 issue1 = Issue.generate!(:parent_issue_id => parent.id)
308 issue2 = Issue.generate!(:parent_issue_id => parent.id, :estimated_hours => 0)
309 assert_equal 0, parent.reload.done_ratio
310 issue1.reload.update_attribute :status_id, 5
311 assert_equal 50, parent.reload.done_ratio
312 issue2.reload.update_attribute :status_id, 5
313 assert_equal 100, parent.reload.done_ratio
314 end
315
305 316 def test_parent_estimate_should_be_sum_of_leaves
306 317 parent = Issue.generate!
307 318 Issue.generate!(:estimated_hours => nil, :parent_issue_id => parent.id)
308 319 assert_equal nil, parent.reload.estimated_hours
309 320 Issue.generate!(:estimated_hours => 5, :parent_issue_id => parent.id)
310 321 assert_equal 5, parent.reload.estimated_hours
311 322 Issue.generate!(:estimated_hours => 7, :parent_issue_id => parent.id)
312 323 assert_equal 12, parent.reload.estimated_hours
313 324 end
314 325
315 326 def test_move_parent_updates_old_parent_attributes
316 327 first_parent = Issue.generate!
317 328 second_parent = Issue.generate!
318 329 child = Issue.generate!(:estimated_hours => 5, :parent_issue_id => first_parent.id)
319 330 assert_equal 5, first_parent.reload.estimated_hours
320 331 child.update_attributes(:estimated_hours => 7, :parent_issue_id => second_parent.id)
321 332 assert_equal 7, second_parent.reload.estimated_hours
322 333 assert_nil first_parent.reload.estimated_hours
323 334 end
324 335
325 336 def test_reschuling_a_parent_should_reschedule_subtasks
326 337 parent = Issue.generate!
327 338 c1 = Issue.generate!(:start_date => '2010-05-12', :due_date => '2010-05-18', :parent_issue_id => parent.id)
328 339 c2 = Issue.generate!(:start_date => '2010-06-03', :due_date => '2010-06-10', :parent_issue_id => parent.id)
329 340 parent.reload
330 341 parent.reschedule_on!(Date.parse('2010-06-02'))
331 342 c1.reload
332 343 assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-08')], [c1.start_date, c1.due_date]
333 344 c2.reload
334 345 assert_equal [Date.parse('2010-06-03'), Date.parse('2010-06-10')], [c2.start_date, c2.due_date] # no change
335 346 parent.reload
336 347 assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-10')], [parent.start_date, parent.due_date]
337 348 end
338 349
339 350 def test_project_copy_should_copy_issue_tree
340 351 p = Project.create!(:name => 'Tree copy', :identifier => 'tree-copy', :tracker_ids => [1, 2])
341 352 i1 = Issue.generate!(:project => p, :subject => 'i1')
342 353 i2 = Issue.generate!(:project => p, :subject => 'i2', :parent_issue_id => i1.id)
343 354 i3 = Issue.generate!(:project => p, :subject => 'i3', :parent_issue_id => i1.id)
344 355 i4 = Issue.generate!(:project => p, :subject => 'i4', :parent_issue_id => i2.id)
345 356 i5 = Issue.generate!(:project => p, :subject => 'i5')
346 357 c = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1, 2])
347 358 c.copy(p, :only => 'issues')
348 359 c.reload
349 360
350 361 assert_equal 5, c.issues.count
351 362 ic1, ic2, ic3, ic4, ic5 = c.issues.order('subject').all
352 363 assert ic1.root?
353 364 assert_equal ic1, ic2.parent
354 365 assert_equal ic1, ic3.parent
355 366 assert_equal ic2, ic4.parent
356 367 assert ic5.root?
357 368 end
358 369 end
General Comments 0
You need to be logged in to leave comments. Login now