Project

General

Profile

Defect #17068 » 0001-Copy-relations-between-subtasks-when-copying-an-issu.patch

Florian Walchshofer, 2026-10-19 23:18

View differences:

app/models/issue.rb
1849 1849
        end
1850 1850
        copied_issue_ids[child.id] = copy.id
1851 1851
      end
1852

  
1853
      # Copy the relations between the copied subtasks
1854
      IssueRelation.where(:issue_from_id => copied_issue_ids.keys,
1855
                          :issue_to_id => copied_issue_ids.keys).each do |source_relation|
1856
        relation = IssueRelation.new
1857
        relation.attributes = source_relation.attributes.except('id', 'issue_from_id', 'issue_to_id')
1858
        relation.issue_from_id = copied_issue_ids[source_relation.issue_from_id]
1859
        relation.issue_to_id = copied_issue_ids[source_relation.issue_to_id]
1860
        unless relation.save
1861
          if logger
1862
            logger.error(
1863
              "Could not copy relation ##{source_relation.id} " \
1864
                "while copying ##{@copied_from.id} to ##{id} due to validation errors: " \
1865
                "#{relation.errors.full_messages.join(', ')}"
1866
            )
1867
          end
1868
        end
1869
      end
1852 1870
    end
1853 1871
    @after_create_from_copy_handled = true
1854 1872
  end
test/unit/issue_test.rb
1475 1475
    assert_equal copy.author, child_copy.author
1476 1476
  end
1477 1477

  
1478
  def test_copy_should_copy_relations_between_subtasks
1479
    parent = Issue.generate!
1480
    child1 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child1')
1481
    child2 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child2')
1482
    child21 = Issue.generate!(:parent_issue_id => child2.id, :subject => 'Child21')
1483
    other = Issue.generate!
1484
    IssueRelation.create!(:issue_from => child1, :issue_to => child2,
1485
                          :relation_type => IssueRelation::TYPE_PRECEDES, :delay => 2)
1486
    IssueRelation.create!(:issue_from => child1, :issue_to => child21,
1487
                          :relation_type => IssueRelation::TYPE_BLOCKS)
1488
    IssueRelation.create!(:issue_from => child1, :issue_to => other,
1489
                          :relation_type => IssueRelation::TYPE_RELATES)
1490

  
1491
    copy = parent.reload.copy
1492
    copy.author = User.find(7)
1493
    # copied_to relations for the issue and its 3 subtasks, and the 2 relations between subtasks
1494
    assert_difference 'IssueRelation.count', 4 + 2 do
1495
      assert copy.save
1496
    end
1497

  
1498
    copies = copy.reload.descendants.index_by(&:subject)
1499
    assert_equal [[copies['Child2'].id, IssueRelation::TYPE_PRECEDES, 2],
1500
                  [copies['Child21'].id, IssueRelation::TYPE_BLOCKS, nil]].sort_by(&:first),
1501
                 copies['Child1'].relations_from.map {|r| [r.issue_to_id, r.relation_type, r.delay]}.sort_by(&:first)
1502
    # Relations to issues outside of the copied subtree are not copied
1503
    assert_equal [child1.id], other.reload.relations.map(&:issue_from_id)
1504
  end
1505

  
1506
  def test_copy_without_subtasks_should_not_copy_relations_between_subtasks
1507
    parent = Issue.generate!
1508
    child1 = Issue.generate!(:parent_issue_id => parent.id)
1509
    child2 = Issue.generate!(:parent_issue_id => parent.id)
1510
    IssueRelation.create!(:issue_from => child1, :issue_to => child2,
1511
                          :relation_type => IssueRelation::TYPE_PRECEDES)
1512

  
1513
    copy = parent.reload.copy({}, :subtasks => false)
1514
    copy.author = User.find(7)
1515
    assert_difference 'IssueRelation.count', 1 do
1516
      assert copy.save
1517
    end
1518
    assert_empty copy.reload.descendants
1519
  end
1520

  
1478 1521
  def test_copy_as_a_child_of_copied_issue_should_not_copy_itself
1479 1522
    parent = Issue.generate!
1480 1523
    child1 = Issue.generate!(:parent_issue_id => parent.id, :subject => 'Child 1')
(4-4/4)