Commit 8522ef44 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre
Browse files

Recreates missing group labels when moving project to another group

parent 583092a0c2a1
# Labels::TransferService class
#
# User for recreate the missing group labels at project level
#
module Labels
class TransferService
def initialize(current_user, group, project)
@current_user = current_user
@group = group
@project = project
end
def execute
return unless group.present?
Label.transaction do
labels_to_transfer = Label.where(id: label_links.select(:label_id).uniq)
labels_to_transfer.find_each do |label|
new_label_id = find_or_create_label!(label)
LabelLink.where(label_id: label.id).update_all(label_id: new_label_id)
end
end
end
private
attr_reader :current_user, :group, :project
def label_links
label_link_ids = []
label_link_ids << LabelLink.where(target: project.issues, label: group.labels).select(:id)
label_link_ids << LabelLink.where(target: project.merge_requests, label: group.labels).select(:id)
union = Gitlab::SQL::Union.new(label_link_ids)
LabelLink.where("label_links.id IN (#{union.to_sql})")
end
def labels
@labels ||= LabelsFinder.new(current_user, project_id: project.id).execute
end
def find_or_create_label!(label)
new_label = labels.find_by(title: label.title)
new_label ||= project.labels.create!(label.attributes.slice("title", "description", "color"))
new_label.id
end
end
end
......@@ -28,6 +28,7 @@ def transfer(project, new_namespace)
Project.transaction do
old_path = project.path_with_namespace
old_namespace = project.namespace
old_group = project.group
new_path = File.join(new_namespace.try(:path) || '', project.path)
if Project.where(path: project.path, namespace_id: new_namespace.try(:id)).present?
......@@ -57,6 +58,9 @@ def transfer(project, new_namespace)
# Move wiki repo also if present
gitlab_shell.mv_repository(project.repository_storage_path, "#{old_path}.wiki", "#{new_path}.wiki")
# Move missing group labels to project
Labels::TransferService.new(current_user, old_group, project).execute
# clear project cached events
project.reset_events_cache
......
......@@ -68,5 +68,15 @@
factory :closed_merge_request, traits: [:closed]
factory :reopened_merge_request, traits: [:reopened]
factory :merge_request_with_diffs, traits: [:with_diffs]
factory :labeled_merge_request do
transient do
labels []
end
after(:create) do |merge_request, evaluator|
merge_request.update_attributes(labels: evaluator.labels)
end
end
end
end
require 'spec_helper'
describe Labels::TransferService, services: true do
describe '#execute' do
let(:user) { create(:user) }
let(:group_1) { create(:group) }
let(:group_2) { create(:group) }
let(:project) { create(:project, namespace: group_2) }
let(:group_label_1) { create(:group_label, group: group_1, name: 'Group Label 1') }
let(:group_label_2) { create(:group_label, group: group_1, name: 'Group Label 2') }
let(:group_label_3) { create(:group_label, group: group_1, name: 'Group Label 3') }
let(:group_label_4) { create(:group_label, group: group_2, name: 'Group Label 4') }
let(:project_label_1) { create(:label, project: project, name: 'Project Label 1') }
subject(:service) { described_class.new(user, group_1, project) }
before do
create(:labeled_issue, project: project, labels: [group_label_1])
create(:labeled_issue, project: project, labels: [group_label_4])
create(:labeled_issue, project: project, labels: [project_label_1])
create(:labeled_merge_request, source_project: project, labels: [group_label_1, group_label_2])
end
it 'recreates the missing group labels at project level' do
expect { service.execute }.to change(project.labels, :count).by(2)
end
it 'does not recreate missing group labels that are not applied to issues or merge requests' do
service.execute
expect(project.labels.where(title: group_label_3.title)).to be_empty
end
it 'does not recreate missing group labels that already exist in the project group' do
service.execute
expect(project.labels.where(title: group_label_4.title)).to be_empty
end
end
end
......@@ -71,4 +71,14 @@ def transfer_project(project, user, new_namespace)
it { expect(private_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) }
end
end
context 'missing group labels applied to issues or merge requests' do
it 'delegates tranfer to Labels::TransferService' do
group.add_owner(user)
expect_any_instance_of(Labels::TransferService).to receive(:execute).once.and_call_original
transfer_project(project, user, group)
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