summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/markdown/relative_link_filter_spec.rb
blob: 5ee5310825d7b10f21dce3335cce6239ac855abb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
require 'spec_helper'

module Gitlab::Markdown
  describe RelativeLinkFilter do
    def filter(doc)
      described_class.call(doc, {
        commit:         project.commit,
        project:        project,
        project_wiki:   project_wiki,
        ref:            ref,
        requested_path: requested_path
      })
    end

    def image(path)
      %(<img src="#{path}" />)
    end

    def link(path)
      %(<a href="#{path}">#{path}</a>)
    end

    let(:project)        { create(:project) }
    let(:project_path)   { project.path_with_namespace }
    let(:ref)            { 'markdown' }
    let(:project_wiki)   { nil }
    let(:requested_path) { '/' }

    shared_examples :preserve_unchanged do
      it 'does not modify any relative URL in anchor' do
        doc = filter(link('README.md'))
        expect(doc.at_css('a')['href']).to eq 'README.md'
      end

      it 'does not modify any relative URL in image' do
        doc = filter(image('files/images/logo-black.png'))
        expect(doc.at_css('img')['src']).to eq 'files/images/logo-black.png'
      end
    end

    shared_examples :relative_to_requested do
      it 'rebuilds URL relative to the requested path' do
        doc = filter(link('users.md'))
        expect(doc.at_css('a')['href']).
          to eq "/#{project_path}/blob/#{ref}/doc/api/users.md"
      end
    end

    context 'with a project_wiki' do
      let(:project_wiki) { double('ProjectWiki') }
      include_examples :preserve_unchanged
    end

    context 'without a repository' do
      let(:project) { create(:empty_project) }
      include_examples :preserve_unchanged
    end

    context 'with an empty repository' do
      let(:project) { create(:project_empty_repo) }
      include_examples :preserve_unchanged
    end

    it 'does not raise an exception on invalid URIs' do
      act = link("://foo")
      expect { filter(act) }.not_to raise_error
    end

    context 'with a valid repository' do
      it 'rebuilds relative URL for a file in the repo' do
        doc = filter(link('doc/api/README.md'))
        expect(doc.at_css('a')['href']).
          to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
      end

      it 'rebuilds relative URL for a file in the repo with an anchor' do
        doc = filter(link('README.md#section'))
        expect(doc.at_css('a')['href']).
          to eq "/#{project_path}/blob/#{ref}/README.md#section"
      end

      it 'rebuilds relative URL for a directory in the repo' do
        doc = filter(link('doc/api/'))
        expect(doc.at_css('a')['href']).
          to eq "/#{project_path}/tree/#{ref}/doc/api"
      end

      it 'rebuilds relative URL for an image in the repo' do
        doc = filter(link('files/images/logo-black.png'))
        expect(doc.at_css('a')['href']).
          to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png"
      end

      it 'does not modify relative URL with an anchor only' do
        doc = filter(link('#section-1'))
        expect(doc.at_css('a')['href']).to eq '#section-1'
      end

      it 'does not modify absolute URL' do
        doc = filter(link('http://example.com'))
        expect(doc.at_css('a')['href']).to eq 'http://example.com'
      end

      context 'when requested path is a file in the repo' do
        let(:requested_path) { 'doc/api/README.md' }
        include_examples :relative_to_requested
      end

      context 'when requested path is a directory in the repo' do
        let(:requested_path) { 'doc/api' }
        include_examples :relative_to_requested
      end
    end
  end
end