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 »