summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2016-02-26 12:04:29 +0100
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2016-03-17 07:39:15 +0100
commit3c493c24c70f7c8dc8e1f3bcf29e18d1ef0944a7 (patch)
tree1f89261db74631a92f2ef5187ff0785a41b49333
parentefd8251751c85285e6519fd3dd756f74579da15b (diff)
downloadgitlab-ce-3c493c24c70f7c8dc8e1f3bcf29e18d1ef0944a7.tar.gz
Add reference unfold pipeline used when moving issue
-rw-r--r--app/services/issues/move_service.rb11
-rw-r--r--lib/banzai/filter/reference_unfold_filter.rb46
-rw-r--r--lib/banzai/pipeline/reference_unfold_pipeline.rb9
-rw-r--r--spec/lib/banzai/pipeline/reference_unfold_pipeline_spec.rb59
-rw-r--r--spec/services/issues/move_service_spec.rb4
5 files changed, 123 insertions, 6 deletions
diff --git a/app/services/issues/move_service.rb b/app/services/issues/move_service.rb
index a404a64cfe9..cf935f30ce3 100644
--- a/app/services/issues/move_service.rb
+++ b/app/services/issues/move_service.rb
@@ -86,10 +86,13 @@ module Issues
:snippets, :commits, :commit_ranges]
cross_project_mentionables.each do |type|
- references.public_send(type).each do |mentionable|
- new_content.gsub!(mentionable.to_reference,
- mentionable.to_reference(@project_new))
- end
+ referables = references.public_send(type)
+
+ context = { objects: referables, project: @project_new,
+ pipeline: :reference_unfold }
+
+ new_content = Banzai.render_result(new_content, context)
+ new_content = new_content[:output].to_s
end
new_content
diff --git a/lib/banzai/filter/reference_unfold_filter.rb b/lib/banzai/filter/reference_unfold_filter.rb
new file mode 100644
index 00000000000..a6145261651
--- /dev/null
+++ b/lib/banzai/filter/reference_unfold_filter.rb
@@ -0,0 +1,46 @@
+module Banzai
+ module Filter
+ ##
+ # Filter than unfolds local references.
+ #
+ # Replaces all local references with project cross reference version
+ # in all objects passed to this filter in context.
+ #
+ # Requires objects array with each element implementing `Referable`.
+ #
+ class ReferenceUnfoldFilter < ReferenceFilter
+ def initialize(*)
+ super
+
+ @objects = context[:objects]
+ @project = context[:project]
+
+ unless @objects.all? { |object| object.respond_to?(:to_reference) }
+ raise StandardError, "No `to_reference` method implemented in one of the objects !"
+ end
+
+ unless @project.kind_of?(Project)
+ raise StandardError, 'No valid project passed in context!'
+ end
+ end
+
+ def call
+ @objects.each do |object|
+ pattern = /#{Regexp.escape(object.to_reference)}/
+ replace_text_nodes_matching(pattern) do |content|
+ content.gsub(pattern, object.to_reference(@project))
+ end
+ end
+
+ doc
+ end
+
+ private
+
+ def validate
+ needs :project
+ needs :objects
+ end
+ end
+ end
+end
diff --git a/lib/banzai/pipeline/reference_unfold_pipeline.rb b/lib/banzai/pipeline/reference_unfold_pipeline.rb
new file mode 100644
index 00000000000..5b555d7c2d7
--- /dev/null
+++ b/lib/banzai/pipeline/reference_unfold_pipeline.rb
@@ -0,0 +1,9 @@
+module Banzai
+ module Pipeline
+ class ReferenceUnfoldPipeline < BasePipeline
+ def self.filters
+ [Filter::ReferenceUnfoldFilter]
+ end
+ end
+ end
+end
diff --git a/spec/lib/banzai/pipeline/reference_unfold_pipeline_spec.rb b/spec/lib/banzai/pipeline/reference_unfold_pipeline_spec.rb
new file mode 100644
index 00000000000..af9d6f4ad0d
--- /dev/null
+++ b/spec/lib/banzai/pipeline/reference_unfold_pipeline_spec.rb
@@ -0,0 +1,59 @@
+require 'spec_helper'
+
+describe Banzai::Pipeline::ReferenceUnfoldPipeline do
+ let(:text) { 'some text' }
+ let(:project) { create(:project) }
+ let(:objects) { [] }
+
+ let(:result) do
+ described_class.to_html(text, project: project, objects: objects)
+ end
+
+ context 'invalid initializers' do
+ subject { -> { result } }
+
+ context 'project context is invalid' do
+ let(:project) { nil }
+ it { is_expected.to raise_error StandardError, /No valid project/ }
+ end
+
+ context 'objects context is invalid' do
+ let(:objects) { ['issue'] }
+ it { is_expected.to raise_error StandardError, /No `to_reference` method/ }
+ end
+ end
+
+ context 'multiple issues and merge requests referenced' do
+ subject { result }
+
+ let(:main_project) { create(:project) }
+
+ let(:issue_first) { create(:issue, project: main_project) }
+ let(:issue_second) { create(:issue, project: main_project) }
+ let(:merge_request) { create(:merge_request, source_project: main_project) }
+
+ let(:objects) { [issue_first, issue_second, merge_request] }
+
+ context 'plain text description' do
+ let(:text) { 'Description that references #1, #2 and !1' }
+
+ it { is_expected.to include issue_first.to_reference(project) }
+ it { is_expected.to include issue_second.to_reference(project) }
+ it { is_expected.to include merge_request.to_reference(project) }
+ end
+
+ context 'description with ignored elements' do
+ let(:text) do
+ <<-EOF
+ Hi. This references #1, but not `#2`
+ <pre>and not !1</pre>
+ EOF
+ end
+
+
+ it { is_expected.to include issue_first.to_reference(project) }
+ it { is_expected.to_not include issue_second.to_reference(project) }
+ it { is_expected.to_not include merge_request.to_reference(project) }
+ end
+ end
+end
diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb
index cd051175612..d516bd4830a 100644
--- a/spec/services/issues/move_service_spec.rb
+++ b/spec/services/issues/move_service_spec.rb
@@ -11,7 +11,7 @@ describe Issues::MoveService, services: true do
let(:old_issue) do
create(:issue, title: title, description: description,
- project: old_project, author: author)
+ project: old_project, author: author)
end
let(:move_service) do
@@ -133,7 +133,7 @@ describe Issues::MoveService, services: true do
before do
create(:merge_request, source_project: old_project)
create(:note, noteable: old_issue, project: old_project, author: author,
- note: 'Note with reference to merge request !1')
+ note: 'Note with reference to merge request !1')
end
include_context 'issue move executed'