Commit 72c6be2d1a9794c19fa18148434f821d52e20018
Exists in
master
and in
4 other branches
Merge pull request #1183 from riyad/gitlab-flavored-markdown
Gitlab flavored markdown
Showing
34 changed files
with
634 additions
and
143 deletions
Show diff stats
app/controllers/refs_controller.rb
| @@ -90,6 +90,7 @@ class RefsController < ApplicationController | @@ -90,6 +90,7 @@ class RefsController < ApplicationController | ||
| 90 | 90 | ||
| 91 | @repo = project.repo | 91 | @repo = project.repo |
| 92 | @commit = project.commit(@ref) | 92 | @commit = project.commit(@ref) |
| 93 | + @commit = CommitDecorator.decorate(@commit) | ||
| 93 | @tree = Tree.new(@commit.tree, project, @ref, params[:path]) | 94 | @tree = Tree.new(@commit.tree, project, @ref, params[:path]) |
| 94 | @tree = TreeDecorator.new(@tree) | 95 | @tree = TreeDecorator.new(@tree) |
| 95 | @hex_path = Digest::SHA1.hexdigest(params[:path] || "/") | 96 | @hex_path = Digest::SHA1.hexdigest(params[:path] || "/") |
app/helpers/application_helper.rb
| @@ -42,8 +42,88 @@ module ApplicationHelper | @@ -42,8 +42,88 @@ module ApplicationHelper | ||
| 42 | grouped_options_for_select(options, @ref || @project.default_branch) | 42 | grouped_options_for_select(options, @ref || @project.default_branch) |
| 43 | end | 43 | end |
| 44 | 44 | ||
| 45 | + def gfm(text, html_options = {}) | ||
| 46 | + return text if text.nil? | ||
| 47 | + raise "@project is not set" if @project.nil? | ||
| 48 | + | ||
| 49 | + # Extract pre blocks | ||
| 50 | + # from http://github.github.com/github-flavored-markdown/ | ||
| 51 | + extractions = {} | ||
| 52 | + text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) do |match| | ||
| 53 | + md5 = Digest::MD5.hexdigest(match) | ||
| 54 | + extractions[md5] = match | ||
| 55 | + "{gfm-extraction-#{md5}}" | ||
| 56 | + end | ||
| 57 | + | ||
| 58 | + # match 1 2 3 4 5 6 | ||
| 59 | + text.gsub!(/(\W)?(@([\w\._]+)|[#!$](\d+)|([\h]{6,40}))(\W)?/) do |match| | ||
| 60 | + prefix = $1 | ||
| 61 | + reference = $2 | ||
| 62 | + user_name = $3 | ||
| 63 | + issue_id = $4 | ||
| 64 | + merge_request_id = $4 | ||
| 65 | + snippet_id = $4 | ||
| 66 | + commit_id = $5 | ||
| 67 | + suffix = $6 | ||
| 68 | + | ||
| 69 | + # TODO: add popups with additional information | ||
| 70 | + ref_link = case reference | ||
| 71 | + | ||
| 72 | + # team member: @foo | ||
| 73 | + when /^@/ | ||
| 74 | + user = @project.users.where(:name => user_name).first | ||
| 75 | + member = @project.users_projects.where(:user_id => user).first if user | ||
| 76 | + link_to("@#{user_name}", project_team_member_path(@project, member), html_options.merge(:class => "gfm gfm-team_member #{html_options[:class]}")) if member | ||
| 77 | + | ||
| 78 | + # issue: #123 | ||
| 79 | + when /^#/ | ||
| 80 | + # avoid HTML entities | ||
| 81 | + unless prefix.try(:end_with?, "&") && suffix.try(:start_with?, ";") | ||
| 82 | + issue = @project.issues.where(:id => issue_id).first | ||
| 83 | + link_to("##{issue_id}", project_issue_path(@project, issue), html_options.merge(:title => "Issue: #{issue.title}", :class => "gfm gfm-issue #{html_options[:class]}")) if issue | ||
| 84 | + end | ||
| 85 | + | ||
| 86 | + # merge request: !123 | ||
| 87 | + when /^!/ | ||
| 88 | + merge_request = @project.merge_requests.where(:id => merge_request_id).first | ||
| 89 | + link_to("!#{merge_request_id}", project_merge_request_path(@project, merge_request), html_options.merge(:title => "Merge Request: #{merge_request.title}", :class => "gfm gfm-merge_request #{html_options[:class]}")) if merge_request | ||
| 90 | + | ||
| 91 | + # snippet: $123 | ||
| 92 | + when /^\$/ | ||
| 93 | + snippet = @project.snippets.where(:id => snippet_id).first | ||
| 94 | + link_to("$#{snippet_id}", project_snippet_path(@project, snippet), html_options.merge(:title => "Snippet: #{snippet.title}", :class => "gfm gfm-snippet #{html_options[:class]}")) if snippet | ||
| 95 | + | ||
| 96 | + # commit: 123456... | ||
| 97 | + when /^\h/ | ||
| 98 | + commit = @project.commit(commit_id) | ||
| 99 | + link_to(commit_id, project_commit_path(@project, :id => commit.id), html_options.merge(:title => "Commit: #{commit.author_name} - #{CommitDecorator.new(commit).title}", :class => "gfm gfm-commit #{html_options[:class]}")) if commit | ||
| 100 | + | ||
| 101 | + end # case | ||
| 102 | + | ||
| 103 | + ref_link.nil? ? match : "#{prefix}#{ref_link}#{suffix}" | ||
| 104 | + end # gsub | ||
| 105 | + | ||
| 106 | + # Insert pre block extractions | ||
| 107 | + text.gsub!(/\{gfm-extraction-(\h{32})\}/) do | ||
| 108 | + extractions[$1] | ||
| 109 | + end | ||
| 110 | + | ||
| 111 | + text.html_safe | ||
| 112 | + end | ||
| 113 | + | ||
| 114 | + # circumvents nesting links, which will behave bad in browsers | ||
| 115 | + def link_to_gfm(body, url, html_options = {}) | ||
| 116 | + gfm_body = gfm(body, html_options) | ||
| 117 | + | ||
| 118 | + gfm_body.gsub!(%r{<a.*?>.*?</a>}m) do |match| | ||
| 119 | + "</a>#{match}#{link_to("", url, html_options)[0..-5]}" # "</a>".length +1 | ||
| 120 | + end | ||
| 121 | + | ||
| 122 | + link_to(gfm_body.html_safe, url, html_options) | ||
| 123 | + end | ||
| 124 | + | ||
| 45 | def markdown(text) | 125 | def markdown(text) |
| 46 | - @__renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::GitlabHTML.new({ filter_html: true, with_toc_data: true }), { | 126 | + @__renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::GitlabHTML.new(self, filter_html: true, with_toc_data: true), { |
| 47 | no_intra_emphasis: true, | 127 | no_intra_emphasis: true, |
| 48 | tables: true, | 128 | tables: true, |
| 49 | fenced_code_blocks: true, | 129 | fenced_code_blocks: true, |
app/helpers/commits_helper.rb
| 1 | module CommitsHelper | 1 | module CommitsHelper |
| 2 | - def commit_msg_with_link_to_issues(project, message) | ||
| 3 | - return '' unless message | ||
| 4 | - out = '' | ||
| 5 | - message.split(/(#[0-9]+)/m).each do |m| | ||
| 6 | - if m =~ /(#([0-9]+))/m | ||
| 7 | - begin | ||
| 8 | - issue = project.issues.find($2) | ||
| 9 | - out += link_to($1, project_issue_path(project, $2)) | ||
| 10 | - rescue | ||
| 11 | - out += $1 | ||
| 12 | - end | ||
| 13 | - else | ||
| 14 | - out += m | ||
| 15 | - end | ||
| 16 | - end | ||
| 17 | - preserve out | ||
| 18 | - end | ||
| 19 | - | ||
| 20 | def identification_type(line) | 2 | def identification_type(line) |
| 21 | if line[0] == "+" | 3 | if line[0] == "+" |
| 22 | "new" | 4 | "new" |
app/mailers/notify.rb
| @@ -16,59 +16,69 @@ class Notify < ActionMailer::Base | @@ -16,59 +16,69 @@ class Notify < ActionMailer::Base | ||
| 16 | 16 | ||
| 17 | def new_issue_email(issue_id) | 17 | def new_issue_email(issue_id) |
| 18 | @issue = Issue.find(issue_id) | 18 | @issue = Issue.find(issue_id) |
| 19 | - mail(:to => @issue.assignee_email, :subject => "gitlab | New Issue was created") | 19 | + @project = @issue.project |
| 20 | + mail(:to => @issue.assignee_email, :subject => "gitlab | new issue ##{@issue.id} | #{@issue.title} | #{@project.name}") | ||
| 20 | end | 21 | end |
| 21 | 22 | ||
| 22 | def note_wall_email(recipient_id, note_id) | 23 | def note_wall_email(recipient_id, note_id) |
| 23 | recipient = User.find(recipient_id) | 24 | recipient = User.find(recipient_id) |
| 24 | @note = Note.find(note_id) | 25 | @note = Note.find(note_id) |
| 25 | - mail(:to => recipient.email, :subject => "gitlab | #{@note.project_name} ") | 26 | + @project = @note.project |
| 27 | + mail(:to => recipient.email, :subject => "gitlab | #{@project.name}") | ||
| 26 | end | 28 | end |
| 27 | 29 | ||
| 28 | def note_commit_email(recipient_id, note_id) | 30 | def note_commit_email(recipient_id, note_id) |
| 29 | recipient = User.find(recipient_id) | 31 | recipient = User.find(recipient_id) |
| 30 | @note = Note.find(note_id) | 32 | @note = Note.find(note_id) |
| 31 | @commit = @note.target | 33 | @commit = @note.target |
| 32 | - mail(:to => recipient.email, :subject => "gitlab | note for commit | #{@note.project_name} ") | 34 | + @commit = CommitDecorator.decorate(@commit) |
| 35 | + @project = @note.project | ||
| 36 | + mail(:to => recipient.email, :subject => "gitlab | note for commit #{@commit.short_id} | #{@commit.title} | #{@project.name}") | ||
| 33 | end | 37 | end |
| 34 | 38 | ||
| 35 | def note_merge_request_email(recipient_id, note_id) | 39 | def note_merge_request_email(recipient_id, note_id) |
| 36 | recipient = User.find(recipient_id) | 40 | recipient = User.find(recipient_id) |
| 37 | @note = Note.find(note_id) | 41 | @note = Note.find(note_id) |
| 38 | @merge_request = @note.noteable | 42 | @merge_request = @note.noteable |
| 39 | - mail(:to => recipient.email, :subject => "gitlab | note for merge request | #{@note.project_name} ") | 43 | + @project = @note.project |
| 44 | + mail(:to => recipient.email, :subject => "gitlab | note for merge request !#{@merge_request.id} | #{@project.name}") | ||
| 40 | end | 45 | end |
| 41 | 46 | ||
| 42 | def note_issue_email(recipient_id, note_id) | 47 | def note_issue_email(recipient_id, note_id) |
| 43 | recipient = User.find(recipient_id) | 48 | recipient = User.find(recipient_id) |
| 44 | @note = Note.find(note_id) | 49 | @note = Note.find(note_id) |
| 45 | @issue = @note.noteable | 50 | @issue = @note.noteable |
| 46 | - mail(:to => recipient.email, :subject => "gitlab | note for issue #{@issue.id} | #{@note.project_name} ") | 51 | + @project = @note.project |
| 52 | + mail(:to => recipient.email, :subject => "gitlab | note for issue ##{@issue.id} | #{@project.name}") | ||
| 47 | end | 53 | end |
| 48 | 54 | ||
| 49 | def note_wiki_email(recipient_id, note_id) | 55 | def note_wiki_email(recipient_id, note_id) |
| 50 | recipient = User.find(recipient_id) | 56 | recipient = User.find(recipient_id) |
| 51 | @note = Note.find(note_id) | 57 | @note = Note.find(note_id) |
| 52 | @wiki = @note.noteable | 58 | @wiki = @note.noteable |
| 53 | - mail(:to => recipient.email, :subject => "gitlab | note for wiki | #{@note.project_name}") | 59 | + @project = @note.project |
| 60 | + mail(:to => recipient.email, :subject => "gitlab | note for wiki | #{@project.name}") | ||
| 54 | end | 61 | end |
| 55 | 62 | ||
| 56 | def new_merge_request_email(merge_request_id) | 63 | def new_merge_request_email(merge_request_id) |
| 57 | @merge_request = MergeRequest.find(merge_request_id) | 64 | @merge_request = MergeRequest.find(merge_request_id) |
| 58 | - mail(:to => @merge_request.assignee_email, :subject => "gitlab | new merge request | #{@merge_request.title} ") | 65 | + @project = @merge_request.project |
| 66 | + mail(:to => @merge_request.assignee_email, :subject => "gitlab | new merge request !#{@merge_request.id} | #{@merge_request.title} | #{@project.name}") | ||
| 59 | end | 67 | end |
| 60 | 68 | ||
| 61 | def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id) | 69 | def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id) |
| 62 | recipient = User.find(recipient_id) | 70 | recipient = User.find(recipient_id) |
| 63 | @merge_request = MergeRequest.find(merge_request_id) | 71 | @merge_request = MergeRequest.find(merge_request_id) |
| 64 | @previous_assignee ||= User.find(previous_assignee_id) | 72 | @previous_assignee ||= User.find(previous_assignee_id) |
| 65 | - mail(:to => recipient.email, :subject => "gitlab | merge request changed | #{@merge_request.title} ") | 73 | + @project = @merge_request.project |
| 74 | + mail(:to => recipient.email, :subject => "gitlab | changed merge request !#{@merge_request.id} | #{@merge_request.title} | #{@project.name}") | ||
| 66 | end | 75 | end |
| 67 | 76 | ||
| 68 | def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id) | 77 | def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id) |
| 69 | recipient = User.find(recipient_id) | 78 | recipient = User.find(recipient_id) |
| 70 | @issue = Issue.find(issue_id) | 79 | @issue = Issue.find(issue_id) |
| 71 | @previous_assignee ||= User.find(previous_assignee_id) | 80 | @previous_assignee ||= User.find(previous_assignee_id) |
| 72 | - mail(:to => recipient.email, :subject => "gitlab | changed issue | #{@issue.title} ") | 81 | + @project = @issue.project |
| 82 | + mail(:to => recipient.email, :subject => "gitlab | changed issue ##{@issue.id} | #{@issue.title} | #{@project.name}") | ||
| 73 | end | 83 | end |
| 74 | end | 84 | end |
app/views/commits/_commit.html.haml
| @@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
| 7 | %strong.cgray= commit.author_name | 7 | %strong.cgray= commit.author_name |
| 8 | – | 8 | – |
| 9 | = image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16 | 9 | = image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16 |
| 10 | - = link_to truncate(commit.title, :length => 50), project_commit_path(@project, :id => commit.id), :class => "row_title" | 10 | + = link_to_gfm truncate(commit.title, :length => 50), project_commit_path(@project, :id => commit.id), :class => "row_title" |
| 11 | 11 | ||
| 12 | %span.committed_ago | 12 | %span.committed_ago |
| 13 | = time_ago_in_words(commit.committed_date) | 13 | = time_ago_in_words(commit.committed_date) |
app/views/commits/_commit_box.html.haml
| @@ -11,10 +11,10 @@ | @@ -11,10 +11,10 @@ | ||
| 11 | = link_to tree_project_ref_path(@project, @commit.id), :class => "browse-button primary grouped" do | 11 | = link_to tree_project_ref_path(@project, @commit.id), :class => "browse-button primary grouped" do |
| 12 | %strong Browse Code » | 12 | %strong Browse Code » |
| 13 | %h3.commit-title.page_title | 13 | %h3.commit-title.page_title |
| 14 | - = commit_msg_with_link_to_issues(@project, @commit.title) | 14 | + = gfm @commit.title |
| 15 | - if @commit.description.present? | 15 | - if @commit.description.present? |
| 16 | %pre.commit-description | 16 | %pre.commit-description |
| 17 | - = commit_msg_with_link_to_issues(@project, @commit.description) | 17 | + = gfm @commit.description |
| 18 | .commit-info | 18 | .commit-info |
| 19 | .row | 19 | .row |
| 20 | .span4 | 20 | .span4 |
app/views/commits/index.atom.builder
| @@ -17,7 +17,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear | @@ -17,7 +17,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear | ||
| 17 | xml.name commit.author_name | 17 | xml.name commit.author_name |
| 18 | xml.email commit.author_email | 18 | xml.email commit.author_email |
| 19 | end | 19 | end |
| 20 | - xml.summary commit.description | 20 | + xml.summary gfm(commit.description) |
| 21 | end | 21 | end |
| 22 | end | 22 | end |
| 23 | end | 23 | end |
app/views/dashboard/issues.html.haml
| @@ -8,8 +8,8 @@ | @@ -8,8 +8,8 @@ | ||
| 8 | - if @issues.any? | 8 | - if @issues.any? |
| 9 | - @issues.group_by(&:project).each do |group| | 9 | - @issues.group_by(&:project).each do |group| |
| 10 | %div.ui-box | 10 | %div.ui-box |
| 11 | - - project = group[0] | ||
| 12 | - %h5= project.name | 11 | + - @project = group[0] |
| 12 | + %h5= @project.name | ||
| 13 | %ul.unstyled.issues_table | 13 | %ul.unstyled.issues_table |
| 14 | - group[1].each do |issue| | 14 | - group[1].each do |issue| |
| 15 | = render(:partial => 'issues/show', :locals => {:issue => issue}) | 15 | = render(:partial => 'issues/show', :locals => {:issue => issue}) |
app/views/dashboard/merge_requests.html.haml
| @@ -7,8 +7,8 @@ | @@ -7,8 +7,8 @@ | ||
| 7 | - if @merge_requests.any? | 7 | - if @merge_requests.any? |
| 8 | - @merge_requests.group_by(&:project).each do |group| | 8 | - @merge_requests.group_by(&:project).each do |group| |
| 9 | %ul.unstyled.ui-box | 9 | %ul.unstyled.ui-box |
| 10 | - - project = group[0] | ||
| 11 | - %h5= project.name | 10 | + - @project = group[0] |
| 11 | + %h5= @project.name | ||
| 12 | - group[1].each do |merge_request| | 12 | - group[1].each do |merge_request| |
| 13 | = render(:partial => 'merge_requests/merge_request', :locals => {:merge_request => merge_request}) | 13 | = render(:partial => 'merge_requests/merge_request', :locals => {:merge_request => merge_request}) |
| 14 | %hr | 14 | %hr |
app/views/events/_commit.html.haml
| @@ -5,5 +5,5 @@ | @@ -5,5 +5,5 @@ | ||
| 5 | %strong.cdark= commit.author_name | 5 | %strong.cdark= commit.author_name |
| 6 | – | 6 | – |
| 7 | = image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16 | 7 | = image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16 |
| 8 | - = truncate(commit.title, :length => 50) rescue "--broken encoding" | 8 | + = gfm truncate(commit.title, :length => 50), project_commit_path(project, :id => commit.id) rescue "--broken encoding" |
| 9 | 9 |
app/views/issues/_show.html.haml
| @@ -25,7 +25,7 @@ | @@ -25,7 +25,7 @@ | ||
| 25 | - else | 25 | - else |
| 26 | = image_tag "no_avatar.png", :class => "avatar" | 26 | = image_tag "no_avatar.png", :class => "avatar" |
| 27 | 27 | ||
| 28 | - %p= link_to truncate(issue.title, :length => 100), project_issue_path(issue.project, issue), :class => "row_title" | 28 | + %p= link_to_gfm truncate(issue.title, :length => 100), project_issue_path(issue.project, issue), :class => "row_title" |
| 29 | 29 | ||
| 30 | %span.update-author | 30 | %span.update-author |
| 31 | %small.cdark= "##{issue.id}" | 31 | %small.cdark= "##{issue.id}" |
app/views/issues/show.html.haml
| @@ -31,7 +31,7 @@ | @@ -31,7 +31,7 @@ | ||
| 31 | .alert-message.error.status_info Closed | 31 | .alert-message.error.status_info Closed |
| 32 | - else | 32 | - else |
| 33 | .alert-message.success.status_info Open | 33 | .alert-message.success.status_info Open |
| 34 | - = @issue.title | 34 | + = gfm @issue.title |
| 35 | 35 | ||
| 36 | .middle_box_content | 36 | .middle_box_content |
| 37 | %cite.cgray Created by | 37 | %cite.cgray Created by |
| @@ -46,7 +46,7 @@ | @@ -46,7 +46,7 @@ | ||
| 46 | - if @issue.milestone | 46 | - if @issue.milestone |
| 47 | - milestone = @issue.milestone | 47 | - milestone = @issue.milestone |
| 48 | %cite.cgray and attached to milestone | 48 | %cite.cgray and attached to milestone |
| 49 | - %strong= link_to truncate(milestone.title, :length => 20), project_milestone_path(milestone.project, milestone) | 49 | + %strong= link_to_gfm truncate(milestone.title, :length => 20), project_milestone_path(milestone.project, milestone) |
| 50 | 50 | ||
| 51 | .right | 51 | .right |
| 52 | - @issue.labels.each do |label| | 52 | - @issue.labels.each do |label| |
app/views/merge_requests/_merge_request.html.haml
| @@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
| 16 | = merge_request.target_branch | 16 | = merge_request.target_branch |
| 17 | = image_tag gravatar_icon(merge_request.author_email), :class => "avatar" | 17 | = image_tag gravatar_icon(merge_request.author_email), :class => "avatar" |
| 18 | 18 | ||
| 19 | - %p= link_to truncate(merge_request.title, :length => 80), project_merge_request_path(merge_request.project, merge_request), :class => "row_title" | 19 | + %p= link_to_gfm truncate(merge_request.title, :length => 80), project_merge_request_path(merge_request.project, merge_request), :class => "row_title" |
| 20 | 20 | ||
| 21 | %span.update-author | 21 | %span.update-author |
| 22 | %small.cdark= "##{merge_request.id}" | 22 | %small.cdark= "##{merge_request.id}" |
app/views/merge_requests/show/_mr_box.html.haml
| @@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
| 5 | .alert-message.error.status_info Closed | 5 | .alert-message.error.status_info Closed |
| 6 | - else | 6 | - else |
| 7 | .alert-message.success.status_info Open | 7 | .alert-message.success.status_info Open |
| 8 | - = @merge_request.title | 8 | + = gfm @merge_request.title |
| 9 | 9 | ||
| 10 | .middle_box_content | 10 | .middle_box_content |
| 11 | %div | 11 | %div |
app/views/milestones/_milestone.html.haml
| @@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
| 7 | - if can? current_user, :admin_milestone, milestone.project | 7 | - if can? current_user, :admin_milestone, milestone.project |
| 8 | = link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), :class => "btn small edit-milestone-link grouped" | 8 | = link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), :class => "btn small edit-milestone-link grouped" |
| 9 | %h4 | 9 | %h4 |
| 10 | - = link_to truncate(milestone.title, :length => 100), project_milestone_path(milestone.project, milestone), :class => "row_title" | 10 | + = link_to_gfm truncate(milestone.title, :length => 100), project_milestone_path(milestone.project, milestone), :class => "row_title" |
| 11 | %small | 11 | %small |
| 12 | = milestone.expires_at | 12 | = milestone.expires_at |
| 13 | %br | 13 | %br |
app/views/milestones/show.html.haml
| @@ -21,7 +21,7 @@ | @@ -21,7 +21,7 @@ | ||
| 21 | .alert-message.error.status_info Closed | 21 | .alert-message.error.status_info Closed |
| 22 | - else | 22 | - else |
| 23 | .alert-message.success.status_info Open | 23 | .alert-message.success.status_info Open |
| 24 | - = @milestone.title | 24 | + = gfm @milestone.title |
| 25 | %small.right= @milestone.expires_at | 25 | %small.right= @milestone.expires_at |
| 26 | 26 | ||
| 27 | .middle_box_content | 27 | .middle_box_content |
| @@ -51,7 +51,7 @@ | @@ -51,7 +51,7 @@ | ||
| 51 | = link_to [@project, issue] do | 51 | = link_to [@project, issue] do |
| 52 | %span.badge.badge-info ##{issue.id} | 52 | %span.badge.badge-info ##{issue.id} |
| 53 | – | 53 | – |
| 54 | - = link_to truncate(issue.title, :length => 60), [@project, issue] | 54 | + = link_to_gfm truncate(issue.title, :length => 60), [@project, issue] |
| 55 | %br | 55 | %br |
| 56 | = paginate @issues, :theme => "gitlab" | 56 | = paginate @issues, :theme => "gitlab" |
| 57 | 57 |
app/views/notify/new_issue_email.html.haml
| @@ -10,7 +10,6 @@ | @@ -10,7 +10,6 @@ | ||
| 10 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 10 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 11 | %td{:align => "left", :style => "padding: 20px 0 0;"} | 11 | %td{:align => "left", :style => "padding: 20px 0 0;"} |
| 12 | %h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} | 12 | %h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} |
| 13 | - = link_to project_issue_url(@issue.project, @issue), :title => @issue.title do | ||
| 14 | - = "Issue ##{@issue.id.to_s}" | ||
| 15 | - = truncate(@issue.title, :length => 45) | 13 | + = "Issue ##{@issue.id}" |
| 14 | + = link_to_gfm truncate(@issue.title, :length => 45), project_issue_url(@issue.project, @issue), :title => @issue.title | ||
| 16 | %br | 15 | %br |
app/views/notify/new_merge_request_email.html.haml
| @@ -4,8 +4,8 @@ | @@ -4,8 +4,8 @@ | ||
| 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} | 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} |
| 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} | 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} |
| 7 | - New Merge Request | ||
| 8 | - = link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request) | 7 | + = "New Merge Request !#{@merge_request.id}" |
| 8 | + = link_to_gfm truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request) | ||
| 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 10 | %tr | 10 | %tr |
| 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
app/views/notify/note_commit_email.html.haml
| @@ -4,8 +4,8 @@ | @@ -4,8 +4,8 @@ | ||
| 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} | 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} |
| 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} | 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} |
| 7 | - New comment for commit | ||
| 8 | - = link_to truncate(@commit.id.to_s, :length => 16), project_commit_url(@note.project, :id => @commit.id, :anchor => "note_#{@note.id}") | 7 | + = "New comment for Commit #{@commit.short_id}" |
| 8 | + = link_to_gfm truncate(@commit.title, :length => 16), project_commit_url(@note.project, :id => @commit.id, :anchor => "note_#{@note.id}") | ||
| 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 10 | %tr | 10 | %tr |
| 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
app/views/notify/note_issue_email.html.haml
| @@ -4,10 +4,8 @@ | @@ -4,10 +4,8 @@ | ||
| 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} | 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} |
| 6 | %h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} | 6 | %h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} |
| 7 | - New comment - | ||
| 8 | - = link_to project_issue_url(@issue.project, @issue, :anchor => "note_#{@note.id}") do | ||
| 9 | - = "Issue ##{@issue.id.to_s}" | ||
| 10 | - = truncate(@issue.title, :length => 35) | 7 | + = "New comment for Issue ##{@issue.id}" |
| 8 | + = link_to_gfm truncate(@issue.title, :length => 35), project_issue_url(@issue.project, @issue, :anchor => "note_#{@note.id}") | ||
| 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 12 | %tr | 10 | %tr |
| 13 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
app/views/notify/note_merge_request_email.html.haml
| @@ -4,8 +4,8 @@ | @@ -4,8 +4,8 @@ | ||
| 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} | 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} |
| 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} | 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} |
| 7 | - New comment for Merge Request | ||
| 8 | - = link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request, :anchor => "note_#{@note.id}") | 7 | + = "New comment for Merge Request !#{@merge_request.id}" |
| 8 | + = link_to_gfm truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request, :anchor => "note_#{@note.id}") | ||
| 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 10 | %tr | 10 | %tr |
| 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
app/views/notify/note_wiki_email.html.haml
| @@ -4,9 +4,8 @@ | @@ -4,9 +4,8 @@ | ||
| 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} | 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} |
| 6 | %h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} | 6 | %h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} |
| 7 | - New comment - | ||
| 8 | - = link_to project_issue_url(@wiki.project, @wiki, :anchor => "note_#{@note.id}") do | ||
| 9 | - = "Wiki ##{@wiki.title.to_s}" | 7 | + New comment for Wiki page |
| 8 | + = link_to_gfm @wiki.title, project_issue_url(@wiki.project, @wiki, :anchor => "note_#{@note.id}") | ||
| 10 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 11 | %tr | 10 | %tr |
| 12 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
app/views/notify/reassigned_issue_email.html.haml
| @@ -4,8 +4,8 @@ | @@ -4,8 +4,8 @@ | ||
| 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} | 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} |
| 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} | 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} |
| 7 | - Reassigned Issue | ||
| 8 | - = link_to truncate(@issue.title, :length => 16), project_issue_url(@issue.project, @issue) | 7 | + = "Reassigned Issue ##{@issue.id}" |
| 8 | + = link_to_gfm truncate(@issue.title, :length => 16), project_issue_url(@issue.project, @issue) | ||
| 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 10 | %tr | 10 | %tr |
| 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
app/views/notify/reassigned_merge_request_email.html.haml
| @@ -4,8 +4,8 @@ | @@ -4,8 +4,8 @@ | ||
| 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 4 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} | 5 | %td{:align => "left", :style => "padding: 20px 0 0;"} |
| 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} | 6 | %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} |
| 7 | - Reassigned Merge Request | ||
| 8 | - = link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request) | 7 | + = "Reassigned Merge Request !#{@merge_request.id}" |
| 8 | + = link_to_gfm truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request) | ||
| 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 9 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
| 10 | %tr | 10 | %tr |
| 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} | 11 | %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} |
app/views/refs/_tree_commit.html.haml
| 1 | - if tm | 1 | - if tm |
| 2 | %strong= link_to "[#{tm.user_name}]", project_team_member_path(@project, tm) | 2 | %strong= link_to "[#{tm.user_name}]", project_team_member_path(@project, tm) |
| 3 | -= link_to truncate(content_commit.title, :length => tm ? 30 : 50), project_commit_path(@project, content_commit.id), :class => "tree-commit-link" | 3 | += link_to_gfm truncate(content_commit.title, :length => tm ? 30 : 50), project_commit_path(@project, content_commit.id), :class => "tree-commit-link" |
app/views/refs/blame.html.haml
| @@ -33,7 +33,7 @@ | @@ -33,7 +33,7 @@ | ||
| 33 | %td.blame_commit | 33 | %td.blame_commit |
| 34 | | 34 | |
| 35 | %code= link_to commit.short_id, project_commit_path(@project, :id => commit.id) | 35 | %code= link_to commit.short_id, project_commit_path(@project, :id => commit.id) |
| 36 | - = link_to truncate(commit.title, :length => 30), project_commit_path(@project, :id => commit.id), :class => "row_title" rescue "--broken encoding" | 36 | + = link_to_gfm truncate(commit.title, :length => 30), project_commit_path(@project, :id => commit.id), :class => "row_title" rescue "--broken encoding" |
| 37 | %td.lines | 37 | %td.lines |
| 38 | = preserve do | 38 | = preserve do |
| 39 | %pre | 39 | %pre |
app/views/repositories/_branch.html.haml
| @@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
| 11 | %code= commit.short_id | 11 | %code= commit.short_id |
| 12 | 12 | ||
| 13 | = image_tag gravatar_icon(commit.author_email), :class => "", :width => 16 | 13 | = image_tag gravatar_icon(commit.author_email), :class => "", :width => 16 |
| 14 | - = truncate(commit.title, :length => 40) | 14 | + = gfm truncate(commit.title, :length => 40) |
| 15 | %td | 15 | %td |
| 16 | %span.update-author.right | 16 | %span.update-author.right |
| 17 | = time_ago_in_words(commit.committed_date) | 17 | = time_ago_in_words(commit.committed_date) |
app/views/repositories/_feed.html.haml
| @@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
| 13 | = link_to project_commits_path(@project, commit.id) do | 13 | = link_to project_commits_path(@project, commit.id) do |
| 14 | %code= commit.short_id | 14 | %code= commit.short_id |
| 15 | = image_tag gravatar_icon(commit.author_email), :class => "", :width => 16 | 15 | = image_tag gravatar_icon(commit.author_email), :class => "", :width => 16 |
| 16 | - = truncate(commit.title, :length => 40) | 16 | + = gfm truncate(commit.title, :length => 40) |
| 17 | %td | 17 | %td |
| 18 | %span.right.cgray | 18 | %span.right.cgray |
| 19 | = time_ago_in_words(commit.committed_date) | 19 | = time_ago_in_words(commit.committed_date) |
app/views/repositories/tags.html.haml
| @@ -17,7 +17,7 @@ | @@ -17,7 +17,7 @@ | ||
| 17 | = link_to project_commit_path(@project, commit.id) do | 17 | = link_to project_commit_path(@project, commit.id) do |
| 18 | %code= commit.short_id | 18 | %code= commit.short_id |
| 19 | = image_tag gravatar_icon(commit.author_email), :class => "", :width => 16 | 19 | = image_tag gravatar_icon(commit.author_email), :class => "", :width => 16 |
| 20 | - = truncate(commit.title, :length => 40) | 20 | + = gfm truncate(commit.title, :length => 40) |
| 21 | %td | 21 | %td |
| 22 | %span.update-author.right | 22 | %span.update-author.right |
| 23 | = time_ago_in_words(commit.committed_date) | 23 | = time_ago_in_words(commit.committed_date) |
lib/redcarpet/render/gitlab_html.rb
| 1 | class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | 1 | class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML |
| 2 | + | ||
| 3 | + attr_reader :template | ||
| 4 | + alias_method :h, :template | ||
| 5 | + | ||
| 6 | + def initialize(template, options = {}) | ||
| 7 | + @template = template | ||
| 8 | + @project = @template.instance_variable_get("@project") | ||
| 9 | + super options | ||
| 10 | + end | ||
| 11 | + | ||
| 2 | def block_code(code, language) | 12 | def block_code(code, language) |
| 3 | if Pygments::Lexer.find(language) | 13 | if Pygments::Lexer.find(language) |
| 4 | Pygments.highlight(code, :lexer => language, :options => {:encoding => 'utf-8'}) | 14 | Pygments.highlight(code, :lexer => language, :options => {:encoding => 'utf-8'}) |
| @@ -6,4 +16,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | @@ -6,4 +16,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | ||
| 6 | Pygments.highlight(code, :options => {:encoding => 'utf-8'}) | 16 | Pygments.highlight(code, :options => {:encoding => 'utf-8'}) |
| 7 | end | 17 | end |
| 8 | end | 18 | end |
| 19 | + | ||
| 20 | + def postprocess(full_document) | ||
| 21 | + h.gfm(full_document) | ||
| 22 | + end | ||
| 9 | end | 23 | end |
spec/helpers/commit_helper_spec.rb
| @@ -1,67 +0,0 @@ | @@ -1,67 +0,0 @@ | ||
| 1 | -require "spec_helper" | ||
| 2 | -include Haml::Helpers | ||
| 3 | - | ||
| 4 | -describe CommitsHelper do | ||
| 5 | - | ||
| 6 | - before do | ||
| 7 | - @project = Factory :project | ||
| 8 | - @other_project = Factory :project, :path => "OtherPath", :code => "OtherCode" | ||
| 9 | - @fake_user = Factory :user | ||
| 10 | - @valid_issue = Factory :issue, :assignee => @fake_user, :author => @fake_user, :project => @project | ||
| 11 | - @invalid_issue = Factory :issue, :assignee => @fake_user, :author => @fake_user, :project => @other_project | ||
| 12 | - end | ||
| 13 | - | ||
| 14 | - it "should provides return message untouched if no issue number present" do | ||
| 15 | - message = "Dummy message without issue number" | ||
| 16 | - | ||
| 17 | - commit_msg_with_link_to_issues(@project, message).should eql message | ||
| 18 | - end | ||
| 19 | - | ||
| 20 | - it "should returns message handled by preserve" do | ||
| 21 | - message = "My brand new | ||
| 22 | - Commit on multiple | ||
| 23 | - lines !" | ||
| 24 | - | ||
| 25 | - #\n are converted to 
 as specified in preserve_rspec | ||
| 26 | - expected = "My brand new
 Commit on multiple
 lines !" | ||
| 27 | - | ||
| 28 | - commit_msg_with_link_to_issues(@project, message).should eql expected | ||
| 29 | - end | ||
| 30 | - | ||
| 31 | - it "should returns empty string if message undefined" do | ||
| 32 | - commit_msg_with_link_to_issues(@project, nil).should eql '' | ||
| 33 | - end | ||
| 34 | - | ||
| 35 | - it "should returns link_to issue for one valid issue in message" do | ||
| 36 | - issue_id = @valid_issue.id | ||
| 37 | - message = "One commit message ##{issue_id}" | ||
| 38 | - expected = "One commit message <a href=\"/#{@project.code}/issues/#{issue_id}\">##{issue_id}</a>" | ||
| 39 | - | ||
| 40 | - commit_msg_with_link_to_issues(@project, message).should eql expected | ||
| 41 | - end | ||
| 42 | - | ||
| 43 | - it "should returns message untouched for one invalid issue in message" do | ||
| 44 | - issue_id = @invalid_issue.id | ||
| 45 | - message = "One commit message ##{issue_id}" | ||
| 46 | - | ||
| 47 | - commit_msg_with_link_to_issues(@project, message).should eql message | ||
| 48 | - end | ||
| 49 | - | ||
| 50 | - it "should handle multiple issue references in commit message" do | ||
| 51 | - issue_id = @valid_issue.id | ||
| 52 | - invalid_issue_id = @invalid_issue.id | ||
| 53 | - | ||
| 54 | - message = "One big commit message with a valid issue ##{issue_id} and an invalid one ##{invalid_issue_id}. | ||
| 55 | - We reference valid ##{issue_id} multiple times (##{issue_id}) as the invalid ##{invalid_issue_id} is also | ||
| 56 | - referenced another time (##{invalid_issue_id})" | ||
| 57 | - | ||
| 58 | - expected = "One big commit message with a valid issue <a href=\"/#{@project.code}/issues/#{issue_id}\">##{issue_id}</a>"+ | ||
| 59 | - " and an invalid one ##{invalid_issue_id}.
 "+ | ||
| 60 | - "We reference valid <a href=\"/#{@project.code}/issues/#{issue_id}\">##{issue_id}</a> multiple times "+ | ||
| 61 | - "(<a href=\"/#{@project.code}/issues/#{issue_id}\">##{issue_id}</a>) "+ | ||
| 62 | - "as the invalid ##{invalid_issue_id} is also
 referenced another time (##{invalid_issue_id})" | ||
| 63 | - | ||
| 64 | - commit_msg_with_link_to_issues(@project, message).should eql expected | ||
| 65 | - end | ||
| 66 | - | ||
| 67 | -end | ||
| 68 | \ No newline at end of file | 0 | \ No newline at end of file |
| @@ -0,0 +1,232 @@ | @@ -0,0 +1,232 @@ | ||
| 1 | +require "spec_helper" | ||
| 2 | + | ||
| 3 | +describe ApplicationHelper do | ||
| 4 | + before do | ||
| 5 | + @project = Project.find_by_path("gitlabhq") || Factory(:project) | ||
| 6 | + @commit = @project.repo.commits.first.parents.first | ||
| 7 | + @commit = CommitDecorator.decorate(Commit.new(@commit)) | ||
| 8 | + @other_project = Factory :project, :path => "OtherPath", :code => "OtherCode" | ||
| 9 | + @fake_user = Factory :user, :name => "fred" | ||
| 10 | + end | ||
| 11 | + | ||
| 12 | + describe "#gfm" do | ||
| 13 | + it "should raiase an error if @project is not set" do | ||
| 14 | + @project = nil | ||
| 15 | + | ||
| 16 | + expect { gfm("foo") }.to raise_error | ||
| 17 | + end | ||
| 18 | + | ||
| 19 | + describe "referencing a commit" do | ||
| 20 | + it "should link using a full id" do | ||
| 21 | + gfm("Reverts changes from #{@commit.id}").should == "Reverts changes from #{link_to @commit.id, project_commit_path(@project, :id => @commit.id), :title => "Commit: #{@commit.author_name} - #{@commit.title}", :class => "gfm gfm-commit "}" | ||
| 22 | + end | ||
| 23 | + | ||
| 24 | + it "should link using a short id" do | ||
| 25 | + gfm("Backported from #{@commit.id[0, 6]}").should == "Backported from #{link_to @commit.id[0, 6], project_commit_path(@project, :id => @commit.id), :title => "Commit: #{@commit.author_name} - #{@commit.title}", :class => "gfm gfm-commit "}" | ||
| 26 | + end | ||
| 27 | + | ||
| 28 | + it "should link with adjecent text" do | ||
| 29 | + gfm("Reverted (see #{@commit.id})").should == "Reverted (see #{link_to @commit.id, project_commit_path(@project, :id => @commit.id), :title => "Commit: #{@commit.author_name} - #{@commit.title}", :class => "gfm gfm-commit "})" | ||
| 30 | + end | ||
| 31 | + | ||
| 32 | + it "should not link with an invalid id" do | ||
| 33 | + gfm("What happened in 12345678?").should == "What happened in 12345678?" | ||
| 34 | + end | ||
| 35 | + end | ||
| 36 | + | ||
| 37 | + describe "referencing a team member" do | ||
| 38 | + it "should link using a simple name" do | ||
| 39 | + user = Factory :user, name: "barry" | ||
| 40 | + @project.users << user | ||
| 41 | + member = @project.users_projects.where(:user_id => user).first | ||
| 42 | + | ||
| 43 | + gfm("@#{user.name} you are right").should == "#{link_to "@#{user.name}", project_team_member_path(@project, member), :class => "gfm gfm-team_member "} you are right" | ||
| 44 | + end | ||
| 45 | + | ||
| 46 | + it "should link using a name with dots" do | ||
| 47 | + user = Factory :user, name: "alphA.Beta" | ||
| 48 | + @project.users << user | ||
| 49 | + member = @project.users_projects.where(:user_id => user).first | ||
| 50 | + | ||
| 51 | + gfm("@#{user.name} you are right").should == "#{link_to "@#{user.name}", project_team_member_path(@project, member), :class => "gfm gfm-team_member "} you are right" | ||
| 52 | + end | ||
| 53 | + | ||
| 54 | + it "should link using name with underscores" do | ||
| 55 | + user = Factory :user, name: "ping_pong_king" | ||
| 56 | + @project.users << user | ||
| 57 | + member = @project.users_projects.where(:user_id => user).first | ||
| 58 | + | ||
| 59 | + gfm("@#{user.name} you are right").should == "#{link_to "@#{user.name}", project_team_member_path(@project, member), :class => "gfm gfm-team_member "} you are right" | ||
| 60 | + end | ||
| 61 | + | ||
| 62 | + it "should link with adjecent text" do | ||
| 63 | + user = Factory.create(:user, :name => "ace") | ||
| 64 | + @project.users << user | ||
| 65 | + member = @project.users_projects.where(:user_id => user).first | ||
| 66 | + | ||
| 67 | + gfm("Mail the Admin (@#{user.name})").should == "Mail the Admin (#{link_to "@#{user.name}", project_team_member_path(@project, member), :class => "gfm gfm-team_member "})" | ||
| 68 | + end | ||
| 69 | + | ||
| 70 | + it "should add styles" do | ||
| 71 | + user = Factory :user, name: "barry" | ||
| 72 | + @project.users << user | ||
| 73 | + gfm("@#{user.name} you are right").should have_selector(".gfm.gfm-team_member") | ||
| 74 | + end | ||
| 75 | + | ||
| 76 | + it "should not link using a bogus name" do | ||
| 77 | + gfm("What hapened to @foo?").should == "What hapened to @foo?" | ||
| 78 | + end | ||
| 79 | + end | ||
| 80 | + | ||
| 81 | + describe "referencing an issue" do | ||
| 82 | + before do | ||
| 83 | + @issue = Factory :issue, :assignee => @fake_user, :author => @fake_user, :project => @project | ||
| 84 | + @invalid_issue = Factory :issue, :assignee => @fake_user, :author => @fake_user, :project => @other_project | ||
| 85 | + end | ||
| 86 | + | ||
| 87 | + it "should link using a correct id" do | ||
| 88 | + gfm("Fixes ##{@issue.id}").should == "Fixes #{link_to "##{@issue.id}", project_issue_path(@project, @issue), :title => "Issue: #{@issue.title}", :class => "gfm gfm-issue "}" | ||
| 89 | + end | ||
| 90 | + | ||
| 91 | + it "should link with adjecent text" do | ||
| 92 | + gfm("This has already been discussed (see ##{@issue.id})").should == "This has already been discussed (see #{link_to "##{@issue.id}", project_issue_path(@project, @issue), :title => "Issue: #{@issue.title}", :class => "gfm gfm-issue "})" | ||
| 93 | + end | ||
| 94 | + | ||
| 95 | + it "should add styles" do | ||
| 96 | + gfm("Fixes ##{@issue.id}").should have_selector(".gfm.gfm-issue") | ||
| 97 | + end | ||
| 98 | + | ||
| 99 | + it "should not link using an invalid id" do | ||
| 100 | + gfm("##{@invalid_issue.id} has been marked duplicate of this").should == "##{@invalid_issue.id} has been marked duplicate of this" | ||
| 101 | + end | ||
| 102 | + end | ||
| 103 | + | ||
| 104 | + describe "referencing a merge request" do | ||
| 105 | + before do | ||
| 106 | + @merge_request = Factory :merge_request, :assignee => @fake_user, :author => @fake_user, :project => @project | ||
| 107 | + @invalid_merge_request = Factory :merge_request, :assignee => @fake_user, :author => @fake_user, :project => @other_project | ||
| 108 | + end | ||
| 109 | + | ||
| 110 | + it "should link using a correct id" do | ||
| 111 | + gfm("Fixed in !#{@merge_request.id}").should == "Fixed in #{link_to "!#{@merge_request.id}", project_merge_request_path(@project, @merge_request), :title => "Merge Request: #{@merge_request.title}", :class => "gfm gfm-merge_request "}" | ||
| 112 | + end | ||
| 113 | + | ||
| 114 | + it "should link with adjecent text" do | ||
| 115 | + gfm("This has been fixed already (see !#{@merge_request.id})").should == "This has been fixed already (see #{link_to "!#{@merge_request.id}", project_merge_request_path(@project, @merge_request), :title => "Merge Request: #{@merge_request.title}", :class => "gfm gfm-merge_request "})" | ||
| 116 | + end | ||
| 117 | + | ||
| 118 | + it "should add styles" do | ||
| 119 | + gfm("Fixed in !#{@merge_request.id}").should have_selector(".gfm.gfm-merge_request") | ||
| 120 | + end | ||
| 121 | + | ||
| 122 | + it "should not link using an invalid id" do | ||
| 123 | + gfm("!#{@invalid_merge_request.id} violates our coding guidelines") | ||
| 124 | + end | ||
| 125 | + end | ||
| 126 | + | ||
| 127 | + describe "referencing a snippet" do | ||
| 128 | + before do | ||
| 129 | + @snippet = Factory.create(:snippet, | ||
| 130 | + :title => "Render asset to string", | ||
| 131 | + :author => @fake_user, | ||
| 132 | + :project => @project) | ||
| 133 | + end | ||
| 134 | + | ||
| 135 | + it "should link using a correct id" do | ||
| 136 | + gfm("Check out $#{@snippet.id}").should == "Check out #{link_to "$#{@snippet.id}", project_snippet_path(@project, @snippet), :title => "Snippet: #{@snippet.title}", :class => "gfm gfm-snippet "}" | ||
| 137 | + end | ||
| 138 | + | ||
| 139 | + it "should link with adjecent text" do | ||
| 140 | + gfm("I have created a snippet for that ($#{@snippet.id})").should == "I have created a snippet for that (#{link_to "$#{@snippet.id}", project_snippet_path(@project, @snippet), :title => "Snippet: #{@snippet.title}", :class => "gfm gfm-snippet "})" | ||
| 141 | + end | ||
| 142 | + | ||
| 143 | + it "should add styles" do | ||
| 144 | + gfm("Check out $#{@snippet.id}").should have_selector(".gfm.gfm-snippet") | ||
| 145 | + end | ||
| 146 | + | ||
| 147 | + it "should not link using an invalid id" do | ||
| 148 | + gfm("Don't use $1234").should == "Don't use $1234" | ||
| 149 | + end | ||
| 150 | + end | ||
| 151 | + | ||
| 152 | + it "should link to multiple things" do | ||
| 153 | + user = Factory :user, name: "barry" | ||
| 154 | + @project.users << user | ||
| 155 | + member = @project.users_projects.where(:user_id => user).first | ||
| 156 | + | ||
| 157 | + gfm("Let @#{user.name} fix the *mess* in #{@commit.id}").should == "Let #{link_to "@#{user.name}", project_team_member_path(@project, member), :class => "gfm gfm-team_member "} fix the *mess* in #{link_to @commit.id, project_commit_path(@project, :id => @commit.id), :title => "Commit: #{@commit.author_name} - #{@commit.title}", :class => "gfm gfm-commit "}" | ||
| 158 | + end | ||
| 159 | + | ||
| 160 | + it "should not trip over other stuff", :focus => true do | ||
| 161 | + gfm("_Please_ *stop* 'helping' and all the other b*$#%' you do.").should == "_Please_ *stop* 'helping' and all the other b*$#%' you do." | ||
| 162 | + end | ||
| 163 | + | ||
| 164 | + it "should not touch HTML entities" do | ||
| 165 | + gfm("We'll accept good pull requests.").should == "We'll accept good pull requests." | ||
| 166 | + end | ||
| 167 | + | ||
| 168 | + it "should forward HTML options to links" do | ||
| 169 | + gfm("fixed in #{@commit.id}", :class => "foo").should have_selector("a.foo") | ||
| 170 | + end | ||
| 171 | + end | ||
| 172 | + | ||
| 173 | + describe "#link_to_gfm" do | ||
| 174 | + let(:issue1) { Factory :issue, :assignee => @fake_user, :author => @fake_user, :project => @project } | ||
| 175 | + let(:issue2) { Factory :issue, :assignee => @fake_user, :author => @fake_user, :project => @project } | ||
| 176 | + | ||
| 177 | + it "should handle references nested in links with all the text" do | ||
| 178 | + link_to_gfm("This should finally fix ##{issue1.id} and ##{issue2.id} for real", project_commit_path(@project, :id => @commit.id)).should == "#{link_to "This should finally fix ", project_commit_path(@project, :id => @commit.id)}#{link_to "##{issue1.id}", project_issue_path(@project, issue1), :title => "Issue: #{issue1.title}", :class => "gfm gfm-issue "}#{link_to " and ", project_commit_path(@project, :id => @commit.id)}#{link_to "##{issue2.id}", project_issue_path(@project, issue2), :title => "Issue: #{issue2.title}", :class => "gfm gfm-issue "}#{link_to " for real", project_commit_path(@project, :id => @commit.id)}" | ||
| 179 | + end | ||
| 180 | + | ||
| 181 | + it "should forward HTML options" do | ||
| 182 | + link_to_gfm("This should finally fix ##{issue1.id} for real", project_commit_path(@project, :id => @commit.id), :class => "foo").should have_selector(".foo") | ||
| 183 | + end | ||
| 184 | + end | ||
| 185 | + | ||
| 186 | + describe "#markdown" do | ||
| 187 | + before do | ||
| 188 | + @issue = Factory :issue, :assignee => @fake_user, :author => @fake_user, :project => @project | ||
| 189 | + @merge_request = Factory :merge_request, :assignee => @fake_user, :author => @fake_user, :project => @project | ||
| 190 | + @note = Factory.create(:note, | ||
| 191 | + :note => "Screenshot of the new feature", | ||
| 192 | + :project => @project, | ||
| 193 | + :noteable_id => @commit.id, | ||
| 194 | + :noteable_type => "Commit", | ||
| 195 | + :attachment => "screenshot123.jpg") | ||
| 196 | + @snippet = Factory.create(:snippet, | ||
| 197 | + :title => "Render asset to string", | ||
| 198 | + :author => @fake_user, | ||
| 199 | + :project => @project) | ||
| 200 | + | ||
| 201 | + @other_user = Factory :user, name: "bill" | ||
| 202 | + @project.users << @other_user | ||
| 203 | + @member = @project.users_projects.where(:user_id => @other_user).first | ||
| 204 | + end | ||
| 205 | + | ||
| 206 | + it "should handle references in paragraphs" do | ||
| 207 | + markdown("\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. #{@commit.id} Nam pulvinar sapien eget odio adipiscing at faucibus orci vestibulum.\n").should == "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. #{link_to @commit.id, project_commit_path(@project, :id => @commit.id), :title => "Commit: #{@commit.author_name} - #{@commit.title}", :class => "gfm gfm-commit "} Nam pulvinar sapien eget odio adipiscing at faucibus orci vestibulum.</p>\n" | ||
| 208 | + end | ||
| 209 | + | ||
| 210 | + it "should handle references in headers" do | ||
| 211 | + markdown("\n# Working around ##{@issue.id} for now\n## Apply !#{@merge_request.id}").should == "<h1 id=\"toc_0\">Working around #{link_to "##{@issue.id}", project_issue_path(@project, @issue), :title => "Issue: #{@issue.title}", :class => "gfm gfm-issue "} for now</h1>\n\n<h2 id=\"toc_1\">Apply #{link_to "!#{@merge_request.id}", project_merge_request_path(@project, @merge_request), :title => "Merge Request: #{@merge_request.title}", :class => "gfm gfm-merge_request "}</h2>\n" | ||
| 212 | + end | ||
| 213 | + | ||
| 214 | + it "should handle references in lists" do | ||
| 215 | + markdown("\n* dark: ##{@issue.id}\n* light by @#{@other_user.name}\n").should == "<ul>\n<li>dark: #{link_to "##{@issue.id}", project_issue_path(@project, @issue), :title => "Issue: #{@issue.title}", :class => "gfm gfm-issue "}</li>\n<li>light by #{link_to "@#{@other_user.name}", project_team_member_path(@project, @member), :class => "gfm gfm-team_member "}</li>\n</ul>\n" | ||
| 216 | + end | ||
| 217 | + | ||
| 218 | + it "should handle references in <em>" do | ||
| 219 | + markdown("Apply _!#{@merge_request.id}_ ASAP").should == "<p>Apply <em>#{link_to "!#{@merge_request.id}", project_merge_request_path(@project, @merge_request), :title => "Merge Request: #{@merge_request.title}", :class => "gfm gfm-merge_request "}</em> ASAP</p>\n" | ||
| 220 | + end | ||
| 221 | + | ||
| 222 | + it "should leave code blocks untouched" do | ||
| 223 | + markdown("\n some code from $#{@snippet.id}\n here too\n").should == "<div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{@snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre>\n</div>\n" | ||
| 224 | + | ||
| 225 | + markdown("\n```\nsome code from $#{@snippet.id}\nhere too\n```\n").should == "<div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{@snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre>\n</div>\n" | ||
| 226 | + end | ||
| 227 | + | ||
| 228 | + it "should leave inline code untouched" do | ||
| 229 | + markdown("\nDon't use `$#{@snippet.id}` here.\n").should == "<p>Don't use <code>$#{@snippet.id}</code> here.</p>\n" | ||
| 230 | + end | ||
| 231 | + end | ||
| 232 | +end |
spec/mailers/notify_spec.rb
| @@ -60,7 +60,7 @@ describe Notify do | @@ -60,7 +60,7 @@ describe Notify do | ||
| 60 | it_behaves_like 'an assignee email' | 60 | it_behaves_like 'an assignee email' |
| 61 | 61 | ||
| 62 | it 'has the correct subject' do | 62 | it 'has the correct subject' do |
| 63 | - should have_subject /New Issue was created/ | 63 | + should have_subject /new issue ##{issue.id}/ |
| 64 | end | 64 | end |
| 65 | 65 | ||
| 66 | it 'contains a link to the new issue' do | 66 | it 'contains a link to the new issue' do |
| @@ -102,7 +102,7 @@ describe Notify do | @@ -102,7 +102,7 @@ describe Notify do | ||
| 102 | it_behaves_like 'an assignee email' | 102 | it_behaves_like 'an assignee email' |
| 103 | 103 | ||
| 104 | it 'has the correct subject' do | 104 | it 'has the correct subject' do |
| 105 | - should have_subject /new merge request/ | 105 | + should have_subject /new merge request !#{merge_request.id}/ |
| 106 | end | 106 | end |
| 107 | 107 | ||
| 108 | it 'contains a link to the new merge request' do | 108 | it 'contains a link to the new merge request' do |
| @@ -126,7 +126,7 @@ describe Notify do | @@ -126,7 +126,7 @@ describe Notify do | ||
| 126 | it_behaves_like 'a multiple recipients email' | 126 | it_behaves_like 'a multiple recipients email' |
| 127 | 127 | ||
| 128 | it 'has the correct subject' do | 128 | it 'has the correct subject' do |
| 129 | - should have_subject /merge request changed/ | 129 | + should have_subject /changed merge request !#{merge_request.id}/ |
| 130 | end | 130 | end |
| 131 | 131 | ||
| 132 | it 'contains the name of the previous assignee' do | 132 | it 'contains the name of the previous assignee' do |
| @@ -188,6 +188,8 @@ describe Notify do | @@ -188,6 +188,8 @@ describe Notify do | ||
| 188 | mock(:commit).tap do |commit| | 188 | mock(:commit).tap do |commit| |
| 189 | commit.stub(:id).and_return('fauxsha1') | 189 | commit.stub(:id).and_return('fauxsha1') |
| 190 | commit.stub(:project).and_return(project) | 190 | commit.stub(:project).and_return(project) |
| 191 | + commit.stub(:short_id).and_return('fauxsha1') | ||
| 192 | + commit.stub(:safe_message).and_return('some message') | ||
| 191 | end | 193 | end |
| 192 | end | 194 | end |
| 193 | before(:each) { note.stub(:target).and_return(commit) } | 195 | before(:each) { note.stub(:target).and_return(commit) } |
| @@ -197,7 +199,7 @@ describe Notify do | @@ -197,7 +199,7 @@ describe Notify do | ||
| 197 | it_behaves_like 'a note email' | 199 | it_behaves_like 'a note email' |
| 198 | 200 | ||
| 199 | it 'has the correct subject' do | 201 | it 'has the correct subject' do |
| 200 | - should have_subject /note for commit/ | 202 | + should have_subject /note for commit #{commit.short_id}/ |
| 201 | end | 203 | end |
| 202 | 204 | ||
| 203 | it 'contains a link to the commit' do | 205 | it 'contains a link to the commit' do |
| @@ -215,7 +217,7 @@ describe Notify do | @@ -215,7 +217,7 @@ describe Notify do | ||
| 215 | it_behaves_like 'a note email' | 217 | it_behaves_like 'a note email' |
| 216 | 218 | ||
| 217 | it 'has the correct subject' do | 219 | it 'has the correct subject' do |
| 218 | - should have_subject /note for merge request/ | 220 | + should have_subject /note for merge request !#{merge_request.id}/ |
| 219 | end | 221 | end |
| 220 | 222 | ||
| 221 | it 'contains a link to the merge request note' do | 223 | it 'contains a link to the merge request note' do |
| @@ -233,7 +235,7 @@ describe Notify do | @@ -233,7 +235,7 @@ describe Notify do | ||
| 233 | it_behaves_like 'a note email' | 235 | it_behaves_like 'a note email' |
| 234 | 236 | ||
| 235 | it 'has the correct subject' do | 237 | it 'has the correct subject' do |
| 236 | - should have_subject /note for issue #{issue.id}/ | 238 | + should have_subject /note for issue ##{issue.id}/ |
| 237 | end | 239 | end |
| 238 | 240 | ||
| 239 | it 'contains a link to the issue note' do | 241 | it 'contains a link to the issue note' do |
| @@ -0,0 +1,241 @@ | @@ -0,0 +1,241 @@ | ||
| 1 | +require 'spec_helper' | ||
| 2 | + | ||
| 3 | +describe "Gitlab Flavored Markdown" do | ||
| 4 | + let(:project) { Factory :project } | ||
| 5 | + let(:issue) { Factory :issue, :project => project } | ||
| 6 | + let(:merge_request) { Factory :merge_request, :project => project } | ||
| 7 | + let(:fred) do | ||
| 8 | + u = Factory :user, :name => "fred" | ||
| 9 | + project.users << u | ||
| 10 | + u | ||
| 11 | + end | ||
| 12 | + | ||
| 13 | + before do | ||
| 14 | + # add test branch | ||
| 15 | + @branch_name = "gfm-test" | ||
| 16 | + r = project.repo | ||
| 17 | + i = r.index | ||
| 18 | + # add test file | ||
| 19 | + @test_file = "gfm_test_file" | ||
| 20 | + i.add(@test_file, "foo\nbar\n") | ||
| 21 | + # add commit with gfm | ||
| 22 | + i.commit("fix ##{issue.id}\n\nask @#{fred.name} for details", :head => @branch_name) | ||
| 23 | + | ||
| 24 | + # add test tag | ||
| 25 | + @tag_name = "gfm-test-tag" | ||
| 26 | + r.git.native(:tag, {}, @tag_name, commit.id) | ||
| 27 | + end | ||
| 28 | + after do | ||
| 29 | + # delete test branch and tag | ||
| 30 | + project.repo.git.native(:branch, {:D => true}, @branch_name) | ||
| 31 | + project.repo.git.native(:tag, {:d => true}, @tag_name) | ||
| 32 | + project.repo.gc_auto | ||
| 33 | + end | ||
| 34 | + | ||
| 35 | + let(:commit) { project.commits(@branch_name).first } | ||
| 36 | + | ||
| 37 | + before do | ||
| 38 | + login_as :user | ||
| 39 | + project.add_access(@user, :read, :write) | ||
| 40 | + end | ||
| 41 | + | ||
| 42 | + | ||
| 43 | + describe "for commits" do | ||
| 44 | + it "should render title in commits#index" do | ||
| 45 | + visit project_commits_path(project, :ref => @branch_name) | ||
| 46 | + | ||
| 47 | + page.should have_link("##{issue.id}") | ||
| 48 | + end | ||
| 49 | + | ||
| 50 | + it "should render title in commits#show" do | ||
| 51 | + visit project_commit_path(project, :id => commit.id) | ||
| 52 | + | ||
| 53 | + page.should have_link("##{issue.id}") | ||
| 54 | + end | ||
| 55 | + | ||
| 56 | + it "should render description in commits#show" do | ||
| 57 | + visit project_commit_path(project, :id => commit.id) | ||
| 58 | + | ||
| 59 | + page.should have_link("@#{fred.name}") | ||
| 60 | + end | ||
| 61 | + | ||
| 62 | + it "should render title in refs#tree", :js => true do | ||
| 63 | + visit tree_project_ref_path(project, :id => @branch_name) | ||
| 64 | + | ||
| 65 | + within(".tree_commit") do | ||
| 66 | + page.should have_link("##{issue.id}") | ||
| 67 | + end | ||
| 68 | + end | ||
| 69 | + | ||
| 70 | + it "should render title in refs#blame" do | ||
| 71 | + visit blame_file_project_ref_path(project, :id => @branch_name, :path => @test_file) | ||
| 72 | + | ||
| 73 | + within(".blame_commit") do | ||
| 74 | + page.should have_link("##{issue.id}") | ||
| 75 | + end | ||
| 76 | + end | ||
| 77 | + | ||
| 78 | + it "should render title in repositories#branches" do | ||
| 79 | + visit branches_project_repository_path(project) | ||
| 80 | + | ||
| 81 | + page.should have_link("##{issue.id}") | ||
| 82 | + end | ||
| 83 | + | ||
| 84 | + it "should render title in repositories#tags" do | ||
| 85 | + visit tags_project_repository_path(project) | ||
| 86 | + | ||
| 87 | + page.should have_link("##{issue.id}") | ||
| 88 | + end | ||
| 89 | + end | ||
| 90 | + | ||
| 91 | + | ||
| 92 | + describe "for issues" do | ||
| 93 | + before do | ||
| 94 | + @other_issue = Factory :issue, | ||
| 95 | + :author => @user, | ||
| 96 | + :assignee => @user, | ||
| 97 | + :project => project | ||
| 98 | + @issue = Factory :issue, | ||
| 99 | + :author => @user, | ||
| 100 | + :assignee => @user, | ||
| 101 | + :project => project, | ||
| 102 | + :title => "fix ##{@other_issue.id}", | ||
| 103 | + :description => "ask @#{fred.name} for details" | ||
| 104 | + end | ||
| 105 | + | ||
| 106 | + it "should render subject in issues#index" do | ||
| 107 | + visit project_issues_path(project) | ||
| 108 | + | ||
| 109 | + page.should have_link("##{@other_issue.id}") | ||
| 110 | + end | ||
| 111 | + | ||
| 112 | + it "should render subject in issues#show" do | ||
| 113 | + visit project_issue_path(project, @issue) | ||
| 114 | + | ||
| 115 | + page.should have_link("##{@other_issue.id}") | ||
| 116 | + end | ||
| 117 | + | ||
| 118 | + it "should render details in issues#show" do | ||
| 119 | + visit project_issue_path(project, @issue) | ||
| 120 | + | ||
| 121 | + page.should have_link("@#{fred.name}") | ||
| 122 | + end | ||
| 123 | + end | ||
| 124 | + | ||
| 125 | + | ||
| 126 | + describe "for merge requests" do | ||
| 127 | + before do | ||
| 128 | + @merge_request = Factory :merge_request, | ||
| 129 | + :project => project, | ||
| 130 | + :title => "fix ##{issue.id}" | ||
| 131 | + end | ||
| 132 | + | ||
| 133 | + it "should render title in merge_requests#index" do | ||
| 134 | + visit project_merge_requests_path(project) | ||
| 135 | + | ||
| 136 | + page.should have_link("##{issue.id}") | ||
| 137 | + end | ||
| 138 | + | ||
| 139 | + it "should render title in merge_requests#show" do | ||
| 140 | + visit project_merge_request_path(project, @merge_request) | ||
| 141 | + | ||
| 142 | + page.should have_link("##{issue.id}") | ||
| 143 | + end | ||
| 144 | + end | ||
| 145 | + | ||
| 146 | + | ||
| 147 | + describe "for milestones" do | ||
| 148 | + before do | ||
| 149 | + @milestone = Factory :milestone, | ||
| 150 | + :project => project, | ||
| 151 | + :title => "fix ##{issue.id}", | ||
| 152 | + :description => "ask @#{fred.name} for details" | ||
| 153 | + end | ||
| 154 | + | ||
| 155 | + it "should render title in milestones#index" do | ||
| 156 | + visit project_milestones_path(project) | ||
| 157 | + | ||
| 158 | + page.should have_link("##{issue.id}") | ||
| 159 | + end | ||
| 160 | + | ||
| 161 | + it "should render title in milestones#show" do | ||
| 162 | + visit project_milestone_path(project, @milestone) | ||
| 163 | + | ||
| 164 | + page.should have_link("##{issue.id}") | ||
| 165 | + end | ||
| 166 | + | ||
| 167 | + it "should render description in milestones#show" do | ||
| 168 | + visit project_milestone_path(project, @milestone) | ||
| 169 | + | ||
| 170 | + page.should have_link("@#{fred.name}") | ||
| 171 | + end | ||
| 172 | + end | ||
| 173 | + | ||
| 174 | + | ||
| 175 | + describe "for notes" do | ||
| 176 | + it "should render in commits#show", :js => true do | ||
| 177 | + visit project_commit_path(project, :id => commit.id) | ||
| 178 | + fill_in "note_note", :with => "see ##{issue.id}" | ||
| 179 | + click_button "Add Comment" | ||
| 180 | + | ||
| 181 | + page.should have_link("##{issue.id}") | ||
| 182 | + end | ||
| 183 | + | ||
| 184 | + it "should render in issue#show", :js => true do | ||
| 185 | + visit project_issue_path(project, issue) | ||
| 186 | + fill_in "note_note", :with => "see ##{issue.id}" | ||
| 187 | + click_button "Add Comment" | ||
| 188 | + | ||
| 189 | + page.should have_link("##{issue.id}") | ||
| 190 | + end | ||
| 191 | + | ||
| 192 | + it "should render in merge_request#show", :js => true do | ||
| 193 | + visit project_merge_request_path(project, merge_request) | ||
| 194 | + fill_in "note_note", :with => "see ##{issue.id}" | ||
| 195 | + click_button "Add Comment" | ||
| 196 | + | ||
| 197 | + page.should have_link("##{issue.id}") | ||
| 198 | + end | ||
| 199 | + | ||
| 200 | + it "should render in projects#wall", :js => true do | ||
| 201 | + visit wall_project_path(project) | ||
| 202 | + fill_in "note_note", :with => "see ##{issue.id}" | ||
| 203 | + click_button "Add Comment" | ||
| 204 | + | ||
| 205 | + page.should have_link("##{issue.id}") | ||
| 206 | + end | ||
| 207 | + | ||
| 208 | + it "should render in wikis#index", :js => true do | ||
| 209 | + visit project_wiki_path(project, :index) | ||
| 210 | + fill_in "Title", :with => 'Test title' | ||
| 211 | + fill_in "Content", :with => '[link test](test)' | ||
| 212 | + click_on "Save" | ||
| 213 | + | ||
| 214 | + fill_in "note_note", :with => "see ##{issue.id}" | ||
| 215 | + click_button "Add Comment" | ||
| 216 | + | ||
| 217 | + page.should have_link("##{issue.id}") | ||
| 218 | + end | ||
| 219 | + end | ||
| 220 | + | ||
| 221 | + | ||
| 222 | + describe "for wikis" do | ||
| 223 | + before do | ||
| 224 | + visit project_wiki_path(project, :index) | ||
| 225 | + fill_in "Title", :with => "Circumvent ##{issue.id}" | ||
| 226 | + fill_in "Content", :with => "# Other pages\n\n* [Foo](foo)\n* [Bar](bar)\n\nAlso look at ##{issue.id} :-)" | ||
| 227 | + click_on "Save" | ||
| 228 | + end | ||
| 229 | + | ||
| 230 | + it "should NOT render title in wikis#show" do | ||
| 231 | + within(".content h3") do # page title | ||
| 232 | + page.should have_content("Circumvent ##{issue.id}") | ||
| 233 | + page.should_not have_link("##{issue.id}") | ||
| 234 | + end | ||
| 235 | + end | ||
| 236 | + | ||
| 237 | + it "should render content in wikis#show" do | ||
| 238 | + page.should have_link("##{issue.id}") | ||
| 239 | + end | ||
| 240 | + end | ||
| 241 | +end |