Recognize issue/MR/snippet/commit links as references.
This commit is contained in:
parent
a7be01cd07
commit
d6a5b45c8e
|
@ -73,16 +73,23 @@ class Commit
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
(?:#{Project.reference_pattern}#{reference_prefix})?
|
||||
(?<commit>\h{6,40})
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(?:#{Project.reference_pattern}#{reference_prefix})?
|
||||
(?<commit>\h{6,40})
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
def self.link_reference_pattern
|
||||
super("commit", /(?<commit>\h{6,40})/)
|
||||
end
|
||||
|
||||
def to_reference(from_project = nil)
|
||||
if cross_project_reference?(from_project)
|
||||
"#{project.to_reference}@#{id}"
|
||||
project.to_reference + self.class.reference_prefix + self.short_id
|
||||
else
|
||||
id
|
||||
self.short_id
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -42,11 +42,18 @@ class CommitRange
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
(?:#{Project.reference_pattern}#{reference_prefix})?
|
||||
(?<commit_range>#{PATTERN})
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(?:#{Project.reference_pattern}#{reference_prefix})?
|
||||
(?<commit_range>#{PATTERN})
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
def self.link_reference_pattern
|
||||
super("compare", /(?<commit_range>#{PATTERN})/)
|
||||
end
|
||||
|
||||
# Initialize a CommitRange
|
||||
#
|
||||
# range_string - The String commit range.
|
||||
|
|
|
@ -44,6 +44,25 @@ module Referable
|
|||
def reference_pattern
|
||||
raise NotImplementedError, "#{self} does not implement #{__method__}"
|
||||
end
|
||||
|
||||
def link_reference_pattern(route, pattern)
|
||||
%r{
|
||||
(?<url>
|
||||
#{Regexp.escape(Gitlab.config.gitlab.url)}
|
||||
\/#{Project.reference_pattern}
|
||||
\/#{Regexp.escape(route)}
|
||||
\/#{pattern}
|
||||
(?<path>
|
||||
(\/[a-z0-9_=-]+)*
|
||||
)?
|
||||
(?<query>
|
||||
\?[a-z0-9_=-]+
|
||||
(&[a-z0-9_=-]+)*
|
||||
)?
|
||||
(?<anchor>\#[a-z0-9_-]+)?
|
||||
)
|
||||
}x
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -64,11 +64,18 @@ class Issue < ActiveRecord::Base
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
(#{Project.reference_pattern})?
|
||||
#{Regexp.escape(reference_prefix)}(?<issue>\d+)
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(#{Project.reference_pattern})?
|
||||
#{Regexp.escape(reference_prefix)}(?<issue>\d+)
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
def self.link_reference_pattern
|
||||
super("issues", /(?<issue>\d+)/)
|
||||
end
|
||||
|
||||
def to_reference(from_project = nil)
|
||||
reference = "#{self.class.reference_prefix}#{iid}"
|
||||
|
||||
|
|
|
@ -146,11 +146,18 @@ class MergeRequest < ActiveRecord::Base
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
(#{Project.reference_pattern})?
|
||||
#{Regexp.escape(reference_prefix)}(?<merge_request>\d+)
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(#{Project.reference_pattern})?
|
||||
#{Regexp.escape(reference_prefix)}(?<merge_request>\d+)
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
def self.link_reference_pattern
|
||||
super("merge_requests", /(?<merge_request>\d+)/)
|
||||
end
|
||||
|
||||
def to_reference(from_project = nil)
|
||||
reference = "#{self.class.reference_prefix}#{iid}"
|
||||
|
||||
|
|
|
@ -60,11 +60,18 @@ class Snippet < ActiveRecord::Base
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
(#{Project.reference_pattern})?
|
||||
#{Regexp.escape(reference_prefix)}(?<snippet>\d+)
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(#{Project.reference_pattern})?
|
||||
#{Regexp.escape(reference_prefix)}(?<snippet>\d+)
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
def self.link_reference_pattern
|
||||
super("snippets", /(?<snippet>\d+)/)
|
||||
end
|
||||
|
||||
def to_reference(from_project = nil)
|
||||
reference = "#{self.class.reference_prefix}#{id}"
|
||||
|
||||
|
|
|
@ -181,8 +181,6 @@ module Gitlab
|
|||
Gitlab::Markdown::RelativeLinkFilter,
|
||||
Gitlab::Markdown::EmojiFilter,
|
||||
Gitlab::Markdown::TableOfContentsFilter,
|
||||
Gitlab::Markdown::AutolinkFilter,
|
||||
Gitlab::Markdown::ExternalLinkFilter,
|
||||
|
||||
Gitlab::Markdown::UserReferenceFilter,
|
||||
Gitlab::Markdown::IssueReferenceFilter,
|
||||
|
@ -193,6 +191,9 @@ module Gitlab
|
|||
Gitlab::Markdown::CommitReferenceFilter,
|
||||
Gitlab::Markdown::LabelReferenceFilter,
|
||||
|
||||
Gitlab::Markdown::AutolinkFilter,
|
||||
Gitlab::Markdown::ExternalLinkFilter,
|
||||
|
||||
Gitlab::Markdown::TaskListFilter
|
||||
]
|
||||
end
|
||||
|
|
|
@ -40,7 +40,7 @@ module Gitlab
|
|||
# Returns a String replaced with the return of the block.
|
||||
def self.references_in(text)
|
||||
text.gsub(object_class.reference_pattern) do |match|
|
||||
yield match, $~[object_sym].to_i, $~[:project]
|
||||
yield match, $~[object_sym].to_i, $~[:project], $~
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -74,26 +74,41 @@ module Gitlab
|
|||
# Returns a String with references replaced with links. All links
|
||||
# have `gfm` and `gfm-OBJECT_NAME` class names attached for styling.
|
||||
def object_link_filter(text)
|
||||
references_in(text) do |match, id, project_ref|
|
||||
references_in(text) do |match, id, project_ref, matches|
|
||||
project = project_from_ref(project_ref)
|
||||
|
||||
if project && object = find_object(project, id)
|
||||
title = escape_once("#{object_title}: #{object.title}")
|
||||
title = escape_once(object_link_title(object))
|
||||
klass = reference_class(object_sym)
|
||||
data = data_attribute(project: project.id, object_sym => object.id)
|
||||
url = url_for_object(object, project)
|
||||
data = data_attribute(project: project.id, object_sym => object.id, original: match)
|
||||
url = matches[:url] || url_for_object(object, project)
|
||||
|
||||
text = object.to_reference(context[:project])
|
||||
|
||||
extras = object_link_text_extras(object, matches)
|
||||
text += " (#{extras.join(", ")})" if extras.any?
|
||||
|
||||
%(<a href="#{url}" #{data}
|
||||
title="#{title}"
|
||||
class="#{klass}">#{match}</a>)
|
||||
class="#{klass}">#{text}</a>)
|
||||
else
|
||||
match
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def object_title
|
||||
object_class.name.titleize
|
||||
def object_link_text_extras(object, matches)
|
||||
extras = []
|
||||
|
||||
if matches[:anchor] && matches[:anchor] =~ /\A\#note_(\d+)\z/
|
||||
extras << "comment #{$1}"
|
||||
end
|
||||
|
||||
extras
|
||||
end
|
||||
|
||||
def object_link_title(object)
|
||||
"#{object_class.name.titleize}: #{object.title}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,24 +5,14 @@ module Gitlab
|
|||
# HTML filter that replaces commit range references with links.
|
||||
#
|
||||
# This filter supports cross-project references.
|
||||
class CommitRangeReferenceFilter < ReferenceFilter
|
||||
include CrossProjectReference
|
||||
class CommitRangeReferenceFilter < AbstractReferenceFilter
|
||||
def self.object_class
|
||||
CommitRange
|
||||
end
|
||||
|
||||
# Public: Find commit range references in text
|
||||
#
|
||||
# CommitRangeReferenceFilter.references_in(text) do |match, commit_range, project_ref|
|
||||
# "<a href=...>#{commit_range}</a>"
|
||||
# end
|
||||
#
|
||||
# text - String text to search.
|
||||
#
|
||||
# Yields the String match, the String commit range, and an optional String
|
||||
# of the external project reference.
|
||||
#
|
||||
# Returns a String replaced with the return of the block.
|
||||
def self.references_in(text)
|
||||
text.gsub(CommitRange.reference_pattern) do |match|
|
||||
yield match, $~[:commit_range], $~[:project]
|
||||
yield match, $~[:commit_range], $~[:project], $~
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -31,9 +21,9 @@ module Gitlab
|
|||
return unless project
|
||||
|
||||
id = node.attr("data-commit-range")
|
||||
range = CommitRange.new(id, project)
|
||||
range = find_object(project, id)
|
||||
|
||||
return unless range.valid_commits?
|
||||
return unless range
|
||||
|
||||
{ commit_range: range }
|
||||
end
|
||||
|
@ -44,49 +34,25 @@ module Gitlab
|
|||
@commit_map = {}
|
||||
end
|
||||
|
||||
def call
|
||||
replace_text_nodes_matching(CommitRange.reference_pattern) do |content|
|
||||
commit_range_link_filter(content)
|
||||
end
|
||||
def self.find_object(project, id)
|
||||
range = CommitRange.new(id, project)
|
||||
|
||||
range.valid_commits? ? range : nil
|
||||
end
|
||||
|
||||
# Replace commit range references in text with links to compare the commit
|
||||
# ranges.
|
||||
#
|
||||
# text - String text to replace references in.
|
||||
#
|
||||
# Returns a String with commit range references replaced with links. All
|
||||
# links have `gfm` and `gfm-commit_range` class names attached for
|
||||
# styling.
|
||||
def commit_range_link_filter(text)
|
||||
self.class.references_in(text) do |match, id, project_ref|
|
||||
project = self.project_from_ref(project_ref)
|
||||
|
||||
range = CommitRange.new(id, project)
|
||||
|
||||
if range.valid_commits?
|
||||
url = url_for_commit_range(project, range)
|
||||
|
||||
title = range.reference_title
|
||||
klass = reference_class(:commit_range)
|
||||
data = data_attribute(project: project.id, commit_range: id)
|
||||
|
||||
project_ref += '@' if project_ref
|
||||
|
||||
%(<a href="#{url}" #{data}
|
||||
title="#{title}"
|
||||
class="#{klass}">#{project_ref}#{range}</a>)
|
||||
else
|
||||
match
|
||||
end
|
||||
end
|
||||
def find_object(*args)
|
||||
self.class.find_object(*args)
|
||||
end
|
||||
|
||||
def url_for_commit_range(project, range)
|
||||
def url_for_object(range, project)
|
||||
h = Gitlab::Application.routes.url_helpers
|
||||
h.namespace_project_compare_url(project.namespace, project,
|
||||
range.to_param.merge(only_path: context[:only_path]))
|
||||
end
|
||||
|
||||
def object_link_title(range)
|
||||
range.reference_title
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,24 +5,14 @@ module Gitlab
|
|||
# HTML filter that replaces commit references with links.
|
||||
#
|
||||
# This filter supports cross-project references.
|
||||
class CommitReferenceFilter < ReferenceFilter
|
||||
include CrossProjectReference
|
||||
class CommitReferenceFilter < AbstractReferenceFilter
|
||||
def self.object_class
|
||||
Commit
|
||||
end
|
||||
|
||||
# Public: Find commit references in text
|
||||
#
|
||||
# CommitReferenceFilter.references_in(text) do |match, commit, project_ref|
|
||||
# "<a href=...>#{commit}</a>"
|
||||
# end
|
||||
#
|
||||
# text - String text to search.
|
||||
#
|
||||
# Yields the String match, the String commit identifier, and an optional
|
||||
# String of the external project reference.
|
||||
#
|
||||
# Returns a String replaced with the return of the block.
|
||||
def self.references_in(text)
|
||||
text.gsub(Commit.reference_pattern) do |match|
|
||||
yield match, $~[:commit], $~[:project]
|
||||
yield match, $~[:commit], $~[:project], $~
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -31,58 +21,32 @@ module Gitlab
|
|||
return unless project
|
||||
|
||||
id = node.attr("data-commit")
|
||||
commit = commit_from_ref(project, id)
|
||||
commit = find_object(project, id)
|
||||
|
||||
return unless commit
|
||||
|
||||
{ commit: commit }
|
||||
end
|
||||
|
||||
def call
|
||||
replace_text_nodes_matching(Commit.reference_pattern) do |content|
|
||||
commit_link_filter(content)
|
||||
end
|
||||
end
|
||||
|
||||
# Replace commit references in text with links to the commit specified.
|
||||
#
|
||||
# text - String text to replace references in.
|
||||
#
|
||||
# Returns a String with commit references replaced with links. All links
|
||||
# have `gfm` and `gfm-commit` class names attached for styling.
|
||||
def commit_link_filter(text)
|
||||
self.class.references_in(text) do |match, id, project_ref|
|
||||
project = self.project_from_ref(project_ref)
|
||||
|
||||
if commit = self.class.commit_from_ref(project, id)
|
||||
url = url_for_commit(project, commit)
|
||||
|
||||
title = escape_once(commit.link_title)
|
||||
klass = reference_class(:commit)
|
||||
data = data_attribute(project: project.id, commit: id)
|
||||
|
||||
project_ref += '@' if project_ref
|
||||
|
||||
%(<a href="#{url}" #{data}
|
||||
title="#{title}"
|
||||
class="#{klass}">#{project_ref}#{commit.short_id}</a>)
|
||||
else
|
||||
match
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.commit_from_ref(project, id)
|
||||
def self.find_object(project, id)
|
||||
if project && project.valid_repo?
|
||||
project.commit(id)
|
||||
end
|
||||
end
|
||||
|
||||
def url_for_commit(project, commit)
|
||||
def find_object(*args)
|
||||
self.class.find_object(*args)
|
||||
end
|
||||
|
||||
def url_for_object(commit, project)
|
||||
h = Gitlab::Application.routes.url_helpers
|
||||
h.namespace_project_commit_url(project.namespace, project, commit,
|
||||
only_path: context[:only_path])
|
||||
end
|
||||
|
||||
def object_link_title(commit)
|
||||
commit.link_title
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,9 @@ module Gitlab
|
|||
doc.search('a').each do |node|
|
||||
next unless node.has_attribute?('href')
|
||||
|
||||
klass = node.attribute('class')
|
||||
next if klass && klass.include?('gfm')
|
||||
|
||||
link = node.attribute('href').value
|
||||
|
||||
# Skip non-HTTP(S) links
|
||||
|
|
|
@ -20,6 +20,16 @@ module Gitlab
|
|||
h.namespace_project_merge_request_url(project.namespace, project, mr,
|
||||
only_path: context[:only_path])
|
||||
end
|
||||
|
||||
def object_link_text_extras(object, matches)
|
||||
extras = super
|
||||
|
||||
if matches[:path] && matches[:path] == '/diffs'
|
||||
extras.unshift "diffs"
|
||||
end
|
||||
|
||||
extras
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,10 @@ module Gitlab
|
|||
def call
|
||||
doc.css('a.gfm').each do |node|
|
||||
unless user_can_reference?(node)
|
||||
node.replace(node.text)
|
||||
# The reference should be replaced by the original text,
|
||||
# which is not always the same as the rendered text.
|
||||
text = node.attribute('data-original') || node.text
|
||||
node.replace(text)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -125,7 +125,44 @@ module Gitlab::Markdown
|
|||
it 'links with adjacent text' do
|
||||
doc = filter("Fixed (#{reference}.)")
|
||||
|
||||
exp = Regexp.escape("#{project2.to_reference}@#{range.to_s}")
|
||||
exp = Regexp.escape("#{project2.to_reference}@#{range.to_reference}")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{exp}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
it 'ignores invalid commit IDs on the referenced project' do
|
||||
exp = act = "Fixed #{project2.to_reference}@#{commit1.id.reverse}...#{commit2.id}"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
|
||||
exp = act = "Fixed #{project2.to_reference}@#{commit1.id}...#{commit2.id.reverse}"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
result = reference_pipeline_result("See #{reference}")
|
||||
expect(result[:references][:commit_range]).not_to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'URL cross-project reference' do
|
||||
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
||||
let(:project2) { create(:project, :public, namespace: namespace) }
|
||||
let(:reference) { urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) }
|
||||
|
||||
before do
|
||||
range.project = project2
|
||||
end
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Fixed (#{reference}.)")
|
||||
|
||||
exp = Regexp.escape(range.to_reference(project))
|
||||
expect(doc.to_html).to match(/\(<a.+>#{exp}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
|
|
|
@ -131,5 +131,36 @@ module Gitlab::Markdown
|
|||
expect(result[:references][:commit]).not_to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'URL cross-project reference' do
|
||||
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
||||
let(:project2) { create(:project, :public, namespace: namespace) }
|
||||
let(:commit) { project2.commit }
|
||||
let(:reference) { urls.namespace_project_commit_url(project2.namespace, project2, commit.id) }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id)
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Fixed (#{reference}.)")
|
||||
|
||||
exp = Regexp.escape(project2.to_reference)
|
||||
expect(doc.to_html).to match(/\(<a.+>#{commit.to_reference(project)}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
it 'ignores invalid commit IDs on the referenced project' do
|
||||
exp = act = "Committed #{invalidate_reference(reference)}"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
result = reference_pipeline_result("See #{reference}")
|
||||
expect(result[:references][:commit]).not_to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -135,5 +135,37 @@ module Gitlab::Markdown
|
|||
expect(result[:references][:issue]).to eq [issue]
|
||||
end
|
||||
end
|
||||
|
||||
context 'URL cross-project reference' do
|
||||
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
||||
let(:project2) { create(:empty_project, :public, namespace: namespace) }
|
||||
let(:issue) { create(:issue, project: project2) }
|
||||
let(:reference) { helper.url_for_issue(issue.iid, project2) + "#note_123" }
|
||||
|
||||
it 'ignores valid references when cross-reference project uses external tracker' do
|
||||
expect_any_instance_of(Project).to receive(:get_issue).
|
||||
with(issue.iid).and_return(nil)
|
||||
|
||||
exp = act = "Issue #{reference}"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq reference
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Fixed (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(issue.to_reference(project))} \(comment 123\)<\/a>\.\)/)
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
result = reference_pipeline_result("Fixed #{reference}")
|
||||
expect(result[:references][:issue]).to eq [issue]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -89,7 +89,7 @@ module Gitlab::Markdown
|
|||
context 'cross-project reference' do
|
||||
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
||||
let(:project2) { create(:project, :public, namespace: namespace) }
|
||||
let(:merge) { create(:merge_request, source_project: project2) }
|
||||
let(:merge) { create(:merge_request, source_project: project2, target_project: project2) }
|
||||
let(:reference) { merge.to_reference(project) }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
|
@ -97,7 +97,7 @@ module Gitlab::Markdown
|
|||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq urls.namespace_project_merge_request_url(project2.namespace,
|
||||
project, merge)
|
||||
project2, merge)
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
|
@ -116,5 +116,30 @@ module Gitlab::Markdown
|
|||
expect(result[:references][:merge_request]).to eq [merge]
|
||||
end
|
||||
end
|
||||
|
||||
context 'URL cross-project reference' do
|
||||
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
||||
let(:project2) { create(:project, :public, namespace: namespace) }
|
||||
let(:merge) { create(:merge_request, source_project: project2, target_project: project2) }
|
||||
let(:reference) { urls.namespace_project_merge_request_url(project2.namespace,
|
||||
project2, merge) + '/diffs#note_123' }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq reference
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Merge (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(merge.to_reference(project))} \(diffs, comment 123\)<\/a>\.\)/)
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
result = reference_pipeline_result("Merge #{reference}")
|
||||
expect(result[:references][:merge_request]).to eq [merge]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -114,5 +114,35 @@ module Gitlab::Markdown
|
|||
expect(result[:references][:snippet]).to eq [snippet]
|
||||
end
|
||||
end
|
||||
|
||||
context 'URL cross-project reference' do
|
||||
let(:namespace) { create(:namespace, name: 'cross-reference') }
|
||||
let(:project2) { create(:empty_project, :public, namespace: namespace) }
|
||||
let(:snippet) { create(:project_snippet, project: project2) }
|
||||
let(:reference) { urls.namespace_project_snippet_url(project2.namespace, project2, snippet) }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("See (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(snippet.to_reference(project))}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
it 'ignores invalid snippet IDs on the referenced project' do
|
||||
exp = act = "See #{invalidate_reference(reference)}"
|
||||
|
||||
expect(filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
result = reference_pipeline_result("Snippet #{reference}")
|
||||
expect(result[:references][:snippet]).to eq [snippet]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue