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