Defect #34108 » fixed-34108-v3.patch
| app/models/issue.rb | ||
|---|---|---|
| 1930 | 1930 | # Closes duplicates if the issue is being closed | 
| 1931 | 1931 | def close_duplicates | 
| 1932 | 1932 | if Setting.close_duplicate_issues? && closing? | 
| 1933 | # Check that there are no circular dependency of relationships | |
| 1934 | duplicate_issue_ids = circular_dependency_duplicate_issue_ids(duplicates) | |
| 1935 | if duplicate_issue_ids.include?(self.id) | |
| 1936 | self.errors.add :base, :circular_dependency | |
| 1937 | throw :abort | |
| 1938 | end | |
| 1939 | ||
| 1933 | 1940 | duplicates.each do |duplicate| | 
| 1934 | 1941 | # Reload is needed in case the duplicate was updated by a previous duplicate | 
| 1935 | 1942 | duplicate.reload | 
| ... | ... | |
| 1946 | 1953 | end | 
| 1947 | 1954 | end | 
| 1948 | 1955 | |
| 1956 | def circular_dependency_duplicate_issue_ids(issues, duplicate_ids = []) | |
| 1957 | issues.each do |issue| | |
| 1958 | next if duplicate_ids.include?(issue.id) | |
| 1959 | ||
| 1960 | duplicate_ids << issue.id | |
| 1961 | duplicate_ids.concat(circular_dependency_duplicate_issue_ids(issue.duplicates, duplicate_ids)) | |
| 1962 | duplicate_ids.uniq! | |
| 1963 | end | |
| 1964 | duplicate_ids | |
| 1965 | end | |
| 1966 | ||
| 1949 | 1967 | # Make sure updated_on is updated when adding a note and set updated_on now | 
| 1950 | 1968 | # so we can set closed_on with the same value on closing | 
| 1951 | 1969 | def force_updated_on_change | 
| app/models/issue_relation.rb | ||
|---|---|---|
| 238 | 238 | issue_from.blocks? issue_to | 
| 239 | 239 | when 'blocks' | 
| 240 | 240 | issue_to.blocks? issue_from | 
| 241 | when 'duplicated' | |
| 242 | self.class.exists?(issue_from_id: issue_from, issue_to_id: issue_to, relation_type: TYPE_DUPLICATES) | |
| 243 | when 'duplicates' | |
| 244 | self.class.exists?(issue_from_id: issue_to, issue_to_id: issue_from, relation_type: TYPE_DUPLICATES) | |
| 241 | 245 | when 'relates' | 
| 242 | 246 | self.class.where(issue_from_id: issue_to, issue_to_id: issue_from).present? | 
| 243 | 247 | else | 
| test/unit/issue_relation_test.rb | ||
|---|---|---|
| 199 | 199 | assert_not_equal [], r.errors[:base] | 
| 200 | 200 | end | 
| 201 | 201 | |
| 202 | def test_validates_circular_dependency_on_reverse_relations_using_duplicates | |
| 203 | with_locale 'en' do | |
| 204 | IssueRelation.delete_all | |
| 205 | issue1 = issues(:issues_001) | |
| 206 | issue2 = issues(:issues_002) | |
| 207 | assert( | |
| 208 | IssueRelation.create!( | |
| 209 | :issue_from => issue1, :issue_to => issue2, | |
| 210 | :relation_type => IssueRelation::TYPE_DUPLICATES | |
| 211 | ) | |
| 212 | ) | |
| 213 | r = | |
| 214 | IssueRelation.new( | |
| 215 | :issue_from => issue2, :issue_to => issue1, | |
| 216 | :relation_type => IssueRelation::TYPE_DUPLICATES | |
| 217 | ) | |
| 218 | assert !r.save | |
| 219 | assert_include 'This relation would create a circular dependency', r.errors.full_messages | |
| 220 | end | |
| 221 | end | |
| 222 | ||
| 202 | 223 | def test_create_with_initialized_journals_should_create_journals | 
| 203 | 224 | from = Issue.find(1) | 
| 204 | 225 | to = Issue.find(2) | 
| test/unit/issue_test.rb | ||
|---|---|---|
| 1615 | 1615 | assert !issue1.reload.closed? | 
| 1616 | 1616 | end | 
| 1617 | 1617 | |
| 1618 | def test_should_not_close_duplicated_issue_with_multiple_circular_dependencies | |
| 1619 | IssueRelation.delete_all | |
| 1620 | issue1 = Issue.generate! | |
| 1621 | issue2 = Issue.generate! | |
| 1622 | issue3 = Issue.generate! | |
| 1623 | ||
| 1624 | IssueRelation.create(:issue_from => issue1, :issue_to => issue2, | |
| 1625 | :relation_type => IssueRelation::TYPE_DUPLICATES).save!(:validate => false) | |
| 1626 | IssueRelation.create(:issue_from => issue2, :issue_to => issue3, | |
| 1627 | :relation_type => IssueRelation::TYPE_DUPLICATES).save!(:validate => false) | |
| 1628 | IssueRelation.create(:issue_from => issue3, :issue_to => issue1, | |
| 1629 | :relation_type => IssueRelation::TYPE_DUPLICATES).save!(:validate => false) | |
| 1630 | ||
| 1631 | issue2_a = Issue.generate! | |
| 1632 | issue2_b = Issue.generate! | |
| 1633 | ||
| 1634 | IssueRelation.create(:issue_from => issue2, :issue_to => issue2_a, | |
| 1635 | :relation_type => IssueRelation::TYPE_DUPLICATES).save!(:validate => false) | |
| 1636 | IssueRelation.create(:issue_from => issue2_a, :issue_to => issue2_b, | |
| 1637 | :relation_type => IssueRelation::TYPE_DUPLICATES).save!(:validate => false) | |
| 1638 | IssueRelation.create(:issue_from => issue2_b, :issue_to => issue2, | |
| 1639 | :relation_type => IssueRelation::TYPE_DUPLICATES).save!(:validate => false) | |
| 1640 | ||
| 1641 | assert_equal 1, issue1.duplicates.count | |
| 1642 | assert_equal [issue3], issue1.duplicates | |
| 1643 | assert_equal 1, issue3.duplicates.count | |
| 1644 | assert_equal [issue2], issue3.duplicates | |
| 1645 | assert_equal 2, issue2.duplicates.count | |
| 1646 | assert_equal [issue1, issue2_b], issue2.duplicates.sort | |
| 1647 | ||
| 1648 | issue1.init_journal(users(:users_002), "Closing issue") | |
| 1649 | issue1.status = IssueStatus.where(:is_closed => true).first | |
| 1650 | assert !issue1.save | |
| 1651 | assert_include 'This relation would create a circular dependency', issue1.errors.full_messages | |
| 1652 | end | |
| 1653 | ||
| 1618 | 1654 | def test_assignable_versions | 
| 1619 | 1655 | issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, | 
| 1620 | 1656 | :status_id => 1, :fixed_version_id => 1, | 
- « Previous
- 1
- 2
- 3
- 4
- Next »