diff options
Diffstat (limited to 'spec/requests/projects/work_items_spec.rb')
-rw-r--r-- | spec/requests/projects/work_items_spec.rb | 176 |
1 files changed, 173 insertions, 3 deletions
diff --git a/spec/requests/projects/work_items_spec.rb b/spec/requests/projects/work_items_spec.rb index 056416d380d..99337771960 100644 --- a/spec/requests/projects/work_items_spec.rb +++ b/spec/requests/projects/work_items_spec.rb @@ -3,16 +3,41 @@ require 'spec_helper' RSpec.describe 'Work Items', feature_category: :team_planning do + include WorkhorseHelpers + + include_context 'workhorse headers' + let_it_be(:work_item) { create(:work_item) } - let_it_be(:developer) { create(:user) } + let_it_be(:current_user) { create(:user) } + let_it_be(:project) { create(:project) } + + let(:file) { fixture_file_upload("spec/fixtures/#{filename}") } before_all do - work_item.project.add_developer(developer) + work_item.project.add_developer(current_user) + end + + shared_examples 'response with 404 status' do + it 'returns 404' do + subject + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + shared_examples 'safely handles uploaded files' do + it 'ensures the upload is handled safely', :aggregate_failures do + allow(Gitlab::Utils).to receive(:check_path_traversal!).and_call_original + expect(Gitlab::Utils).to receive(:check_path_traversal!).with(filename).at_least(:once) + expect(FileUploader).not_to receive(:cache) + + subject + end end describe 'GET /:namespace/:project/work_items/:id' do before do - sign_in(developer) + sign_in(current_user) end it 'renders index' do @@ -21,4 +46,149 @@ RSpec.describe 'Work Items', feature_category: :team_planning do expect(response).to have_gitlab_http_status(:ok) end end + + describe 'POST /:namespace/:project/work_items/import_csv' do + let(:filename) { 'work_items_valid_types.csv' } + let(:params) { { namespace_id: project.namespace.id, path: 'test' } } + + subject { upload_file(file, workhorse_headers, params) } + + shared_examples 'handles authorisation' do + context 'when unauthorized' do + context 'with non-member' do + let_it_be(:current_user) { create(:user) } + + before do + sign_in(current_user) + end + + it 'responds with error' do + subject + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'with anonymous user' do + it 'responds with error' do + subject + + expect(response).to have_gitlab_http_status(:found) + expect(response).to be_redirect + end + end + end + + context 'when authorized' do + before do + sign_in(current_user) + project.add_reporter(current_user) + end + + context 'when import/export work items feature is available and member is a reporter' do + shared_examples 'response with success status' do + it 'returns 200 status and success message' do + subject + + expect(response).to have_gitlab_http_status(:success) + expect(json_response).to eq( + 'message' => "Your work items are being imported. Once finished, you'll receive a confirmation email.") + end + end + + it_behaves_like 'response with success status' + it_behaves_like 'safely handles uploaded files' + + it 'shows error when upload fails' do + expect_next_instance_of(UploadService) do |upload_service| + expect(upload_service).to receive(:execute).and_return(nil) + end + + subject + + expect(json_response).to eq('errors' => 'File upload error.') + end + + context 'when file extension is not csv' do + let(:filename) { 'sample_doc.md' } + + it 'returns error message' do + subject + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response).to eq( + 'errors' => "The uploaded file was invalid. Supported file extensions are .csv.") + end + end + end + + context 'when work items import/export feature is not available' do + before do + stub_feature_flags(import_export_work_items_csv: false) + end + + it_behaves_like 'response with 404 status' + end + end + end + + context 'with public project' do + let_it_be(:project) { create(:project, :public) } + + it_behaves_like 'handles authorisation' + end + + context 'with private project' do + it_behaves_like 'handles authorisation' + end + + def upload_file(file, headers = {}, params = {}) + workhorse_finalize( + import_csv_project_work_items_path(project), + method: :post, + file_key: :file, + params: params.merge(file: file), + headers: headers, + send_rewritten_field: true + ) + end + end + + describe 'POST #authorize' do + subject do + post import_csv_authorize_project_work_items_path(project), + headers: workhorse_headers + end + + before do + sign_in(current_user) + end + + context 'with authorized user' do + before do + project.add_reporter(current_user) + end + + context 'when work items import/export feature is enabled' do + let(:user) { current_user } + + it_behaves_like 'handle uploads authorize request' do + let(:uploader_class) { FileUploader } + let(:maximum_size) { Gitlab::CurrentSettings.max_attachment_size.megabytes } + end + end + + context 'when work items import/export feature is disabled' do + before do + stub_feature_flags(import_export_work_items_csv: false) + end + + it_behaves_like 'response with 404 status' + end + end + + context 'with unauthorized user' do + it_behaves_like 'response with 404 status' + end + end end |