Commit 95400c70 authored by Matthias Käppler's avatar Matthias Käppler

Merge branch 'kassio/bulkimports-import-epic-labels' into 'master'

BulkImports: Import Epic's labels

See merge request gitlab-org/gitlab!52626
parents b52883f2 a7e53cd2
---
title: "BulkImports: Import Epic's labels"
merge_request: 52626
author:
type: changed
......@@ -42,6 +42,11 @@ module EE
iid
}
}
labels {
nodes {
title
}
}
}
}
}
......
......@@ -12,7 +12,7 @@ module EE
end
def load(context, data)
raise NotAllowedError unless context.current_user.can?(:create_epic, context.group)
raise NotAllowedError unless authorized?(context)
# Use `Epic` directly when creating new epics
# instead of `Epics::CreateService` since several
......@@ -20,6 +20,12 @@ module EE
# group_id, parent, children need to be custom set
::Epic.create!(data)
end
private
def authorized?(context)
Ability.allowed?(context.current_user, :admin_epic, context.group)
end
end
end
end
......
......@@ -13,12 +13,13 @@ module EE
.then { |data| add_author_id(context, data) }
.then { |data| add_parent(context, data) }
.then { |data| add_children(context, data) }
.then { |data| add_labels(context, data) }
end
private
def add_group_id(context, data)
data.merge('group_id' => context.entity.namespace_id)
data.merge('group_id' => context.group.id)
end
def add_author_id(context, data)
......@@ -27,7 +28,7 @@ module EE
def add_parent(context, data)
data.merge(
'parent' => context.entity.group.epics.find_by_iid(data.dig('parent', 'iid'))
'parent' => context.group.epics.find_by_iid(data.dig('parent', 'iid'))
)
end
......@@ -35,7 +36,15 @@ module EE
nodes = Array.wrap(data.dig('children', 'nodes'))
children_iids = nodes.filter_map { |child| child['iid'] }
data.merge('children' => context.entity.group.epics.where(iid: children_iids)) # rubocop: disable CodeReuse/ActiveRecord
data.merge('children' => context.group.epics.where(iid: children_iids)) # rubocop: disable CodeReuse/ActiveRecord
end
def add_labels(context, data)
data['labels'] = data.dig('labels', 'nodes').filter_map do |node|
context.group.labels.find_by_title(node['title'])
end
data
end
end
end
......
......@@ -4,32 +4,46 @@ require 'spec_helper'
RSpec.describe EE::BulkImports::Groups::Loaders::EpicsLoader do
describe '#load' do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:bulk_import) { create(:bulk_import, user: user) }
let(:entity) { create(:bulk_import_entity, bulk_import: bulk_import, group: group) }
let(:context) { BulkImports::Pipeline::Context.new(entity) }
it 'creates the epic' do
stub_licensed_features(epics: true)
user = create(:user)
group = create(:group)
group.add_owner(user)
parent_epic = create(:epic, group: group)
child_epic = create(:epic, group: group)
label = create(:group_label, group: group)
bulk_import = create(:bulk_import, user: user)
entity = create(:bulk_import_entity, bulk_import: bulk_import, group: group)
context = BulkImports::Pipeline::Context.new(entity)
let(:data) do
{
'title' => 'epic1',
data = {
'title' => 'epic',
'state' => 'opened',
'confidential' => false,
'iid' => 1,
'iid' => 99,
'author_id' => user.id,
'group_id' => group.id
'group_id' => group.id,
'parent' => parent_epic,
'children' => [child_epic],
'labels' => [
label
]
}
end
before do
stub_licensed_features(epics: true)
group.add_owner(user)
end
it 'creates the epic' do
expect { subject.load(context, data) }.to change(::Epic, :count).by(1)
expect(group.epics.count).to eq(1)
epic = group.epics.last
expect(epic.group).to eq(group)
expect(epic.author).to eq(user)
expect(epic.title).to eq('epic')
expect(epic.state).to eq('opened')
expect(epic.confidential).to eq(false)
expect(epic.iid).to eq(99)
expect(epic.parent).to eq(parent_epic)
expect(epic.children).to contain_exactly(child_epic)
expect(epic.labels).to contain_exactly(label)
end
end
end
......@@ -3,18 +3,18 @@
require 'spec_helper'
RSpec.describe EE::BulkImports::Groups::Pipelines::EpicsPipeline do
let(:cursor) { 'cursor' }
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:cursor) { 'cursor' }
let(:bulk_import) { create(:bulk_import, user: user) }
let(:entity) do
create(
:bulk_import_entity,
group: group,
bulk_import: bulk_import,
source_full_path: 'source/full/path',
destination_name: 'My Destination Group',
destination_namespace: group.full_path,
group: group,
bulk_import: bulk_import
destination_namespace: group.full_path
)
end
......@@ -104,7 +104,10 @@ RSpec.describe EE::BulkImports::Groups::Pipelines::EpicsPipeline do
{
'title' => 'epic1',
'state' => 'closed',
'confidential' => true
'confidential' => true,
'labels' => {
'nodes' => []
}
}
]
......
......@@ -3,69 +3,94 @@
require 'spec_helper'
RSpec.describe EE::BulkImports::Groups::Transformers::EpicAttributesTransformer do
describe '#transform' do
let(:user) { create(:user) }
let(:group) { create(:group, name: 'My Source Group') }
let(:entity) do
instance_double(
BulkImports::Entity,
group: group,
namespace_id: group.id
)
end
let(:group) { create(:group) }
let(:bulk_import) { create(:bulk_import, user: user) }
let(:entity) { create(:bulk_import_entity, bulk_import: bulk_import, group: group) }
let(:context) { ::BulkImports::Pipeline::Context.new(entity) }
let(:context) do
instance_double(
BulkImports::Pipeline::Context,
current_user: user,
entity: entity
)
end
describe '#transform' do
it 'transforms the epic attributes' do
transformed = subject.transform(context, epic_data)
let(:data) do
{
'iid' => '7',
'title' => 'Epic Title',
'description' => 'Epic Description',
expect(transformed).to eq({
'title' => 'title',
'description' => 'description',
'state' => 'opened',
'parent' => {
'iid' => parent_iid
},
'children' => {
'nodes' => [
{
'iid' => child_iid
}
]
}
}
'create_at' => '2021-01-27T03:42:30Z',
'closed_at' => nil,
'start_date' => nil,
'start_date_fixed' => nil,
'start_date_is_fixed' => false,
'due_date_fixed' => nil,
'due_date_is_fixed' => false,
'relative_position' => 1073716855,
'confidential' => false,
'group_id' => group.id,
'author_id' => user.id,
'parent' => nil,
'children' => [],
'labels' => []
})
end
context 'when parent and child iids are nil' do
let(:parent_iid) { nil }
let(:child_iid) { nil }
context 'labels' do
it 'maps the existing labels' do
label = create(:group_label, group: group)
data = epic_data(labels_titles: [label.title, 'NON EXISTING TITLE'])
it 'sets group_id, author_id from context' do
transformed_data = subject.transform(context, data)
expect(transformed_data['group_id']).to eq(group.id)
expect(transformed_data['author_id']).to eq(user.id)
expect(transformed_data['parent']).to be_nil
expect(transformed_data['labels'].to_a).to contain_exactly(label)
end
end
context 'when parent and child iids are present' do
let(:parent) { create(:epic, group: group) }
let(:child) { create(:epic, group: group) }
let(:parent_iid) { parent.iid }
let(:child_iid) { child.iid }
context 'parent and children epics' do
it 'sets parent and child epics when they exist' do
parent = create(:epic, group: group)
child = create(:epic, group: group)
data = epic_data(parent_iid: parent.iid, children_iids: [child.iid])
it 'sets parent and child epics' do
transformed_data = subject.transform(context, data)
expect(transformed_data['parent']).to eq(parent)
expect(transformed_data['children']).to contain_exactly(child)
end
it 'removes the parent and children id when they dont exist' do
data = epic_data(parent_iid: 9998, children_iids: [9999])
transformed_data = subject.transform(context, data)
expect(transformed_data['parent']).to be_nil
expect(transformed_data['children']).to be_empty
end
end
def epic_data(parent_iid: nil, children_iids: [], labels_titles: [])
{
'title' => 'title',
'description' => 'description',
'state' => 'opened',
'create_at' => '2021-01-27T03:42:30Z',
'closed_at' => nil,
'start_date' => nil,
'start_date_fixed' => nil,
'start_date_is_fixed' => false,
'due_date_fixed' => nil,
'due_date_is_fixed' => false,
'relative_position' => 1073716855,
'confidential' => false,
'parent' => {
'iid' => parent_iid
},
'children' => {
'nodes' => children_iids.map { |iid| { 'iid' => iid } }
},
'labels' => {
'nodes' => labels_titles.map { |title| { 'title' => title } }
}
}
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