summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-09-12 19:13:56 -0300
committerDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-09-16 10:56:48 -0300
commitd2283aa1597a5588f2d4f10fe3982463ba63db2f (patch)
treeca5e49cf8283124dcf6e64efe93f22500177090a
parent54d2cc07eb7cc1ac8d2c8b6dacbd3aa55a4983b6 (diff)
downloadgitlab-ce-d2283aa1597a5588f2d4f10fe3982463ba63db2f.tar.gz
Add service to create labels for a group/project
-rw-r--r--app/controllers/groups/labels_controller.rb2
-rw-r--r--app/controllers/projects/labels_controller.rb2
-rw-r--r--app/models/label.rb2
-rw-r--r--app/services/labels/create_service.rb42
-rw-r--r--spec/models/label_spec.rb2
-rw-r--r--spec/services/labels/create_service_spec.rb53
6 files changed, 100 insertions, 3 deletions
diff --git a/app/controllers/groups/labels_controller.rb b/app/controllers/groups/labels_controller.rb
index 2e847d65df9..51605a9586c 100644
--- a/app/controllers/groups/labels_controller.rb
+++ b/app/controllers/groups/labels_controller.rb
@@ -15,7 +15,7 @@ class Groups::LabelsController < Groups::ApplicationController
end
def create
- @label = @group.labels.create(label_params)
+ @label = Labels::CreateService.new(@group, current_user, label_params).execute
if @label.valid?
redirect_to group_labels_path(@group)
diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb
index 28fa4a5b141..8d1935eff59 100644
--- a/app/controllers/projects/labels_controller.rb
+++ b/app/controllers/projects/labels_controller.rb
@@ -27,7 +27,7 @@ class Projects::LabelsController < Projects::ApplicationController
end
def create
- @label = @project.labels.create(label_params)
+ @label = Labels::CreateService.new(@project, current_user, label_params).execute
if @label.valid?
redirect_to namespace_project_labels_path(@project.namespace, @project)
diff --git a/app/models/label.rb b/app/models/label.rb
index 9b5f0044544..53c7eb581aa 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -26,7 +26,7 @@ class Label < ActiveRecord::Base
validates :title,
presence: true,
format: { with: /\A[^,]+\z/ },
- uniqueness: { scope: :subject_id }
+ uniqueness: { scope: [:subject_id, :subject_type] }
before_save :nullify_priority
diff --git a/app/services/labels/create_service.rb b/app/services/labels/create_service.rb
new file mode 100644
index 00000000000..1462d07326e
--- /dev/null
+++ b/app/services/labels/create_service.rb
@@ -0,0 +1,42 @@
+module Labels
+ class CreateService
+ def initialize(subject, user, params = {})
+ @subject, @user, @params = subject, user, params.dup
+ end
+
+ def execute
+ label = subject.labels.build(params)
+
+ return label if subject.is_a?(Project) && subject.group.present? && subject.group.labels.where(title: title).exists?
+
+ if label.save
+ if subject.is_a?(Group)
+ subject.projects.each do |project|
+ project.labels.find_or_create_by!(title: title) do |label|
+ label.color = color
+ label.description = description
+ end
+ end
+ end
+ end
+
+ label
+ end
+
+ private
+
+ attr_reader :subject, :user, :params
+
+ def title
+ params[:title]
+ end
+
+ def color
+ params[:color]
+ end
+
+ def description
+ params[:description]
+ end
+ end
+end
diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb
index a8bd01e1a73..80b963c9433 100644
--- a/spec/models/label_spec.rb
+++ b/spec/models/label_spec.rb
@@ -43,6 +43,8 @@ describe Label, models: true do
expect(label).to allow_value('G&ITLAB').for(:title)
expect(label).to allow_value("customer's request").for(:title)
end
+
+ it { is_expected.to validate_uniqueness_of(:title).scoped_to([:subject_id, :subject_type]) }
end
describe '#title' do
diff --git a/spec/services/labels/create_service_spec.rb b/spec/services/labels/create_service_spec.rb
new file mode 100644
index 00000000000..b06424bcde4
--- /dev/null
+++ b/spec/services/labels/create_service_spec.rb
@@ -0,0 +1,53 @@
+require 'spec_helper'
+
+describe Labels::CreateService, services: true do
+ describe '#execute' do
+ let(:group) { create(:group) }
+ let!(:project) { create(:empty_project, group: group) }
+
+ let(:params) do
+ {
+ title: 'Security',
+ color: '#5CB85C',
+ description: 'Security related stuff.'
+ }
+ end
+
+ context 'with a group as subject' do
+ subject(:service) { described_class.new(group, double, params) }
+
+ it 'creates a label' do
+ expect { service.execute }.to change(group.labels, :count).by(1)
+ end
+
+ it 'becames available to all already existing projects of the group' do
+ service.execute
+
+ expect(project.labels.where(params)).not_to be_empty
+ end
+
+ it 'does not overwrite label that already exists in the project' do
+ params = { title: 'Security', color: '#FF0000', description: 'Sample' }
+ project.labels.create(params)
+
+ service.execute
+
+ expect(project.labels.where(params)).not_to be_empty
+ end
+ end
+
+ context 'with a project as subject' do
+ subject(:service) { described_class.new(project, double, params) }
+
+ it 'creates a label' do
+ expect { service.execute }.to change(project.labels, :count).by(1)
+ end
+
+ it 'does not create a label that already exists on the group level' do
+ group.labels.create(params)
+
+ expect { service.execute }.not_to change(project.labels, :count)
+ end
+ end
+ end
+end