summaryrefslogtreecommitdiff
path: root/spec/services/projects/lfs_pointers/lfs_download_link_list_service_spec.rb
blob: d8427d0bf7821cccb240e3d12f377db261a9df4a (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
# frozen_string_literal: true
require 'spec_helper'

describe Projects::LfsPointers::LfsDownloadLinkListService do
  let(:import_url) { 'http://www.gitlab.com/demo/repo.git' }
  let(:lfs_endpoint) { "#{import_url}/info/lfs/objects/batch" }
  let!(:project) { create(:project, import_url: import_url) }
  let(:new_oids) { { 'oid1' => 123, 'oid2' => 125 } }
  let(:remote_uri) { URI.parse(lfs_endpoint) }

  let(:objects_response) do
    body = new_oids.map do |oid, size|
      {
        'oid' => oid,
        'size' => size,
        'actions' => {
          'download' => { 'href' => "#{import_url}/gitlab-lfs/objects/#{oid}" }
        }
      }
    end

    Struct.new(:success?, :objects).new(true, body)
  end

  let(:invalid_object_response) do
    [
      'oid' => 'whatever',
      'size' => 123
    ]
  end

  subject { described_class.new(project, remote_uri: remote_uri) }

  before do
    allow(project).to receive(:lfs_enabled?).and_return(true)
    allow(Gitlab::HTTP).to receive(:post).and_return(objects_response)
  end

  describe '#execute' do
    it 'retrieves each download link of every non existent lfs object' do
      subject.execute(new_oids).each do |lfs_download_object|
        expect(lfs_download_object.link).to eq "#{import_url}/gitlab-lfs/objects/#{lfs_download_object.oid}"
      end
    end

    context 'credentials' do
      context 'when the download link and the lfs_endpoint have the same host' do
        context 'when lfs_endpoint has credentials' do
          let(:import_url) { 'http://user:password@www.gitlab.com/demo/repo.git' }

          it 'adds credentials to the download_link' do
            result = subject.execute(new_oids)

            result.each do |lfs_download_object|
              expect(lfs_download_object.link.starts_with?('http://user:password@')).to be_truthy
            end
          end
        end

        context 'when lfs_endpoint does not have any credentials' do
          it 'does not add any credentials' do
            result = subject.execute(new_oids)

            result.each do |lfs_download_object|
              expect(lfs_download_object.link.starts_with?('http://user:password@')).to be_falsey
            end
          end
        end
      end

      context 'when the download link and the lfs_endpoint have different hosts' do
        let(:import_url_with_credentials) { 'http://user:password@www.otherdomain.com/demo/repo.git' }
        let(:lfs_endpoint) { "#{import_url_with_credentials}/info/lfs/objects/batch" }

        it 'downloads without any credentials' do
          result = subject.execute(new_oids)

          result.each do |lfs_download_object|
            expect(lfs_download_object.link.starts_with?('http://user:password@')).to be_falsey
          end
        end
      end
    end
  end

  describe '#get_download_links' do
    it 'raise error if request fails' do
      allow(Gitlab::HTTP).to receive(:post).and_return(Struct.new(:success?, :message).new(false, 'Failed request'))

      expect { subject.send(:get_download_links, new_oids) }.to raise_error(described_class::DownloadLinksError)
    end
  end

  describe '#parse_response_links' do
    it 'does not add oid entry if href not found' do
      expect(subject).to receive(:log_error).with("Link for Lfs Object with oid whatever not found or invalid.")

      result = subject.send(:parse_response_links, invalid_object_response)

      expect(result).to be_empty
    end
  end
end