Skip to content
Snippets Groups Projects
Commit 9124ebce authored by Grzegorz Bizon's avatar Grzegorz Bizon
Browse files

Use internal reference extractor in banzai unfold pipeline

parent 3c493c24
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -72,30 +72,22 @@ module Issues
end
 
def add_moved_from_note
SystemNoteService.noteable_moved(:from, @issue_new, @project_new, @issue_old, @current_user)
SystemNoteService.noteable_moved(:from, @issue_new, @project_new,
@issue_old, @current_user)
end
 
def add_moved_to_note
SystemNoteService.noteable_moved(:to, @issue_old, @project_old, @issue_new, @current_user)
SystemNoteService.noteable_moved(:to, @issue_old, @project_old,
@issue_new, @current_user)
end
 
def rewrite_references(noteable)
references = noteable.all_references
new_content = noteable_content(noteable).dup
cross_project_mentionables = [:issues, :merge_requests, :milestones,
:snippets, :commits, :commit_ranges]
content = noteable_content(noteable).dup
context = { pipeline: :reference_unfold,
project: @project_old, new_project: @project_new }
 
cross_project_mentionables.each do |type|
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
new_content = Banzai.render_result(content, context)
new_content[:output].to_s
end
 
def noteable_content(noteable)
Loading
Loading
require 'html/pipeline/filter'
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
class ReferenceUnfoldFilter < HTML::Pipeline::Filter
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 !"
unless result[:references].is_a?(Hash)
raise StandardError, 'References not processed!'
end
 
unless @project.kind_of?(Project)
raise StandardError, 'No valid project passed in context!'
end
@text = context[:text].dup
@new_project = context[:new_project]
@referables = result[:references].values.flatten
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
@referables.each do |referable|
pattern = /#{Regexp.escape(referable.to_reference)}/
@text.gsub!(pattern, referable.to_reference(@new_project))
end
 
doc
@text
end
 
private
 
def validate
needs :project
needs :objects
needs :new_project
needs :text
end
end
end
Loading
Loading
Loading
Loading
@@ -2,7 +2,19 @@ module Banzai
module Pipeline
class ReferenceUnfoldPipeline < BasePipeline
def self.filters
[Filter::ReferenceUnfoldFilter]
FullPipeline.filters +
[Filter::ReferenceGathererFilter,
Filter::ReferenceUnfoldFilter]
end
def self.call(text, context = {})
context = context.merge(text: text)
super
end
class << self
alias_method :to_document, :call
alias_method :to_html, :call
end
end
end
Loading
Loading
Loading
Loading
@@ -2,58 +2,61 @@ require 'spec_helper'
 
describe Banzai::Pipeline::ReferenceUnfoldPipeline do
let(:text) { 'some text' }
let(:project) { create(:project) }
let(:objects) { [] }
let(:old_project) { create(:project) }
let(:new_project) { create(:project) }
let(:pipeline_context) do
{ project: old_project, new_project: new_project }
end
 
let(:result) do
described_class.to_html(text, project: project, objects: objects)
described_class.to_document(text, pipeline_context)
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/ }
context 'project context is missing' do
let(:pipeline_context) { { new_project: new_project } }
it { is_expected.to raise_error ArgumentError, /Missing context keys/ }
end
 
context 'objects context is invalid' do
let(:objects) { ['issue'] }
it { is_expected.to raise_error StandardError, /No `to_reference` method/ }
context 'new project context is missing' do
let(:pipeline_context) { { project: old_project } }
it { is_expected.to raise_error ArgumentError, /Missing context keys/ }
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) }
subject { result[:output] }
 
let(:objects) { [issue_first, issue_second, merge_request] }
let!(:issue_first) { create(:issue, project: old_project) }
let!(:issue_second) { create(:issue, project: old_project) }
let!(:merge_request) { create(:merge_request, source_project: old_project) }
 
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) }
it { is_expected.to include issue_first.to_reference(new_project) }
it { is_expected.to include issue_second.to_reference(new_project) }
it { is_expected.to include merge_request.to_reference(new_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
"Hi. This references #1, but not `#2`\n" +
'<pre>and not !1</pre>'
end
 
it { is_expected.to include issue_first.to_reference(new_project) }
it { is_expected.to_not include issue_second.to_reference(new_project) }
it { is_expected.to_not include merge_request.to_reference(new_project) }
end
context 'description ambigous elements' do
let(:url) { 'http://gitlab.com/#1' }
let(:text) { "This references #1, but not #{url}" }
 
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) }
it { is_expected.to include url }
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment