Commit 94af0501 authored by Robert Speicher's avatar Robert Speicher
Browse files

Use `to_reference` in reference filter specs

parent f48023e70c1f
......@@ -8,33 +8,36 @@ module Gitlab::Markdown
let(:commit1) { project.commit }
let(:commit2) { project.commit("HEAD~2") }
let(:range) { CommitRange.new("#{commit1.id}...#{commit2.id}") }
let(:range2) { CommitRange.new("#{commit1.id}..#{commit2.id}") }
it 'requires project context' do
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
end
%w(pre code a style).each do |elem|
it "ignores valid references contained inside '#{elem}' element" do
exp = act = "<#{elem}>Commit Range #{commit1.id}..#{commit2.id}</#{elem}>"
exp = act = "<#{elem}>Commit Range #{range.to_reference}</#{elem}>"
expect(filter(act).to_html).to eq exp
end
end
context 'internal reference' do
let(:reference) { "#{commit1.id}...#{commit2.id}" }
let(:reference2) { "#{commit1.id}..#{commit2.id}" }
let(:reference) { range.to_reference }
let(:reference2) { range2.to_reference }
it 'links to a valid two-dot reference' do
doc = filter("See #{reference2}")
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_compare_url(project.namespace, project, from: "#{commit1.id}^", to: commit2.id)
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}")
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_compare_url(project.namespace, project, from: commit1.id, to: commit2.id)
to eq urls.namespace_project_compare_url(project.namespace, project, range.to_param)
end
it 'links to a valid short ID' do
......@@ -50,7 +53,7 @@ module Gitlab::Markdown
it 'links with adjacent text' do
doc = filter("See (#{reference}.)")
exp = Regexp.escape("#{commit1.short_id}...#{commit2.short_id}")
exp = Regexp.escape(range.to_s)
expect(doc.to_html).to match(/\(<a.+>#{exp}<\/a>\.\)/)
end
......@@ -64,7 +67,7 @@ module Gitlab::Markdown
it 'includes a title attribute' do
doc = filter("See #{reference}")
expect(doc.css('a').first.attr('title')).to eq "Commits #{commit1.id} through #{commit2.id}"
expect(doc.css('a').first.attr('title')).to eq range.reference_title
end
it 'includes default classes' do
......@@ -94,9 +97,11 @@ module Gitlab::Markdown
context 'cross-project reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, namespace: namespace) }
let(:commit1) { project.commit }
let(:commit2) { project.commit("HEAD~2") }
let(:reference) { "#{project2.path_with_namespace}@#{commit1.id}...#{commit2.id}" }
let(:reference) { range.to_reference(project) }
before do
range.project = project2
end
context 'when user can access reference' do
before { allow_cross_reference! }
......@@ -105,21 +110,21 @@ module Gitlab::Markdown
doc = filter("See #{reference}")
expect(doc.css('a').first.attr('href')).
to eq urls.namespace_project_compare_url(project2.namespace, project2, from: commit1.id, to: commit2.id)
to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
end
it 'links with adjacent text' do
doc = filter("Fixed (#{reference}.)")
exp = Regexp.escape("#{project2.path_with_namespace}@#{commit1.short_id}...#{commit2.short_id}")
exp = Regexp.escape("#{project2.to_reference}@#{range.to_s}")
expect(doc.to_html).to match(/\(<a.+>#{exp}<\/a>\.\)/)
end
it 'ignores invalid commit IDs on the referenced project' do
exp = act = "Fixed #{project2.path_with_namespace}##{commit1.id.reverse}...#{commit2.id}"
exp = act = "Fixed #{project2.to_reference}@#{commit1.id.reverse}...#{commit2.id}"
expect(filter(act).to_html).to eq exp
exp = act = "Fixed #{project2.path_with_namespace}##{commit1.id}...#{commit2.id.reverse}"
exp = act = "Fixed #{project2.to_reference}@#{commit1.id}...#{commit2.id.reverse}"
expect(filter(act).to_html).to eq exp
end
......
......@@ -8,8 +8,7 @@ module Gitlab::Markdown
let(:commit) { project.commit }
it 'requires project context' do
expect { described_class.call('Commit 1c002d', {}) }.
to raise_error(ArgumentError, /:project/)
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
end
%w(pre code a style).each do |elem|
......@@ -47,10 +46,11 @@ module Gitlab::Markdown
end
it 'ignores invalid commit IDs' do
exp = act = "See #{reference.reverse}"
invalid = invalidate_reference(reference)
exp = act = "See #{invalid}"
expect(project).to receive(:valid_repo?).and_return(true)
expect(project.repository).to receive(:commit).with(reference.reverse)
expect(project.repository).to receive(:commit).with(invalid)
expect(filter(act).to_html).to eq exp
end
......@@ -93,8 +93,8 @@ module Gitlab::Markdown
context 'cross-project reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, namespace: namespace) }
let(:commit) { project.commit }
let(:reference) { "#{project2.path_with_namespace}@#{commit.id}" }
let(:commit) { project2.commit }
let(:reference) { commit.to_reference(project) }
context 'when user can access reference' do
before { allow_cross_reference! }
......@@ -109,12 +109,12 @@ module Gitlab::Markdown
it 'links with adjacent text' do
doc = filter("Fixed (#{reference}.)")
exp = Regexp.escape(project2.path_with_namespace)
exp = Regexp.escape(project2.to_reference)
expect(doc.to_html).to match(/\(<a.+>#{exp}@#{commit.short_id}<\/a>\.\)/)
end
it 'ignores invalid commit IDs on the referenced project' do
exp = act = "Committed #{project2.path_with_namespace}##{commit.id.reverse}"
exp = act = "Committed #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
......
......@@ -9,19 +9,18 @@ def helper
end
let(:project) { create(:jira_project) }
let(:issue) { double('issue', iid: 123) }
context 'JIRA issue references' do
let(:reference) { "JIRA-#{issue.iid}" }
let(:issue) { ExternalIssue.new('JIRA-123', project) }
let(:reference) { issue.to_reference }
it 'requires project context' do
expect { described_class.call('Issue JIRA-123', {}) }.
to raise_error(ArgumentError, /:project/)
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
end
%w(pre code a style).each do |elem|
it "ignores valid references contained inside '#{elem}' element" do
exp = act = "<#{elem}>Issue JIRA-#{issue.iid}</#{elem}>"
exp = act = "<#{elem}>Issue #{reference}</#{elem}>"
expect(filter(act).to_html).to eq exp
end
end
......@@ -33,13 +32,6 @@ def helper
expect(filter(act).to_html).to eq exp
end
%w(pre code a style).each do |elem|
it "ignores references contained inside '#{elem}' element" do
exp = act = "<#{elem}>Issue #{reference}</#{elem}>"
expect(filter(act).to_html).to eq exp
end
end
it 'links to a valid reference' do
doc = filter("Issue #{reference}")
expect(doc.css('a').first.attr('href'))
......
......@@ -12,24 +12,23 @@ def helper
let(:issue) { create(:issue, project: project) }
it 'requires project context' do
expect { described_class.call('Issue #123', {}) }.
to raise_error(ArgumentError, /:project/)
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
end
%w(pre code a style).each do |elem|
it "ignores valid references contained inside '#{elem}' element" do
exp = act = "<#{elem}>Issue ##{issue.iid}</#{elem}>"
exp = act = "<#{elem}>Issue #{issue.to_reference}</#{elem}>"
expect(filter(act).to_html).to eq exp
end
end
context 'internal reference' do
let(:reference) { "##{issue.iid}" }
let(:reference) { issue.to_reference }
it 'ignores valid references when using non-default tracker' do
expect(project).to receive(:get_issue).with(issue.iid).and_return(nil)
exp = act = "Issue ##{issue.iid}"
exp = act = "Issue #{reference}"
expect(filter(act).to_html).to eq exp
end
......@@ -46,9 +45,9 @@ def helper
end
it 'ignores invalid issue IDs' do
exp = act = "Fixed ##{issue.iid + 1}"
invalid = invalidate_reference(reference)
exp = act = "Fixed #{invalid}"
expect(project).to receive(:get_issue).with(issue.iid + 1).and_return(nil)
expect(filter(act).to_html).to eq exp
end
......@@ -92,7 +91,7 @@ def helper
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:empty_project, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
let(:reference) { "#{project2.path_with_namespace}##{issue.iid}" }
let(:reference) { issue.to_reference(project) }
context 'when user can access reference' do
before { allow_cross_reference! }
......@@ -101,7 +100,7 @@ def helper
expect_any_instance_of(Project).to receive(:get_issue).
with(issue.iid).and_return(nil)
exp = act = "Issue ##{issue.iid}"
exp = act = "Issue #{reference}"
expect(filter(act).to_html).to eq exp
end
......@@ -118,7 +117,7 @@ def helper
end
it 'ignores invalid issue IDs on the referenced project' do
exp = act = "Fixed #{project2.path_with_namespace}##{issue.iid + 1}"
exp = act = "Fixed #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
......
......@@ -7,11 +7,10 @@ module Gitlab::Markdown
let(:project) { create(:empty_project) }
let(:label) { create(:label, project: project) }
let(:reference) { "~#{label.id}" }
let(:reference) { label.to_reference }
it 'requires project context' do
expect { described_class.call('Label ~123', {}) }.
to raise_error(ArgumentError, /:project/)
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
end
%w(pre code a style).each do |elem|
......@@ -36,7 +35,7 @@ module Gitlab::Markdown
link = doc.css('a').first.attr('href')
expect(link).not_to match %r(https?://)
expect(link).to eq urls.namespace_project_issues_url(project.namespace, project, label_name: label.name, only_path: true)
expect(link).to eq urls.namespace_project_issues_path(project.namespace, project, label_name: label.name)
end
it 'adds to the results hash' do
......@@ -70,7 +69,7 @@ module Gitlab::Markdown
end
it 'ignores invalid label IDs' do
exp = act = "Label ~#{label.id + 1}"
exp = act = "Label #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
......@@ -78,7 +77,7 @@ module Gitlab::Markdown
context 'String-based single-word references' do
let(:label) { create(:label, name: 'gfm', project: project) }
let(:reference) { "~#{label.name}" }
let(:reference) { "#{Label.reference_prefix}#{label.name}" }
it 'links to a valid reference' do
doc = filter("See #{reference}")
......@@ -94,7 +93,7 @@ module Gitlab::Markdown
end
it 'ignores invalid label names' do
exp = act = "Label ~#{label.name.reverse}"
exp = act = "Label #{Label.reference_prefix}#{label.name.reverse}"
expect(filter(act).to_html).to eq exp
end
......@@ -104,7 +103,7 @@ module Gitlab::Markdown
let(:label) { create(:label, name: 'gfm references', project: project) }
context 'in single quotes' do
let(:reference) { "~'#{label.name}'" }
let(:reference) { "#{Label.reference_prefix}'#{label.name}'" }
it 'links to a valid reference' do
doc = filter("See #{reference}")
......@@ -120,14 +119,14 @@ module Gitlab::Markdown
end
it 'ignores invalid label names' do
exp = act = "Label ~'#{label.name.reverse}'"
exp = act = "Label #{Label.reference_prefix}'#{label.name.reverse}'"
expect(filter(act).to_html).to eq exp
end
end
context 'in double quotes' do
let(:reference) { %(~"#{label.name}") }
let(:reference) { %(#{Label.reference_prefix}"#{label.name}") }
it 'links to a valid reference' do
doc = filter("See #{reference}")
......@@ -143,7 +142,7 @@ module Gitlab::Markdown
end
it 'ignores invalid label names' do
exp = act = %(Label ~"#{label.name.reverse}")
exp = act = %(Label #{Label.reference_prefix}"#{label.name.reverse}")
expect(filter(act).to_html).to eq exp
end
......
......@@ -8,19 +8,18 @@ module Gitlab::Markdown
let(:merge) { create(:merge_request, source_project: project) }
it 'requires project context' do
expect { described_class.call('MergeRequest !123', {}) }.
to raise_error(ArgumentError, /:project/)
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
end
%w(pre code a style).each do |elem|
it "ignores valid references contained inside '#{elem}' element" do
exp = act = "<#{elem}>Merge !#{merge.iid}</#{elem}>"
exp = act = "<#{elem}>Merge #{merge.to_reference}</#{elem}>"
expect(filter(act).to_html).to eq exp
end
end
context 'internal reference' do
let(:reference) { "!#{merge.iid}" }
let(:reference) { merge.to_reference }
it 'links to a valid reference' do
doc = filter("See #{reference}")
......@@ -35,7 +34,7 @@ module Gitlab::Markdown
end
it 'ignores invalid merge IDs' do
exp = act = "Merge !#{merge.iid + 1}"
exp = act = "Merge #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
......@@ -80,7 +79,7 @@ module Gitlab::Markdown
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, namespace: namespace) }
let(:merge) { create(:merge_request, source_project: project2) }
let(:reference) { "#{project2.path_with_namespace}!#{merge.iid}" }
let(:reference) { merge.to_reference(project) }
context 'when user can access reference' do
before { allow_cross_reference! }
......@@ -99,7 +98,7 @@ module Gitlab::Markdown
end
it 'ignores invalid merge IDs on the referenced project' do
exp = act = "Merge #{project2.path_with_namespace}!#{merge.iid + 1}"
exp = act = "Merge #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
......
......@@ -6,11 +6,10 @@ module Gitlab::Markdown
let(:project) { create(:empty_project) }
let(:snippet) { create(:project_snippet, project: project) }
let(:reference) { "$#{snippet.id}" }
let(:reference) { snippet.to_reference }
it 'requires project context' do
expect { described_class.call('Snippet $123', {}) }.
to raise_error(ArgumentError, /:project/)
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
end
%w(pre code a style).each do |elem|
......@@ -34,7 +33,7 @@ module Gitlab::Markdown
end
it 'ignores invalid snippet IDs' do
exp = act = "Snippet $#{snippet.id + 1}"
exp = act = "Snippet #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
......@@ -79,7 +78,7 @@ module Gitlab::Markdown
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:empty_project, namespace: namespace) }
let(:snippet) { create(:project_snippet, project: project2) }
let(:reference) { "#{project2.path_with_namespace}$#{snippet.id}" }
let(:reference) { snippet.to_reference(project) }
context 'when user can access reference' do
before { allow_cross_reference! }
......@@ -97,7 +96,7 @@ module Gitlab::Markdown
end
it 'ignores invalid snippet IDs on the referenced project' do
exp = act = "See #{project2.path_with_namespace}$#{snippet.id + 1}"
exp = act = "See #{invalidate_reference(reference)}"
expect(filter(act).to_html).to eq exp
end
......
......@@ -4,65 +4,63 @@ module Gitlab::Markdown
describe UserReferenceFilter do
include ReferenceFilterSpecHelper
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
let(:reference) { user.to_reference }
it 'requires project context' do
expect { described_class.call('Example @mention', {}) }.
to raise_error(ArgumentError, /:project/)
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
end
it 'ignores invalid users' do
exp = act = 'Hey @somebody'
exp = act = "Hey #{invalidate_reference(reference)}"
expect(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 @#{user.username}</#{elem}>"
exp = act = "<#{elem}>Hey #{reference}</#{elem}>"
expect(filter(act).to_html).to eq exp
end
end
context 'mentioning @all' do
let(:reference) { User.reference_prefix + 'all' }
before do
project.team << [project.creator, :developer]
end
it 'supports a special @all mention' do
doc = filter("Hey @all")
doc = 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)
end
it 'adds to the results hash' do
result = pipeline_result('Hey @all')
result = pipeline_result("Hey #{reference}")
expect(result[:references][:user]).to eq [project.creator]
end
end
context 'mentioning a user' do
let(:reference) { "@#{user.username}" }
it 'links to a User' do
doc = filter("Hey #{reference}")
expect(doc.css('a').first.attr('href')).to eq urls.user_url(user)
end
# TODO (rspeicher): This test might be overkill
it 'links to a User with a period' do
user = create(:user, name: 'alphA.Beta')
doc = filter("Hey @#{user.username}")
doc = filter("Hey #{user.to_reference}")
expect(doc.css('a').length).to eq 1
end
# TODO (rspeicher): This test might be overkill
it 'links to a User with an underscore' do
user = create(:user, name: 'ping_pong_king')
doc = filter("Hey @#{user.username}")
doc = filter("Hey #{user.to_reference}")
expect(doc.css('a').length).to eq 1
end
......@@ -73,10 +71,9 @@ module Gitlab::Markdown
end
context 'mentioning a group' do
let(:group) { create(:group) }
let(:user) { create(:user) }
let(:reference) { "@#{group.name}" }
let(:group) { create(:group) }
let(:user) { create(:user) }
let(:reference) { group.to_reference }
context 'that the current user can read' do
before do
......@@ -108,23 +105,23 @@ module Gitlab::Markdown
end
it 'links with adjacent text' do
skip 'TODO (rspeicher): Re-enable when usernames can\'t end in periods.'
doc = filter("Mention me (@#{user.username}.)")
expect(doc.to_html).to match(/\(<a.+>@#{user.username}<\/a>\.\)/)
skip "TODO (rspeicher): Re-enable when usernames can't end in periods."
doc = filter("Mention me (#{reference}.)")
expect(doc.to_html).to match(/\(<a.+>#{reference}<\/a>\.\)/)
end
it 'includes default classes' do
doc = filter("Hey @#{user.username}")
doc = filter("Hey #{reference}")
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-project_member'
end
it 'includes an optional custom class' do
doc = filter("Hey @#{user.username}", reference_class: 'custom')
doc = filter("Hey #{reference}", reference_class: 'custom')
expect(doc.css('a').first.attr('class')).to include 'custom'
end
it 'supports an :only_path context' do
doc = filter("Hey @#{user.username}", only_path: true)
doc = filter("Hey #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
expect(link).not_to match %r(https?://)
......
......@@ -10,9 +10,10 @@ def urls
Rails.application.routes.url_helpers
end
# Modify a reference to make it invalid
# Modify a String reference to make it invalid
#
# Commit SHAs get reversed, IDs get incremented by 1
# Commit SHAs get reversed, IDs get incremented by 1, all other Strings get
# their word characters reversed.
#
# reference - String reference to modify
#
......@@ -25,7 +26,7 @@ def invalidate_reference(reference)
# SHA-based reference with optional prefix
reference.gsub(/\h{6,40}\z/) { |v| v.reverse }
else
reference
reference.gsub(/\w+\z/) { |v| v.reverse }
end
end
......