Merge pull request #2208 from jouve/username2
Allow proper use of @username in Git(lab|hub) Flavored Markdown.
This commit is contained in:
commit
85db534afc
|
@ -26,15 +26,19 @@ module Gitlab
|
||||||
# => "<img alt=\":trollface:\" class=\"emoji\" src=\"/images/trollface.png" title=\":trollface:\" />
|
# => "<img alt=\":trollface:\" class=\"emoji\" src=\"/images/trollface.png" title=\":trollface:\" />
|
||||||
module Markdown
|
module Markdown
|
||||||
REFERENCE_PATTERN = %r{
|
REFERENCE_PATTERN = %r{
|
||||||
(\W)? # Prefix (1)
|
(?<prefix>\W)? # Prefix
|
||||||
( # Reference (2)
|
( # Reference
|
||||||
@([\w\._]+) # User name (3)
|
@(?<user>[a-zA-Z][a-zA-Z0-9_\-\.]*) # User name
|
||||||
|[#!$](\d+) # Issue/MR/Snippet ID (4)
|
|\#(?<issue>\d+) # Issue ID
|
||||||
|([\h]{6,40}) # Commit ID (5)
|
|!(?<merge_request>\d+) # MR ID
|
||||||
|
|\$(?<snippet>\d+) # Snippet ID
|
||||||
|
|(?<commit>[\h]{6,40}) # Commit ID
|
||||||
)
|
)
|
||||||
(\W)? # Suffix (6)
|
(?<suffix>\W)? # Suffix
|
||||||
}x.freeze
|
}x.freeze
|
||||||
|
|
||||||
|
TYPES = [:user, :issue, :merge_request, :snippet, :commit].freeze
|
||||||
|
|
||||||
EMOJI_PATTERN = %r{(:(\S+):)}.freeze
|
EMOJI_PATTERN = %r{(:(\S+):)}.freeze
|
||||||
|
|
||||||
attr_reader :html_options
|
attr_reader :html_options
|
||||||
|
@ -95,16 +99,16 @@ module Gitlab
|
||||||
def parse_references(text)
|
def parse_references(text)
|
||||||
# parse reference links
|
# parse reference links
|
||||||
text.gsub!(REFERENCE_PATTERN) do |match|
|
text.gsub!(REFERENCE_PATTERN) do |match|
|
||||||
prefix = $1 || ''
|
prefix = $~[:prefix]
|
||||||
reference = $2
|
suffix = $~[:suffix]
|
||||||
identifier = $3 || $4 || $5
|
type = TYPES.select{|t| !$~[t].nil?}.first
|
||||||
suffix = $6 || ''
|
identifier = $~[type]
|
||||||
|
|
||||||
# Avoid HTML entities
|
# Avoid HTML entities
|
||||||
if prefix.ends_with?('&') || suffix.starts_with?(';')
|
if prefix && suffix && prefix[0] == '&' && suffix[-1] == ';'
|
||||||
match
|
match
|
||||||
elsif ref_link = reference_link(reference, identifier)
|
elsif ref_link = reference_link(type, identifier)
|
||||||
prefix + ref_link + suffix
|
"#{prefix}#{ref_link}#{suffix}"
|
||||||
else
|
else
|
||||||
match
|
match
|
||||||
end
|
end
|
||||||
|
@ -137,19 +141,12 @@ module Gitlab
|
||||||
# identifier - Object identifier (Issue ID, SHA hash, etc.)
|
# identifier - Object identifier (Issue ID, SHA hash, etc.)
|
||||||
#
|
#
|
||||||
# Returns string rendered by the processing method
|
# Returns string rendered by the processing method
|
||||||
def reference_link(reference, identifier)
|
def reference_link(type, identifier)
|
||||||
case reference
|
send("reference_#{type}", identifier)
|
||||||
when /^@/ then reference_user(identifier)
|
|
||||||
when /^#/ then reference_issue(identifier)
|
|
||||||
when /^!/ then reference_merge_request(identifier)
|
|
||||||
when /^\$/ then reference_snippet(identifier)
|
|
||||||
when /^\h/ then reference_commit(identifier)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def reference_user(identifier)
|
def reference_user(identifier)
|
||||||
if user = @project.users.where(name: identifier).first
|
if member = @project.users_projects.joins(:user).where(users: { username: identifier }).first
|
||||||
member = @project.users_projects.where(user_id: user).first
|
|
||||||
link_to("@#{identifier}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
|
link_to("@#{identifier}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ require "spec_helper"
|
||||||
describe GitlabMarkdownHelper do
|
describe GitlabMarkdownHelper do
|
||||||
let!(:project) { create(:project) }
|
let!(:project) { create(:project) }
|
||||||
|
|
||||||
let(:user) { create(:user, name: 'gfm') }
|
let(:user) { create(:user, username: 'gfm') }
|
||||||
let(:commit) { CommitDecorator.decorate(project.commit) }
|
let(:commit) { CommitDecorator.decorate(project.commit) }
|
||||||
let(:issue) { create(:issue, project: project) }
|
let(:issue) { create(:issue, project: project) }
|
||||||
let(:merge_request) { create(:merge_request, project: project) }
|
let(:merge_request) { create(:merge_request, project: project) }
|
||||||
|
@ -81,7 +81,7 @@ describe GitlabMarkdownHelper do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "referencing a team member" do
|
describe "referencing a team member" do
|
||||||
let(:actual) { "@#{user.name} you are right." }
|
let(:actual) { "@#{user.username} you are right." }
|
||||||
let(:expected) { project_team_member_path(project, member) }
|
let(:expected) { project_team_member_path(project, member) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
@ -103,18 +103,18 @@ describe GitlabMarkdownHelper do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should link with adjacent text" do
|
it "should link with adjacent text" do
|
||||||
actual = "Mail the admin (@gfm)"
|
actual = "Mail the admin (@#{user.username})"
|
||||||
gfm(actual).should match(expected)
|
gfm(actual).should match(expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should keep whitespace intact" do
|
it "should keep whitespace intact" do
|
||||||
actual = "Yes, @#{user.name} is right."
|
actual = "Yes, @#{user.username} is right."
|
||||||
expected = /Yes, <a.+>@#{user.name}<\/a> is right/
|
expected = /Yes, <a.+>@#{user.username}<\/a> is right/
|
||||||
gfm(actual).should match(expected)
|
gfm(actual).should match(expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not link with an invalid id" do
|
it "should not link with an invalid id" do
|
||||||
actual = expected = "@#{user.name.reverse} you are right."
|
actual = expected = "@#{user.username.reverse} you are right."
|
||||||
gfm(actual).should == expected
|
gfm(actual).should == expected
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -316,10 +316,10 @@ describe GitlabMarkdownHelper do
|
||||||
it "should handle references in lists" do
|
it "should handle references in lists" do
|
||||||
project.users << user
|
project.users << user
|
||||||
|
|
||||||
actual = "\n* dark: ##{issue.id}\n* light by @#{member.user_name}"
|
actual = "\n* dark: ##{issue.id}\n* light by @#{member.user.username}"
|
||||||
|
|
||||||
markdown(actual).should match(%r{<li>dark: <a.+>##{issue.id}</a></li>})
|
markdown(actual).should match(%r{<li>dark: <a.+>##{issue.id}</a></li>})
|
||||||
markdown(actual).should match(%r{<li>light by <a.+>@#{member.user_name}</a></li>})
|
markdown(actual).should match(%r{<li>light by <a.+>@#{member.user.username}</a></li>})
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should handle references in <em>" do
|
it "should handle references in <em>" do
|
||||||
|
|
|
@ -19,7 +19,7 @@ describe "Gitlab Flavored Markdown" do
|
||||||
@test_file = "gfm_test_file"
|
@test_file = "gfm_test_file"
|
||||||
i.add(@test_file, "foo\nbar\n")
|
i.add(@test_file, "foo\nbar\n")
|
||||||
# add commit with gfm
|
# add commit with gfm
|
||||||
i.commit("fix ##{issue.id}\n\nask @#{fred.name} for details", head: @branch_name)
|
i.commit("fix ##{issue.id}\n\nask @#{fred.username} for details", head: @branch_name)
|
||||||
|
|
||||||
# add test tag
|
# add test tag
|
||||||
@tag_name = "gfm-test-tag"
|
@tag_name = "gfm-test-tag"
|
||||||
|
@ -56,7 +56,7 @@ describe "Gitlab Flavored Markdown" do
|
||||||
it "should render description in commits#show" do
|
it "should render description in commits#show" do
|
||||||
visit project_commit_path(project, commit)
|
visit project_commit_path(project, commit)
|
||||||
|
|
||||||
page.should have_link("@#{fred.name}")
|
page.should have_link("@#{fred.username}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should render title in refs#tree", js: true do
|
it "should render title in refs#tree", js: true do
|
||||||
|
@ -93,7 +93,7 @@ describe "Gitlab Flavored Markdown" do
|
||||||
assignee: @user,
|
assignee: @user,
|
||||||
project: project,
|
project: project,
|
||||||
title: "fix ##{@other_issue.id}",
|
title: "fix ##{@other_issue.id}",
|
||||||
description: "ask @#{fred.name} for details")
|
description: "ask @#{fred.username} for details")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should render subject in issues#index" do
|
it "should render subject in issues#index" do
|
||||||
|
@ -111,7 +111,7 @@ describe "Gitlab Flavored Markdown" do
|
||||||
it "should render details in issues#show" do
|
it "should render details in issues#show" do
|
||||||
visit project_issue_path(project, @issue)
|
visit project_issue_path(project, @issue)
|
||||||
|
|
||||||
page.should have_link("@#{fred.name}")
|
page.should have_link("@#{fred.username}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ describe "Gitlab Flavored Markdown" do
|
||||||
@milestone = create(:milestone,
|
@milestone = create(:milestone,
|
||||||
project: project,
|
project: project,
|
||||||
title: "fix ##{issue.id}",
|
title: "fix ##{issue.id}",
|
||||||
description: "ask @#{fred.name} for details")
|
description: "ask @#{fred.username} for details")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should render title in milestones#index" do
|
it "should render title in milestones#index" do
|
||||||
|
@ -160,7 +160,7 @@ describe "Gitlab Flavored Markdown" do
|
||||||
it "should render description in milestones#show" do
|
it "should render description in milestones#show" do
|
||||||
visit project_milestone_path(project, @milestone)
|
visit project_milestone_path(project, @milestone)
|
||||||
|
|
||||||
page.should have_link("@#{fred.name}")
|
page.should have_link("@#{fred.username}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue