Commit d41caca1 authored by Peter Leitzen's avatar Peter Leitzen

Merge branch 'jira-user-importer' into 'master'

Map jira issue assignee and author

See merge request gitlab-org/gitlab!30498
parents 52661728 e38ec7c6
---
title: Map Jira issue assignee and author
merge_request: 30498
author:
type: added
......@@ -21,7 +21,8 @@ module Gitlab
state_id: map_status(jira_issue.status.statusCategory),
updated_at: jira_issue.updated,
created_at: jira_issue.created,
author_id: project.creator_id, # TODO: map actual author: https://gitlab.com/gitlab-org/gitlab/-/issues/210580
author_id: reporter,
assignee_ids: assignees,
label_ids: label_ids
}
end
......@@ -34,8 +35,6 @@ module Gitlab
def description
body = []
body << formatter.author_line(jira_issue.reporter.displayName)
body << formatter.assignee_line(jira_issue.assignee.displayName) if jira_issue.assignee
body << jira_issue.description
body << MetadataCollector.new(jira_issue).execute
......@@ -51,6 +50,38 @@ module Gitlab
end
end
def map_user_id(email)
return unless email
# We also include emails that are not yet confirmed
users = User.by_any_email(email).to_a
# this event should never happen but we should log it in case we have invalid data
log_user_mapping_message('Multiple users found for an email address', email) if users.count > 1
user = users.first
unless project.project_member(user)
log_user_mapping_message('Jira user not found', email)
return
end
user.id
end
def reporter
map_user_id(jira_issue&.reporter&.emailAddress) || project.creator_id
end
def assignees
found_user_id = map_user_id(jira_issue&.assignee&.emailAddress)
return unless found_user_id
[found_user_id]
end
# We already create labels in Gitlab::JiraImport::LabelsImporter stage but
# there is a possibility it may fail or
# new labels were created on the Jira in the meantime
......@@ -59,6 +90,19 @@ module Gitlab
Gitlab::JiraImport::HandleLabelsService.new(project, jira_issue.fields['labels']).execute
end
def logger
@logger ||= Gitlab::Import::Logger.build
end
def log_user_mapping_message(message, email)
logger.info(
project_id: project.id,
project_path: project.full_path,
user_email: email,
message: message
)
end
end
end
end
......@@ -16,7 +16,8 @@ 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(displayName: 'Solver', emailAddress: 'assignee@example.com') }
let(:reporter) { double(displayName: 'Reporter', emailAddress: 'reporter@example.com') }
let(:jira_status) { 'new' }
let(:parent_field) do
......@@ -42,7 +43,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,10 +55,6 @@ describe Gitlab::JiraImport::IssueSerializer do
let(:expected_description) do
<<~MD
*Created by: Reporter*
*Assigned to: Solver*
basic description
---
......@@ -80,6 +77,7 @@ describe Gitlab::JiraImport::IssueSerializer do
updated_at: updated_at,
created_at: created_at,
author_id: project.creator_id,
assignee_ids: nil,
label_ids: [project_label.id, group_label.id] + Label.reorder(id: :asc).last(2).pluck(:id)
)
end
......@@ -88,22 +86,108 @@ describe Gitlab::JiraImport::IssueSerializer do
expect(Issue.new(subject)).to be_valid
end
it 'creates all missing labels (on project level)' do
expect { subject }.to change { Label.count }.from(3).to(5)
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) }
expect(Label.find_by(title: 'frontend').project).to eq(project)
expect(Label.find_by(title: 'backend').project).to eq(project)
it 'assigns the labels to the Issue hash' do
expect(subject[:label_ids]).to match_array([project_label.id, group_label.id])
end
it 'does not create new labels' do
expect { subject }.not_to change { Label.count }.from(3)
end
end
end
context 'when there are no new labels' do
let(:labels_field) { %w(bug dev) }
context 'author' do
context 'when reporter maps to a GitLab user who is a project member' do
let!(:user) { create(:user, email: 'reporter@example.com') }
it 'assigns the labels to the Issue hash' do
expect(subject[:label_ids]).to match_array([project_label.id, group_label.id])
it 'sets the issue author to the mapped user' do
project.add_developer(user)
expect(subject[:author_id]).to eq(user.id)
end
end
it 'does not create new labels' do
expect { subject }.not_to change { Label.count }.from(3)
context 'when reporter maps to a GitLab user who is not a project member' do
let!(:user) { create(:user, email: 'reporter@example.com') }
it 'defaults the issue author to project creator' do
expect(subject[:author_id]).to eq(project.creator.id)
end
end
context 'when reporter does not map to a GitLab user' do
it 'defaults the issue author to project creator' do
expect(subject[:author_id]).to eq(project.creator.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(project.creator.id)
end
end
context 'when reporter field is missing email address' do
let(:reporter) { double(name: 'Reporter', emailAddress: nil) }
it 'defaults the issue author to project creator' do
expect(subject[:author_id]).to eq(project.creator.id)
end
end
end
context 'assignee' do
context 'when assignee maps to a GitLab user who is a project member' do
let!(:user) { create(:user, email: 'assignee@example.com') }
it 'sets the issue assignees to the mapped user' do
project.add_developer(user)
expect(subject[:assignee_ids]).to eq([user.id])
end
end
context 'when assignee maps to a GitLab user who is not a project member' do
let!(:user) { create(:user, email: 'assignee@example.com') }
it 'leaves the assignee empty' do
expect(subject[:assignee_ids]).to be_nil
end
end
context 'when assignee does not map to a 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
context 'when assginee field is missing email address' do
let(:assignee) { double(name: 'Assignee', emailAddress: nil) }
it 'leaves the assignee empty' do
expect(subject[:assignee_ids]).to be_nil
end
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment