summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2015-12-01 16:26:05 +0100
committerDouwe Maan <douwe@gitlab.com>2015-12-01 16:53:07 +0100
commitd4030a845eebcb913a7aac1e8fd502706669d0cc (patch)
tree6165574318aa1c48b413b8aac303f605596e3e2e
parent1d6d757dbd563500671f57f45faa808510a612d1 (diff)
downloadgitlab-ce-d4030a845eebcb913a7aac1e8fd502706669d0cc.tar.gz
Pick up direct links to issues/MRs as references.
-rw-r--r--lib/gitlab/markdown/abstract_reference_filter.rb17
-rw-r--r--spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb2
-rw-r--r--spec/lib/gitlab/markdown/commit_reference_filter_spec.rb2
-rw-r--r--spec/lib/gitlab/markdown/issue_reference_filter_spec.rb56
-rw-r--r--spec/lib/gitlab/markdown/label_reference_filter_spec.rb71
-rw-r--r--spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb2
-rw-r--r--spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb2
-rw-r--r--spec/lib/gitlab/markdown/user_reference_filter_spec.rb51
8 files changed, 161 insertions, 42 deletions
diff --git a/lib/gitlab/markdown/abstract_reference_filter.rb b/lib/gitlab/markdown/abstract_reference_filter.rb
index b044a73ed17..0ec55c0207e 100644
--- a/lib/gitlab/markdown/abstract_reference_filter.rb
+++ b/lib/gitlab/markdown/abstract_reference_filter.rb
@@ -60,17 +60,27 @@ module Gitlab
end
def call
+ # `#123`
replace_text_nodes_matching(object_class.reference_pattern) do |content|
object_link_filter(content, object_class.reference_pattern)
end
+ # `[Issue](#123)`, which is turned into
+ # `<a href="#123">Issue</a>`
replace_link_nodes_with_href(object_class.reference_pattern) do |link, text|
object_link_filter(link, object_class.reference_pattern, link_text: text)
end
+ # `http://gitlab.example.com/namespace/project/issues/123`, which is turned into
+ # `<a href="http://gitlab.example.com/namespace/project/issues/123">http://gitlab.example.com/namespace/project/issues/123</a>`
replace_link_nodes_with_text(object_class.link_reference_pattern) do |text|
object_link_filter(text, object_class.link_reference_pattern)
end
+
+ # `[Issue](http://gitlab.example.com/namespace/project/issues/123)`, which is turned into
+ # `<a href="http://gitlab.example.com/namespace/project/issues/123">Issue</a>`
+ replace_link_nodes_with_href(object_class.link_reference_pattern) do |link, text|
+ object_link_filter(link, object_class.link_reference_pattern, link_text: text)
end
end
@@ -88,7 +98,12 @@ module Gitlab
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)
+
+ data = data_attribute(
+ original: link_text || match,
+ project: project.id,
+ object_sym => object.id
+ )
url = matches[:url] if matches.names.include?("url")
url ||= url_for_object(object, project)
diff --git a/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb b/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
index 92158382790..9ce63f9af46 100644
--- a/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
@@ -143,7 +143,7 @@ module Gitlab::Markdown
end
end
- context 'URL cross-project reference' do
+ context 'cross-project URL reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, :public, namespace: namespace) }
let(:range) { CommitRange.new("#{commit1.id}...master", project) }
diff --git a/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb b/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
index 6fe9b165ff5..78a3603269c 100644
--- a/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
@@ -132,7 +132,7 @@ module Gitlab::Markdown
end
end
- context 'URL cross-project reference' do
+ context 'cross-project URL reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, :public, namespace: namespace) }
let(:commit) { project2.commit }
diff --git a/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb b/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
index 0a741688b82..078ff3ed4b2 100644
--- a/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
@@ -136,30 +136,70 @@ module Gitlab::Markdown
end
end
- context 'URL cross-project reference' do
+ context 'cross-project URL 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)
+ it 'links to a valid reference' do
+ doc = reference_filter("See #{reference}")
- exp = act = "Issue #{reference}"
- expect(reference_filter(act).to_html).to match(/<a.+>#{Regexp.escape(reference)}<\/a>/)
+ expect(doc.css('a').first.attr('href')).
+ to eq reference
+ end
+
+ it 'links with adjacent text' do
+ doc = reference_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
+
+ context 'cross-project reference in link href' do
+ let(:namespace) { create(:namespace, name: 'cross-reference') }
+ let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:issue) { create(:issue, project: project2) }
+ let(:reference) { %Q{<a href="#{issue.to_reference(project)}">Reference</a>} }
+
+ it 'links to a valid reference' do
+ 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 = reference_filter("Fixed (#{reference}.)")
+ expect(doc.to_html).to match(/\(<a.+>Reference<\/a>\.\)/)
end
+ it 'adds to the results hash' do
+ result = reference_pipeline_result("Fixed #{reference}")
+ expect(result[:references][:issue]).to eq [issue]
+ end
+ end
+
+ context 'cross-project URL in link href' do
+ let(:namespace) { create(:namespace, name: 'cross-reference') }
+ let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:issue) { create(:issue, project: project2) }
+ let(:reference) { %Q{<a href="#{helper.url_for_issue(issue.iid, project2) + "#note_123"}">Reference</a>} }
+
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.attr('href')).
- to eq reference
+ to eq helper.url_for_issue(issue.iid, project2) + "#note_123"
end
it 'links with adjacent text' do
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.+>Reference<\/a>\.\)/)
end
it 'adds to the results hash' do
diff --git a/spec/lib/gitlab/markdown/label_reference_filter_spec.rb b/spec/lib/gitlab/markdown/label_reference_filter_spec.rb
index fc21b65a843..ef6dd524aba 100644
--- a/spec/lib/gitlab/markdown/label_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/label_reference_filter_spec.rb
@@ -16,17 +16,17 @@ module Gitlab::Markdown
%w(pre code a style).each do |elem|
it "ignores valid references contained inside '#{elem}' element" do
exp = act = "<#{elem}>Label #{reference}</#{elem}>"
- expect(filter(act).to_html).to eq exp
+ expect(reference_filter(act).to_html).to eq exp
end
end
it 'includes default classes' do
- doc = filter("Label #{reference}")
+ doc = reference_filter("Label #{reference}")
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-label'
end
it 'includes a data-project attribute' do
- doc = filter("Label #{reference}")
+ doc = reference_filter("Label #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project')
@@ -34,7 +34,7 @@ module Gitlab::Markdown
end
it 'includes a data-label attribute' do
- doc = filter("See #{reference}")
+ doc = reference_filter("See #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-label')
@@ -42,7 +42,7 @@ module Gitlab::Markdown
end
it 'supports an :only_path context' do
- doc = filter("Label #{reference}", only_path: true)
+ doc = reference_filter("Label #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
expect(link).not_to match %r(https?://)
@@ -56,33 +56,33 @@ module Gitlab::Markdown
describe 'label span element' do
it 'includes default classes' do
- doc = filter("Label #{reference}")
+ doc = reference_filter("Label #{reference}")
expect(doc.css('a span').first.attr('class')).to eq 'label color-label'
end
it 'includes a style attribute' do
- doc = filter("Label #{reference}")
+ doc = reference_filter("Label #{reference}")
expect(doc.css('a span').first.attr('style')).to match(/\Abackground-color: #\h{6}; color: #\h{6}\z/)
end
end
context 'Integer-based references' 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_issues_url(project.namespace, project, label_name: label.name)
end
it 'links with adjacent text' do
- doc = filter("Label (#{reference}.)")
+ doc = reference_filter("Label (#{reference}.)")
expect(doc.to_html).to match(%r(\(<a.+><span.+>#{label.name}</span></a>\.\)))
end
it 'ignores invalid label IDs' do
exp = act = "Label #{invalidate_reference(reference)}"
- expect(filter(act).to_html).to eq exp
+ expect(reference_filter(act).to_html).to eq exp
end
end
@@ -91,7 +91,7 @@ module Gitlab::Markdown
let(:reference) { "#{Label.reference_prefix}#{label.name}" }
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_issues_url(project.namespace, project, label_name: label.name)
@@ -99,14 +99,14 @@ module Gitlab::Markdown
end
it 'links with adjacent text' do
- doc = filter("Label (#{reference}.)")
+ doc = reference_filter("Label (#{reference}.)")
expect(doc.to_html).to match(%r(\(<a.+><span.+>#{label.name}</span></a>\.\)))
end
it 'ignores invalid label names' do
exp = act = "Label #{Label.reference_prefix}#{label.name.reverse}"
- expect(filter(act).to_html).to eq exp
+ expect(reference_filter(act).to_html).to eq exp
end
end
@@ -115,7 +115,7 @@ module Gitlab::Markdown
let(:reference) { label.to_reference(:name) }
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_issues_url(project.namespace, project, label_name: label.name)
@@ -123,21 +123,58 @@ module Gitlab::Markdown
end
it 'links with adjacent text' do
- doc = filter("Label (#{reference}.)")
+ doc = reference_filter("Label (#{reference}.)")
expect(doc.to_html).to match(%r(\(<a.+><span.+>#{label.name}</span></a>\.\)))
end
it 'ignores invalid label names' do
exp = act = %(Label #{Label.reference_prefix}"#{label.name.reverse}")
- expect(filter(act).to_html).to eq exp
+ expect(reference_filter(act).to_html).to eq exp
end
end
describe 'edge cases' do
it 'gracefully handles non-references matching the pattern' do
exp = act = '(format nil "~0f" 3.0) ; 3.0'
- expect(filter(act).to_html).to eq exp
+ expect(reference_filter(act).to_html).to eq exp
+ end
+ end
+
+ describe 'referencing a label in a link href' do
+ let(:reference) { %Q{<a href="#{label.to_reference}">Label</a>} }
+
+ it 'links to a valid reference' do
+ doc = reference_filter("See #{reference}")
+
+ expect(doc.css('a').first.attr('href')).to eq urls.
+ namespace_project_issues_url(project.namespace, project, label_name: label.name)
+ end
+
+ it 'links with adjacent text' do
+ doc = reference_filter("Label (#{reference}.)")
+ expect(doc.to_html).to match(%r(\(<a.+>Label</a>\.\)))
+ end
+
+ it 'includes a data-project attribute' do
+ doc = reference_filter("Label #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-project')
+ expect(link.attr('data-project')).to eq project.id.to_s
+ end
+
+ it 'includes a data-label attribute' do
+ doc = reference_filter("See #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-label')
+ expect(link.attr('data-label')).to eq label.id.to_s
+ end
+
+ it 'adds to the results hash' do
+ result = reference_pipeline_result("Label #{reference}")
+ expect(result[:references][:label]).to eq [label]
end
end
end
diff --git a/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb b/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
index cdb3390e793..4a232051127 100644
--- a/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
@@ -117,7 +117,7 @@ module Gitlab::Markdown
end
end
- context 'URL cross-project reference' do
+ context 'cross-project URL 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) }
diff --git a/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb b/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
index 73d20957a56..b6f05710c3b 100644
--- a/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
@@ -115,7 +115,7 @@ module Gitlab::Markdown
end
end
- context 'URL cross-project reference' do
+ context 'cross-project URL reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:empty_project, :public, namespace: namespace) }
let(:snippet) { create(:project_snippet, project: project2) }
diff --git a/spec/lib/gitlab/markdown/user_reference_filter_spec.rb b/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
index d9e0d7c42db..25379f0670e 100644
--- a/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
@@ -14,13 +14,13 @@ module Gitlab::Markdown
it 'ignores invalid users' do
exp = act = "Hey #{invalidate_reference(reference)}"
- expect(filter(act).to_html).to eq(exp)
+ expect(reference_filter(act).to_html).to eq(exp)
end
%w(pre code a style).each do |elem|
it "ignores valid references contained inside '#{elem}' element" do
exp = act = "<#{elem}>Hey #{reference}</#{elem}>"
- expect(filter(act).to_html).to eq exp
+ expect(reference_filter(act).to_html).to eq exp
end
end
@@ -32,7 +32,7 @@ module Gitlab::Markdown
end
it 'supports a special @all mention' do
- doc = filter("Hey #{reference}")
+ doc = reference_filter("Hey #{reference}")
expect(doc.css('a').length).to eq 1
expect(doc.css('a').first.attr('href'))
.to eq urls.namespace_project_url(project.namespace, project)
@@ -46,26 +46,26 @@ module Gitlab::Markdown
context 'mentioning a user' do
it 'links to a User' do
- doc = filter("Hey #{reference}")
+ doc = reference_filter("Hey #{reference}")
expect(doc.css('a').first.attr('href')).to eq urls.user_url(user)
end
it 'links to a User with a period' do
user = create(:user, name: 'alphA.Beta')
- doc = filter("Hey #{user.to_reference}")
+ doc = reference_filter("Hey #{user.to_reference}")
expect(doc.css('a').length).to eq 1
end
it 'links to a User with an underscore' do
user = create(:user, name: 'ping_pong_king')
- doc = filter("Hey #{user.to_reference}")
+ doc = reference_filter("Hey #{user.to_reference}")
expect(doc.css('a').length).to eq 1
end
it 'includes a data-user attribute' do
- doc = filter("Hey #{reference}")
+ doc = reference_filter("Hey #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-user')
@@ -83,12 +83,12 @@ module Gitlab::Markdown
let(:reference) { group.to_reference }
it 'links to the Group' do
- doc = filter("Hey #{reference}")
+ doc = reference_filter("Hey #{reference}")
expect(doc.css('a').first.attr('href')).to eq urls.group_url(group)
end
it 'includes a data-group attribute' do
- doc = filter("Hey #{reference}")
+ doc = reference_filter("Hey #{reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-group')
@@ -102,21 +102,48 @@ module Gitlab::Markdown
end
it 'links with adjacent text' do
- doc = filter("Mention me (#{reference}.)")
+ doc = reference_filter("Mention me (#{reference}.)")
expect(doc.to_html).to match(/\(<a.+>#{reference}<\/a>\.\)/)
end
it 'includes default classes' do
- doc = filter("Hey #{reference}")
+ doc = reference_filter("Hey #{reference}")
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-project_member'
end
it 'supports an :only_path context' do
- doc = filter("Hey #{reference}", only_path: true)
+ doc = reference_filter("Hey #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
expect(link).not_to match %r(https?://)
expect(link).to eq urls.user_path(user)
end
+
+ context 'referencing a user in a link href' do
+ let(:reference) { %Q{<a href="#{user.to_reference}">User</a>} }
+
+ it 'links to a User' do
+ doc = reference_filter("Hey #{reference}")
+ expect(doc.css('a').first.attr('href')).to eq urls.user_url(user)
+ end
+
+ it 'links with adjacent text' do
+ doc = reference_filter("Mention me (#{reference}.)")
+ expect(doc.to_html).to match(/\(<a.+>User<\/a>\.\)/)
+ end
+
+ it 'includes a data-user attribute' do
+ doc = reference_filter("Hey #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-user')
+ expect(link.attr('data-user')).to eq user.namespace.owner_id.to_s
+ end
+
+ it 'adds to the results hash' do
+ result = reference_pipeline_result("Hey #{reference}")
+ expect(result[:references][:user]).to eq [user]
+ end
+ end
end
end