Autolink first so we don't pick up numeric anchors as issue references.
This commit is contained in:
parent
62c14ba2ed
commit
f3ea06eb7f
|
@ -73,11 +73,8 @@ class Commit
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(?:#{Project.reference_pattern}#{reference_prefix})?
|
||||
(?<commit>\h{6,40})
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
|
|
|
@ -44,11 +44,8 @@ class CommitRange
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(?:#{Project.reference_pattern}#{reference_prefix})?
|
||||
(?<commit_range>#{STRICT_PATTERN})
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
|
|
|
@ -64,11 +64,8 @@ class Issue < ActiveRecord::Base
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(#{Project.reference_pattern})?
|
||||
#{Regexp.escape(reference_prefix)}(?<issue>\d+)
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
|
|
|
@ -146,11 +146,8 @@ class MergeRequest < ActiveRecord::Base
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(#{Project.reference_pattern})?
|
||||
#{Regexp.escape(reference_prefix)}(?<merge_request>\d+)
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
|
|
|
@ -60,11 +60,8 @@ class Snippet < ActiveRecord::Base
|
|||
# This pattern supports cross-project references.
|
||||
def self.reference_pattern
|
||||
%r{
|
||||
#{link_reference_pattern} |
|
||||
(?:
|
||||
(#{Project.reference_pattern})?
|
||||
#{Regexp.escape(reference_prefix)}(?<snippet>\d+)
|
||||
)
|
||||
}x
|
||||
end
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ module Gitlab
|
|||
class ClosingIssueExtractor
|
||||
ISSUE_CLOSING_REGEX = begin
|
||||
pattern = Gitlab.config.gitlab.issue_closing_pattern
|
||||
pattern = pattern.sub('%{issue_ref}', "(?:#{Issue.reference_pattern})")
|
||||
pattern = pattern.sub('%{issue_ref}', "(?:(?:#{Issue.link_reference_pattern})|(?:#{Issue.reference_pattern}))")
|
||||
Regexp.new(pattern).freeze
|
||||
end
|
||||
|
||||
|
|
|
@ -181,6 +181,8 @@ module Gitlab
|
|||
Gitlab::Markdown::RelativeLinkFilter,
|
||||
Gitlab::Markdown::EmojiFilter,
|
||||
Gitlab::Markdown::TableOfContentsFilter,
|
||||
Gitlab::Markdown::AutolinkFilter,
|
||||
Gitlab::Markdown::ExternalLinkFilter,
|
||||
|
||||
Gitlab::Markdown::UserReferenceFilter,
|
||||
Gitlab::Markdown::IssueReferenceFilter,
|
||||
|
@ -191,9 +193,6 @@ module Gitlab
|
|||
Gitlab::Markdown::CommitReferenceFilter,
|
||||
Gitlab::Markdown::LabelReferenceFilter,
|
||||
|
||||
Gitlab::Markdown::AutolinkFilter,
|
||||
Gitlab::Markdown::ExternalLinkFilter,
|
||||
|
||||
Gitlab::Markdown::TaskListFilter
|
||||
]
|
||||
end
|
||||
|
|
|
@ -37,8 +37,8 @@ module Gitlab
|
|||
# of the external project reference, and all of the matchdata.
|
||||
#
|
||||
# Returns a String replaced with the return of the block.
|
||||
def self.references_in(text)
|
||||
text.gsub(object_class.reference_pattern) do |match|
|
||||
def self.references_in(text, pattern = object_class.reference_pattern)
|
||||
text.gsub(pattern) do |match|
|
||||
yield match, $~[object_sym].to_i, $~[:project], $~
|
||||
end
|
||||
end
|
||||
|
@ -61,7 +61,11 @@ module Gitlab
|
|||
|
||||
def call
|
||||
replace_text_nodes_matching(object_class.reference_pattern) do |content|
|
||||
object_link_filter(content)
|
||||
object_link_filter(content, object_class.reference_pattern)
|
||||
end
|
||||
|
||||
replace_link_nodes_matching(object_class.link_reference_pattern) do |content|
|
||||
object_link_filter(content, object_class.link_reference_pattern)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -72,15 +76,17 @@ 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, matches|
|
||||
def object_link_filter(text, pattern)
|
||||
references_in(text, pattern) do |match, id, project_ref, matches|
|
||||
project = project_from_ref(project_ref)
|
||||
|
||||
if project && object = find_object(project, id)
|
||||
title = escape_once(object_link_title(object))
|
||||
klass = reference_class(object_sym)
|
||||
data = data_attribute(project: project.id, object_sym => object.id, original: match)
|
||||
url = matches[:url] || url_for_object(object, project)
|
||||
|
||||
url = matches[:url] if matches.names.include?("url")
|
||||
url ||= url_for_object(object, project)
|
||||
|
||||
text = object.reference_link_text(context[:project])
|
||||
|
||||
|
@ -99,7 +105,7 @@ module Gitlab
|
|||
def object_link_text_extras(object, matches)
|
||||
extras = []
|
||||
|
||||
if matches[:anchor] && matches[:anchor] =~ /\A\#note_(\d+)\z/
|
||||
if matches.names.include?("anchor") && matches[:anchor] && matches[:anchor] =~ /\A\#note_(\d+)\z/
|
||||
extras << "comment #{$1}"
|
||||
end
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ module Gitlab
|
|||
CommitRange
|
||||
end
|
||||
|
||||
def self.references_in(text)
|
||||
text.gsub(CommitRange.reference_pattern) do |match|
|
||||
def self.references_in(text, pattern = CommitRange.reference_pattern)
|
||||
text.gsub(pattern) do |match|
|
||||
yield match, $~[:commit_range], $~[:project], $~
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,8 +10,8 @@ module Gitlab
|
|||
Commit
|
||||
end
|
||||
|
||||
def self.references_in(text)
|
||||
text.gsub(Commit.reference_pattern) do |match|
|
||||
def self.references_in(text, pattern = Commit.reference_pattern)
|
||||
text.gsub(pattern) do |match|
|
||||
yield match, $~[:commit], $~[:project], $~
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,12 +8,9 @@ module Gitlab
|
|||
class ExternalLinkFilter < HTML::Pipeline::Filter
|
||||
def call
|
||||
doc.search('a').each do |node|
|
||||
next unless node.has_attribute?('href')
|
||||
link = node.attr('href')
|
||||
|
||||
klass = node.attribute('class')
|
||||
next if klass && klass.include?('gfm')
|
||||
|
||||
link = node.attribute('href').value
|
||||
next unless link
|
||||
|
||||
# Skip non-HTTP(S) links
|
||||
next unless link.start_with?('http')
|
||||
|
|
|
@ -24,7 +24,7 @@ module Gitlab
|
|||
def object_link_text_extras(object, matches)
|
||||
extras = super
|
||||
|
||||
if matches[:path] && matches[:path] == '/diffs'
|
||||
if matches.names.include?("path") && matches[:path] && matches[:path] == '/diffs'
|
||||
extras.unshift "diffs"
|
||||
end
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ module Gitlab
|
|||
unless user_can_reference?(node)
|
||||
# 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
|
||||
text = node.attr('data-original') || node.text
|
||||
node.replace(text)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -122,6 +122,29 @@ module Gitlab
|
|||
doc
|
||||
end
|
||||
|
||||
def replace_link_nodes_matching(pattern)
|
||||
return doc if project.nil?
|
||||
|
||||
doc.search('a').each do |node|
|
||||
klass = node.attr('class')
|
||||
next if klass && klass.include?('gfm')
|
||||
|
||||
link = node.attr('href')
|
||||
text = node.text
|
||||
|
||||
# Ignore ending punctionation like periods or commas
|
||||
next unless link == text && text =~ /\A#{pattern}/
|
||||
|
||||
html = yield text
|
||||
|
||||
next if html == text
|
||||
|
||||
node.replace(html)
|
||||
end
|
||||
|
||||
doc
|
||||
end
|
||||
|
||||
# Ensure that a :project key exists in context
|
||||
#
|
||||
# Note that while the key might exist, its value could be nil!
|
||||
|
|
|
@ -58,7 +58,15 @@ module Gitlab
|
|||
reference_filter: filter
|
||||
}
|
||||
|
||||
pipeline = HTML::Pipeline.new([filter, Gitlab::Markdown::ReferenceGathererFilter], context)
|
||||
# We need to autolink first to finds links to referables, and to prevent
|
||||
# numeric anchors to be parsed as issue references.
|
||||
filters = [
|
||||
Gitlab::Markdown::AutolinkFilter,
|
||||
filter,
|
||||
Gitlab::Markdown::ReferenceGathererFilter
|
||||
]
|
||||
|
||||
pipeline = HTML::Pipeline.new(filters, context)
|
||||
result = pipeline.call(@text)
|
||||
|
||||
values = result[:references][filter_type].uniq
|
||||
|
|
|
@ -18,7 +18,7 @@ module Gitlab::Markdown
|
|||
%w(pre code a style).each do |elem|
|
||||
it "ignores valid references contained inside '#{elem}' element" do
|
||||
exp = act = "<#{elem}>Commit Range #{range.to_reference}</#{elem}>"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -27,14 +27,14 @@ module Gitlab::Markdown
|
|||
let(:reference2) { range2.to_reference }
|
||||
|
||||
it 'links to a valid two-dot reference' do
|
||||
doc = filter("See #{reference2}")
|
||||
doc = reference_filter("See #{reference2}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq urls.namespace_project_compare_url(project.namespace, project, range2.to_param)
|
||||
end
|
||||
|
||||
it 'links to a valid three-dot reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq urls.namespace_project_compare_url(project.namespace, project, range.to_param)
|
||||
|
@ -46,12 +46,12 @@ module Gitlab::Markdown
|
|||
|
||||
exp = commit1.short_id + '...' + commit2.short_id
|
||||
|
||||
expect(filter("See #{reference}").css('a').first.text).to eq exp
|
||||
expect(filter("See #{reference2}").css('a').first.text).to eq exp
|
||||
expect(reference_filter("See #{reference}").css('a').first.text).to eq exp
|
||||
expect(reference_filter("See #{reference2}").css('a').first.text).to eq exp
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("See (#{reference}.)")
|
||||
doc = reference_filter("See (#{reference}.)")
|
||||
|
||||
exp = Regexp.escape(range.reference_link_text)
|
||||
expect(doc.to_html).to match(/\(<a.+>#{exp}<\/a>\.\)/)
|
||||
|
@ -63,21 +63,21 @@ module Gitlab::Markdown
|
|||
expect(project).to receive(:valid_repo?).and_return(true)
|
||||
expect(project.repository).to receive(:commit).with(commit1.id.reverse)
|
||||
expect(project.repository).to receive(:commit).with(commit2.id)
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'includes a title attribute' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
expect(doc.css('a').first.attr('title')).to eq range.reference_title
|
||||
end
|
||||
|
||||
it 'includes default classes' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-commit_range'
|
||||
end
|
||||
|
||||
it 'includes a data-project attribute' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-project')
|
||||
|
@ -85,7 +85,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'includes a data-commit-range attribute' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-commit-range')
|
||||
|
@ -93,7 +93,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'supports an :only_path option' do
|
||||
doc = filter("See #{reference}", only_path: true)
|
||||
doc = reference_filter("See #{reference}", only_path: true)
|
||||
link = doc.css('a').first.attr('href')
|
||||
|
||||
expect(link).not_to match %r(https?://)
|
||||
|
@ -116,14 +116,14 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_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}.)")
|
||||
doc = reference_filter("Fixed (#{reference}.)")
|
||||
|
||||
exp = Regexp.escape("#{project2.to_reference}@#{range.reference_link_text}")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{exp}<\/a>\.\)/)
|
||||
|
@ -131,10 +131,10 @@ module Gitlab::Markdown
|
|||
|
||||
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
|
||||
expect(reference_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
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
|
@ -154,14 +154,14 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq reference
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Fixed (#{reference}.)")
|
||||
doc = reference_filter("Fixed (#{reference}.)")
|
||||
|
||||
exp = Regexp.escape(range.reference_link_text(project))
|
||||
expect(doc.to_html).to match(/\(<a.+>#{exp}<\/a>\.\)/)
|
||||
|
@ -169,10 +169,10 @@ module Gitlab::Markdown
|
|||
|
||||
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
|
||||
expect(reference_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
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
|
|
|
@ -14,7 +14,7 @@ module Gitlab::Markdown
|
|||
%w(pre code a style).each do |elem|
|
||||
it "ignores valid references contained inside '#{elem}' element" do
|
||||
exp = act = "<#{elem}>Commit #{commit.id}</#{elem}>"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -24,7 +24,7 @@ module Gitlab::Markdown
|
|||
# Let's test a variety of commit SHA sizes just to be paranoid
|
||||
[6, 8, 12, 18, 20, 32, 40].each do |size|
|
||||
it "links to a valid reference of #{size} characters" do
|
||||
doc = filter("See #{reference[0...size]}")
|
||||
doc = reference_filter("See #{reference[0...size]}")
|
||||
|
||||
expect(doc.css('a').first.text).to eq commit.short_id
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
|
@ -33,15 +33,15 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'always uses the short ID as the link text' do
|
||||
doc = filter("See #{commit.id}")
|
||||
doc = reference_filter("See #{commit.id}")
|
||||
expect(doc.text).to eq "See #{commit.short_id}"
|
||||
|
||||
doc = filter("See #{commit.id[0...6]}")
|
||||
doc = reference_filter("See #{commit.id[0...6]}")
|
||||
expect(doc.text).to eq "See #{commit.short_id}"
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("See (#{reference}.)")
|
||||
doc = reference_filter("See (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{commit.short_id}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
|
@ -51,28 +51,28 @@ module Gitlab::Markdown
|
|||
|
||||
expect(project).to receive(:valid_repo?).and_return(true)
|
||||
expect(project.repository).to receive(:commit).with(invalid)
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'includes a title attribute' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
expect(doc.css('a').first.attr('title')).to eq commit.link_title
|
||||
end
|
||||
|
||||
it 'escapes the title attribute' do
|
||||
allow_any_instance_of(Commit).to receive(:title).and_return(%{"></a>whatever<a title="})
|
||||
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
expect(doc.text).to eq "See #{commit.short_id}"
|
||||
end
|
||||
|
||||
it 'includes default classes' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-commit'
|
||||
end
|
||||
|
||||
it 'includes a data-project attribute' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-project')
|
||||
|
@ -80,7 +80,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'includes a data-commit attribute' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-commit')
|
||||
|
@ -88,7 +88,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'supports an :only_path context' do
|
||||
doc = filter("See #{reference}", only_path: true)
|
||||
doc = reference_filter("See #{reference}", only_path: true)
|
||||
link = doc.css('a').first.attr('href')
|
||||
|
||||
expect(link).not_to match %r(https?://)
|
||||
|
@ -108,14 +108,14 @@ module Gitlab::Markdown
|
|||
let(:reference) { commit.to_reference(project) }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_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}.)")
|
||||
doc = reference_filter("Fixed (#{reference}.)")
|
||||
|
||||
exp = Regexp.escape(project2.to_reference)
|
||||
expect(doc.to_html).to match(/\(<a.+>#{exp}@#{commit.short_id}<\/a>\.\)/)
|
||||
|
@ -123,7 +123,7 @@ module Gitlab::Markdown
|
|||
|
||||
it 'ignores invalid commit IDs on the referenced project' do
|
||||
exp = act = "Committed #{invalidate_reference(reference)}"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
|
@ -139,21 +139,21 @@ module Gitlab::Markdown
|
|||
let(:reference) { urls.namespace_project_commit_url(project2.namespace, project2, commit.id) }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_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}.)")
|
||||
doc = reference_filter("Fixed (#{reference}.)")
|
||||
|
||||
expect(doc.to_html).to match(/\(<a.+>#{commit.reference_link_text(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
|
||||
expect(reference_filter(act).to_html).to match(/<a.+>#{Regexp.escape(invalidate_reference(reference))}<\/a>/)
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
|
|
|
@ -18,7 +18,7 @@ module Gitlab::Markdown
|
|||
%w(pre code a style).each do |elem|
|
||||
it "ignores valid references contained inside '#{elem}' element" do
|
||||
exp = act = "<#{elem}>Issue #{issue.to_reference}</#{elem}>"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -29,18 +29,18 @@ module Gitlab::Markdown
|
|||
expect(project).to receive(:get_issue).with(issue.iid).and_return(nil)
|
||||
|
||||
exp = act = "Issue #{reference}"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("Fixed #{reference}")
|
||||
doc = reference_filter("Fixed #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq helper.url_for_issue(issue.iid, project)
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Fixed (#{reference}.)")
|
||||
doc = reference_filter("Fixed (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
|
@ -48,28 +48,28 @@ module Gitlab::Markdown
|
|||
invalid = invalidate_reference(reference)
|
||||
exp = act = "Fixed #{invalid}"
|
||||
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'includes a title attribute' do
|
||||
doc = filter("Issue #{reference}")
|
||||
doc = reference_filter("Issue #{reference}")
|
||||
expect(doc.css('a').first.attr('title')).to eq "Issue: #{issue.title}"
|
||||
end
|
||||
|
||||
it 'escapes the title attribute' do
|
||||
issue.update_attribute(:title, %{"></a>whatever<a title="})
|
||||
|
||||
doc = filter("Issue #{reference}")
|
||||
doc = reference_filter("Issue #{reference}")
|
||||
expect(doc.text).to eq "Issue #{reference}"
|
||||
end
|
||||
|
||||
it 'includes default classes' do
|
||||
doc = filter("Issue #{reference}")
|
||||
doc = reference_filter("Issue #{reference}")
|
||||
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-issue'
|
||||
end
|
||||
|
||||
it 'includes a data-project attribute' do
|
||||
doc = filter("Issue #{reference}")
|
||||
doc = reference_filter("Issue #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-project')
|
||||
|
@ -77,7 +77,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'includes a data-issue attribute' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-issue')
|
||||
|
@ -85,7 +85,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'supports an :only_path context' do
|
||||
doc = filter("Issue #{reference}", only_path: true)
|
||||
doc = reference_filter("Issue #{reference}", only_path: true)
|
||||
link = doc.css('a').first.attr('href')
|
||||
|
||||
expect(link).not_to match %r(https?://)
|
||||
|
@ -109,25 +109,25 @@ module Gitlab::Markdown
|
|||
with(issue.iid).and_return(nil)
|
||||
|
||||
exp = act = "Issue #{reference}"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq helper.url_for_issue(issue.iid, project2)
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Fixed (#{reference}.)")
|
||||
doc = reference_filter("Fixed (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
it 'ignores invalid issue IDs on the referenced project' do
|
||||
exp = act = "Fixed #{invalidate_reference(reference)}"
|
||||
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
|
@ -147,18 +147,18 @@ module Gitlab::Markdown
|
|||
with(issue.iid).and_return(nil)
|
||||
|
||||
exp = act = "Issue #{reference}"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to match(/<a.+>#{Regexp.escape(reference)}<\/a>/)
|
||||
end
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq reference
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Fixed (#{reference}.)")
|
||||
doc = reference_filter("Fixed (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(issue.to_reference(project))} \(comment 123\)<\/a>\.\)/)
|
||||
end
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ module Gitlab::Markdown
|
|||
%w(pre code a style).each do |elem|
|
||||
it "ignores valid references contained inside '#{elem}' element" do
|
||||
exp = act = "<#{elem}>Merge #{merge.to_reference}</#{elem}>"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -22,42 +22,42 @@ module Gitlab::Markdown
|
|||
let(:reference) { merge.to_reference }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).to eq urls.
|
||||
namespace_project_merge_request_url(project.namespace, project, merge)
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Merge (#{reference}.)")
|
||||
doc = reference_filter("Merge (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
it 'ignores invalid merge IDs' do
|
||||
exp = act = "Merge #{invalidate_reference(reference)}"
|
||||
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'includes a title attribute' do
|
||||
doc = filter("Merge #{reference}")
|
||||
doc = reference_filter("Merge #{reference}")
|
||||
expect(doc.css('a').first.attr('title')).to eq "Merge Request: #{merge.title}"
|
||||
end
|
||||
|
||||
it 'escapes the title attribute' do
|
||||
merge.update_attribute(:title, %{"></a>whatever<a title="})
|
||||
|
||||
doc = filter("Merge #{reference}")
|
||||
doc = reference_filter("Merge #{reference}")
|
||||
expect(doc.text).to eq "Merge #{reference}"
|
||||
end
|
||||
|
||||
it 'includes default classes' do
|
||||
doc = filter("Merge #{reference}")
|
||||
doc = reference_filter("Merge #{reference}")
|
||||
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-merge_request'
|
||||
end
|
||||
|
||||
it 'includes a data-project attribute' do
|
||||
doc = filter("Merge #{reference}")
|
||||
doc = reference_filter("Merge #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-project')
|
||||
|
@ -65,7 +65,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'includes a data-merge-request attribute' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-merge-request')
|
||||
|
@ -73,7 +73,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'supports an :only_path context' do
|
||||
doc = filter("Merge #{reference}", only_path: true)
|
||||
doc = reference_filter("Merge #{reference}", only_path: true)
|
||||
link = doc.css('a').first.attr('href')
|
||||
|
||||
expect(link).not_to match %r(https?://)
|
||||
|
@ -93,7 +93,7 @@ module Gitlab::Markdown
|
|||
let(:reference) { merge.to_reference(project) }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq urls.namespace_project_merge_request_url(project2.namespace,
|
||||
|
@ -101,14 +101,14 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Merge (#{reference}.)")
|
||||
doc = reference_filter("Merge (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
it 'ignores invalid merge IDs on the referenced project' do
|
||||
exp = act = "Merge #{invalidate_reference(reference)}"
|
||||
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
|
@ -124,14 +124,14 @@ module Gitlab::Markdown
|
|||
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}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).
|
||||
to eq reference
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Merge (#{reference}.)")
|
||||
doc = reference_filter("Merge (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(merge.to_reference(project))} \(diffs, comment 123\)<\/a>\.\)/)
|
||||
end
|
||||
|
||||
|
|
|
@ -15,48 +15,48 @@ module Gitlab::Markdown
|
|||
%w(pre code a style).each do |elem|
|
||||
it "ignores valid references contained inside '#{elem}' element" do
|
||||
exp = act = "<#{elem}>Snippet #{reference}</#{elem}>"
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
end
|
||||
|
||||
context 'internal reference' do
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
|
||||
expect(doc.css('a').first.attr('href')).to eq urls.
|
||||
namespace_project_snippet_url(project.namespace, project, snippet)
|
||||
end
|
||||
|
||||
it 'links with adjacent text' do
|
||||
doc = filter("Snippet (#{reference}.)")
|
||||
doc = reference_filter("Snippet (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/a>\.\)/)
|
||||
end
|
||||
|
||||
it 'ignores invalid snippet IDs' do
|
||||
exp = act = "Snippet #{invalidate_reference(reference)}"
|
||||
|
||||
expect(filter(act).to_html).to eq exp
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'includes a title attribute' do
|
||||
doc = filter("Snippet #{reference}")
|
||||
doc = reference_filter("Snippet #{reference}")
|
||||
expect(doc.css('a').first.attr('title')).to eq "Snippet: #{snippet.title}"
|
||||
end
|
||||
|
||||
it 'escapes the title attribute' do
|
||||
snippet.update_attribute(:title, %{"></a>whatever<a title="})
|
||||
|
||||
doc = filter("Snippet #{reference}")
|
||||
doc = reference_filter("Snippet #{reference}")
|
||||
expect(doc.text).to eq "Snippet #{reference}"
|
||||
end
|
||||
|
||||
it 'includes default classes' do
|
||||
doc = filter("Snippet #{reference}")
|
||||
doc = reference_filter("Snippet #{reference}")
|
||||
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-snippet'
|
||||
end
|
||||
|
||||
it 'includes a data-project attribute' do
|
||||
doc = filter("Snippet #{reference}")
|
||||
doc = reference_filter("Snippet #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-project')
|
||||
|
@ -64,7 +64,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'includes a data-snippet attribute' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_filter("See #{reference}")
|
||||
link = doc.css('a').first
|
||||
|
||||
expect(link).to have_attribute('data-snippet')
|
||||
|
@ -72,7 +72,7 @@ module Gitlab::Markdown
|
|||
end
|
||||
|
||||
it 'supports an :only_path context' do
|
||||
doc = filter("Snippet #{reference}", only_path: true)
|
||||
doc = reference_filter("Snippet #{reference}", only_path: true)
|
||||
link = doc.css('a').first.attr('href')
|
||||
|
||||
expect(link).not_to match %r(https?://)
|
||||
|
@ -92,21 +92,21 @@ module Gitlab::Markdown
|
|||
let(:reference) { snippet.to_reference(project) }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_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}.)")
|
||||
doc = reference_filter("See (#{reference}.)")
|
||||
expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(reference)}<\/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
|
||||
expect(reference_filter(act).to_html).to eq exp
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
|
@ -122,21 +122,21 @@ module Gitlab::Markdown
|
|||
let(:reference) { urls.namespace_project_snippet_url(project2.namespace, project2, snippet) }
|
||||
|
||||
it 'links to a valid reference' do
|
||||
doc = filter("See #{reference}")
|
||||
doc = reference_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}.)")
|
||||
doc = reference_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
|
||||
expect(reference_filter(act).to_html).to match(/<a.+>#{Regexp.escape(invalidate_reference(reference))}<\/a>/)
|
||||
end
|
||||
|
||||
it 'adds to the results hash' do
|
||||
|
|
|
@ -35,11 +35,24 @@ module FilterSpecHelper
|
|||
pipeline.call(body)
|
||||
end
|
||||
|
||||
def reference_pipeline_result(body, contexts = {})
|
||||
def reference_pipeline(contexts = {})
|
||||
contexts.reverse_merge!(project: project) if defined?(project)
|
||||
|
||||
pipeline = HTML::Pipeline.new([described_class, Gitlab::Markdown::ReferenceGathererFilter], contexts)
|
||||
pipeline.call(body)
|
||||
filters = [
|
||||
Gitlab::Markdown::AutolinkFilter,
|
||||
described_class,
|
||||
Gitlab::Markdown::ReferenceGathererFilter
|
||||
]
|
||||
|
||||
HTML::Pipeline.new(filters, contexts)
|
||||
end
|
||||
|
||||
def reference_pipeline_result(body, contexts = {})
|
||||
reference_pipeline(contexts).call(body)
|
||||
end
|
||||
|
||||
def reference_filter(html, contexts = {})
|
||||
reference_pipeline(contexts).to_document(html)
|
||||
end
|
||||
|
||||
# Modify a String reference to make it invalid
|
||||
|
|
Loading…
Reference in New Issue