##// END OF EJS Templates
Fixed circular dependencies possibly introduced when using reverse relations, for instance "blocked by" relations (#8616)....
Jean-Baptiste Barth -
r6004:f982c5b90d52
parent child
Show More
@@ -47,7 +47,12 class IssueRelation < ActiveRecord::Base
47 if issue_from && issue_to
47 if issue_from && issue_to
48 errors.add :issue_to_id, :invalid if issue_from_id == issue_to_id
48 errors.add :issue_to_id, :invalid if issue_from_id == issue_to_id
49 errors.add :issue_to_id, :not_same_project unless issue_from.project_id == issue_to.project_id || Setting.cross_project_issue_relations?
49 errors.add :issue_to_id, :not_same_project unless issue_from.project_id == issue_to.project_id || Setting.cross_project_issue_relations?
50 errors.add_to_base :circular_dependency if issue_to.all_dependent_issues.include? issue_from
50 #detect circular dependencies depending wether the relation should be reversed
51 if TYPES.has_key?(relation_type) && TYPES[relation_type][:reverse]
52 errors.add_to_base :circular_dependency if issue_from.all_dependent_issues.include? issue_to
53 else
54 errors.add_to_base :circular_dependency if issue_to.all_dependent_issues.include? issue_from
55 end
51 errors.add_to_base :cant_link_an_issue_with_a_descendant if issue_from.is_descendant_of?(issue_to) || issue_from.is_ancestor_of?(issue_to)
56 errors.add_to_base :cant_link_an_issue_with_a_descendant if issue_from.is_descendant_of?(issue_to) || issue_from.is_ancestor_of?(issue_to)
52 end
57 end
53 end
58 end
@@ -74,6 +74,8 class IssueRelationsControllerTest < ActionController::TestCase
74 :relation => {:issue_to_id => '4', :relation_type => 'relates', :delay => ''}
74 :relation => {:issue_to_id => '4', :relation_type => 'relates', :delay => ''}
75 end
75 end
76 end
76 end
77
78 should "prevent relation creation when there's a circular dependency"
77
79
78 def test_destroy
80 def test_destroy
79 assert_difference 'IssueRelation.count', -1 do
81 assert_difference 'IssueRelation.count', -1 do
@@ -44,6 +44,9 class IssueRelationTest < ActiveSupport::TestCase
44 assert_equal from, relation.issue_to
44 assert_equal from, relation.issue_to
45 end
45 end
46
46
47 # TODO : document why it shouldn't be reversed if validation fails : having
48 # relations reversed before the validation would allow simpler code for the
49 # validation
47 def test_follows_relation_should_not_be_reversed_if_validation_fails
50 def test_follows_relation_should_not_be_reversed_if_validation_fails
48 from = Issue.find(1)
51 from = Issue.find(1)
49 to = Issue.find(2)
52 to = Issue.find(2)
@@ -82,4 +85,13 class IssueRelationTest < ActiveSupport::TestCase
82 assert !r.save
85 assert !r.save
83 assert_not_nil r.errors.on(:base)
86 assert_not_nil r.errors.on(:base)
84 end
87 end
88
89 def test_validates_circular_dependency_on_reverse_relations
90 IssueRelation.delete_all
91 assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(3), :relation_type => IssueRelation::TYPE_BLOCKS)
92 assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => IssueRelation::TYPE_BLOCKED)
93 r = IssueRelation.new(:issue_from => Issue.find(2), :issue_to => Issue.find(1), :relation_type => IssueRelation::TYPE_BLOCKED)
94 assert !r.save
95 assert_not_nil r.errors.on(:base)
96 end
85 end
97 end
General Comments 0
You need to be logged in to leave comments. Login now