diff options
Diffstat (limited to 'spec/lib/gitlab/lfs/client_spec.rb')
-rw-r--r-- | spec/lib/gitlab/lfs/client_spec.rb | 132 |
1 files changed, 119 insertions, 13 deletions
diff --git a/spec/lib/gitlab/lfs/client_spec.rb b/spec/lib/gitlab/lfs/client_spec.rb index 03563a632d6..1c50a2a7500 100644 --- a/spec/lib/gitlab/lfs/client_spec.rb +++ b/spec/lib/gitlab/lfs/client_spec.rb @@ -7,6 +7,8 @@ RSpec.describe Gitlab::Lfs::Client do let(:username) { 'user' } let(:password) { 'password' } let(:credentials) { { user: username, password: password, auth_method: 'password' } } + let(:git_lfs_content_type) { 'application/vnd.git-lfs+json' } + let(:git_lfs_user_agent) { "GitLab #{Gitlab::VERSION} LFS client" } let(:basic_auth_headers) do { 'Authorization' => "Basic #{Base64.strict_encode64("#{username}:#{password}")}" } @@ -21,6 +23,18 @@ RSpec.describe Gitlab::Lfs::Client do } end + let(:verify_action) do + { + "href" => "#{base_url}/some/file/verify", + "header" => { + "Key" => "value" + } + } + end + + let(:authorized_upload_action) { upload_action.tap { |action| action['header']['Authorization'] = 'foo' } } + let(:authorized_verify_action) { verify_action.tap { |action| action['header']['Authorization'] = 'foo' } } + subject(:lfs_client) { described_class.new(base_url, credentials: credentials) } describe '#batch' do @@ -34,10 +48,10 @@ RSpec.describe Gitlab::Lfs::Client do ).to_return( status: 200, body: { 'objects' => 'anything', 'transfer' => 'basic' }.to_json, - headers: { 'Content-Type' => 'application/vnd.git-lfs+json' } + headers: { 'Content-Type' => git_lfs_content_type } ) - result = lfs_client.batch('upload', objects) + result = lfs_client.batch!('upload', objects) expect(stub).to have_been_requested expect(result).to eq('objects' => 'anything', 'transfer' => 'basic') @@ -48,7 +62,7 @@ RSpec.describe Gitlab::Lfs::Client do it 'raises an error' do stub_batch(objects: objects, headers: basic_auth_headers).to_return(status: 400) - expect { lfs_client.batch('upload', objects) }.to raise_error(/Failed/) + expect { lfs_client.batch!('upload', objects) }.to raise_error(/Failed/) end end @@ -56,7 +70,7 @@ RSpec.describe Gitlab::Lfs::Client do it 'raises an error' do stub_batch(objects: objects, headers: basic_auth_headers).to_return(status: 400) - expect { lfs_client.batch('upload', objects) }.to raise_error(/Failed/) + expect { lfs_client.batch!('upload', objects) }.to raise_error(/Failed/) end end @@ -68,17 +82,23 @@ RSpec.describe Gitlab::Lfs::Client do ).to_return( status: 200, body: { 'transfer' => 'carrier-pigeon' }.to_json, - headers: { 'Content-Type' => 'application/vnd.git-lfs+json' } + headers: { 'Content-Type' => git_lfs_content_type } ) - expect { lfs_client.batch('upload', objects) }.to raise_error(/Unsupported transfer/) + expect { lfs_client.batch!('upload', objects) }.to raise_error(/Unsupported transfer/) end end def stub_batch(objects:, headers:, operation: 'upload', transfer: 'basic') - objects = objects.map { |o| { oid: o.oid, size: o.size } } + objects = objects.as_json(only: [:oid, :size]) body = { operation: operation, 'transfers': [transfer], objects: objects }.to_json + headers = { + 'Accept' => git_lfs_content_type, + 'Content-Type' => git_lfs_content_type, + 'User-Agent' => git_lfs_user_agent + }.merge(headers) + stub_request(:post, base_url + '/info/lfs/objects/batch').with(body: body, headers: headers) end end @@ -90,7 +110,7 @@ RSpec.describe Gitlab::Lfs::Client do it "makes an HTTP PUT with expected parameters" do stub_upload(object: object, headers: upload_action['header']).to_return(status: 200) - lfs_client.upload(object, upload_action, authenticated: true) + lfs_client.upload!(object, upload_action, authenticated: true) end end @@ -101,7 +121,20 @@ RSpec.describe Gitlab::Lfs::Client do headers: basic_auth_headers.merge(upload_action['header']) ).to_return(status: 200) - lfs_client.upload(object, upload_action, authenticated: false) + lfs_client.upload!(object, upload_action, authenticated: false) + + expect(stub).to have_been_requested + end + end + + context 'request is not marked as authenticated but includes an authorization header' do + it 'prefers the provided authorization header' do + stub = stub_upload( + object: object, + headers: authorized_upload_action['header'] + ).to_return(status: 200) + + lfs_client.upload!(object, authorized_upload_action, authenticated: false) expect(stub).to have_been_requested end @@ -110,13 +143,13 @@ RSpec.describe Gitlab::Lfs::Client do context 'LFS object has no file' do let(:object) { LfsObject.new } - it 'makes an HJTT PUT with expected parameters' do + it 'makes an HTTP PUT with expected parameters' do stub = stub_upload( object: object, headers: upload_action['header'] ).to_return(status: 200) - lfs_client.upload(object, upload_action, authenticated: true) + lfs_client.upload!(object, upload_action, authenticated: true) expect(stub).to have_been_requested end @@ -126,7 +159,7 @@ RSpec.describe Gitlab::Lfs::Client do it 'raises an error' do stub_upload(object: object, headers: upload_action['header']).to_return(status: 400) - expect { lfs_client.upload(object, upload_action, authenticated: true) }.to raise_error(/Failed/) + expect { lfs_client.upload!(object, upload_action, authenticated: true) }.to raise_error(/Failed/) end end @@ -134,15 +167,88 @@ RSpec.describe Gitlab::Lfs::Client do it 'raises an error' do stub_upload(object: object, headers: upload_action['header']).to_return(status: 500) - expect { lfs_client.upload(object, upload_action, authenticated: true) }.to raise_error(/Failed/) + expect { lfs_client.upload!(object, upload_action, authenticated: true) }.to raise_error(/Failed/) end end def stub_upload(object:, headers:) + headers = { + 'Content-Type' => 'application/octet-stream', + 'Content-Length' => object.size.to_s, + 'User-Agent' => git_lfs_user_agent + }.merge(headers) + stub_request(:put, upload_action['href']).with( body: object.file.read, headers: headers.merge('Content-Length' => object.size.to_s) ) end end + + describe "#verify" do + let_it_be(:object) { create(:lfs_object) } + + context 'server returns 200 OK to an authenticated request' do + it "makes an HTTP POST with expected parameters" do + stub_verify(object: object, headers: verify_action['header']).to_return(status: 200) + + lfs_client.verify!(object, verify_action, authenticated: true) + end + end + + context 'server returns 200 OK to an unauthenticated request' do + it "makes an HTTP POST with expected parameters" do + stub = stub_verify( + object: object, + headers: basic_auth_headers.merge(upload_action['header']) + ).to_return(status: 200) + + lfs_client.verify!(object, verify_action, authenticated: false) + + expect(stub).to have_been_requested + end + end + + context 'request is not marked as authenticated but includes an authorization header' do + it 'prefers the provided authorization header' do + stub = stub_verify( + object: object, + headers: authorized_verify_action['header'] + ).to_return(status: 200) + + lfs_client.verify!(object, authorized_verify_action, authenticated: false) + + expect(stub).to have_been_requested + end + end + + context 'server returns 400 error' do + it 'raises an error' do + stub_verify(object: object, headers: verify_action['header']).to_return(status: 400) + + expect { lfs_client.verify!(object, verify_action, authenticated: true) }.to raise_error(/Failed/) + end + end + + context 'server returns 500 error' do + it 'raises an error' do + stub_verify(object: object, headers: verify_action['header']).to_return(status: 500) + + expect { lfs_client.verify!(object, verify_action, authenticated: true) }.to raise_error(/Failed/) + end + end + + def stub_verify(object:, headers:) + headers = { + 'Accept' => git_lfs_content_type, + 'Content-Type' => git_lfs_content_type, + 'User-Agent' => git_lfs_user_agent + }.merge(headers) + + stub_request(:post, verify_action['href']).with( + body: object.to_json(only: [:oid, :size]), + headers: headers + ) + end + end end |