2018-02-07 13:00:53 +00:00
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
describe 'Git LFS File Locking API' do
|
|
|
|
include WorkhorseHelpers
|
|
|
|
|
2019-01-16 12:09:29 +00:00
|
|
|
let(:project) { create(:project) }
|
2018-07-11 14:36:08 +00:00
|
|
|
let(:maintainer) { create(:user) }
|
2018-02-07 13:00:53 +00:00
|
|
|
let(:developer) { create(:user) }
|
|
|
|
let(:guest) { create(:user) }
|
|
|
|
let(:path) { 'README.md' }
|
|
|
|
let(:headers) do
|
|
|
|
{
|
|
|
|
'Authorization' => authorization
|
|
|
|
}.compact
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples 'unauthorized request' do
|
|
|
|
context 'when user is not authorized' do
|
|
|
|
let(:authorization) { authorize_user(guest) }
|
|
|
|
|
|
|
|
it 'returns a forbidden 403 response' do
|
|
|
|
post_lfs_json url, body, headers
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(403)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
|
|
|
|
|
2018-07-11 14:36:08 +00:00
|
|
|
project.add_developer(maintainer)
|
2018-02-07 13:00:53 +00:00
|
|
|
project.add_developer(developer)
|
|
|
|
project.add_guest(guest)
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'Create File Lock endpoint' do
|
|
|
|
let(:url) { "#{project.http_url_to_repo}/info/lfs/locks" }
|
|
|
|
let(:authorization) { authorize_user(developer) }
|
|
|
|
let(:body) { { path: path } }
|
|
|
|
|
|
|
|
include_examples 'unauthorized request'
|
|
|
|
|
|
|
|
context 'with an existent lock' do
|
|
|
|
before do
|
|
|
|
lock_file('README.md', developer)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'return an error message' do
|
|
|
|
post_lfs_json url, body, headers
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(409)
|
|
|
|
|
|
|
|
expect(json_response.keys).to match_array(%w(lock message documentation_url))
|
|
|
|
expect(json_response['message']).to match(/already locked/)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the existen lock' do
|
|
|
|
post_lfs_json url, body, headers
|
|
|
|
|
|
|
|
expect(json_response['lock']['path']).to eq('README.md')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'without an existent lock' do
|
|
|
|
it 'creates the lock' do
|
|
|
|
post_lfs_json url, body, headers
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(201)
|
|
|
|
|
|
|
|
expect(json_response['lock'].keys).to match_array(%w(id path locked_at owner))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'Listing File Locks endpoint' do
|
|
|
|
let(:url) { "#{project.http_url_to_repo}/info/lfs/locks" }
|
|
|
|
let(:authorization) { authorize_user(developer) }
|
|
|
|
|
|
|
|
include_examples 'unauthorized request'
|
|
|
|
|
|
|
|
it 'returns the list of locked files' do
|
|
|
|
lock_file('README.md', developer)
|
|
|
|
lock_file('README', developer)
|
|
|
|
|
|
|
|
do_get url, nil, headers
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(200)
|
|
|
|
|
|
|
|
expect(json_response['locks'].size).to eq(2)
|
|
|
|
expect(json_response['locks'].first.keys).to match_array(%w(id path locked_at owner))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'List File Locks for verification endpoint' do
|
|
|
|
let(:url) { "#{project.http_url_to_repo}/info/lfs/locks/verify" }
|
|
|
|
let(:authorization) { authorize_user(developer) }
|
|
|
|
|
|
|
|
include_examples 'unauthorized request'
|
|
|
|
|
|
|
|
it 'returns the list of locked files grouped by owner' do
|
2018-07-11 14:36:08 +00:00
|
|
|
lock_file('README.md', maintainer)
|
2018-02-07 13:00:53 +00:00
|
|
|
lock_file('README', developer)
|
|
|
|
|
|
|
|
post_lfs_json url, nil, headers
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(200)
|
|
|
|
|
|
|
|
expect(json_response['ours'].size).to eq(1)
|
|
|
|
expect(json_response['ours'].first['path']).to eq('README')
|
|
|
|
expect(json_response['theirs'].size).to eq(1)
|
|
|
|
expect(json_response['theirs'].first['path']).to eq('README.md')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'Delete File Lock endpoint' do
|
|
|
|
let!(:lock) { lock_file('README.md', developer) }
|
|
|
|
let(:url) { "#{project.http_url_to_repo}/info/lfs/locks/#{lock[:id]}/unlock" }
|
|
|
|
let(:authorization) { authorize_user(developer) }
|
|
|
|
|
|
|
|
include_examples 'unauthorized request'
|
|
|
|
|
|
|
|
context 'with an existent lock' do
|
|
|
|
it 'deletes the lock' do
|
|
|
|
post_lfs_json url, nil, headers
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(200)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the deleted lock' do
|
|
|
|
post_lfs_json url, nil, headers
|
|
|
|
|
|
|
|
expect(json_response['lock'].keys).to match_array(%w(id path locked_at owner))
|
|
|
|
end
|
2019-01-15 21:05:36 +00:00
|
|
|
|
|
|
|
context 'when a maintainer uses force' do
|
|
|
|
let(:authorization) { authorize_user(maintainer) }
|
|
|
|
|
|
|
|
it 'deletes the lock' do
|
|
|
|
project.add_maintainer(maintainer)
|
|
|
|
post_lfs_json url, { force: true }, headers
|
|
|
|
|
|
|
|
expect(response).to have_gitlab_http_status(200)
|
|
|
|
end
|
|
|
|
end
|
2018-02-07 13:00:53 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def lock_file(path, author)
|
|
|
|
result = Lfs::LockFileService.new(project, author, { path: path }).execute
|
|
|
|
|
|
|
|
result[:lock]
|
|
|
|
end
|
|
|
|
|
|
|
|
def authorize_user(user)
|
|
|
|
ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password)
|
|
|
|
end
|
|
|
|
|
|
|
|
def post_lfs_json(url, body = nil, headers = nil)
|
2018-12-17 22:52:17 +00:00
|
|
|
post(url, params: body.try(:to_json), headers: (headers || {}).merge('Content-Type' => LfsRequest::CONTENT_TYPE))
|
2018-02-07 13:00:53 +00:00
|
|
|
end
|
|
|
|
|
2019-01-16 12:09:29 +00:00
|
|
|
def do_get(url, params = nil, headers = nil)
|
2018-12-17 22:52:17 +00:00
|
|
|
get(url, params: (params || {}), headers: (headers || {}).merge('Content-Type' => LfsRequest::CONTENT_TYPE))
|
2018-02-07 13:00:53 +00:00
|
|
|
end
|
|
|
|
end
|