Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-11 12:08:39 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-11 12:08:39 +0300
commit1078b7bf25c2cb6e03c57da9ae25b0512858556f (patch)
treea50fbfaddb22aca89055296c4c532c7ecb2b1ca0 /spec/requests
parent55733b19c526145cceb120e8bb874d476a84383a (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/requests')
-rw-r--r--spec/requests/api/group_import_spec.rb268
1 files changed, 268 insertions, 0 deletions
diff --git a/spec/requests/api/group_import_spec.rb b/spec/requests/api/group_import_spec.rb
new file mode 100644
index 00000000000..016ed6ff491
--- /dev/null
+++ b/spec/requests/api/group_import_spec.rb
@@ -0,0 +1,268 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::GroupImport do
+ include WorkhorseHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let(:path) { '/groups/import' }
+ let(:file) { File.join('spec', 'fixtures', 'group_export.tar.gz') }
+ let(:export_path) { "#{Dir.tmpdir}/group_export_spec" }
+ let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
+ let(:workhorse_header) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token } }
+
+ before do
+ allow_next_instance_of(Gitlab::ImportExport) do |import_export|
+ expect(import_export).to receive(:storage_path).and_return(export_path)
+ end
+
+ stub_uploads_object_storage(ImportExportUploader)
+ end
+
+ after do
+ FileUtils.rm_rf(export_path, secure: true)
+ end
+
+ describe 'POST /groups/import' do
+ let(:file_upload) { fixture_file_upload(file) }
+ let(:params) do
+ {
+ path: 'test-import-group',
+ name: 'test-import-group',
+ file: fixture_file_upload(file)
+ }
+ end
+
+ subject { post api('/groups/import', user), params: params, headers: workhorse_header }
+
+ shared_examples 'when all params are correct' do
+ context 'when user is authorized to create new group' do
+ it 'creates new group and accepts request' do
+ subject
+
+ expect(response).to have_gitlab_http_status(202)
+ end
+
+ context 'when importing to a parent group' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'creates new group and accepts request' do
+ params[:parent_id] = group.id
+
+ subject
+
+ expect(response).to have_gitlab_http_status(202)
+ expect(group.children.count).to eq(1)
+ end
+
+ context 'when parent group is invalid' do
+ it 'returns 404 and does not create new group' do
+ params[:parent_id] = 99999
+
+ expect { subject }.not_to change { Group.count }
+
+ expect(response).to have_gitlab_http_status(404)
+ expect(json_response['message']).to eq('404 Group Not Found')
+ end
+
+ context 'when user is not an owner of parent group' do
+ it 'returns 403 Forbidden HTTP status' do
+ params[:parent_id] = create(:group).id
+
+ subject
+
+ expect(response).to have_gitlab_http_status(403)
+ expect(json_response['message']).to eq('403 Forbidden')
+ end
+ end
+ end
+ end
+
+ context 'when group creation failed' do
+ before do
+ allow_next_instance_of(Group) do |group|
+ allow(group).to receive(:persisted?).and_return(false)
+ end
+ end
+
+ it 'returns 400 HTTP status' do
+ subject
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+ end
+ end
+
+ context 'when user is not authorized to create new group' do
+ let(:user) { create(:user, can_create_group: false) }
+
+ it 'forbids the request' do
+ subject
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+ end
+ end
+
+ shared_examples 'when some params are missing' do
+ context 'when required params are missing' do
+ shared_examples 'missing parameter' do |params, error_message|
+ it 'returns 400 HTTP status' do
+ params[:file] = file_upload
+
+ expect do
+ post api('/groups/import', user), params: params, headers: workhorse_header
+ end.not_to change { Group.count }.from(1)
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['error']).to eq(error_message)
+ end
+ end
+
+ include_examples 'missing parameter', { name: 'test' }, 'path is missing'
+ include_examples 'missing parameter', { path: 'test' }, 'name is missing'
+ end
+ end
+
+ context 'with object storage disabled' do
+ before do
+ stub_uploads_object_storage(ImportExportUploader, enabled: false)
+ end
+
+ context 'without a file from workhorse' do
+ it 'rejects the request' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+
+ context 'without a workhorse header' do
+ it 'rejects request without a workhorse header' do
+ post api('/groups/import', user), params: params
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context 'when params from workhorse are correct' do
+ let(:params) do
+ {
+ path: 'test-import-group',
+ name: 'test-import-group',
+ 'file.path' => file_upload.path,
+ 'file.name' => file_upload.original_filename
+ }
+ end
+
+ include_examples 'when all params are correct'
+ include_examples 'when some params are missing'
+ end
+
+ it "doesn't attempt to migrate file to object storage" do
+ expect(ObjectStorage::BackgroundMoveWorker).not_to receive(:perform_async)
+
+ subject
+ end
+ end
+
+ context 'with object storage enabled' do
+ before do
+ stub_uploads_object_storage(ImportExportUploader, enabled: true)
+
+ allow(ImportExportUploader).to receive(:workhorse_upload_path).and_return('/')
+ end
+
+ context 'with direct upload enabled' do
+ let(:file_name) { 'group_export.tar.gz' }
+ let!(:fog_connection) do
+ stub_uploads_object_storage(ImportExportUploader, direct_upload: true)
+ end
+ let(:tmp_object) do
+ fog_connection.directories.new(key: 'uploads').files.create(
+ key: "tmp/uploads/#{file_name}",
+ body: file_upload
+ )
+ end
+ let(:fog_file) { fog_to_uploaded_file(tmp_object) }
+ let(:params) do
+ {
+ path: 'test-import-group',
+ name: 'test-import-group',
+ file: fog_file,
+ 'file.remote_id' => file_name,
+ 'file.size' => fog_file.size
+ }
+ end
+
+ it 'accepts the request and stores the file' do
+ expect { subject }.to change { Group.count }.by(1)
+
+ expect(response).to have_gitlab_http_status(:accepted)
+ end
+
+ include_examples 'when all params are correct'
+ include_examples 'when some params are missing'
+ end
+ end
+ end
+
+ describe 'POST /groups/import/authorize' do
+ subject { post api('/groups/import/authorize', user), headers: workhorse_header }
+
+ it 'authorizes importing group with workhorse header' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ end
+
+ it 'rejects requests that bypassed gitlab-workhorse' do
+ workhorse_header.delete(Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+
+ context 'when using remote storage' do
+ context 'when direct upload is enabled' do
+ before do
+ stub_uploads_object_storage(ImportExportUploader, enabled: true, direct_upload: true)
+ end
+
+ it 'responds with status 200, location of file remote store and object details' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ expect(json_response).not_to have_key('TempPath')
+ expect(json_response['RemoteObject']).to have_key('ID')
+ expect(json_response['RemoteObject']).to have_key('GetURL')
+ expect(json_response['RemoteObject']).to have_key('StoreURL')
+ expect(json_response['RemoteObject']).to have_key('DeleteURL')
+ expect(json_response['RemoteObject']).to have_key('MultipartUpload')
+ end
+ end
+
+ context 'when direct upload is disabled' do
+ before do
+ stub_uploads_object_storage(ImportExportUploader, enabled: true, direct_upload: false)
+ end
+
+ it 'handles as a local file' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ expect(json_response['TempPath']).to eq(ImportExportUploader.workhorse_local_upload_path)
+ expect(json_response['RemoteObject']).to be_nil
+ end
+ end
+ end
+ end
+end