comparison test/unit/issue_nested_set_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.
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 IssueNestedSetTest < ActiveSupport::TestCase 20 class IssueNestedSetTest < ActiveSupport::TestCase
21 fixtures :projects, :users, :members, :member_roles, :roles, 21 fixtures :projects, :users, :roles,
22 :trackers, :projects_trackers, 22 :trackers, :projects_trackers,
23 :versions, 23 :issue_statuses, :issue_categories, :issue_relations,
24 :issue_statuses, :issue_categories, :issue_relations, :workflows,
25 :enumerations, 24 :enumerations,
26 :issues, 25 :issues
27 :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values, 26
28 :time_entries 27 def test_new_record_is_leaf
28 i = Issue.new
29 assert i.leaf?
30 end
29 31
30 def test_create_root_issue 32 def test_create_root_issue
33 lft1 = new_issue_lft
31 issue1 = Issue.generate! 34 issue1 = Issue.generate!
35 lft2 = new_issue_lft
32 issue2 = Issue.generate! 36 issue2 = Issue.generate!
33 issue1.reload 37 issue1.reload
34 issue2.reload 38 issue2.reload
35 39 assert_equal [issue1.id, nil, lft1, lft1 + 1], [issue1.root_id, issue1.parent_id, issue1.lft, issue1.rgt]
36 assert_equal [issue1.id, nil, 1, 2], [issue1.root_id, issue1.parent_id, issue1.lft, issue1.rgt] 40 assert_equal [issue2.id, nil, lft2, lft2 + 1], [issue2.root_id, issue2.parent_id, issue2.lft, issue2.rgt]
37 assert_equal [issue2.id, nil, 1, 2], [issue2.root_id, issue2.parent_id, issue2.lft, issue2.rgt]
38 end 41 end
39 42
40 def test_create_child_issue 43 def test_create_child_issue
41 parent = Issue.generate! 44 lft = new_issue_lft
42 child = Issue.generate!(:parent_issue_id => parent.id) 45 parent = Issue.generate!
46 child = parent.generate_child!
43 parent.reload 47 parent.reload
44 child.reload 48 child.reload
45 49 assert_equal [parent.id, nil, lft, lft + 3], [parent.root_id, parent.parent_id, parent.lft, parent.rgt]
46 assert_equal [parent.id, nil, 1, 4], [parent.root_id, parent.parent_id, parent.lft, parent.rgt] 50 assert_equal [parent.id, parent.id, lft + 1, lft + 2], [child.root_id, child.parent_id, child.lft, child.rgt]
47 assert_equal [parent.id, parent.id, 2, 3], [child.root_id, child.parent_id, child.lft, child.rgt]
48 end 51 end
49 52
50 def test_creating_a_child_in_a_subproject_should_validate 53 def test_creating_a_child_in_a_subproject_should_validate
51 issue = Issue.generate! 54 issue = Issue.generate!
52 child = Issue.new(:project_id => 3, :tracker_id => 2, :author_id => 1, 55 child = Issue.new(:project_id => 3, :tracker_id => 2, :author_id => 1,
58 def test_creating_a_child_in_an_invalid_project_should_not_validate 61 def test_creating_a_child_in_an_invalid_project_should_not_validate
59 issue = Issue.generate! 62 issue = Issue.generate!
60 child = Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1, 63 child = Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
61 :subject => 'child', :parent_issue_id => issue.id) 64 :subject => 'child', :parent_issue_id => issue.id)
62 assert !child.save 65 assert !child.save
63 assert_not_nil child.errors[:parent_issue_id] 66 assert_not_equal [], child.errors[:parent_issue_id]
64 end 67 end
65 68
66 def test_move_a_root_to_child 69 def test_move_a_root_to_child
70 lft = new_issue_lft
67 parent1 = Issue.generate! 71 parent1 = Issue.generate!
68 parent2 = Issue.generate! 72 parent2 = Issue.generate!
69 child = Issue.generate!(:parent_issue_id => parent1.id) 73 child = parent1.generate_child!
70
71 parent2.parent_issue_id = parent1.id 74 parent2.parent_issue_id = parent1.id
72 parent2.save! 75 parent2.save!
73 child.reload 76 child.reload
74 parent1.reload 77 parent1.reload
75 parent2.reload 78 parent2.reload
76 79 assert_equal [parent1.id, lft, lft + 5], [parent1.root_id, parent1.lft, parent1.rgt]
77 assert_equal [parent1.id, 1, 6], [parent1.root_id, parent1.lft, parent1.rgt] 80 assert_equal [parent1.id, lft + 3, lft + 4], [parent2.root_id, parent2.lft, parent2.rgt]
78 assert_equal [parent1.id, 4, 5], [parent2.root_id, parent2.lft, parent2.rgt] 81 assert_equal [parent1.id, lft + 1, lft + 2], [child.root_id, child.lft, child.rgt]
79 assert_equal [parent1.id, 2, 3], [child.root_id, child.lft, child.rgt]
80 end 82 end
81 83
82 def test_move_a_child_to_root 84 def test_move_a_child_to_root
83 parent1 = Issue.generate! 85 lft1 = new_issue_lft
86 parent1 = Issue.generate!
87 lft2 = new_issue_lft
84 parent2 = Issue.generate! 88 parent2 = Issue.generate!
85 child = Issue.generate!(:parent_issue_id => parent1.id) 89 child = parent1.generate_child!
86
87 child.parent_issue_id = nil 90 child.parent_issue_id = nil
88 child.save! 91 child.save!
89 child.reload 92 child.reload
90 parent1.reload 93 parent1.reload
91 parent2.reload 94 parent2.reload
92 95 assert_equal [parent1.id, lft1, lft1 + 1], [parent1.root_id, parent1.lft, parent1.rgt]
93 assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt] 96 assert_equal [parent2.id, lft2, lft2 + 1], [parent2.root_id, parent2.lft, parent2.rgt]
94 assert_equal [parent2.id, 1, 2], [parent2.root_id, parent2.lft, parent2.rgt]
95 assert_equal [child.id, 1, 2], [child.root_id, child.lft, child.rgt] 97 assert_equal [child.id, 1, 2], [child.root_id, child.lft, child.rgt]
96 end 98 end
97 99
98 def test_move_a_child_to_another_issue 100 def test_move_a_child_to_another_issue
99 parent1 = Issue.generate! 101 lft1 = new_issue_lft
102 parent1 = Issue.generate!
103 lft2 = new_issue_lft
100 parent2 = Issue.generate! 104 parent2 = Issue.generate!
101 child = Issue.generate!(:parent_issue_id => parent1.id) 105 child = parent1.generate_child!
102
103 child.parent_issue_id = parent2.id 106 child.parent_issue_id = parent2.id
104 child.save! 107 child.save!
105 child.reload 108 child.reload
106 parent1.reload 109 parent1.reload
107 parent2.reload 110 parent2.reload
108 111 assert_equal [parent1.id, lft1, lft1 + 1], [parent1.root_id, parent1.lft, parent1.rgt]
109 assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt] 112 assert_equal [parent2.id, lft2, lft2 + 3], [parent2.root_id, parent2.lft, parent2.rgt]
110 assert_equal [parent2.id, 1, 4], [parent2.root_id, parent2.lft, parent2.rgt] 113 assert_equal [parent2.id, lft2 + 1, lft2 + 2], [child.root_id, child.lft, child.rgt]
111 assert_equal [parent2.id, 2, 3], [child.root_id, child.lft, child.rgt]
112 end 114 end
113 115
114 def test_move_a_child_with_descendants_to_another_issue 116 def test_move_a_child_with_descendants_to_another_issue
115 parent1 = Issue.generate! 117 lft1 = new_issue_lft
118 parent1 = Issue.generate!
119 lft2 = new_issue_lft
116 parent2 = Issue.generate! 120 parent2 = Issue.generate!
117 child = Issue.generate!(:parent_issue_id => parent1.id) 121 child = parent1.generate_child!
118 grandchild = Issue.generate!(:parent_issue_id => child.id) 122 grandchild = child.generate_child!
119
120 parent1.reload 123 parent1.reload
121 parent2.reload 124 parent2.reload
122 child.reload 125 child.reload
123 grandchild.reload 126 grandchild.reload
124 127 assert_equal [parent1.id, lft1, lft1 + 5], [parent1.root_id, parent1.lft, parent1.rgt]
125 assert_equal [parent1.id, 1, 6], [parent1.root_id, parent1.lft, parent1.rgt] 128 assert_equal [parent2.id, lft2, lft2 + 1], [parent2.root_id, parent2.lft, parent2.rgt]
126 assert_equal [parent2.id, 1, 2], [parent2.root_id, parent2.lft, parent2.rgt] 129 assert_equal [parent1.id, lft1 + 1, lft1 + 4], [child.root_id, child.lft, child.rgt]
127 assert_equal [parent1.id, 2, 5], [child.root_id, child.lft, child.rgt] 130 assert_equal [parent1.id, lft1 + 2, lft1 + 3], [grandchild.root_id, grandchild.lft, grandchild.rgt]
128 assert_equal [parent1.id, 3, 4], [grandchild.root_id, grandchild.lft, grandchild.rgt]
129
130 child.reload.parent_issue_id = parent2.id 131 child.reload.parent_issue_id = parent2.id
131 child.save! 132 child.save!
132 child.reload 133 child.reload
133 grandchild.reload 134 grandchild.reload
134 parent1.reload 135 parent1.reload
135 parent2.reload 136 parent2.reload
136 137 assert_equal [parent1.id, lft1, lft1 + 1], [parent1.root_id, parent1.lft, parent1.rgt]
137 assert_equal [parent1.id, 1, 2], [parent1.root_id, parent1.lft, parent1.rgt] 138 assert_equal [parent2.id, lft2, lft2 + 5], [parent2.root_id, parent2.lft, parent2.rgt]
138 assert_equal [parent2.id, 1, 6], [parent2.root_id, parent2.lft, parent2.rgt] 139 assert_equal [parent2.id, lft2 + 1, lft2 + 4], [child.root_id, child.lft, child.rgt]
139 assert_equal [parent2.id, 2, 5], [child.root_id, child.lft, child.rgt] 140 assert_equal [parent2.id, lft2 + 2, lft2 + 3], [grandchild.root_id, grandchild.lft, grandchild.rgt]
140 assert_equal [parent2.id, 3, 4], [grandchild.root_id, grandchild.lft, grandchild.rgt]
141 end 141 end
142 142
143 def test_move_a_child_with_descendants_to_another_project 143 def test_move_a_child_with_descendants_to_another_project
144 parent1 = Issue.generate! 144 lft1 = new_issue_lft
145 child = Issue.generate!(:parent_issue_id => parent1.id) 145 parent1 = Issue.generate!
146 grandchild = Issue.generate!(:parent_issue_id => child.id) 146 child = parent1.generate_child!
147 147 grandchild = child.generate_child!
148 child.reload 148 child.reload
149 child.project = Project.find(2) 149 child.project = Project.find(2)
150 assert child.save 150 assert child.save
151 child.reload 151 child.reload
152 grandchild.reload 152 grandchild.reload
153 parent1.reload 153 parent1.reload
154 154 assert_equal [1, parent1.id, lft1, lft1 + 1], [parent1.project_id, parent1.root_id, parent1.lft, parent1.rgt]
155 assert_equal [1, parent1.id, 1, 2], [parent1.project_id, parent1.root_id, parent1.lft, parent1.rgt]
156 assert_equal [2, child.id, 1, 4], [child.project_id, child.root_id, child.lft, child.rgt] 155 assert_equal [2, child.id, 1, 4], [child.project_id, child.root_id, child.lft, child.rgt]
157 assert_equal [2, child.id, 2, 3], [grandchild.project_id, grandchild.root_id, grandchild.lft, grandchild.rgt] 156 assert_equal [2, child.id, 2, 3], [grandchild.project_id, grandchild.root_id, grandchild.lft, grandchild.rgt]
158 end 157 end
159 158
160 def test_moving_an_issue_to_a_descendant_should_not_validate 159 def test_moving_an_issue_to_a_descendant_should_not_validate
161 parent1 = Issue.generate! 160 parent1 = Issue.generate!
162 parent2 = Issue.generate! 161 parent2 = Issue.generate!
163 child = Issue.generate!(:parent_issue_id => parent1.id) 162 child = parent1.generate_child!
164 grandchild = Issue.generate!(:parent_issue_id => child.id) 163 grandchild = child.generate_child!
165 164
166 child.reload 165 child.reload
167 child.parent_issue_id = grandchild.id 166 child.parent_issue_id = grandchild.id
168 assert !child.save 167 assert !child.save
169 assert_not_nil child.errors[:parent_issue_id] 168 assert_not_equal [], child.errors[:parent_issue_id]
170 end 169 end
171 170
172 def test_moving_an_issue_should_keep_valid_relations_only 171 def test_updating_a_root_issue_should_not_trigger_update_nested_set_attributes_on_parent_change
172 issue = Issue.find(Issue.generate!.id)
173 issue.parent_issue_id = ""
174 issue.expects(:update_nested_set_attributes_on_parent_change).never
175 issue.save!
176 end
177
178 def test_updating_a_child_issue_should_not_trigger_update_nested_set_attributes_on_parent_change
179 issue = Issue.find(Issue.generate!(:parent_issue_id => 1).id)
180 issue.parent_issue_id = "1"
181 issue.expects(:update_nested_set_attributes_on_parent_change).never
182 issue.save!
183 end
184
185 def test_moving_a_root_issue_should_trigger_update_nested_set_attributes_on_parent_change
186 issue = Issue.find(Issue.generate!.id)
187 issue.parent_issue_id = "1"
188 issue.expects(:update_nested_set_attributes_on_parent_change).once
189 issue.save!
190 end
191
192 def test_moving_a_child_issue_to_another_parent_should_trigger_update_nested_set_attributes_on_parent_change
193 issue = Issue.find(Issue.generate!(:parent_issue_id => 1).id)
194 issue.parent_issue_id = "2"
195 issue.expects(:update_nested_set_attributes_on_parent_change).once
196 issue.save!
197 end
198
199 def test_moving_a_child_issue_to_root_should_trigger_update_nested_set_attributes_on_parent_change
200 issue = Issue.find(Issue.generate!(:parent_issue_id => 1).id)
201 issue.parent_issue_id = ""
202 issue.expects(:update_nested_set_attributes_on_parent_change).once
203 issue.save!
204 end
205
206 def test_destroy_should_destroy_children
207 lft1 = new_issue_lft
173 issue1 = Issue.generate! 208 issue1 = Issue.generate!
174 issue2 = Issue.generate! 209 issue2 = Issue.generate!
175 issue3 = Issue.generate!(:parent_issue_id => issue2.id) 210 issue3 = issue2.generate_child!
176 issue4 = Issue.generate! 211 issue4 = issue1.generate_child!
177 r1 = IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
178 r2 = IssueRelation.create!(:issue_from => issue1, :issue_to => issue3, :relation_type => IssueRelation::TYPE_PRECEDES)
179 r3 = IssueRelation.create!(:issue_from => issue2, :issue_to => issue4, :relation_type => IssueRelation::TYPE_PRECEDES)
180 issue2.reload
181 issue2.parent_issue_id = issue1.id
182 issue2.save!
183 assert !IssueRelation.exists?(r1.id)
184 assert !IssueRelation.exists?(r2.id)
185 assert IssueRelation.exists?(r3.id)
186 end
187
188 def test_destroy_should_destroy_children
189 issue1 = Issue.generate!
190 issue2 = Issue.generate!
191 issue3 = Issue.generate!(:parent_issue_id => issue2.id)
192 issue4 = Issue.generate!(:parent_issue_id => issue1.id)
193
194 issue3.init_journal(User.find(2)) 212 issue3.init_journal(User.find(2))
195 issue3.subject = 'child with journal' 213 issue3.subject = 'child with journal'
196 issue3.save! 214 issue3.save!
197
198 assert_difference 'Issue.count', -2 do 215 assert_difference 'Issue.count', -2 do
199 assert_difference 'Journal.count', -1 do 216 assert_difference 'Journal.count', -1 do
200 assert_difference 'JournalDetail.count', -1 do 217 assert_difference 'JournalDetail.count', -1 do
201 Issue.find(issue2.id).destroy 218 Issue.find(issue2.id).destroy
202 end 219 end
203 end 220 end
204 end 221 end
205
206 issue1.reload 222 issue1.reload
207 issue4.reload 223 issue4.reload
208 assert !Issue.exists?(issue2.id) 224 assert !Issue.exists?(issue2.id)
209 assert !Issue.exists?(issue3.id) 225 assert !Issue.exists?(issue3.id)
210 assert_equal [issue1.id, 1, 4], [issue1.root_id, issue1.lft, issue1.rgt] 226 assert_equal [issue1.id, lft1, lft1 + 3], [issue1.root_id, issue1.lft, issue1.rgt]
211 assert_equal [issue1.id, 2, 3], [issue4.root_id, issue4.lft, issue4.rgt] 227 assert_equal [issue1.id, lft1 + 1, lft1 + 2], [issue4.root_id, issue4.lft, issue4.rgt]
212 end 228 end
213 229
214 def test_destroy_child_should_update_parent 230 def test_destroy_child_should_update_parent
231 lft1 = new_issue_lft
215 issue = Issue.generate! 232 issue = Issue.generate!
216 child1 = Issue.generate!(:parent_issue_id => issue.id) 233 child1 = issue.generate_child!
217 child2 = Issue.generate!(:parent_issue_id => issue.id) 234 child2 = issue.generate_child!
218
219 issue.reload 235 issue.reload
220 assert_equal [issue.id, 1, 6], [issue.root_id, issue.lft, issue.rgt] 236 assert_equal [issue.id, lft1, lft1 + 5], [issue.root_id, issue.lft, issue.rgt]
221
222 child2.reload.destroy 237 child2.reload.destroy
223
224 issue.reload 238 issue.reload
225 assert_equal [issue.id, 1, 4], [issue.root_id, issue.lft, issue.rgt] 239 assert_equal [issue.id, lft1, lft1 + 3], [issue.root_id, issue.lft, issue.rgt]
226 end 240 end
227 241
228 def test_destroy_parent_issue_updated_during_children_destroy 242 def test_destroy_parent_issue_updated_during_children_destroy
229 parent = Issue.generate! 243 parent = Issue.generate!
230 Issue.generate!(:start_date => Date.today, :parent_issue_id => parent.id) 244 parent.generate_child!(:start_date => Date.today)
231 Issue.generate!(:start_date => 2.days.from_now, :parent_issue_id => parent.id) 245 parent.generate_child!(:start_date => 2.days.from_now)
232 246
233 assert_difference 'Issue.count', -3 do 247 assert_difference 'Issue.count', -3 do
234 Issue.find(parent.id).destroy 248 Issue.find(parent.id).destroy
235 end 249 end
236 end 250 end
237 251
238 def test_destroy_child_issue_with_children 252 def test_destroy_child_issue_with_children
239 root = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'root') 253 root = Issue.generate!
240 child = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => root.id) 254 child = root.generate_child!
241 leaf = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'leaf', :parent_issue_id => child.id) 255 leaf = child.generate_child!
242 leaf.init_journal(User.find(2)) 256 leaf.init_journal(User.find(2))
243 leaf.subject = 'leaf with journal' 257 leaf.subject = 'leaf with journal'
244 leaf.save! 258 leaf.save!
245 259
246 assert_difference 'Issue.count', -2 do 260 assert_difference 'Issue.count', -2 do
254 root = Issue.find(root.id) 268 root = Issue.find(root.id)
255 assert root.leaf?, "Root issue is not a leaf (lft: #{root.lft}, rgt: #{root.rgt})" 269 assert root.leaf?, "Root issue is not a leaf (lft: #{root.lft}, rgt: #{root.rgt})"
256 end 270 end
257 271
258 def test_destroy_issue_with_grand_child 272 def test_destroy_issue_with_grand_child
259 parent = Issue.generate! 273 lft1 = new_issue_lft
260 issue = Issue.generate!(:parent_issue_id => parent.id) 274 parent = Issue.generate!
261 child = Issue.generate!(:parent_issue_id => issue.id) 275 issue = parent.generate_child!
262 grandchild1 = Issue.generate!(:parent_issue_id => child.id) 276 child = issue.generate_child!
263 grandchild2 = Issue.generate!(:parent_issue_id => child.id) 277 grandchild1 = child.generate_child!
264 278 grandchild2 = child.generate_child!
265 assert_difference 'Issue.count', -4 do 279 assert_difference 'Issue.count', -4 do
266 Issue.find(issue.id).destroy 280 Issue.find(issue.id).destroy
267 parent.reload 281 parent.reload
268 assert_equal [1, 2], [parent.lft, parent.rgt] 282 assert_equal [lft1, lft1 + 1], [parent.lft, parent.rgt]
269 end 283 end
270 end 284 end
271 285
272 def test_parent_priority_should_be_the_highest_child_priority 286 def test_parent_priority_should_be_the_highest_child_priority
273 parent = Issue.generate!(:priority => IssuePriority.find_by_name('Normal')) 287 parent = Issue.generate!(:priority => IssuePriority.find_by_name('Normal'))
274 # Create children 288 # Create children
275 child1 = Issue.generate!(:priority => IssuePriority.find_by_name('High'), :parent_issue_id => parent.id) 289 child1 = parent.generate_child!(:priority => IssuePriority.find_by_name('High'))
276 assert_equal 'High', parent.reload.priority.name 290 assert_equal 'High', parent.reload.priority.name
277 child2 = Issue.generate!(:priority => IssuePriority.find_by_name('Immediate'), :parent_issue_id => child1.id) 291 child2 = child1.generate_child!(:priority => IssuePriority.find_by_name('Immediate'))
278 assert_equal 'Immediate', child1.reload.priority.name 292 assert_equal 'Immediate', child1.reload.priority.name
279 assert_equal 'Immediate', parent.reload.priority.name 293 assert_equal 'Immediate', parent.reload.priority.name
280 child3 = Issue.generate!(:priority => IssuePriority.find_by_name('Low'), :parent_issue_id => parent.id) 294 child3 = parent.generate_child!(:priority => IssuePriority.find_by_name('Low'))
281 assert_equal 'Immediate', parent.reload.priority.name 295 assert_equal 'Immediate', parent.reload.priority.name
282 # Destroy a child 296 # Destroy a child
283 child1.destroy 297 child1.destroy
284 assert_equal 'Low', parent.reload.priority.name 298 assert_equal 'Low', parent.reload.priority.name
285 # Update a child 299 # Update a child
288 assert_equal 'Normal', parent.reload.priority.name 302 assert_equal 'Normal', parent.reload.priority.name
289 end 303 end
290 304
291 def test_parent_dates_should_be_lowest_start_and_highest_due_dates 305 def test_parent_dates_should_be_lowest_start_and_highest_due_dates
292 parent = Issue.generate! 306 parent = Issue.generate!
293 Issue.generate!(:start_date => '2010-01-25', :due_date => '2010-02-15', :parent_issue_id => parent.id) 307 parent.generate_child!(:start_date => '2010-01-25', :due_date => '2010-02-15')
294 Issue.generate!( :due_date => '2010-02-13', :parent_issue_id => parent.id) 308 parent.generate_child!( :due_date => '2010-02-13')
295 Issue.generate!(:start_date => '2010-02-01', :due_date => '2010-02-22', :parent_issue_id => parent.id) 309 parent.generate_child!(:start_date => '2010-02-01', :due_date => '2010-02-22')
296 parent.reload 310 parent.reload
297 assert_equal Date.parse('2010-01-25'), parent.start_date 311 assert_equal Date.parse('2010-01-25'), parent.start_date
298 assert_equal Date.parse('2010-02-22'), parent.due_date 312 assert_equal Date.parse('2010-02-22'), parent.due_date
299 end 313 end
300 314
301 def test_parent_done_ratio_should_be_average_done_ratio_of_leaves 315 def test_parent_done_ratio_should_be_average_done_ratio_of_leaves
302 parent = Issue.generate! 316 parent = Issue.generate!
303 Issue.generate!(:done_ratio => 20, :parent_issue_id => parent.id) 317 parent.generate_child!(:done_ratio => 20)
304 assert_equal 20, parent.reload.done_ratio 318 assert_equal 20, parent.reload.done_ratio
305 Issue.generate!(:done_ratio => 70, :parent_issue_id => parent.id) 319 parent.generate_child!(:done_ratio => 70)
306 assert_equal 45, parent.reload.done_ratio 320 assert_equal 45, parent.reload.done_ratio
307 321
308 child = Issue.generate!(:done_ratio => 0, :parent_issue_id => parent.id) 322 child = parent.generate_child!(:done_ratio => 0)
309 assert_equal 30, parent.reload.done_ratio 323 assert_equal 30, parent.reload.done_ratio
310 324
311 Issue.generate!(:done_ratio => 30, :parent_issue_id => child.id) 325 child.generate_child!(:done_ratio => 30)
312 assert_equal 30, child.reload.done_ratio 326 assert_equal 30, child.reload.done_ratio
313 assert_equal 40, parent.reload.done_ratio 327 assert_equal 40, parent.reload.done_ratio
314 end 328 end
315 329
316 def test_parent_done_ratio_should_be_weighted_by_estimated_times_if_any 330 def test_parent_done_ratio_should_be_weighted_by_estimated_times_if_any
317 parent = Issue.generate! 331 parent = Issue.generate!
318 Issue.generate!(:estimated_hours => 10, :done_ratio => 20, :parent_issue_id => parent.id) 332 parent.generate_child!(:estimated_hours => 10, :done_ratio => 20)
319 assert_equal 20, parent.reload.done_ratio 333 assert_equal 20, parent.reload.done_ratio
320 Issue.generate!(:estimated_hours => 20, :done_ratio => 50, :parent_issue_id => parent.id) 334 parent.generate_child!(:estimated_hours => 20, :done_ratio => 50)
321 assert_equal (50 * 20 + 20 * 10) / 30, parent.reload.done_ratio 335 assert_equal (50 * 20 + 20 * 10) / 30, parent.reload.done_ratio
322 end 336 end
323 337
338 def test_parent_done_ratio_with_child_estimate_to_0_should_reach_100
339 parent = Issue.generate!
340 issue1 = parent.generate_child!
341 issue2 = parent.generate_child!(:estimated_hours => 0)
342 assert_equal 0, parent.reload.done_ratio
343 issue1.reload.close!
344 assert_equal 50, parent.reload.done_ratio
345 issue2.reload.close!
346 assert_equal 100, parent.reload.done_ratio
347 end
348
324 def test_parent_estimate_should_be_sum_of_leaves 349 def test_parent_estimate_should_be_sum_of_leaves
325 parent = Issue.generate! 350 parent = Issue.generate!
326 Issue.generate!(:estimated_hours => nil, :parent_issue_id => parent.id) 351 parent.generate_child!(:estimated_hours => nil)
327 assert_equal nil, parent.reload.estimated_hours 352 assert_equal nil, parent.reload.estimated_hours
328 Issue.generate!(:estimated_hours => 5, :parent_issue_id => parent.id) 353 parent.generate_child!(:estimated_hours => 5)
329 assert_equal 5, parent.reload.estimated_hours 354 assert_equal 5, parent.reload.estimated_hours
330 Issue.generate!(:estimated_hours => 7, :parent_issue_id => parent.id) 355 parent.generate_child!(:estimated_hours => 7)
331 assert_equal 12, parent.reload.estimated_hours 356 assert_equal 12, parent.reload.estimated_hours
357 end
358
359 def test_done_ratio_of_parent_with_a_child_without_estimated_time_should_not_exceed_100
360 parent = Issue.generate!
361 parent.generate_child!(:estimated_hours => 40)
362 parent.generate_child!(:estimated_hours => 40)
363 parent.generate_child!(:estimated_hours => 20)
364 parent.generate_child!
365 parent.reload.children.each(&:close!)
366 assert_equal 100, parent.reload.done_ratio
367 end
368
369 def test_done_ratio_of_parent_with_a_child_with_estimated_time_at_0_should_not_exceed_100
370 parent = Issue.generate!
371 parent.generate_child!(:estimated_hours => 40)
372 parent.generate_child!(:estimated_hours => 40)
373 parent.generate_child!(:estimated_hours => 20)
374 parent.generate_child!(:estimated_hours => 0)
375 parent.reload.children.each(&:close!)
376 assert_equal 100, parent.reload.done_ratio
332 end 377 end
333 378
334 def test_move_parent_updates_old_parent_attributes 379 def test_move_parent_updates_old_parent_attributes
335 first_parent = Issue.generate! 380 first_parent = Issue.generate!
336 second_parent = Issue.generate! 381 second_parent = Issue.generate!
337 child = Issue.generate!(:estimated_hours => 5, :parent_issue_id => first_parent.id) 382 child = first_parent.generate_child!(:estimated_hours => 5)
338 assert_equal 5, first_parent.reload.estimated_hours 383 assert_equal 5, first_parent.reload.estimated_hours
339 child.update_attributes(:estimated_hours => 7, :parent_issue_id => second_parent.id) 384 child.update_attributes(:estimated_hours => 7, :parent_issue_id => second_parent.id)
340 assert_equal 7, second_parent.reload.estimated_hours 385 assert_equal 7, second_parent.reload.estimated_hours
341 assert_nil first_parent.reload.estimated_hours 386 assert_nil first_parent.reload.estimated_hours
342 end 387 end
343 388
344 def test_reschuling_a_parent_should_reschedule_subtasks 389 def test_reschuling_a_parent_should_reschedule_subtasks
345 parent = Issue.generate! 390 parent = Issue.generate!
346 c1 = Issue.generate!(:start_date => '2010-05-12', :due_date => '2010-05-18', :parent_issue_id => parent.id) 391 c1 = parent.generate_child!(:start_date => '2010-05-12', :due_date => '2010-05-18')
347 c2 = Issue.generate!(:start_date => '2010-06-03', :due_date => '2010-06-10', :parent_issue_id => parent.id) 392 c2 = parent.generate_child!(:start_date => '2010-06-03', :due_date => '2010-06-10')
348 parent.reload 393 parent.reload
349 parent.reschedule_on!(Date.parse('2010-06-02')) 394 parent.reschedule_on!(Date.parse('2010-06-02'))
350 c1.reload 395 c1.reload
351 assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-08')], [c1.start_date, c1.due_date] 396 assert_equal [Date.parse('2010-06-02'), Date.parse('2010-06-08')], [c1.start_date, c1.due_date]
352 c2.reload 397 c2.reload
356 end 401 end
357 402
358 def test_project_copy_should_copy_issue_tree 403 def test_project_copy_should_copy_issue_tree
359 p = Project.create!(:name => 'Tree copy', :identifier => 'tree-copy', :tracker_ids => [1, 2]) 404 p = Project.create!(:name => 'Tree copy', :identifier => 'tree-copy', :tracker_ids => [1, 2])
360 i1 = Issue.generate!(:project => p, :subject => 'i1') 405 i1 = Issue.generate!(:project => p, :subject => 'i1')
361 i2 = Issue.generate!(:project => p, :subject => 'i2', :parent_issue_id => i1.id) 406 i2 = i1.generate_child!(:project => p, :subject => 'i2')
362 i3 = Issue.generate!(:project => p, :subject => 'i3', :parent_issue_id => i1.id) 407 i3 = i1.generate_child!(:project => p, :subject => 'i3')
363 i4 = Issue.generate!(:project => p, :subject => 'i4', :parent_issue_id => i2.id) 408 i4 = i2.generate_child!(:project => p, :subject => 'i4')
364 i5 = Issue.generate!(:project => p, :subject => 'i5') 409 i5 = Issue.generate!(:project => p, :subject => 'i5')
365 c = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1, 2]) 410 c = Project.new(:name => 'Copy', :identifier => 'copy', :tracker_ids => [1, 2])
366 c.copy(p, :only => 'issues') 411 c.copy(p, :only => 'issues')
367 c.reload 412 c.reload
368 413
369 assert_equal 5, c.issues.count 414 assert_equal 5, c.issues.count
370 ic1, ic2, ic3, ic4, ic5 = c.issues.find(:all, :order => 'subject') 415 ic1, ic2, ic3, ic4, ic5 = c.issues.order('subject').all
371 assert ic1.root? 416 assert ic1.root?
372 assert_equal ic1, ic2.parent 417 assert_equal ic1, ic2.parent
373 assert_equal ic1, ic3.parent 418 assert_equal ic1, ic3.parent
374 assert_equal ic2, ic4.parent 419 assert_equal ic2, ic4.parent
375 assert ic5.root? 420 assert ic5.root?