diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
index ee0ee05c3be..859184b6c3a 100644
--- a/lib/gitlab/markdown.rb
+++ b/lib/gitlab/markdown.rb
@@ -26,15 +26,19 @@ module Gitlab
# => "
module Markdown
REFERENCE_PATTERN = %r{
- (\W)? # Prefix (1)
- ( # Reference (2)
- @([\w\._]+) # User name (3)
- |[#!$](\d+) # Issue/MR/Snippet ID (4)
- |([\h]{6,40}) # Commit ID (5)
+ (?\W)? # Prefix
+ ( # Reference
+ @(?[a-zA-Z][a-zA-Z0-9_\-\.]*) # User name
+ |\#(?\d+) # Issue ID
+ |!(?\d+) # MR ID
+ |\$(?\d+) # Snippet ID
+ |(?[\h]{6,40}) # Commit ID
)
- (\W)? # Suffix (6)
+ (?\W)? # Suffix
}x.freeze
+ TYPES = [:user, :issue, :merge_request, :snippet, :commit].freeze
+
EMOJI_PATTERN = %r{(:(\S+):)}.freeze
attr_reader :html_options
@@ -95,16 +99,16 @@ module Gitlab
def parse_references(text)
# parse reference links
text.gsub!(REFERENCE_PATTERN) do |match|
- prefix = $1 || ''
- reference = $2
- identifier = $3 || $4 || $5
- suffix = $6 || ''
+ prefix = $~[:prefix]
+ suffix = $~[:suffix]
+ type = TYPES.select{|t| !$~[t].nil?}.first
+ identifier = $~[type]
# Avoid HTML entities
- if prefix.ends_with?('&') || suffix.starts_with?(';')
+ if prefix && suffix && prefix[0] == '&' && suffix[-1] == ';'
match
- elsif ref_link = reference_link(reference, identifier)
- prefix + ref_link + suffix
+ elsif ref_link = reference_link(type, identifier)
+ "#{prefix}#{ref_link}#{suffix}"
else
match
end
@@ -137,19 +141,12 @@ module Gitlab
# identifier - Object identifier (Issue ID, SHA hash, etc.)
#
# Returns string rendered by the processing method
- def reference_link(reference, identifier)
- case reference
- 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
+ def reference_link(type, identifier)
+ send("reference_#{type}", identifier)
end
def reference_user(identifier)
- if user = @project.users.where(name: identifier).first
- member = @project.users_projects.where(user_id: user).first
+ if member = @project.users_projects.joins(:user).where(users: { username: identifier }).first
link_to("@#{identifier}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
end
end
diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb
index 05e4527b278..1eafc6663a2 100644
--- a/spec/helpers/gitlab_markdown_helper_spec.rb
+++ b/spec/helpers/gitlab_markdown_helper_spec.rb
@@ -3,7 +3,7 @@ require "spec_helper"
describe GitlabMarkdownHelper do
let!(:project) { create(:project) }
- let(:user) { create(:user, name: 'gfm') }
+ let(:user) { create(:user, username: 'gfm') }
let(:commit) { CommitDecorator.decorate(project.commit) }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, project: project) }
@@ -81,7 +81,7 @@ describe GitlabMarkdownHelper do
end
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) }
before do
@@ -103,18 +103,18 @@ describe GitlabMarkdownHelper do
end
it "should link with adjacent text" do
- actual = "Mail the admin (@gfm)"
+ actual = "Mail the admin (@#{user.username})"
gfm(actual).should match(expected)
end
it "should keep whitespace intact" do
- actual = "Yes, @#{user.name} is right."
- expected = /Yes, @#{user.name}<\/a> is right/
+ actual = "Yes, @#{user.username} is right."
+ expected = /Yes, @#{user.username}<\/a> is right/
gfm(actual).should match(expected)
end
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
end
@@ -316,10 +316,10 @@ describe GitlabMarkdownHelper do
it "should handle references in lists" do
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{dark: ##{issue.id}})
- markdown(actual).should match(%r{light by @#{member.user_name}})
+ markdown(actual).should match(%r{light by @#{member.user.username}})
end
it "should handle references in " do
diff --git a/spec/requests/gitlab_flavored_markdown_spec.rb b/spec/requests/gitlab_flavored_markdown_spec.rb
index ad5d7cd7607..98319f81657 100644
--- a/spec/requests/gitlab_flavored_markdown_spec.rb
+++ b/spec/requests/gitlab_flavored_markdown_spec.rb
@@ -19,7 +19,7 @@ describe "Gitlab Flavored Markdown" do
@test_file = "gfm_test_file"
i.add(@test_file, "foo\nbar\n")
# 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
@tag_name = "gfm-test-tag"
@@ -56,7 +56,7 @@ describe "Gitlab Flavored Markdown" do
it "should render description in commits#show" do
visit project_commit_path(project, commit)
- page.should have_link("@#{fred.name}")
+ page.should have_link("@#{fred.username}")
end
it "should render title in refs#tree", js: true do
@@ -93,7 +93,7 @@ describe "Gitlab Flavored Markdown" do
assignee: @user,
project: project,
title: "fix ##{@other_issue.id}",
- description: "ask @#{fred.name} for details")
+ description: "ask @#{fred.username} for details")
end
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
visit project_issue_path(project, @issue)
- page.should have_link("@#{fred.name}")
+ page.should have_link("@#{fred.username}")
end
end
@@ -142,7 +142,7 @@ describe "Gitlab Flavored Markdown" do
@milestone = create(:milestone,
project: project,
title: "fix ##{issue.id}",
- description: "ask @#{fred.name} for details")
+ description: "ask @#{fred.username} for details")
end
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
visit project_milestone_path(project, @milestone)
- page.should have_link("@#{fred.name}")
+ page.should have_link("@#{fred.username}")
end
end