debian-mirror-gitlab/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb

227 lines
6.1 KiB
Ruby
Raw Normal View History

2019-07-31 22:56:46 +05:30
# frozen_string_literal: true
2018-11-08 19:23:39 +05:30
require 'spec_helper'
describe Projects::LfsPointers::LfsDownloadService do
2019-06-05 12:25:43 +05:30
include StubRequests
2018-11-08 19:23:39 +05:30
let(:project) { create(:project) }
2019-01-03 12:48:30 +05:30
let(:lfs_content) { SecureRandom.random_bytes(10) }
2019-02-02 18:00:53 +05:30
let(:oid) { Digest::SHA256.hexdigest(lfs_content) }
let(:download_link) { "http://gitlab.com/#{oid}" }
let(:size) { lfs_content.size }
let(:lfs_object) { LfsDownloadObject.new(oid: oid, size: size, link: download_link) }
let(:local_request_setting) { false }
2018-11-08 19:23:39 +05:30
2019-02-02 18:00:53 +05:30
subject { described_class.new(project, lfs_object) }
2018-11-08 19:23:39 +05:30
before do
2019-02-02 18:00:53 +05:30
ApplicationSetting.create_from_defaults
2019-10-12 21:52:04 +05:30
stub_application_setting(allow_local_requests_from_web_hooks_and_services: local_request_setting)
2018-11-08 19:23:39 +05:30
allow(project).to receive(:lfs_enabled?).and_return(true)
2019-02-02 18:00:53 +05:30
end
shared_examples 'lfs temporal file is removed' do
it do
subject.execute
2019-01-03 12:48:30 +05:30
2019-02-02 18:00:53 +05:30
expect(File.exist?(subject.send(:tmp_filename))).to be false
end
end
shared_examples 'no lfs object is created' do
it do
expect { subject.execute }.not_to change { LfsObject.count }
end
it 'returns error result' do
expect(subject.execute[:status]).to eq :error
end
it 'an error is logged' do
expect(subject).to receive(:log_error)
subject.execute
end
it_behaves_like 'lfs temporal file is removed'
end
shared_examples 'lfs object is created' do
it do
expect(subject).to receive(:download_and_save_file!).and_call_original
expect { subject.execute }.to change { LfsObject.count }.by(1)
end
it 'returns success result' do
expect(subject.execute[:status]).to eq :success
end
it_behaves_like 'lfs temporal file is removed'
2018-11-08 19:23:39 +05:30
end
describe '#execute' do
context 'when file download succeeds' do
2019-02-02 18:00:53 +05:30
before do
2019-06-05 12:25:43 +05:30
stub_full_request(download_link).to_return(body: lfs_content)
2018-11-08 19:23:39 +05:30
end
2019-02-02 18:00:53 +05:30
it_behaves_like 'lfs object is created'
2018-11-08 19:23:39 +05:30
it 'has the same oid' do
2019-02-02 18:00:53 +05:30
subject.execute
2018-11-08 19:23:39 +05:30
expect(LfsObject.first.oid).to eq oid
end
2019-02-02 18:00:53 +05:30
it 'has the same size' do
subject.execute
expect(LfsObject.first.size).to eq size
end
2018-11-08 19:23:39 +05:30
it 'stores the content' do
2019-02-02 18:00:53 +05:30
subject.execute
2018-11-08 19:23:39 +05:30
2019-01-03 12:48:30 +05:30
expect(File.binread(LfsObject.first.file.file.file)).to eq lfs_content
2018-11-08 19:23:39 +05:30
end
end
context 'when file download fails' do
2019-02-02 18:00:53 +05:30
before do
allow(Gitlab::HTTP).to receive(:get).and_return(code: 500, 'success?' => false)
end
it_behaves_like 'no lfs object is created'
it 'raise StandardError exception' do
expect(subject).to receive(:download_and_save_file!).and_raise(StandardError)
subject.execute
end
end
context 'when downloaded lfs file has a different size' do
let(:size) { 1 }
before do
2019-06-05 12:25:43 +05:30
stub_full_request(download_link).to_return(body: lfs_content)
2019-02-02 18:00:53 +05:30
end
it_behaves_like 'no lfs object is created'
it 'raise SizeError exception' do
expect(subject).to receive(:download_and_save_file!).and_raise(described_class::SizeError)
subject.execute
end
end
context 'when downloaded lfs file has a different oid' do
before do
2019-06-05 12:25:43 +05:30
stub_full_request(download_link).to_return(body: lfs_content)
2019-02-02 18:00:53 +05:30
allow_any_instance_of(Digest::SHA256).to receive(:hexdigest).and_return('foobar')
end
it_behaves_like 'no lfs object is created'
it 'raise OidError exception' do
expect(subject).to receive(:download_and_save_file!).and_raise(described_class::OidError)
subject.execute
2018-11-08 19:23:39 +05:30
end
end
context 'when credentials present' do
let(:download_link_with_credentials) { "http://user:password@gitlab.com/#{oid}" }
2019-02-02 18:00:53 +05:30
let(:lfs_object) { LfsDownloadObject.new(oid: oid, size: size, link: download_link_with_credentials) }
2018-11-08 19:23:39 +05:30
before do
2019-06-05 12:25:43 +05:30
stub_full_request(download_link).with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' }).to_return(body: lfs_content)
2018-11-08 19:23:39 +05:30
end
it 'the request adds authorization headers' do
2019-02-02 18:00:53 +05:30
subject
2018-11-08 19:23:39 +05:30
end
end
2019-01-03 12:48:30 +05:30
context 'when localhost requests are allowed' do
let(:download_link) { 'http://192.168.2.120' }
2019-02-02 18:00:53 +05:30
let(:local_request_setting) { true }
2019-01-03 12:48:30 +05:30
before do
2019-06-05 12:25:43 +05:30
stub_full_request(download_link, ip_address: '192.168.2.120').to_return(body: lfs_content)
2019-01-03 12:48:30 +05:30
end
2019-02-02 18:00:53 +05:30
it_behaves_like 'lfs object is created'
2019-01-03 12:48:30 +05:30
end
2018-12-15 14:41:45 +05:30
context 'when a bad URL is used' do
2019-01-03 12:48:30 +05:30
where(download_link: ['/etc/passwd', 'ftp://example.com', 'http://127.0.0.2', 'http://192.168.2.120'])
2018-12-15 14:41:45 +05:30
with_them do
it 'does not download the file' do
2019-02-02 18:00:53 +05:30
expect(subject).not_to receive(:download_lfs_file!)
expect { subject.execute }.not_to change { LfsObject.count }
2018-12-15 14:41:45 +05:30
end
end
end
2019-01-03 12:48:30 +05:30
context 'when the URL points to a redirected URL' do
context 'that is blocked' do
where(redirect_link: ['ftp://example.com', 'http://127.0.0.2', 'http://192.168.2.120'])
with_them do
before do
2019-06-05 12:25:43 +05:30
stub_full_request(download_link, ip_address: '192.168.2.120')
.to_return(status: 301, headers: { 'Location' => redirect_link })
2019-01-03 12:48:30 +05:30
end
2019-02-02 18:00:53 +05:30
it_behaves_like 'no lfs object is created'
2019-01-03 12:48:30 +05:30
end
end
2019-02-02 18:00:53 +05:30
context 'that is not blocked' do
2019-01-03 12:48:30 +05:30
let(:redirect_link) { "http://example.com/"}
before do
2019-06-05 12:25:43 +05:30
stub_full_request(download_link).to_return(status: 301, headers: { 'Location' => redirect_link })
stub_full_request(redirect_link).to_return(body: lfs_content)
2019-01-03 12:48:30 +05:30
end
2019-02-02 18:00:53 +05:30
it_behaves_like 'lfs object is created'
end
end
context 'when the lfs object attributes are invalid' do
let(:oid) { 'foobar' }
before do
expect(lfs_object).to be_invalid
end
it_behaves_like 'no lfs object is created'
it 'does not download the file' do
expect(subject).not_to receive(:download_lfs_file!)
subject.execute
2019-01-03 12:48:30 +05:30
end
end
2019-03-02 22:35:43 +05:30
context 'when an lfs object with the same oid already exists' do
2018-11-08 19:23:39 +05:30
before do
2019-02-02 18:00:53 +05:30
create(:lfs_object, oid: oid)
2018-11-08 19:23:39 +05:30
end
it 'does not download the file' do
2019-02-02 18:00:53 +05:30
expect(subject).not_to receive(:download_lfs_file!)
2018-11-08 19:23:39 +05:30
2019-02-02 18:00:53 +05:30
subject.execute
2018-11-08 19:23:39 +05:30
end
end
end
end