BigW Consortium Gitlab

markup_helper_spec.rb 7.81 KB
Newer Older
1
require 'spec_helper'
Riyad Preukschas committed
2

3
describe MarkupHelper do
4
  let!(:project) { create(:project, :repository) }
5

6
  let(:user)          { create(:user, username: 'gfm') }
7
  let(:commit)        { project.commit }
8
  let(:issue)         { create(:issue, project: project) }
9
  let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
Andrew8xx8 committed
10
  let(:snippet)       { create(:project_snippet, project: project) }
11

Riyad Preukschas committed
12
  before do
13 14 15
    # Ensure the generated reference links aren't redacted
    project.team << [user, :master]

16
    # Helper expects a @project instance variable
17 18 19 20
    helper.instance_variable_set(:@project, project)

    # Stub the `current_user` helper
    allow(helper).to receive(:current_user).and_return(user)
Riyad Preukschas committed
21 22
  end

23
  describe "#markdown" do
24
    describe "referencing multiple objects" do
25
      let(:actual) { "#{merge_request.to_reference} -> #{commit.to_reference} -> #{issue.to_reference}" }
26

27
      it "links to the merge request" do
Vinnie Okada committed
28
        expected = namespace_project_merge_request_path(project.namespace, project, merge_request)
29
        expect(helper.markdown(actual)).to match(expected)
Riyad Preukschas committed
30 31
      end

32
      it "links to the commit" do
Vinnie Okada committed
33
        expected = namespace_project_commit_path(project.namespace, project, commit)
34
        expect(helper.markdown(actual)).to match(expected)
Riyad Preukschas committed
35 36
      end

37
      it "links to the issue" do
Vinnie Okada committed
38
        expected = namespace_project_issue_path(project.namespace, project, issue)
39
        expect(helper.markdown(actual)).to match(expected)
Riyad Preukschas committed
40 41
      end
    end
42 43 44

    describe "override default project" do
      let(:actual) { issue.to_reference }
45
      let(:second_project) { create(:project, :public) }
46 47
      let(:second_issue) { create(:issue, project: second_project) }

48
      it 'links to the issue' do
49 50 51 52
        expected = namespace_project_issue_path(second_project.namespace, second_project, second_issue)
        expect(markdown(actual, project: second_project)).to match(expected)
      end
    end
53
  end
Riyad Preukschas committed
54

55
  describe '#link_to_gfm' do
56
    let(:link)    { '/commits/0a1b2c3d' }
57
    let(:issues)  { create_list(:issue, 2, project: project) }
Riyad Preukschas committed
58

59
    it 'handles references nested in links with all the text' do
60
      actual = helper.link_to_gfm("This should finally fix #{issues[0].to_reference} and #{issues[1].to_reference} for real", link)
61
      doc = Nokogiri::HTML.parse(actual)
Riyad Preukschas committed
62

63 64 65
      # Make sure we didn't create invalid markup
      expect(doc.errors).to be_empty

66
      # Leading commit link
67
      expect(doc.css('a')[0].attr('href')).to eq link
68
      expect(doc.css('a')[0].text).to eq 'This should finally fix '
Riyad Preukschas committed
69

70
      # First issue link
71 72
      expect(doc.css('a')[1].attr('href')).
        to eq namespace_project_issue_path(project.namespace, project, issues[0])
73
      expect(doc.css('a')[1].text).to eq issues[0].to_reference
74

75
      # Internal commit link
76
      expect(doc.css('a')[2].attr('href')).to eq link
77
      expect(doc.css('a')[2].text).to eq ' and '
78

79
      # Second issue link
80 81
      expect(doc.css('a')[3].attr('href')).
        to eq namespace_project_issue_path(project.namespace, project, issues[1])
82
      expect(doc.css('a')[3].text).to eq issues[1].to_reference
83 84

      # Trailing commit link
85
      expect(doc.css('a')[4].attr('href')).to eq link
86
      expect(doc.css('a')[4].text).to eq ' for real'
87 88
    end

89
    it 'forwards HTML options' do
90
      actual = helper.link_to_gfm("Fixed in #{commit.id}", link, class: 'foo')
91 92 93 94 95 96 97 98
      doc = Nokogiri::HTML.parse(actual)

      expect(doc.css('a')).to satisfy do |v|
        # 'foo' gets added to all links
        v.all? { |a| a.attr('class').match(/foo$/) }
      end
    end

99
    it "escapes HTML passed in as the body" do
100
      actual = "This is a <h1>test</h1> - see #{issues[0].to_reference}"
101
      expect(helper.link_to_gfm(actual, link)).
102
        to match('&lt;h1&gt;test&lt;/h1&gt;')
103
    end
104 105 106

    it 'ignores reference links when they are the entire body' do
      text = issues[0].to_reference
107
      act = helper.link_to_gfm(text, '/foo')
108 109
      expect(act).to eq %Q(<a href="/foo">#{issues[0].to_reference}</a>)
    end
SAKATA Sinji committed
110

111
    it 'replaces commit message with emoji to link' do
112
      actual = link_to_gfm(':book: Book', '/foo')
SAKATA Sinji committed
113
      expect(actual).
114
        to eq '<gl-emoji title="open book" data-name="book" data-unicode-version="6.0">📖</gl-emoji><a href="/foo"> Book</a>'
SAKATA Sinji committed
115
    end
116
  end
117

118
  describe '#render_wiki_content' do
119
    before do
skv committed
120
      @wiki = double('WikiPage')
121
      allow(@wiki).to receive(:content).and_return('wiki content')
122
      allow(@wiki).to receive(:slug).and_return('nested/page')
123
      helper.instance_variable_set(:@project_wiki, @wiki)
124 125
    end

126
    it "uses Wiki pipeline for markdown files" do
127
      allow(@wiki).to receive(:format).and_return(:markdown)
128

Toon Claes committed
129
      expect(helper).to receive(:markdown_unsafe).with('wiki content', pipeline: :wiki, project: project, project_wiki: @wiki, page_slug: "nested/page")
130 131 132 133

      helper.render_wiki_content(@wiki)
    end

134
    it "uses Asciidoctor for asciidoc files" do
135 136
      allow(@wiki).to receive(:format).and_return(:asciidoc)

Douwe Maan committed
137
      expect(helper).to receive(:asciidoc_unsafe).with('wiki content')
138 139 140 141

      helper.render_wiki_content(@wiki)
    end

142
    it "uses the Gollum renderer for all other file types" do
143
      allow(@wiki).to receive(:format).and_return(:rdoc)
skv committed
144
      formatted_content_stub = double('formatted_content')
145 146
      expect(formatted_content_stub).to receive(:html_safe)
      allow(@wiki).to receive(:formatted_content).and_return(formatted_content_stub)
147 148 149 150

      helper.render_wiki_content(@wiki)
    end
  end
151

Douwe Maan committed
152
  describe 'markup' do
153 154 155 156
    let(:content) { 'Noël' }

    it 'preserves encoding' do
      expect(content.encoding.name).to eq('UTF-8')
Douwe Maan committed
157
      expect(helper.markup('foo.rst', content).encoding.name).to eq('UTF-8')
158 159
    end

Douwe Maan committed
160
    it "delegates to #markdown_unsafe when file name corresponds to Markdown" do
161
      expect(helper).to receive(:gitlab_markdown?).with('foo.md').and_return(true)
Douwe Maan committed
162
      expect(helper).to receive(:markdown_unsafe).and_return('NOEL')
163

Douwe Maan committed
164
      expect(helper.markup('foo.md', content)).to eq('NOEL')
165 166
    end

Douwe Maan committed
167
    it "delegates to #asciidoc_unsafe when file name corresponds to AsciiDoc" do
168
      expect(helper).to receive(:asciidoc?).with('foo.adoc').and_return(true)
Douwe Maan committed
169
      expect(helper).to receive(:asciidoc_unsafe).and_return('NOEL')
170

Douwe Maan committed
171
      expect(helper.markup('foo.adoc', content)).to eq('NOEL')
172 173 174
    end
  end

175 176
  describe '#first_line_in_markdown' do
    it 'truncates Markdown properly' do
177
      text = "@#{user.username}, can you look at this?\nHello world\n"
178 179 180 181 182 183 184 185 186 187 188 189 190 191
      actual = first_line_in_markdown(text, 100, project: project)

      doc = Nokogiri::HTML.parse(actual)

      # Make sure we didn't create invalid markup
      expect(doc.errors).to be_empty

      # Leading user link
      expect(doc.css('a').length).to eq(1)
      expect(doc.css('a')[0].attr('href')).to eq user_path(user)
      expect(doc.css('a')[0].text).to eq "@#{user.username}"

      expect(doc.content).to eq "@#{user.username}, can you look at this?..."
    end
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208

    it 'truncates Markdown with emoji properly' do
      text = "foo :wink:\nbar :grinning:"
      actual = first_line_in_markdown(text, 100, project: project)

      doc = Nokogiri::HTML.parse(actual)

      # Make sure we didn't create invalid markup
      # But also account for the 2 errors caused by the unknown `gl-emoji` elements
      expect(doc.errors.length).to eq(2)

      expect(doc.css('gl-emoji').length).to eq(2)
      expect(doc.css('gl-emoji')[0].attr('data-name')).to eq 'wink'
      expect(doc.css('gl-emoji')[1].attr('data-name')).to eq 'grinning'

      expect(doc.content).to eq "foo 😉\nbar 😀"
    end
209
  end
210 211 212 213 214 215 216 217 218 219

  describe '#cross_project_reference' do
    it 'shows the full MR reference' do
      expect(helper.cross_project_reference(project, merge_request)).to include(project.path_with_namespace)
    end

    it 'shows the full issue reference' do
      expect(helper.cross_project_reference(project, issue)).to include(project.path_with_namespace)
    end
  end
Riyad Preukschas committed
220
end