diff --git a/app/services/import_csv/preprocess_milestones_service.rb b/app/services/import_csv/preprocess_milestones_service.rb index 97fb381c58e07cd13176744f788fa574b632b29b..295c76184d3e7fca5650c54437acdb1edb9cfff6 100644 --- a/app/services/import_csv/preprocess_milestones_service.rb +++ b/app/services/import_csv/preprocess_milestones_service.rb @@ -14,8 +14,9 @@ def initialize(user, project, provided_titles) attr_reader :user, :project, :provided_titles, :results, :milestone_errors def execute - available_milestones = find_milestones_by_titles - return ServiceResponse.success if provided_titles.sort == available_milestones.sort + result = find_milestones_by_titles + available_milestones = result.map(&:title).uniq.sort + return ServiceResponse.success(payload: result) if provided_titles.sort == available_milestones milestone_errors[:missing][:header] = 'Milestone' milestone_errors[:missing][:titles] = provided_titles.difference(available_milestones) || [] @@ -29,7 +30,7 @@ def find_milestones_by_titles title: provided_titles } finder_params[:group_ids] = project.group.self_and_ancestors.select(:id) if project.group - MilestonesFinder.new(finder_params).execute.map(&:title).uniq + MilestonesFinder.new(finder_params).execute end end end diff --git a/app/services/issuable/import_csv/base_service.rb b/app/services/issuable/import_csv/base_service.rb index 95338374ca6b0a9088002661ced7b7538ed4dc62..c26fb016f79ecb73f6ac8b69039394aef2e44cea 100644 --- a/app/services/issuable/import_csv/base_service.rb +++ b/app/services/issuable/import_csv/base_service.rb @@ -12,7 +12,8 @@ def attributes_for(row) { title: row[:title], description: row[:description], - due_date: row[:due_date] + due_date: row[:due_date], + milestone_id: find_milestone_by_title(row[:milestone]) } end @@ -34,13 +35,20 @@ def preprocess_milestones! # Pre-Process Milestone if header is present return unless csv_data.lines.first.downcase.include?('milestone') - provided_titles = with_csv_lines.filter_map { |row| row[:milestone]&.strip&.downcase }.uniq + provided_titles = with_csv_lines.filter_map { |row| row[:milestone]&.strip }.uniq result = ::ImportCsv::PreprocessMilestonesService.new(user, project, provided_titles).execute + @available_milestones = result.payload return if result.success? # collate errors here and throw errors results[:preprocess_errors][:milestone_errors] = result.payload end + + def find_milestone_by_title(title) + return unless title + + @available_milestones.find { |milestone| milestone.title == title.to_s.strip } if @available_milestones + end end end end diff --git a/ee/spec/services/ee/issues/import_csv_service_spec.rb b/ee/spec/services/ee/issues/import_csv_service_spec.rb index 1f08aa919615d628581e24ff130e08341115e616..ce28126b8356450c51fed5994697ea2535b9c2da 100644 --- a/ee/spec/services/ee/issues/import_csv_service_spec.rb +++ b/ee/spec/services/ee/issues/import_csv_service_spec.rb @@ -14,6 +14,8 @@ described_class.new(user, project, uploader) end + let!(:test_milestone) { create(:milestone, project: project, title: '15.10') } + describe '#execute' do subject { service.execute } diff --git a/spec/fixtures/csv_complex.csv b/spec/fixtures/csv_complex.csv index 60d8aa5d6f75ecd5729fb5e20a4a012539966ae3..b42a5e99d88198529ac3a6882f45fdca30cad959 100644 --- a/spec/fixtures/csv_complex.csv +++ b/spec/fixtures/csv_complex.csv @@ -1,6 +1,6 @@ -title,description,due date +title,description,due date,milestone Issue in 中文,Test description, "Hello","World", "Title with quote""","Description /assign @csv_assignee -/estimate 1h",2022-06-28 +/estimate 1h",2022-06-28,15.10 diff --git a/spec/fixtures/csv_gitlab_export.csv b/spec/fixtures/csv_gitlab_export.csv index 65422509eef4a4b7a43446acb1f6885af7050343..a39260f9dfffb0b393a839faa22c6f61c1216a0e 100644 --- a/spec/fixtures/csv_gitlab_export.csv +++ b/spec/fixtures/csv_gitlab_export.csv @@ -2,4 +2,4 @@ Issue ID,URL,Title,State,Description,Author,Author Username,Assignee,Assignee Us 1,http://localhost:3000/jashkenas/underscore/issues/1,Title,Open,,Elva Jerde,jamel,Tierra Effertz,aurora_hahn,No,No,,2020-01-17 10:36:26,2020-02-19 10:36:26,,v1.0,,"Brene,Cutlass,Escort,GVM",0,0,, 3,http://localhost:3000/jashkenas/underscore/issues/3,Nihil impedit neque quos totam ut aut enim cupiditate doloribus molestiae.,Open,Omnis aliquid sint laudantium quam.,Marybeth Goodwin,rocio.blanda,Annemarie Von,reynalda_howe,No,No,,2020-01-23 10:36:26,2020-02-19 10:36:27,,v1.0,,"Brene,Cutlass,Escort,GVM",0,0,, 34,http://localhost:3000/jashkenas/underscore/issues/34,Dismiss Cipher with no integrity,Open,,Marybeth Goodwin,rocio.blanda,"","",No,No,,2020-02-19 10:38:49,2020-02-19 10:38:49,,,,,0,0,, -35,http://localhost:3000/jashkenas/underscore/issues/35,Test Title,Open,Test Description,Marybeth Goodwin,rocio.blanda,"","",No,No,,2020-02-19 10:38:49,2020-02-19 10:38:49,,,,,0,0,, +35,http://localhost:3000/jashkenas/underscore/issues/35,Test Title,Open,Test Description,Marybeth Goodwin,rocio.blanda,"","",No,No,,2020-02-19 10:38:49,2020-02-19 10:38:49,,v1.0,,,0,0,, diff --git a/spec/services/issues/import_csv_service_spec.rb b/spec/services/issues/import_csv_service_spec.rb index 660686cf805c2baf22661905d3de261fd76b99bd..d3d7277e3e379e5bb9db25d29f6231487059c44b 100644 --- a/spec/services/issues/import_csv_service_spec.rb +++ b/spec/services/issues/import_csv_service_spec.rb @@ -14,6 +14,8 @@ described_class.new(user, project, uploader) end + let!(:test_milestone) { create(:milestone, project: project, title: '15.10') } + include_examples 'issuable import csv service', 'issue' do let(:issuables) { project.issues } let(:email_method) { :import_issues_csv_email } @@ -36,7 +38,8 @@ description: 'Description', time_estimate: 3600, assignees: include(assignee), - due_date: Date.new(2022, 6, 28) + due_date: Date.new(2022, 6, 28), + milestone_id: test_milestone.id ) ) end diff --git a/spec/support/shared_examples/services/issuable/issuable_import_csv_service_shared_examples.rb b/spec/support/shared_examples/services/issuable/issuable_import_csv_service_shared_examples.rb index 8a3ab07bbfe803b2debb5f36051eceb6e4bf6c18..aa31bd2b60410f132cc1792a6f2be47557fdbfcb 100644 --- a/spec/support/shared_examples/services/issuable/issuable_import_csv_service_shared_examples.rb +++ b/spec/support/shared_examples/services/issuable/issuable_import_csv_service_shared_examples.rb @@ -30,7 +30,7 @@ context 'with a file generated by Gitlab CSV export' do let(:file) { fixture_file_upload('spec/fixtures/csv_gitlab_export.csv') } - let!(:test_milestone) { create(:milestone, project: project, title: 'v1.0') } + let_it_be(:test_milestone) { create(:milestone, project: project, title: 'v1.0') } it 'imports the CSV without errors' do expect(subject[:success]).to eq(4) @@ -41,7 +41,19 @@ it 'correctly sets the issuable attributes' do expect { subject }.to change { issuables.count }.by 4 - expect(issuables.reload).to include(have_attributes({ title: 'Test Title', description: 'Test Description' })) + if issuable_type == 'issue' + expect(issuables.reload).to include( + have_attributes({ title: 'Test Title', description: 'Test Description', milestone_id: test_milestone.id }), + have_attributes({ title: 'Title', milestone_id: test_milestone.id }), + have_attributes( + { title: 'Nihil impedit neque quos totam ut aut enim cupiditate doloribus molestiae.', + description: 'Omnis aliquid sint laudantium quam.', + milestone_id: test_milestone.id }) + ) + + else + expect(issuables.reload).to include(have_attributes({ title: 'Test Title', description: 'Test Description' })) + end end it_behaves_like 'importer with email notification'