From beb20e7c6e906b1b5c892841c1948cb50df86e3e Mon Sep 17 00:00:00 2001
From: Jean-Philippe Lang <jp_lang@yahoo.fr>
Date: Fri, 18 Dec 2009 20:35:16 +0000
Subject: [PATCH] Adds 'follows' relation (#1432).

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3190 e93f8b46-1217-0410-a6f0-8f06a7374b81
---
 app/models/issue_relation.rb      | 17 +++++++++++-
 public/javascripts/application.js |  2 +-
 test/unit/issue_relation_test.rb  | 46 +++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 2 deletions(-)
 create mode 100644 test/unit/issue_relation_test.rb

diff --git a/app/models/issue_relation.rb b/app/models/issue_relation.rb
index d26292c37..2728d77aa 100644
--- a/app/models/issue_relation.rb
+++ b/app/models/issue_relation.rb
@@ -23,20 +23,24 @@ class IssueRelation < ActiveRecord::Base
   TYPE_DUPLICATES   = "duplicates"
   TYPE_BLOCKS       = "blocks"
   TYPE_PRECEDES     = "precedes"
+  TYPE_FOLLOWS      = "follows"
   
   TYPES = { TYPE_RELATES =>     { :name => :label_relates_to, :sym_name => :label_relates_to, :order => 1 },
             TYPE_DUPLICATES =>  { :name => :label_duplicates, :sym_name => :label_duplicated_by, :order => 2 },
             TYPE_BLOCKS =>      { :name => :label_blocks, :sym_name => :label_blocked_by, :order => 3 },
             TYPE_PRECEDES =>    { :name => :label_precedes, :sym_name => :label_follows, :order => 4 },
+            TYPE_FOLLOWS =>     { :name => :label_follows, :sym_name => :label_precedes, :order => 5 }
           }.freeze
   
   validates_presence_of :issue_from, :issue_to, :relation_type
-  validates_inclusion_of :relation_type, :in => TYPES.keys
+  validates_inclusion_of :relation_type, :in => [TYPE_RELATES, TYPE_DUPLICATES, TYPE_BLOCKS, TYPE_PRECEDES]
   validates_numericality_of :delay, :allow_nil => true
   validates_uniqueness_of :issue_to_id, :scope => :issue_from_id
   
   attr_protected :issue_from_id, :issue_to_id
   
+  before_validation :reverse_if_needed
+  
   def validate
     if issue_from && issue_to
       errors.add :issue_to_id, :invalid if issue_from_id == issue_to_id
@@ -78,4 +82,15 @@ class IssueRelation < ActiveRecord::Base
   def <=>(relation)
     TYPES[self.relation_type][:order] <=> TYPES[relation.relation_type][:order]
   end
+  
+  private
+  
+  def reverse_if_needed
+    if (TYPE_FOLLOWS == relation_type)
+      issue_tmp = issue_to
+      self.issue_to = issue_from
+      self.issue_from = issue_tmp
+      self.relation_type = TYPE_PRECEDES
+    end
+  end
 end
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 5221bf4ce..57419d0b0 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -124,7 +124,7 @@ function displayTabsButtons() {
 
 function setPredecessorFieldsVisibility() {
     relationType = $('relation_relation_type');
-    if (relationType && relationType.value == "precedes") {
+    if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
         Element.show('predecessor_fields');
     } else {
         Element.hide('predecessor_fields');
diff --git a/test/unit/issue_relation_test.rb b/test/unit/issue_relation_test.rb
new file mode 100644
index 000000000..cba105e73
--- /dev/null
+++ b/test/unit/issue_relation_test.rb
@@ -0,0 +1,46 @@
+# Redmine - project management software
+# Copyright (C) 2006-2009  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.dirname(__FILE__) + '/../test_helper'
+
+class IssueRelationTest < ActiveSupport::TestCase
+  fixtures :issue_relations, :issues
+
+  def test_create
+    from = Issue.find(1)
+    to = Issue.find(2)
+    
+    relation = IssueRelation.new :issue_from => from, :issue_to => to, :relation_type => IssueRelation::TYPE_PRECEDES
+    assert relation.save
+    relation.reload
+    assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type
+    assert_equal from, relation.issue_from
+    assert_equal to, relation.issue_to
+  end
+  
+  def test_follows_relation_should_be_reversed
+    from = Issue.find(1)
+    to = Issue.find(2)
+    
+    relation = IssueRelation.new :issue_from => from, :issue_to => to, :relation_type => IssueRelation::TYPE_FOLLOWS
+    assert relation.save
+    relation.reload
+    assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type
+    assert_equal to, relation.issue_from
+    assert_equal from, relation.issue_to
+  end
+end
-- 
GitLab