annotate test/unit/issue_nested_set_test.rb @ 1082:997f6d7738f7 bug_531

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