Project

General

Profile

Defect #13654 ยป defect-13654.diff

Patch by 62mkv (rev. 1) - Kirill Marchuk, 2015-12-09 18:22

View differences:

app/models/issue.rb
660 660
    elsif @parent_issue
661 661
      if !valid_parent_project?(@parent_issue)
662 662
        errors.add :parent_issue_id, :invalid
663
      elsif (@parent_issue != parent) && (all_dependent_issues.include?(@parent_issue) || @parent_issue.all_dependent_issues.include?(self))
663
      elsif (@parent_issue != parent) && (@parent_issue.blocks_or_precedes?(self))
664 664
        errors.add :parent_issue_id, :invalid
665 665
      elsif !new_record?
666 666
        # moving an existing issue
......
1132 1132
    dependencies
1133 1133
  end
1134 1134

  
1135
  # Returns true if this issue blocks or precedes another issue, otherwise returns false
1136
  def blocks_or_precedes?(other)
1137
     return true if self == other
1138
     i_all = [self]
1139
     i_last = [self]
1140
     while i_last.length>0 do
1141
        i_current = []
1142
        i_last.collect do |i|
1143
            i.relations_from.find_all {|ir| ir.relation_type == IssueRelation::TYPE_PRECEDES || ir.relation_type == IssueRelation::TYPE_BLOCKS }.
1144
             collect { |ir| ir.issue_to }.
1145
             collect { |i| i_current << i if (!i_all.include? i) && (!i_last.include? i) && (!i_current.include? i)}
1146
        end
1147
      
1148
        # collect parents for all of the "last" issues
1149
        i_last.collect { |i| i_current << Issue.find_by_id(i.parent_issue_id) if !i.parent_issue_id.nil? }
1150
        
1151
        return true if i_current.include? other
1152
        
1153
        i_last = i_current
1154
        i_all = i_all.concat(i_last)
1155
     end    
1156
     
1157
     return false
1158
  end
1159

  
1135 1160
  # Returns an array of issues that duplicate this one
1136 1161
  def duplicates
1137 1162
    relations_to.select {|r| r.relation_type == IssueRelation::TYPE_DUPLICATES}.collect {|r| r.issue_from}
test/unit/issue_test.rb
1690 1690
    assert closed_statuses.empty?
1691 1691
  end
1692 1692

  
1693
def test_blocks_or_precedes_with_parent
1694
    issue1 = Issue.generate!
1695
    issue2 = Issue.generate!
1696
    issue3 = Issue.generate!
1697
    issue4 = Issue.generate!
1698
     
1699
    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
1700
    issue2.parent_issue_id = issue3.id
1701
    issue2.save
1702
    IssueRelation.create!(:issue_from => issue3, :issue_to => issue4, :relation_type => IssueRelation::TYPE_BLOCKS)
1703
    
1704
    assert issue1.blocks_or_precedes?(issue2), "issue1 should be blocking/preceding issue2" 
1705
    assert issue1.blocks_or_precedes?(issue3), "issue1 should be blocking/preceding issue3" 
1706
    assert issue1.blocks_or_precedes?(issue4), "issue1 should be blocking/preceding issue4" 
1707
    
1708
    assert !issue2.blocks_or_precedes?(issue1), "issue2 should NOT be blocking/preceding issue1" 
1709
    assert issue2.blocks_or_precedes?(issue3), "issue2 should be blocking/preceding issue3" 
1710
    assert issue2.blocks_or_precedes?(issue4), "issue2 should be blocking/preceding issue4" 
1711
    
1712
    assert !issue3.blocks_or_precedes?(issue1), "issue3 should NOT be blocking/preceding issue1" 
1713
    assert !issue3.blocks_or_precedes?(issue2), "issue3 should NOT be blocking/preceding issue2" 
1714
    assert issue3.blocks_or_precedes?(issue4), "issue3 should be blocking/preceding issue4" 
1715

  
1716
    assert !issue4.blocks_or_precedes?(issue1), "issue4 should be blocking/preceding issue1" 
1717
    assert !issue4.blocks_or_precedes?(issue2), "issue4 should be blocking/preceding issue2" 
1718
    assert !issue4.blocks_or_precedes?(issue3), "issue4 should be blocking/preceding issue3" 
1719
      
1720
  end
1721
  
1693 1722
  def test_unblocked_issues_allow_closed_statuses
1694 1723
    blocking_issue = Issue.find(10)
1695 1724

  
......
1848 1877
    end
1849 1878
  end
1850 1879

  
1851
  def test_setting_parent_to_a_dependent_issue_should_not_validate
1880
  # this is to make sure that Defect #13654 is Solved
1881
  def test_setting_parent_to_a_parent_of_related_issue_should_validate
1852 1882
    set_language_if_valid 'en'
1853 1883
    issue1 = Issue.generate!
1854 1884
    issue2 = Issue.generate!
1885
    issue2.parent_issue_id = issue1.id
1886
    issue2.save!
1855 1887
    issue3 = Issue.generate!
1856
    IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
1857
    IssueRelation.create!(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_PRECEDES)
1888
    IssueRelation.create!(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
1858 1889
    issue3.reload
1859 1890
    issue3.parent_issue_id = issue2.id
1860
    assert !issue3.valid?
1861
    assert_include 'Parent task is invalid', issue3.errors.full_messages
1891
    assert issue3.valid?
1862 1892
  end
1863 1893

  
1894
  # this is to make sure that Defect #8794 is Solved
1864 1895
  def test_setting_parent_should_not_allow_circular_dependency
1865 1896
    set_language_if_valid 'en'
1866 1897
    issue1 = Issue.generate!
    (1-1/1)