From befd725b8b2441787b2e48369afa54dfbb0223ed Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Sat, 15 Jan 2011 14:12:18 +0000 Subject: [PATCH] Prevent SystemStackError on Issue#all_dependent_issues with circular dependency (#7320). git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4723 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/models/issue.rb | 9 ++++++--- test/unit/issue_test.rb | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/app/models/issue.rb b/app/models/issue.rb index abea0b839..4892a71bb 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -456,11 +456,14 @@ class Issue < ActiveRecord::Base (relations_from + relations_to).sort end - def all_dependent_issues + def all_dependent_issues(except=nil) + except ||= self dependencies = [] relations_from.each do |relation| - dependencies << relation.issue_to - dependencies += relation.issue_to.all_dependent_issues + if relation.issue_to && relation.issue_to != except + dependencies << relation.issue_to + dependencies += relation.issue_to.all_dependent_issues(except) + end end dependencies end diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index 4d771d9b7..d284c7469 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -618,6 +618,25 @@ class IssueTest < ActiveSupport::TestCase end end + def test_all_dependent_issues + IssueRelation.delete_all + assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => IssueRelation::TYPE_PRECEDES) + assert IssueRelation.create!(:issue_from => Issue.find(2), :issue_to => Issue.find(3), :relation_type => IssueRelation::TYPE_PRECEDES) + assert IssueRelation.create!(:issue_from => Issue.find(3), :issue_to => Issue.find(8), :relation_type => IssueRelation::TYPE_PRECEDES) + + assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort + end + + def test_all_dependent_issues_with_persistent_circular_dependency + IssueRelation.delete_all + assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => IssueRelation::TYPE_PRECEDES) + assert IssueRelation.create!(:issue_from => Issue.find(2), :issue_to => Issue.find(3), :relation_type => IssueRelation::TYPE_PRECEDES) + # Validation skipping + assert IssueRelation.new(:issue_from => Issue.find(3), :issue_to => Issue.find(1), :relation_type => IssueRelation::TYPE_PRECEDES).save(false) + + assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort + end + context "#done_ratio" do setup do @issue = Issue.find(1) -- 2.39.5