blob_helper_spec.rb 8.75 KB
Newer Older
1 2 3
require 'spec_helper'

describe BlobHelper do
4 5
  include TreeHelper

6
  describe '#highlight' do
7 8
    it 'wraps highlighted content' do
      expect(helper.highlight('test.rb', '52')).to eq(%q[<pre class="code highlight"><code><span id="LC1" class="line" lang="ruby"><span class="mi">52</span></span></code></pre>])
9 10
    end

11 12
    it 'handles plain version' do
      expect(helper.highlight('test.rb', '52', plain: true)).to eq(%q[<pre class="code highlight"><code><span id="LC1" class="line" lang="">52</span></code></pre>])
Stan Hu's avatar
Stan Hu committed
13
    end
14
  end
15

Douwe Maan's avatar
Douwe Maan committed
16
  describe "#sanitize_svg_data" do
17
    let(:input_svg_path) { File.join(Rails.root, 'spec', 'fixtures', 'unsanitized.svg') }
18
    let(:data) { File.read(input_svg_path) }
19
    let(:expected_svg_path) { File.join(Rails.root, 'spec', 'fixtures', 'sanitized.svg') }
20
    let(:expected) { File.read(expected_svg_path) }
21

22
    it 'retains essential elements' do
Douwe Maan's avatar
Douwe Maan committed
23
      expect(sanitize_svg_data(data)).to eq(expected)
24 25
    end
  end
26

James Lopez's avatar
James Lopez committed
27
  describe "#edit_blob_link" do
28
    let(:namespace) { create(:namespace, name: 'gitlab' )}
29
    let(:project) { create(:project, :repository, namespace: namespace) }
30 31

    before do
32
      allow(self).to receive(:current_user).and_return(nil)
33
      allow(self).to receive(:can_collaborate_with_project?).and_return(true)
34 35 36
    end

    it 'verifies blob is text' do
37
      expect(helper).not_to receive(:blob_text_viewable?)
38

39
      button = edit_blob_button(project, 'refs/heads/master', 'README.md')
40 41 42

      expect(button).to start_with('<button')
    end
43 44 45 46 47 48

    it 'uses the passed blob instead retrieve from repository' do
      blob = project.repository.blob_at('refs/heads/master', 'README.md')

      expect(project.repository).not_to receive(:blob_at)

49
      edit_blob_button(project, 'refs/heads/master', 'README.md', blob: blob)
50 51 52
    end

    it 'returns a link with the proper route' do
53
      stub_feature_flags(web_ide_default: false)
54
      link = edit_blob_button(project, 'master', 'README.md')
55

56
      expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md")
57 58
    end

59 60 61 62 63 64
    it 'returns a link with a Web IDE route' do
      link = edit_blob_button(project, 'master', 'README.md')

      expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/-/ide/project/#{project.full_path}/edit/master/-/README.md")
    end

65
    it 'returns a link with the passed link_opts on the expected route' do
66
      stub_feature_flags(web_ide_default: false)
67
      link = edit_blob_button(project, 'master', 'README.md', link_opts: { mr_id: 10 })
68

69
      expect(Capybara.string(link).find_link('Edit')[:href]).to eq("/#{project.full_path}/edit/master/README.md?mr_id=10")
70
    end
71
  end
Douwe Maan's avatar
Douwe Maan committed
72 73 74 75

  context 'viewer related' do
    include FakeBlobHelpers

76
    let(:project) { build(:project, lfs_enabled: true) }
Douwe Maan's avatar
Douwe Maan committed
77 78 79 80

    before do
      allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
    end
Douwe Maan's avatar
Douwe Maan committed
81 82 83

    let(:viewer_class) do
      Class.new(BlobViewer::Base) do
84 85
        include BlobViewer::ServerSide

86 87
        self.collapse_limit = 1.megabyte
        self.size_limit = 5.megabytes
Douwe Maan's avatar
Douwe Maan committed
88 89 90 91 92 93 94 95 96
        self.type = :rich
      end
    end

    let(:viewer) { viewer_class.new(blob) }
    let(:blob) { fake_blob }

    describe '#blob_render_error_reason' do
      context 'for error :too_large' do
97
        context 'when the blob size is larger than the absolute size limit' do
Douwe Maan's avatar
Douwe Maan committed
98 99 100
          let(:blob) { fake_blob(size: 10.megabytes) }

          it 'returns an error message' do
Douwe Maan's avatar
Douwe Maan committed
101
            expect(helper.blob_render_error_reason(viewer)).to eq('it is larger than 5 MB')
Douwe Maan's avatar
Douwe Maan committed
102 103 104
          end
        end

105
        context 'when the blob size is larger than the size limit' do
Douwe Maan's avatar
Douwe Maan committed
106 107 108
          let(:blob) { fake_blob(size: 2.megabytes) }

          it 'returns an error message' do
Douwe Maan's avatar
Douwe Maan committed
109
            expect(helper.blob_render_error_reason(viewer)).to eq('it is larger than 1 MB')
Douwe Maan's avatar
Douwe Maan committed
110 111 112 113
          end
        end
      end

114
      context 'for error :server_side_but_stored_externally' do
Douwe Maan's avatar
Douwe Maan committed
115 116
        let(:blob) { fake_blob(lfs: true) }

Douwe Maan's avatar
Douwe Maan committed
117
        it 'returns an error message' do
Douwe Maan's avatar
Douwe Maan committed
118
          expect(helper.blob_render_error_reason(viewer)).to eq('it is stored in LFS')
Douwe Maan's avatar
Douwe Maan committed
119 120 121 122 123
        end
      end
    end

    describe '#blob_render_error_options' do
Douwe Maan's avatar
Douwe Maan committed
124 125
      before do
        assign(:project, project)
Douwe Maan's avatar
Douwe Maan committed
126
        assign(:blob, blob)
Douwe Maan's avatar
Douwe Maan committed
127 128 129 130 131 132 133 134 135
        assign(:id, File.join('master', blob.path))

        controller.params[:controller] = 'projects/blob'
        controller.params[:action] = 'show'
        controller.params[:namespace_id] = project.namespace.to_param
        controller.params[:project_id] = project.to_param
        controller.params[:id] = File.join('master', blob.path)
      end

Douwe Maan's avatar
Douwe Maan committed
136 137
      context 'for error :collapsed' do
        let(:blob) { fake_blob(size: 2.megabytes) }
Douwe Maan's avatar
Douwe Maan committed
138

Douwe Maan's avatar
Douwe Maan committed
139 140
        it 'includes a "load it anyway" link' do
          expect(helper.blob_render_error_options(viewer)).to include(/load it anyway/)
Douwe Maan's avatar
Douwe Maan committed
141
        end
Douwe Maan's avatar
Douwe Maan committed
142
      end
Douwe Maan's avatar
Douwe Maan committed
143

Douwe Maan's avatar
Douwe Maan committed
144 145
      context 'for error :too_large' do
        let(:blob) { fake_blob(size: 10.megabytes) }
Douwe Maan's avatar
Douwe Maan committed
146

Douwe Maan's avatar
Douwe Maan committed
147 148
        it 'does not include a "load it anyway" link' do
          expect(helper.blob_render_error_options(viewer)).not_to include(/load it anyway/)
Douwe Maan's avatar
Douwe Maan committed
149 150
        end

151 152 153 154 155 156 157 158 159 160 161
        context 'when the viewer is rich' do
          context 'the blob is rendered as text' do
            let(:blob) { fake_blob(path: 'file.md', size: 2.megabytes) }

            it 'includes a "view the source" link' do
              expect(helper.blob_render_error_options(viewer)).to include(/view the source/)
            end
          end

          context 'the blob is not rendered as text' do
            let(:blob) { fake_blob(path: 'file.pdf', binary: true, size: 2.megabytes) }
Douwe Maan's avatar
Douwe Maan committed
162

163 164 165
            it 'does not include a "view the source" link' do
              expect(helper.blob_render_error_options(viewer)).not_to include(/view the source/)
            end
Douwe Maan's avatar
Douwe Maan committed
166 167 168
          end
        end

169 170 171 172 173 174
        context 'when the viewer is not rich' do
          before do
            viewer_class.type = :simple
          end

          let(:blob) { fake_blob(path: 'file.md', size: 2.megabytes) }
Douwe Maan's avatar
Douwe Maan committed
175 176

          it 'does not include a "view the source" link' do
Douwe Maan's avatar
Douwe Maan committed
177
            expect(helper.blob_render_error_options(viewer)).not_to include(/view the source/)
Douwe Maan's avatar
Douwe Maan committed
178 179 180
          end
        end

181 182
        it 'includes a "download it" link' do
          expect(helper.blob_render_error_options(viewer)).to include(/download it/)
Douwe Maan's avatar
Douwe Maan committed
183
        end
184
      end
Douwe Maan's avatar
Douwe Maan committed
185

186
      context 'for error :server_side_but_stored_externally' do
Douwe Maan's avatar
Douwe Maan committed
187
        let(:blob) { fake_blob(path: 'file.md', lfs: true) }
Douwe Maan's avatar
Douwe Maan committed
188

189 190 191 192
        it 'does not include a "load it anyway" link' do
          expect(helper.blob_render_error_options(viewer)).not_to include(/load it anyway/)
        end

Douwe Maan's avatar
Douwe Maan committed
193
        it 'does not include a "view the source" link' do
Douwe Maan's avatar
Douwe Maan committed
194
          expect(helper.blob_render_error_options(viewer)).not_to include(/view the source/)
Douwe Maan's avatar
Douwe Maan committed
195 196
        end

197 198 199
        it 'includes a "download it" link' do
          expect(helper.blob_render_error_options(viewer)).to include(/download it/)
        end
Douwe Maan's avatar
Douwe Maan committed
200 201 202
      end
    end
  end
Phil Hughes's avatar
Phil Hughes committed
203 204 205 206

  describe '#ide_edit_path' do
    let(:project) { create(:project) }

Phil Hughes's avatar
Phil Hughes committed
207 208
    around do |example|
      old_script_name = Rails.application.routes.default_url_options[:script_name]
209 210 211 212 213 214 215
      begin
        example.run
      ensure
        Rails.application.routes.default_url_options[:script_name] = old_script_name
      end
    end

Phil Hughes's avatar
Phil Hughes committed
216
    it 'returns full IDE path' do
217 218
      Rails.application.routes.default_url_options[:script_name] = nil

219 220 221 222 223 224 225
      expect(helper.ide_edit_path(project, "master", "")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/master")
    end

    it 'returns full IDE path with second -' do
      Rails.application.routes.default_url_options[:script_name] = nil

      expect(helper.ide_edit_path(project, "testing/slashes", "readme.md")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/slashes/-/readme.md")
Phil Hughes's avatar
Phil Hughes committed
226 227 228 229 230
    end

    it 'returns IDE path without relative_url_root' do
      Rails.application.routes.default_url_options[:script_name] = "/gitlab"

231
      expect(helper.ide_edit_path(project, "master", "")).to eq("/gitlab/-/ide/project/#{project.namespace.path}/#{project.path}/edit/master")
Phil Hughes's avatar
Phil Hughes committed
232
    end
233 234 235 236 237 238 239 240 241 242 243 244 245

    it 'escapes special characters' do
      Rails.application.routes.default_url_options[:script_name] = nil

      expect(helper.ide_edit_path(project, "testing/#hashes", "readme.md#test")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/#hashes/-/readme.md%23test")
      expect(helper.ide_edit_path(project, "testing/#hashes", "src#/readme.md#test")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/#hashes/-/src%23/readme.md%23test")
    end

    it 'does not escape "/" character' do
      Rails.application.routes.default_url_options[:script_name] = nil

      expect(helper.ide_edit_path(project, "testing/slashes", "readme.md/")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/slashes/-/readme.md/")
    end
Phil Hughes's avatar
Phil Hughes committed
246
  end
247
end