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-05-20 17:34:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-20 17:34:42 +0300
commit9f46488805e86b1bc341ea1620b866016c2ce5ed (patch)
treef9748c7e287041e37d6da49e0a29c9511dc34768 /spec/lib/gitlab/jira_import
parentdfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff)
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'spec/lib/gitlab/jira_import')
-rw-r--r--spec/lib/gitlab/jira_import/base_importer_spec.rb20
-rw-r--r--spec/lib/gitlab/jira_import/handle_labels_service_spec.rb53
-rw-r--r--spec/lib/gitlab/jira_import/issue_serializer_spec.rb150
-rw-r--r--spec/lib/gitlab/jira_import/issues_importer_spec.rb36
-rw-r--r--spec/lib/gitlab/jira_import/labels_importer_spec.rb83
-rw-r--r--spec/lib/gitlab/jira_import/metadata_collector_spec.rb178
-rw-r--r--spec/lib/gitlab/jira_import/user_mapper_spec.rb80
7 files changed, 510 insertions, 90 deletions
diff --git a/spec/lib/gitlab/jira_import/base_importer_spec.rb b/spec/lib/gitlab/jira_import/base_importer_spec.rb
index f22efcb8743..ecaf3def589 100644
--- a/spec/lib/gitlab/jira_import/base_importer_spec.rb
+++ b/spec/lib/gitlab/jira_import/base_importer_spec.rb
@@ -3,12 +3,17 @@
require 'spec_helper'
describe Gitlab::JiraImport::BaseImporter do
+ include JiraServiceHelper
+
let(:project) { create(:project) }
describe 'with any inheriting class' do
- context 'when feature flag disabled' do
+ context 'when an error is returned from the project validation' do
before do
stub_feature_flags(jira_issue_import: false)
+
+ allow(project).to receive(:validate_jira_import_settings!)
+ .and_raise(Projects::ImportService::Error, 'Jira import feature is disabled.')
end
it 'raises exception' do
@@ -16,20 +21,17 @@ describe Gitlab::JiraImport::BaseImporter do
end
end
- context 'when feature flag enabled' do
+ context 'when project validation is ok' do
+ let!(:jira_service) { create(:jira_service, project: project) }
+
before do
stub_feature_flags(jira_issue_import: true)
- end
+ stub_jira_service_test
- context 'when Jira service was not setup' do
- it 'raises exception' do
- expect { described_class.new(project) }.to raise_error(Projects::ImportService::Error, 'Jira integration not configured.')
- end
+ allow(project).to receive(:validate_jira_import_settings!)
end
context 'when Jira service exists' do
- let!(:jira_service) { create(:jira_service, project: project) }
-
context 'when Jira import data is not present' do
it 'raises exception' do
expect { described_class.new(project) }.to raise_error(Projects::ImportService::Error, 'Unable to find Jira project to import data from.')
diff --git a/spec/lib/gitlab/jira_import/handle_labels_service_spec.rb b/spec/lib/gitlab/jira_import/handle_labels_service_spec.rb
new file mode 100644
index 00000000000..0eeff180575
--- /dev/null
+++ b/spec/lib/gitlab/jira_import/handle_labels_service_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::JiraImport::HandleLabelsService do
+ describe '#execute' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+
+ let_it_be(:project_label) { create(:label, project: project, title: 'bug') }
+ let_it_be(:other_project_label) { create(:label, title: 'feature') }
+ let_it_be(:group_label) { create(:group_label, group: group, title: 'dev') }
+ let(:jira_labels) { %w(bug feature dev group::new) }
+
+ subject { described_class.new(project, jira_labels).execute }
+
+ context 'when some provided jira labels are missing' do
+ def created_labels
+ project.labels.reorder(id: :desc).first(2)
+ end
+
+ it 'creates the missing labels on the project level' do
+ expect { subject }.to change { Label.count }.from(3).to(5)
+
+ expect(created_labels.map(&:title)).to match_array(%w(feature group::new))
+ end
+
+ it 'returns the id of all labels matching the title' do
+ expect(subject).to match_array([project_label.id, group_label.id] + created_labels.map(&:id))
+ end
+ end
+
+ context 'when no provided jira labels are missing' do
+ let(:jira_labels) { %w(bug dev) }
+
+ it 'does not create any new labels' do
+ expect { subject }.not_to change { Label.count }.from(3)
+ end
+
+ it 'returns the id of all labels matching the title' do
+ expect(subject).to match_array([project_label.id, group_label.id])
+ end
+ end
+
+ context 'when no labels are provided' do
+ let(:jira_labels) { [] }
+
+ it 'does not create any new labels' do
+ expect { subject }.not_to change { Label.count }.from(3)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/jira_import/issue_serializer_spec.rb b/spec/lib/gitlab/jira_import/issue_serializer_spec.rb
index 808ed6ee2fa..ce38a1234cf 100644
--- a/spec/lib/gitlab/jira_import/issue_serializer_spec.rb
+++ b/spec/lib/gitlab/jira_import/issue_serializer_spec.rb
@@ -4,7 +4,12 @@ require 'spec_helper'
describe Gitlab::JiraImport::IssueSerializer do
describe '#execute' do
- let_it_be(:project) { create(:project) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:project_label) { create(:label, project: project, title: 'bug') }
+ let_it_be(:other_project_label) { create(:label, project: project, title: 'feature') }
+ let_it_be(:group_label) { create(:group_label, group: group, title: 'dev') }
+ let_it_be(:current_user) { create(:user) }
let(:iid) { 5 }
let(:key) { 'PROJECT-5' }
@@ -12,28 +17,21 @@ describe Gitlab::JiraImport::IssueSerializer do
let(:description) { 'basic description' }
let(:created_at) { '2020-01-01 20:00:00' }
let(:updated_at) { '2020-01-10 20:00:00' }
- let(:assignee) { double(displayName: 'Solver') }
+ let(:assignee) { double(attrs: { 'displayName' => 'Solver', 'emailAddress' => 'assignee@example.com' }) }
+ let(:reporter) { double(attrs: { 'displayName' => 'Reporter', 'emailAddress' => 'reporter@example.com' }) }
let(:jira_status) { 'new' }
let(:parent_field) do
{ 'key' => 'FOO-2', 'id' => '1050', 'fields' => { 'summary' => 'parent issue FOO' } }
end
- let(:issue_type_field) { { 'name' => 'Task' } }
- let(:fix_versions_field) { [{ 'name' => '1.0' }, { 'name' => '1.1' }] }
let(:priority_field) { { 'name' => 'Medium' } }
- let(:labels_field) { %w(bug backend) }
- let(:environment_field) { 'staging' }
- let(:duedate_field) { '2020-03-01' }
+ let(:labels_field) { %w(bug dev backend frontend) }
let(:fields) do
{
'parent' => parent_field,
- 'issuetype' => issue_type_field,
- 'fixVersions' => fix_versions_field,
'priority' => priority_field,
- 'labels' => labels_field,
- 'environment' => environment_field,
- 'duedate' => duedate_field
+ 'labels' => labels_field
}
end
@@ -46,7 +44,7 @@ describe Gitlab::JiraImport::IssueSerializer do
created: created_at,
updated: updated_at,
assignee: assignee,
- reporter: double(displayName: 'Reporter'),
+ reporter: reporter,
status: double(statusCategory: { 'key' => jira_status }),
fields: fields
)
@@ -54,27 +52,18 @@ describe Gitlab::JiraImport::IssueSerializer do
let(:params) { { iid: iid } }
- subject { described_class.new(project, jira_issue, params).execute }
+ subject { described_class.new(project, jira_issue, current_user.id, params).execute }
let(:expected_description) do
<<~MD
- *Created by: Reporter*
-
- *Assigned to: Solver*
-
basic description
---
**Issue metadata**
- - Issue type: Task
- Priority: Medium
- - Labels: bug, backend
- - Environment: staging
- - Due date: 2020-03-01
- Parent issue: [FOO-2] parent issue FOO
- - Fix versions: 1.0, 1.1
MD
end
@@ -88,55 +77,102 @@ describe Gitlab::JiraImport::IssueSerializer do
state_id: 1,
updated_at: updated_at,
created_at: created_at,
- author_id: project.creator_id
+ author_id: current_user.id,
+ assignee_ids: nil,
+ label_ids: [project_label.id, group_label.id] + Label.reorder(id: :asc).last(2).pluck(:id)
)
end
- context 'when some metadata fields are missing' do
- let(:assignee) { nil }
- let(:parent_field) { nil }
- let(:fix_versions_field) { [] }
- let(:labels_field) { [] }
- let(:environment_field) { nil }
- let(:duedate_field) { '2020-03-01' }
+ it 'creates a hash for valid issue' do
+ expect(Issue.new(subject)).to be_valid
+ end
+
+ context 'labels' do
+ it 'creates all missing labels (on project level)' do
+ expect { subject }.to change { Label.count }.from(3).to(5)
+
+ expect(Label.find_by(title: 'frontend').project).to eq(project)
+ expect(Label.find_by(title: 'backend').project).to eq(project)
+ end
+
+ context 'when there are no new labels' do
+ let(:labels_field) { %w(bug dev) }
- it 'skips the missing fields' do
- expected_description = <<~MD
- *Created by: Reporter*
+ it 'assigns the labels to the Issue hash' do
+ expect(subject[:label_ids]).to match_array([project_label.id, group_label.id])
+ end
- basic description
+ it 'does not create new labels' do
+ expect { subject }.not_to change { Label.count }.from(3)
+ end
+ end
+ end
- ---
+ context 'author' do
+ context 'when reporter maps to a valid GitLab user' do
+ let!(:user) { create(:user, email: 'reporter@example.com') }
- **Issue metadata**
+ it 'sets the issue author to the mapped user' do
+ project.add_developer(user)
- - Issue type: Task
- - Priority: Medium
- - Due date: 2020-03-01
- MD
+ expect(subject[:author_id]).to eq(user.id)
+ end
+ end
- expect(subject[:description]).to eq(expected_description.strip)
+ context 'when reporter does not map to a valid Gitlab user' do
+ it 'defaults the issue author to project creator' do
+ expect(subject[:author_id]).to eq(current_user.id)
+ end
+ end
+
+ context 'when reporter field is empty' do
+ let(:reporter) { nil }
+
+ it 'defaults the issue author to project creator' do
+ expect(subject[:author_id]).to eq(current_user.id)
+ end
+ end
+
+ context 'when reporter field is missing email address' do
+ let(:reporter) { double(attrs: { 'displayName' => 'Reporter' }) }
+
+ it 'defaults the issue author to project creator' do
+ expect(subject[:author_id]).to eq(current_user.id)
+ end
end
end
- context 'when all metadata fields are missing' do
- let(:assignee) { nil }
- let(:parent_field) { nil }
- let(:issue_type_field) { nil }
- let(:fix_versions_field) { [] }
- let(:priority_field) { nil }
- let(:labels_field) { [] }
- let(:environment_field) { nil }
- let(:duedate_field) { nil }
+ context 'assignee' do
+ context 'when assignee maps to a valid GitLab user' do
+ let!(:user) { create(:user, email: 'assignee@example.com') }
+
+ it 'sets the issue assignees to the mapped user' do
+ project.add_developer(user)
- it 'skips the whole metadata secction' do
- expected_description = <<~MD
- *Created by: Reporter*
+ expect(subject[:assignee_ids]).to eq([user.id])
+ end
+ end
+
+ context 'when assignee does not map to a valid GitLab user' do
+ it 'leaves the assignee empty' do
+ expect(subject[:assignee_ids]).to be_nil
+ end
+ end
+
+ context 'when assginee field is empty' do
+ let(:assignee) { nil }
+
+ it 'leaves the assignee empty' do
+ expect(subject[:assignee_ids]).to be_nil
+ end
+ end
- basic description
- MD
+ context 'when assginee field is missing email address' do
+ let(:assignee) { double(attrs: { 'displayName' => 'Reporter' }) }
- expect(subject[:description]).to eq(expected_description.strip)
+ it 'leaves the assignee empty' do
+ expect(subject[:assignee_ids]).to be_nil
+ end
end
end
end
diff --git a/spec/lib/gitlab/jira_import/issues_importer_spec.rb b/spec/lib/gitlab/jira_import/issues_importer_spec.rb
index 8e16fd3e978..6cf06c20e19 100644
--- a/spec/lib/gitlab/jira_import/issues_importer_spec.rb
+++ b/spec/lib/gitlab/jira_import/issues_importer_spec.rb
@@ -3,15 +3,19 @@
require 'spec_helper'
describe Gitlab::JiraImport::IssuesImporter do
+ include JiraServiceHelper
+
let_it_be(:user) { create(:user) }
+ let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
- let_it_be(:jira_import) { create(:jira_import_state, project: project) }
+ let_it_be(:jira_import) { create(:jira_import_state, project: project, user: current_user) }
let_it_be(:jira_service) { create(:jira_service, project: project) }
subject { described_class.new(project) }
before do
stub_feature_flags(jira_issue_import: true)
+ stub_jira_service_test
end
describe '#imported_items_cache_key' do
@@ -36,8 +40,16 @@ describe Gitlab::JiraImport::IssuesImporter do
context 'with results returned' do
JiraIssue = Struct.new(:id)
- let_it_be(:jira_issue1) { JiraIssue.new(1) }
- let_it_be(:jira_issue2) { JiraIssue.new(2) }
+ let_it_be(:jira_issues) { [JiraIssue.new(1), JiraIssue.new(2)] }
+
+ def mock_issue_serializer(count)
+ serializer = instance_double(Gitlab::JiraImport::IssueSerializer, execute: { key: 'data' })
+
+ count.times do |i|
+ expect(Gitlab::JiraImport::IssueSerializer).to receive(:new)
+ .with(project, jira_issues[i], current_user.id, { iid: i + 1 }).and_return(serializer)
+ end
+ end
context 'when single page of results is returned' do
before do
@@ -45,13 +57,11 @@ describe Gitlab::JiraImport::IssuesImporter do
end
it 'schedules 2 import jobs' do
- expect(subject).to receive(:fetch_issues).and_return([jira_issue1, jira_issue2])
+ expect(subject).to receive(:fetch_issues).with(0).and_return([jira_issues[0], jira_issues[1]])
expect(Gitlab::JiraImport::ImportIssueWorker).to receive(:perform_async).twice
expect(Gitlab::Cache::Import::Caching).to receive(:set_add).twice.and_call_original
expect(Gitlab::Cache::Import::Caching).to receive(:set_includes?).twice.and_call_original
- allow_next_instance_of(Gitlab::JiraImport::IssueSerializer) do |instance|
- allow(instance).to receive(:execute).and_return({ key: 'data' })
- end
+ mock_issue_serializer(2)
job_waiter = subject.execute
@@ -66,13 +76,11 @@ describe Gitlab::JiraImport::IssuesImporter do
end
it 'schedules 3 import jobs' do
- expect(subject).to receive(:fetch_issues).with(0).and_return([jira_issue1, jira_issue2])
+ expect(subject).to receive(:fetch_issues).with(0).and_return([jira_issues[0], jira_issues[1]])
expect(Gitlab::JiraImport::ImportIssueWorker).to receive(:perform_async).twice.times
expect(Gitlab::Cache::Import::Caching).to receive(:set_add).twice.times.and_call_original
expect(Gitlab::Cache::Import::Caching).to receive(:set_includes?).twice.times.and_call_original
- allow_next_instance_of(Gitlab::JiraImport::IssueSerializer) do |instance|
- allow(instance).to receive(:execute).and_return({ key: 'data' })
- end
+ mock_issue_serializer(2)
job_waiter = subject.execute
@@ -87,13 +95,11 @@ describe Gitlab::JiraImport::IssuesImporter do
end
it 'schedules 2 import jobs' do
- expect(subject).to receive(:fetch_issues).with(0).and_return([jira_issue1, jira_issue1])
+ expect(subject).to receive(:fetch_issues).with(0).and_return([jira_issues[0], jira_issues[0]])
expect(Gitlab::JiraImport::ImportIssueWorker).to receive(:perform_async).once
expect(Gitlab::Cache::Import::Caching).to receive(:set_add).once.and_call_original
expect(Gitlab::Cache::Import::Caching).to receive(:set_includes?).twice.times.and_call_original
- allow_next_instance_of(Gitlab::JiraImport::IssueSerializer) do |instance|
- allow(instance).to receive(:execute).and_return({ key: 'data' })
- end
+ mock_issue_serializer(1)
job_waiter = subject.execute
diff --git a/spec/lib/gitlab/jira_import/labels_importer_spec.rb b/spec/lib/gitlab/jira_import/labels_importer_spec.rb
index 3eb4666a74f..67eb541d376 100644
--- a/spec/lib/gitlab/jira_import/labels_importer_spec.rb
+++ b/spec/lib/gitlab/jira_import/labels_importer_spec.rb
@@ -3,35 +3,100 @@
require 'spec_helper'
describe Gitlab::JiraImport::LabelsImporter do
+ include JiraServiceHelper
+
let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
let_it_be(:jira_service) { create(:jira_service, project: project) }
- subject { described_class.new(project).execute }
+ let(:importer) { described_class.new(project) }
+
+ subject { importer.execute }
before do
stub_feature_flags(jira_issue_import: true)
+ stub_const('Gitlab::JiraImport::LabelsImporter::MAX_LABELS', 2)
end
describe '#execute', :clean_gitlab_redis_cache do
+ before do
+ stub_jira_service_test
+ end
+
context 'when label is missing from jira import' do
let_it_be(:no_label_jira_import) { create(:jira_import_state, label: nil, project: project) }
it 'raises error' do
- expect { subject }.to raise_error(Projects::ImportService::Error, 'Failed to find import label for jira import.')
+ expect { subject }.to raise_error(Projects::ImportService::Error, 'Failed to find import label for Jira import.')
end
end
- context 'when label exists' do
- let_it_be(:label) { create(:label) }
+ context 'when jira import label exists' do
+ let_it_be(:label) { create(:label) }
let_it_be(:jira_import_with_label) { create(:jira_import_state, label: label, project: project) }
+ let_it_be(:issue_label) { create(:label, project: project, title: 'bug') }
+
+ let(:jira_labels_1) { { "maxResults" => 2, "startAt" => 0, "total" => 3, "isLast" => false, "values" => %w(backend bug) } }
+ let(:jira_labels_2) { { "maxResults" => 2, "startAt" => 2, "total" => 3, "isLast" => true, "values" => %w(feature) } }
+
+ context 'when labels are returned from jira' do
+ before do
+ client = double
+ expect(importer).to receive(:client).twice.and_return(client)
+ allow(client).to receive(:get).twice.and_return(jira_labels_1, jira_labels_2)
+ end
+
+ it 'caches import label' do
+ expect(Gitlab::Cache::Import::Caching.read(Gitlab::JiraImport.import_label_cache_key(project.id))).to be nil
+
+ subject
+
+ expect(Gitlab::JiraImport.get_import_label_id(project.id).to_i).to eq(label.id)
+ end
+
+ it 'calls Gitlab::JiraImport::HandleLabelsService' do
+ expect(Gitlab::JiraImport::HandleLabelsService).to receive(:new).with(project, %w(backend bug)).and_return(double(execute: [1, 2]))
+ expect(Gitlab::JiraImport::HandleLabelsService).to receive(:new).with(project, %w(feature)).and_return(double(execute: [3]))
+
+ subject
+ end
+ end
+
+ context 'when there are no labels to be handled' do
+ shared_examples 'no labels handling' do
+ it 'does not call Gitlab::JiraImport::HandleLabelsService' do
+ expect(Gitlab::JiraImport::HandleLabelsService).not_to receive(:new)
+
+ subject
+ end
+ end
+
+ let(:jira_labels) { { "maxResults" => 2, "startAt" => 0, "total" => 3, "values" => [] } }
+
+ before do
+ client = double
+ expect(importer).to receive(:client).and_return(client)
+ allow(client).to receive(:get).and_return(jira_labels)
+ end
+
+ context 'when the labels field is empty' do
+ let(:jira_labels) { { "maxResults" => 2, "startAt" => 0, "isLast" => true, "total" => 3, "values" => [] } }
+
+ it_behaves_like 'no labels handling'
+ end
+
+ context 'when the labels field is missing' do
+ let(:jira_labels) { { "maxResults" => 2, "startAt" => 0, "isLast" => true, "total" => 3 } }
- it 'caches import label' do
- expect(Gitlab::Cache::Import::Caching.read(Gitlab::JiraImport.import_label_cache_key(project.id))).to be nil
+ it_behaves_like 'no labels handling'
+ end
- subject
+ context 'when the isLast argument is missing' do
+ let(:jira_labels) { { "maxResults" => 2, "startAt" => 0, "total" => 3, "values" => %w(bug dev) } }
- expect(Gitlab::JiraImport.get_import_label_id(project.id).to_i).to eq(label.id)
+ it_behaves_like 'no labels handling'
+ end
end
end
end
diff --git a/spec/lib/gitlab/jira_import/metadata_collector_spec.rb b/spec/lib/gitlab/jira_import/metadata_collector_spec.rb
new file mode 100644
index 00000000000..af479810df0
--- /dev/null
+++ b/spec/lib/gitlab/jira_import/metadata_collector_spec.rb
@@ -0,0 +1,178 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::JiraImport::MetadataCollector do
+ describe '#execute' do
+ let(:key) { 'PROJECT-5' }
+ let(:summary) { 'some title' }
+ let(:description) { 'basic description' }
+ let(:created_at) { '2020-01-01 20:00:00' }
+ let(:updated_at) { '2020-01-10 20:00:00' }
+ let(:jira_status) { 'new' }
+
+ let(:parent_field) do
+ { 'key' => 'FOO-2', 'id' => '1050', 'fields' => { 'summary' => 'parent issue FOO' } }
+ end
+ let(:issue_type_field) { { 'name' => 'Task' } }
+ let(:fix_versions_field) { [{ 'name' => '1.0' }, { 'name' => '1.1' }] }
+ let(:priority_field) { { 'name' => 'Medium' } }
+ let(:environment_field) { 'staging' }
+ let(:duedate_field) { '2020-03-01' }
+
+ let(:fields) do
+ {
+ 'parent' => parent_field,
+ 'issuetype' => issue_type_field,
+ 'fixVersions' => fix_versions_field,
+ 'priority' => priority_field,
+ 'environment' => environment_field,
+ 'duedate' => duedate_field
+ }
+ end
+ let(:jira_issue) do
+ double(
+ id: '1234',
+ key: key,
+ summary: summary,
+ description: description,
+ created: created_at,
+ updated: updated_at,
+ status: double(statusCategory: { 'key' => jira_status }),
+ fields: fields
+ )
+ end
+
+ subject { described_class.new(jira_issue).execute }
+
+ context 'when all metadata fields are present' do
+ it 'writes all fields' do
+ expected_result = <<~MD
+ ---
+
+ **Issue metadata**
+
+ - Issue type: Task
+ - Priority: Medium
+ - Environment: staging
+ - Due date: 2020-03-01
+ - Parent issue: [FOO-2] parent issue FOO
+ - Fix versions: 1.0, 1.1
+ MD
+
+ expect(subject.strip).to eq(expected_result.strip)
+ end
+ end
+
+ context 'when some fields are in incorrect format' do
+ let(:parent_field) { nil }
+ let(:fix_versions_field) { [] }
+ let(:priority_field) { nil }
+ let(:environment_field) { nil }
+ let(:duedate_field) { nil }
+
+ context 'when fixVersions field is not an array' do
+ let(:fix_versions_field) { { 'title' => '1.0', 'name' => '1.1' } }
+
+ it 'skips these fields' do
+ expected_result = <<~MD
+ ---
+
+ **Issue metadata**
+
+ - Issue type: Task
+ MD
+
+ expect(subject.strip).to eq(expected_result.strip)
+ end
+ end
+
+ context 'when a fixVersions element is in incorrect format' do
+ let(:fix_versions_field) { [{ 'title' => '1.0' }, { 'name' => '1.1' }] }
+
+ it 'skips the element' do
+ expected_result = <<~MD
+ ---
+
+ **Issue metadata**
+
+ - Issue type: Task
+ - Fix versions: 1.1
+ MD
+
+ expect(subject.strip).to eq(expected_result.strip)
+ end
+ end
+
+ context 'when a parent field has incorrectly formatted summary' do
+ let(:parent_field) do
+ { 'key' => 'FOO-2', 'id' => '1050', 'other_field' => { 'summary' => 'parent issue FOO' } }
+ end
+
+ it 'skips the summary' do
+ expected_result = <<~MD
+ ---
+
+ **Issue metadata**
+
+ - Issue type: Task
+ - Parent issue: [FOO-2]
+ MD
+
+ expect(subject.strip).to eq(expected_result.strip)
+ end
+ end
+
+ context 'when a parent field is missing the key' do
+ let(:parent_field) do
+ { 'not_key' => 'FOO-2', 'id' => '1050', 'other_field' => { 'summary' => 'parent issue FOO' } }
+ end
+
+ it 'skips the field' do
+ expected_result = <<~MD
+ ---
+
+ **Issue metadata**
+
+ - Issue type: Task
+ MD
+
+ expect(subject.strip).to eq(expected_result.strip)
+ end
+ end
+ end
+
+ context 'when some metadata fields are missing' do
+ let(:parent_field) { nil }
+ let(:fix_versions_field) { [] }
+ let(:environment_field) { nil }
+
+ it 'skips the missing fields' do
+ expected_result = <<~MD
+ ---
+
+ **Issue metadata**
+
+ - Issue type: Task
+ - Priority: Medium
+ - Due date: 2020-03-01
+ MD
+
+ expect(subject.strip).to eq(expected_result.strip)
+ end
+ end
+
+ context 'when all metadata fields are missing' do
+ let(:parent_field) { nil }
+ let(:issue_type_field) { nil }
+ let(:fix_versions_field) { [] }
+ let(:priority_field) { nil }
+ let(:environment_field) { nil }
+ let(:duedate_field) { nil }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/jira_import/user_mapper_spec.rb b/spec/lib/gitlab/jira_import/user_mapper_spec.rb
new file mode 100644
index 00000000000..c8c8bd3c5b0
--- /dev/null
+++ b/spec/lib/gitlab/jira_import/user_mapper_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::JiraImport::UserMapper do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:user) { create(:user, email: 'user@example.com') }
+ let_it_be(:email) { create(:email, user: user, email: 'second_email@example.com', confirmed_at: nil) }
+
+ let(:jira_user) { { 'acountId' => '1a2b', 'emailAddress' => 'user@example.com' } }
+
+ describe '#execute' do
+ subject { described_class.new(project, jira_user).execute }
+
+ context 'when jira_user is nil' do
+ let(:jira_user) { nil }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'when Gitlab user is not found by email' do
+ let(:jira_user) { { 'acountId' => '1a2b', 'emailAddress' => 'other@example.com' } }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'when jira_user emailAddress is nil' do
+ let(:jira_user) { { 'acountId' => '1a2b', 'emailAddress' => nil } }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'when jira_user emailAddress key is missing' do
+ let(:jira_user) { { 'acountId' => '1a2b' } }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'when found user is not a project member' do
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'when found user is a project member' do
+ it 'returns the found user' do
+ project.add_developer(user)
+
+ expect(subject).to eq(user)
+ end
+ end
+
+ context 'when user found by unconfirmd secondary address is a project member' do
+ let(:jira_user) { { 'acountId' => '1a2b', 'emailAddress' => 'second_email@example.com' } }
+
+ it 'returns the found user' do
+ project.add_developer(user)
+
+ expect(subject).to eq(user)
+ end
+ end
+
+ context 'when user is a group member' do
+ it 'returns the found user' do
+ group.add_developer(user)
+
+ expect(subject).to eq(user)
+ end
+ end
+ end
+end