summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-09-16 05:01:42 -0300
committerDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-09-16 10:56:48 -0300
commit3a1c02844e1d40490c3fe7b6a7dbb76cbad791bc (patch)
treebcc60bf75b6e8d4ff30a604098ab646800bba047
parent6799ac9c4788ecd9e9f3222159fa845eff7fbb03 (diff)
downloadgitlab-ce-3a1c02844e1d40490c3fe7b6a7dbb76cbad791bc.tar.gz
Add CRUD functionality to global labels
-rw-r--r--app/assets/stylesheets/pages/labels.scss2
-rw-r--r--app/controllers/admin/labels_controller.rb41
-rw-r--r--app/helpers/labels_helper.rb8
-rw-r--r--app/services/labels/base_service.rb4
-rw-r--r--app/services/labels/create_service.rb62
-rw-r--r--app/services/labels/destroy_service.rb46
-rw-r--r--app/services/labels/generate_service.rb16
-rw-r--r--app/services/labels/toggle_subscription_service.rb46
-rw-r--r--app/services/labels/update_service.rb49
-rw-r--r--app/views/admin/labels/_label.html.haml55
-rw-r--r--app/views/admin/labels/_label_row.html.haml6
-rw-r--r--app/views/admin/labels/edit.html.haml7
-rw-r--r--app/views/admin/labels/index.html.haml32
-rw-r--r--app/views/admin/labels/new.html.haml7
-rw-r--r--config/routes.rb6
-rw-r--r--features/admin/labels.feature1
-rw-r--r--features/steps/admin/labels.rb8
-rw-r--r--spec/services/labels/create_service_spec.rb70
-rw-r--r--spec/services/labels/destroy_service_spec.rb129
-rw-r--r--spec/services/labels/generate_service_spec.rb2
-rw-r--r--spec/services/labels/toggle_subscription_service_spec.rb147
-rw-r--r--spec/services/labels/update_service_spec.rb144
22 files changed, 729 insertions, 159 deletions
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index 1fc6fe9c55c..01777f0d38c 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -142,7 +142,7 @@
}
}
-.group-labels, .project-labels {
+.global-labels, .group-labels, .project-labels {
margin-top: 30px;
.remove-priority {
diff --git a/app/controllers/admin/labels_controller.rb b/app/controllers/admin/labels_controller.rb
index d496f08a598..e539b17907a 100644
--- a/app/controllers/admin/labels_controller.rb
+++ b/app/controllers/admin/labels_controller.rb
@@ -1,11 +1,8 @@
class Admin::LabelsController < Admin::ApplicationController
- before_action :set_label, only: [:show, :edit, :update, :destroy]
+ before_action :label, only: [:edit, :update, :destroy, :toggle_subscription]
def index
- @labels = Label.templates.page(params[:page])
- end
-
- def show
+ @labels = Label.global_labels.page(params[:page])
end
def new
@@ -16,40 +13,52 @@ class Admin::LabelsController < Admin::ApplicationController
end
def create
- @label = Label.new(label_params)
- @label.template = true
+ service = Labels::CreateService.new(nil, current_user, label_params.merge(label_type: :global_label))
+
+ @label = service.execute
- if @label.save
- redirect_to admin_labels_url, notice: "Label was created"
+ if @label.valid?
+ redirect_to admin_labels_url, notice: 'Label was created.'
else
render :new
end
end
def update
- if @label.update(label_params)
- redirect_to admin_labels_path, notice: 'label was successfully updated.'
+ service = Labels::UpdateService.new(nil, current_user, label_params)
+
+ if service.execute(@label)
+ redirect_to admin_labels_path, notice: 'Label was successfully updated.'
else
render :edit
end
end
def destroy
- @label.destroy
- @labels = Label.templates
+ Labels::DestroyService.new(nil, current_user).execute(@label)
+
+ @labels = Label.global_labels
respond_to do |format|
format.html do
- redirect_to(admin_labels_path, notice: 'Label was removed')
+ redirect_to admin_labels_path, notice: 'Label was removed.'
end
format.js
end
end
+ def toggle_subscription
+ return unless current_user
+
+ Labels::ToggleSubscriptionService.new(nil, current_user).execute(@label)
+
+ head :ok
+ end
+
private
- def set_label
- @label = Label.find(params[:id])
+ def label
+ @label = Label.with_type(:global_label).find(params[:id])
end
def label_params
diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb
index c0b4646bcc6..9959eae577b 100644
--- a/app/helpers/labels_helper.rb
+++ b/app/helpers/labels_helper.rb
@@ -44,15 +44,19 @@ module LabelsHelper
end
def label_filter_path(subject, label, type: issue)
- if subject.is_a?(Project)
+ case subject
+ when Project
send("namespace_project_#{type.to_s.pluralize}_path",
subject.namespace,
subject,
label_name: [label.name])
- else
+ when Group
send("#{type.to_s.pluralize}_group_path",
subject,
label_name: [label.name])
+ else
+ send("#{type.to_s.pluralize}_dashboard_path",
+ label_name: [label.name])
end
end
diff --git a/app/services/labels/base_service.rb b/app/services/labels/base_service.rb
index 48df8811a80..ff5d3f7a23b 100644
--- a/app/services/labels/base_service.rb
+++ b/app/services/labels/base_service.rb
@@ -8,8 +8,8 @@ module Labels
attr_reader :subject, :user, :params
- def find_labels(subject, title)
- Label.with_type(:group_label).where(subject: subject, title: title)
+ def find_labels(subject, label_type, title)
+ Label.with_type(label_type).where(subject: subject, title: title)
end
end
end
diff --git a/app/services/labels/create_service.rb b/app/services/labels/create_service.rb
index 97281b7c048..e7ca812778e 100644
--- a/app/services/labels/create_service.rb
+++ b/app/services/labels/create_service.rb
@@ -1,33 +1,61 @@
module Labels
class CreateService < Labels::BaseService
def execute
- Label.transaction do
- label = subject.labels.build(params)
- label.label_type = subject.is_a?(Group) ? :group_label : :project_label
+ label = Label.new(params.merge(subject: subject))
- return label if subject.is_a?(Project) && exists_at_group_level?
+ return label if label_already_exists?(label)
- if label.save && subject.is_a?(Group)
- replicate_labels_to_projects
+ Label.transaction do
+ if label.save
+ replicate_global_label if label.global_label?
+ replicate_group_label if label.group_label?
end
-
- label
end
+
+ label
end
private
- def exists_at_group_level?
- subject.group && subject.group.labels.where(title: params[:title]).exists?
+ def label_already_exists?(label)
+ return false if label.global_label?
+ return label_exists_at_global_level? if label.group_label?
+
+ label_exists_at_global_level? || label_exists_at_group_level?
end
- def replicate_labels_to_projects
- subject.projects.each do |project|
- project.labels.find_or_create_by!(title: params[:title]) do |label|
- label.color = params[:color]
- label.description = params[:description]
- label.label_type = :group_label
- end
+ def label_exists_at_global_level?
+ find_labels(nil, :global_label, params[:title]).exists?
+ end
+
+ def label_exists_at_group_level?
+ return false unless subject.group.present?
+
+ find_labels(subject.group, :group_label, params[:title]).exists?
+ end
+
+ def replicate_global_label
+ replicate_label_to_groups(Group.all)
+ replicate_label_to_projects(Project.all)
+ end
+
+ def replicate_group_label
+ replicate_label_to_projects(subject.projects)
+ end
+
+ def replicate_label_to_groups(groups)
+ groups.each { |group| replicate_label_to_resource(group) }
+ end
+
+ def replicate_label_to_projects(projects)
+ projects.each { |project| replicate_label_to_resource(project) }
+ end
+
+ def replicate_label_to_resource(resource)
+ resource.labels.find_or_create_by!(title: params[:title]) do |label|
+ label.color = params[:color]
+ label.description = params[:description]
+ label.label_type = params[:label_type]
end
end
end
diff --git a/app/services/labels/destroy_service.rb b/app/services/labels/destroy_service.rb
index 82a1dba3aee..16d07e9687b 100644
--- a/app/services/labels/destroy_service.rb
+++ b/app/services/labels/destroy_service.rb
@@ -4,23 +4,47 @@ module Labels
Label.transaction do
label.destroy
- return unless label.group_label?
+ return if label.project_label?
- if subject.is_a?(Group)
- destroy_labels(subject.projects, label.title)
- end
-
- if subject.is_a?(Project)
- destroy_labels(subject.group, label.title)
- destroy_labels(subject.group.projects - [subject], label.title)
- end
+ destroy_global_label(label.label_type, label.title) if label.global_label?
+ destroy_group_label(label.label_type, label.title) if label.group_label?
end
end
private
- def destroy_labels(subject, title)
- find_labels(subject, title).each(&:destroy)
+ def destroy_global_label(label_type, title)
+ if subject.nil?
+ destroy_labels(Group.all, label_type, title)
+ destroy_labels(Project.all, label_type, title)
+ end
+
+ if subject.is_a?(Group)
+ destroy_labels(nil, label_type, title)
+ destroy_labels(Group.where.not(id: subject), label_type, title)
+ destroy_labels(Project.all, label_type, title)
+ end
+
+ if subject.is_a?(Project)
+ destroy_labels(nil, label_type, title)
+ destroy_labels(Group.all, label_type, title)
+ destroy_labels(Project.where.not(id: subject), label_type, title)
+ end
+ end
+
+ def destroy_group_label(label_type, title)
+ if subject.is_a?(Group)
+ destroy_labels(subject.projects, label_type, title)
+ end
+
+ if subject.is_a?(Project)
+ destroy_labels(subject.group, label_type, title)
+ destroy_labels(subject.group.projects.where.not(id: subject), label_type, title)
+ end
+ end
+
+ def destroy_labels(subject, label_type, title)
+ find_labels(subject, label_type, title).each(&:destroy)
end
end
end
diff --git a/app/services/labels/generate_service.rb b/app/services/labels/generate_service.rb
index 01039b04c11..8c24b570404 100644
--- a/app/services/labels/generate_service.rb
+++ b/app/services/labels/generate_service.rb
@@ -15,14 +15,14 @@ module Labels
green = '#5cb85c'
[
- { title: 'bug', color: red },
- { title: 'critical', color: red },
- { title: 'confirmed', color: red },
- { title: 'documentation', color: yellow },
- { title: 'support', color: yellow },
- { title: 'discussion', color: blue },
- { title: 'suggestion', color: blue },
- { title: 'enhancement', color: green }
+ { title: 'bug', color: red, label_type: params[:label_type] },
+ { title: 'critical', color: red, label_type: params[:label_type] },
+ { title: 'confirmed', color: red, label_type: params[:label_type] },
+ { title: 'documentation', color: yellow, label_type: params[:label_type] },
+ { title: 'support', color: yellow, label_type: params[:label_type] },
+ { title: 'discussion', color: blue, label_type: params[:label_type] },
+ { title: 'suggestion', color: blue, label_type: params[:label_type] },
+ { title: 'enhancement', color: green, label_type: params[:label_type] }
]
end
end
diff --git a/app/services/labels/toggle_subscription_service.rb b/app/services/labels/toggle_subscription_service.rb
index 343f8ba3eee..c643c82c3f2 100644
--- a/app/services/labels/toggle_subscription_service.rb
+++ b/app/services/labels/toggle_subscription_service.rb
@@ -4,23 +4,47 @@ module Labels
Label.transaction do
label.toggle_subscription(user)
- return unless label.group_label?
+ return if label.project_label?
- if subject.is_a?(Group)
- toggle_subscription(subject.projects, label.title)
- end
-
- if subject.is_a?(Project)
- toggle_subscription(subject.group, label.title)
- toggle_subscription(subject.group.projects - [subject], label.title)
- end
+ toggle_subscription_to_global_label(label.label_type, label.title) if label.global_label?
+ toggle_subscription_to_group_label(label.label_type, label.title) if label.group_label?
end
end
private
- def toggle_subscription(subject, title)
- find_labels(subject, title).each { |label| label.toggle_subscription(user) }
+ def toggle_subscription_to_global_label(label_type, title)
+ if subject.nil?
+ toggle_subscription(Group.all, label_type, title)
+ toggle_subscription(Project.all, label_type, title)
+ end
+
+ if subject.is_a?(Group)
+ toggle_subscription(nil, label_type, title)
+ toggle_subscription(Group.where.not(id: subject), label_type, title)
+ toggle_subscription(Project.all, label_type, title)
+ end
+
+ if subject.is_a?(Project)
+ toggle_subscription(nil, label_type, title)
+ toggle_subscription(Group.all, label_type, title)
+ toggle_subscription(Project.where.not(id: subject), label_type, title)
+ end
+ end
+
+ def toggle_subscription_to_group_label(label_type, title)
+ if subject.is_a?(Group)
+ toggle_subscription(subject.projects, label_type, title)
+ end
+
+ if subject.is_a?(Project)
+ toggle_subscription(subject.group, label_type, title)
+ toggle_subscription(subject.group.projects.where.not(id: subject), label_type, title)
+ end
+ end
+
+ def toggle_subscription(subject, label_type, title)
+ find_labels(subject, label_type, title).each { |label| label.toggle_subscription(user) }
end
end
end
diff --git a/app/services/labels/update_service.rb b/app/services/labels/update_service.rb
index dd24e8894a1..12f40120822 100644
--- a/app/services/labels/update_service.rb
+++ b/app/services/labels/update_service.rb
@@ -1,20 +1,15 @@
module Labels
class UpdateService < Labels::BaseService
def execute(label)
+ previous_title = label.title.dup
+
Label.transaction do
- previous_title = label.title.dup
label.update(params)
- return label unless label.valid? && label.group_label?
-
- if subject.is_a?(Group)
- update_labels(subject.projects, previous_title)
- end
+ return label unless label.valid?
- if subject.is_a?(Project)
- update_labels(subject.group, previous_title)
- update_labels(subject.group.projects - [subject], previous_title)
- end
+ replicate_global_label(label.label_type, previous_title) if label.global_label?
+ replicate_group_label(label.label_type, previous_title) if label.group_label?
label
end
@@ -22,8 +17,38 @@ module Labels
private
- def update_labels(subject, title)
- find_labels(subject, title).update_all(params)
+ def replicate_global_label(label_type, title)
+ if subject.nil?
+ replicate_label(Group.all, label_type, title)
+ replicate_label(Project.all, label_type, title)
+ end
+
+ if subject.is_a?(Group)
+ replicate_label(nil, label_type, title)
+ replicate_label(Group.where.not(id: subject), label_type, title)
+ replicate_label(Project.all, label_type, title)
+ end
+
+ if subject.is_a?(Project)
+ replicate_label(nil, label_type, title)
+ replicate_label(Group.all, label_type, title)
+ replicate_label(Project.where.not(id: subject), label_type, title)
+ end
+ end
+
+ def replicate_group_label(label_type, title)
+ if subject.is_a?(Group)
+ replicate_label(subject.projects, label_type, title)
+ end
+
+ if subject.is_a?(Project)
+ replicate_label(subject.group, label_type, title)
+ replicate_label(subject.group.projects.where.not(id: subject), label_type, title)
+ end
+ end
+
+ def replicate_label(subject, label_type, title)
+ find_labels(subject, label_type, title).update_all(params)
end
end
end
diff --git a/app/views/admin/labels/_label.html.haml b/app/views/admin/labels/_label.html.haml
index f417b2e44a4..c6d5c9edce9 100644
--- a/app/views/admin/labels/_label.html.haml
+++ b/app/views/admin/labels/_label.html.haml
@@ -1,7 +1,48 @@
-%li{id: dom_id(label)}
- .label-row
- = render_colored_label(label, tooltip: false)
- = markdown(label.description, pipeline: :single_line)
- .pull-right
- = link_to 'Edit', edit_admin_label_path(label), class: 'btn btn-sm'
- = link_to 'Delete', admin_label_path(label), class: 'btn btn-sm btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Delete this label? Are you sure?"}
+- label_css_id = dom_id(label)
+- open_issues_count = label.open_issues_count(current_user)
+- open_merge_requests_count = label.open_merge_requests_count(current_user)
+
+%li{id: label_css_id, data: { id: label.id } }
+ = render 'label_row', label: label
+
+ .visible-xs.visible-sm-inline-block.visible-md-inline-block.dropdown
+ %button.btn.btn-default.label-options-toggle{ data: { toggle: 'dropdown' } }
+ Options
+ %span.caret
+ .dropdown-menu.dropdown-menu-align-right
+ %ul
+ %li
+ = link_to_label(label, type: :merge_request) do
+ = pluralize open_merge_requests_count, 'merge request'
+ %li
+ = link_to_label(label) do
+ = pluralize open_issues_count, 'open issue'
+ %li.label-subscription{ data: { url: toggle_subscription_admin_label_path(label) } }
+ %a.js-subscribe-button.label-subscribe-button.subscription-status{ role: "button", href: "#", data: { toggle: "tooltip", status: label_subscription_status(label) } }
+ %span= label_subscription_toggle_button_text(label)
+ %li
+ = link_to 'Edit', edit_admin_label_path(label)
+ %li
+ = link_to 'Delete', admin_label_path(label), title: 'Delete', method: :delete, remote: true, data: { confirm: 'Remove this label? Are you sure?' }
+
+ .pull-right.hidden-xs.hidden-sm.hidden-md
+ = link_to_label(label, type: :merge_request, css_class: 'btn btn-transparent btn-action') do
+ = pluralize label.open_merge_requests_count, 'merge request'
+ = link_to_label(label, css_class: 'btn btn-transparent btn-action') do
+ = pluralize open_issues_count, 'open issue'
+
+ .label-subscription.inline{ data: { url: toggle_subscription_admin_label_path(label) } }
+ %button.js-subscribe-button.label-subscribe-button.btn.btn-transparent.btn-action.subscription-status{ type: "button", title: label_subscription_toggle_button_text(label), data: { toggle: "tooltip", status: label_subscription_status(label) } }
+ %span.sr-only= label_subscription_toggle_button_text(label)
+ = icon('eye', class: 'label-subscribe-button-icon')
+ = icon('spinner spin', class: 'label-subscribe-button-loading')
+
+ = link_to edit_admin_label_path(label), title: 'Edit', class: 'btn btn-transparent btn-action', data: { toggle: 'tooltip' } do
+ %span.sr-only Edit
+ = icon('pencil-square-o')
+ = link_to admin_label_path(label), title: 'Delete', class: 'btn btn-transparent btn-action remove-row', method: :delete, remote: true, data: { confirm: 'Remove this label? Are you sure?', toggle: 'tooltip' } do
+ %span.sr-only Delete
+ = icon('trash-o')
+
+ :javascript
+ new Subscription('##{dom_id(label)} .label-subscription');
diff --git a/app/views/admin/labels/_label_row.html.haml b/app/views/admin/labels/_label_row.html.haml
new file mode 100644
index 00000000000..84c5c44ddcb
--- /dev/null
+++ b/app/views/admin/labels/_label_row.html.haml
@@ -0,0 +1,6 @@
+%span.label-row
+ %span.label-name
+ = render_colored_label(label, tooltip: false)
+ - if label.description
+ %span.label-description
+ = markdown(label.description, pipeline: :single_line)
diff --git a/app/views/admin/labels/edit.html.haml b/app/views/admin/labels/edit.html.haml
index 309aedceded..35ce01ccfbf 100644
--- a/app/views/admin/labels/edit.html.haml
+++ b/app/views/admin/labels/edit.html.haml
@@ -1,5 +1,8 @@
-- page_title "Edit", @label.name, "Labels"
+- page_title 'Edit', @label.name, 'Labels'
+
%h3.page-title
- Edit Label
+ = icon('globe')
+ Edit Global Label
%hr
+
= render 'form'
diff --git a/app/views/admin/labels/index.html.haml b/app/views/admin/labels/index.html.haml
index 05d6b9ed238..58c2bdae9f5 100644
--- a/app/views/admin/labels/index.html.haml
+++ b/app/views/admin/labels/index.html.haml
@@ -1,18 +1,22 @@
-- page_title "Labels"
+- page_title 'Labels'
-%div
- = link_to new_admin_label_path, class: "pull-right btn btn-nr btn-new" do
- New label
- %h3.page-title
- Labels
-%hr
+.top-area.adjust
+ .nav-text
+ Labels can be applied to issues and merge requests.
+
+ .nav-controls
+ = link_to new_admin_label_path, class: 'btn btn-new' do
+ New label
.labels
- - if @labels.present?
- %ul.bordered-list.manage-labels-list
- = render @labels
+ .global-labels
+ %h5
+ = icon('globe')
+ Global Labels
+ %ul.content-list.manage-labels-list.js-global-labels
+ - if @labels.present?
+ = render @labels
= paginate @labels, theme: 'gitlab'
- - else
- .light-well
- .nothing-here-block There are no labels yet
-
+ - if @labels.blank?
+ .nothing-here-block
+ There are no labels yet
diff --git a/app/views/admin/labels/new.html.haml b/app/views/admin/labels/new.html.haml
index 0135ad0723d..1ab87bc8ec1 100644
--- a/app/views/admin/labels/new.html.haml
+++ b/app/views/admin/labels/new.html.haml
@@ -1,5 +1,8 @@
-- page_title "New Label"
+- page_title 'New Global Label'
+
%h3.page-title
- New Label
+ = icon('globe')
+ New Global Label
%hr
+
= render 'form'
diff --git a/config/routes.rb b/config/routes.rb
index 180576d7252..f8d610099ef 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -314,7 +314,11 @@ Rails.application.routes.draw do
put :clear_repository_check_states
end
- resources :labels
+ resources :labels, except: [:show], constraints: { id: /\d+/ } do
+ member do
+ post :toggle_subscription
+ end
+ end
resources :runners, only: [:index, :show, :update, :destroy] do
member do
diff --git a/features/admin/labels.feature b/features/admin/labels.feature
index 1af0e700bd4..9632c679ee1 100644
--- a/features/admin/labels.feature
+++ b/features/admin/labels.feature
@@ -25,6 +25,7 @@ Feature: Admin Issues Labels
@javascript
Scenario: I delete all labels
When I delete all labels
+ And I visit admin labels page
Then I should see labels help message
Scenario: I create a label with invalid color
diff --git a/features/steps/admin/labels.rb b/features/steps/admin/labels.rb
index 55ddcc25085..c362c98d66d 100644
--- a/features/steps/admin/labels.rb
+++ b/features/steps/admin/labels.rb
@@ -23,13 +23,13 @@ class Spinach::Features::AdminIssuesLabels < Spinach::FeatureSteps
step 'I have labels: "bug", "feature", "enhancement"' do
["bug", "feature", "enhancement"].each do |title|
- Label.create(title: title, template: true)
+ Label.create(title: title, label_type: Label.label_types[:global_label])
end
end
step 'I delete all labels' do
- page.within '.labels' do
- page.all('.btn-remove').each do |remove|
+ page.within '.global-labels' do
+ page.all('.fa-trash-o').each do |remove|
remove.click
sleep 0.05
end
@@ -112,6 +112,6 @@ class Spinach::Features::AdminIssuesLabels < Spinach::FeatureSteps
end
def bug_label
- Label.templates.find_or_create_by(title: 'bug')
+ Label.global_labels.find_or_create_by(title: 'bug')
end
end
diff --git a/spec/services/labels/create_service_spec.rb b/spec/services/labels/create_service_spec.rb
index 8dfa6f70a6f..298c15b6ec6 100644
--- a/spec/services/labels/create_service_spec.rb
+++ b/spec/services/labels/create_service_spec.rb
@@ -13,10 +13,54 @@ describe Labels::CreateService, services: true do
}
end
- context 'with a group as subject' do
- subject(:service) { described_class.new(group, double, params) }
+ context 'with a global label' do
+ subject(:service) { described_class.new(nil, double, params.merge(label_type: :global_label)) }
- it 'creates a label' do
+ it 'creates the global label' do
+ expect { service.execute }.to change(Label.where(subject: nil, label_type: Label.label_types[:global_label]), :count).by(1)
+ end
+
+ it 'sets label_type to global_label' do
+ service.execute
+
+ expect(Label.last).to have_attributes(label_type: 'global_label')
+ end
+
+ it 'becames available to all already existing groups' do
+ service.execute
+
+ expect(Label.where(params.merge(subject: group, label_type: Label.label_types[:global_label]))).not_to be_empty
+ end
+
+ it 'becames available to all already existing projects' do
+ service.execute
+
+ expect(project.labels.where(params.merge(label_type: Label.label_types[:global_label]))).not_to be_empty
+ end
+
+ it 'does not overwrite label that already exists in a group' do
+ params = { title: 'Security', color: '#FF0000', description: 'Sample', label_type: Label.label_types[:group_label] }
+ group.labels.create(params)
+
+ service.execute
+
+ expect(group.labels.where(params)).not_to be_empty
+ end
+
+ it 'does not overwrite label that already exists in a project' do
+ params = { title: 'Security', color: '#FF0000', description: 'Sample', label_type: Label.label_types[:project_label] }
+ project.labels.create(params)
+
+ service.execute
+
+ expect(project.labels.where(params)).not_to be_empty
+ end
+ end
+
+ context 'with a group label' do
+ subject(:service) { described_class.new(group, double, params.merge(label_type: :group_label)) }
+
+ it 'creates the group label' do
expect { service.execute }.to change(group.labels, :count).by(1)
end
@@ -32,8 +76,14 @@ describe Labels::CreateService, services: true do
expect(project.labels.where(params.merge(label_type: Label.label_types[:group_label]))).not_to be_empty
end
+ it 'does not create a label that already exists on the global level' do
+ Label.create(params.merge(label_type: Label.label_types[:global_label]))
+
+ expect { service.execute }.not_to change(group.labels, :count)
+ end
+
it 'does not overwrite label that already exists in the project' do
- params = { title: 'Security', color: '#FF0000', description: 'Sample' }
+ params = { title: 'Security', color: '#FF0000', description: 'Sample', label_type: Label.label_types[:project_label] }
project.labels.create(params)
service.execute
@@ -42,10 +92,10 @@ describe Labels::CreateService, services: true do
end
end
- context 'with a project as subject' do
- subject(:service) { described_class.new(project, double, params) }
+ context 'with a project label' do
+ subject(:service) { described_class.new(project, double, params.merge(label_type: :project_label)) }
- it 'creates a label' do
+ it 'creates the project label' do
expect { service.execute }.to change(project.labels, :count).by(1)
end
@@ -55,6 +105,12 @@ describe Labels::CreateService, services: true do
expect(Label.last).to have_attributes(label_type: 'project_label')
end
+ it 'does not create a label that already exists on the global level' do
+ Label.create(params.merge(label_type: Label.label_types[:global_label]))
+
+ expect { service.execute }.not_to change(project.labels, :count)
+ end
+
it 'does not create a label that already exists on the group level' do
group.labels.create(params.merge(label_type: Label.label_types[:group_label]))
diff --git a/spec/services/labels/destroy_service_spec.rb b/spec/services/labels/destroy_service_spec.rb
index 6d3810154e6..9452fdf6df2 100644
--- a/spec/services/labels/destroy_service_spec.rb
+++ b/spec/services/labels/destroy_service_spec.rb
@@ -2,20 +2,51 @@ require 'spec_helper'
describe Labels::DestroyService, services: true do
describe '#execute' do
- let!(:group) { create(:group) }
- let!(:project1) { create(:empty_project, group: group) }
- let!(:project2) { create(:empty_project, group: group) }
+ let!(:group1) { create(:group) }
+ let!(:group2) { create(:group) }
+ let!(:project1) { create(:empty_project, group: group1) }
+ let!(:project2) { create(:empty_project, group: group1) }
+
+ context 'with a global label' do
+ let!(:label) { create(:global_label, title: 'Bug') }
+
+ subject(:service) { described_class.new(nil, double) }
+
+ it 'removes the global label' do
+ expect { service.execute(label) }.to change(Label.where(subject: nil, label_type: Label.label_types[:global_label]), :count).by(-1)
+ end
+
+ it 'removes the label of all groups that have the label' do
+ create(:global_label, subject: group1, title: 'Bug')
+ create(:global_label, subject: group2, title: 'Bug')
+
+ service.execute(label)
+
+ expect(group1.reload.labels).to be_empty
+ expect(group2.reload.labels).to be_empty
+ end
+
+ it 'removes the label of all projects that have the label' do
+ create(:global_label, subject: project1, title: 'Bug')
+ create(:global_label, subject: project2, title: 'Bug')
+
+ service.execute(label)
+
+ expect(project1.reload.labels).to be_empty
+ expect(project2.reload.labels).to be_empty
+ end
+ end
context 'with a group label' do
- let!(:label) { create(:group_label, subject: group, title: 'Bug') }
+ let!(:label) { create(:group_label, subject: group1, title: 'Bug') }
- subject(:service) { described_class.new(group, double) }
+ subject(:service) { described_class.new(group1, double) }
it 'removes the group label' do
- expect { service.execute(label) }.to change(group.labels, :count).by(-1)
+ expect { service.execute(label) }.to change(group1.labels, :count).by(-1)
end
- it 'removes the label from all projects inside the group' do
+ it 'removes the label from all projects inside the group that have the label' do
create(:group_label, subject: project1, title: 'Bug')
create(:group_label, subject: project2, title: 'Bug')
@@ -24,6 +55,41 @@ describe Labels::DestroyService, services: true do
expect(project1.labels.where(title: 'Bug')).to be_empty
expect(project2.labels.where(title: 'Bug')).to be_empty
end
+
+ context 'inherited from a global label' do
+ let!(:label) { create(:global_label, subject: group1, title: 'Bug') }
+
+ it 'removes the global label' do
+ create(:global_label, subject: nil, title: 'Bug')
+
+ expect { service.execute(label) }.to change(Label.where(subject: nil, label_type: Label.label_types[:global_label]), :count).by(-1)
+ end
+
+ it 'removes the group label' do
+ create(:global_label, subject: nil, title: 'Bug')
+
+ expect { service.execute(label) }.to change(group1.labels, :count).by(-1)
+ end
+
+ it 'removes the label of all groups that have the label' do
+ create(:global_label, subject: group2, title: 'Bug')
+
+ expect { service.execute(label) }.to change(group2.labels, :count).by(-1)
+ end
+
+ it 'removes the label of all projects that have the label' do
+ project3 = create(:empty_project, group: group2)
+ create(:global_label, subject: project1, title: 'Bug')
+ create(:global_label, subject: project2, title: 'Bug')
+ create(:global_label, subject: project3, title: 'Bug')
+
+ service.execute(label)
+
+ expect(project1.reload.labels).to be_empty
+ expect(project2.reload.labels).to be_empty
+ expect(project3.reload.labels).to be_empty
+ end
+ end
end
context 'with a project label' do
@@ -35,26 +101,61 @@ describe Labels::DestroyService, services: true do
expect { service.execute(label) }.to change(project1.labels, :count).by(-1)
end
+ context 'inherited from a global label' do
+ let!(:label) { create(:global_label, subject: project1, title: 'Bug') }
+
+ it 'removes the global label' do
+ create(:global_label, subject: nil, title: 'Bug')
+
+ expect { service.execute(label) }.to change(Label.where(subject: nil, label_type: Label.label_types[:global_label]), :count).by(-1)
+ end
+
+ it 'removes the project label' do
+ expect { service.execute(label) }.to change(project1.labels, :count).by(-1)
+ end
+
+ it 'removes the label of all groups that have the label' do
+ create(:global_label, subject: group1, title: 'Bug')
+ create(:global_label, subject: group2, title: 'Bug')
+
+ service.execute(label)
+
+ expect(group1.reload.labels).to be_empty
+ expect(group2.reload.labels).to be_empty
+ end
+
+ it 'removes the label of all projects that have the label' do
+ project3 = create(:empty_project, group: group2)
+ create(:global_label, subject: project2, title: 'Bug')
+ create(:global_label, subject: project3, title: 'Bug')
+
+ service.execute(label)
+
+ expect(project2.reload.labels).to be_empty
+ expect(project3.reload.labels).to be_empty
+ end
+ end
+
context 'inherited from a group' do
let!(:label) { create(:group_label, subject: project1, title: 'Bug') }
it 'removes the group label' do
- create(:group_label, subject: group, title: 'Bug')
+ create(:group_label, subject: group1, title: 'Bug')
+
+ expect { service.execute(label) }.to change(group1.labels, :count).by(-1)
+ end
- expect { service.execute(label) }.to change(group.labels, :count).by(-1)
+ it 'removes the project label' do
+ expect { service.execute(label) }.to change(project1.labels, :count).by(-1)
end
- it 'removes the label from all projects inside the group' do
+ it 'removes the label from all projects inside the group that have the label' do
create(:group_label, subject: project2, title: 'Bug')
service.execute(label)
expect(project2.labels.where(title: 'Bug')).to be_empty
end
-
- it 'removes the project label' do
- expect { service.execute(label) }.to change(project1.labels, :count).by(-1)
- end
end
end
end
diff --git a/spec/services/labels/generate_service_spec.rb b/spec/services/labels/generate_service_spec.rb
index e6c27fbe4e3..e07ccac99cb 100644
--- a/spec/services/labels/generate_service_spec.rb
+++ b/spec/services/labels/generate_service_spec.rb
@@ -4,7 +4,7 @@ describe Labels::GenerateService, services: true do
describe '#execute' do
let(:project) { create(:empty_project) }
- subject(:service) { described_class.new(project, double) }
+ subject(:service) { described_class.new(project, double, label_type: :project_label) }
context 'when project labels is empty' do
it 'creates the default labels' do
diff --git a/spec/services/labels/toggle_subscription_service_spec.rb b/spec/services/labels/toggle_subscription_service_spec.rb
index e2cc7af0d5d..82a1958eaa7 100644
--- a/spec/services/labels/toggle_subscription_service_spec.rb
+++ b/spec/services/labels/toggle_subscription_service_spec.rb
@@ -3,14 +3,55 @@ require 'spec_helper'
describe Labels::ToggleSubscriptionService, services: true do
describe '#execute' do
let(:user) { create(:user) }
- let!(:group) { create(:group) }
- let!(:project1) { create(:empty_project, group: group) }
- let!(:project2) { create(:empty_project, group: group) }
+ let!(:group1) { create(:group) }
+ let!(:group2) { create(:group) }
+ let!(:project1) { create(:empty_project, group: group1) }
+ let!(:project2) { create(:empty_project, group: group1) }
+
+ it 'delegates the subscription management to Label#toggle_subscription' do
+ label = create(:label, subject: project1)
+
+ expect(label).to receive(:toggle_subscription).once
+
+ described_class.new(project1, user).execute(label)
+ end
+
+ context 'with a global label' do
+ let(:label) { create(:global_label, title: 'Bug') }
+
+ subject(:service) { described_class.new(nil, user) }
+
+ it 'subscribes to global label' do
+ service.execute(label)
+
+ expect(label.subscribed?(user)).to eq true
+ end
+
+ it 'subscribes to labels of all groups that have the label' do
+ label1 = create(:global_label, subject: group1, title: 'Bug')
+ label2 = create(:global_label, subject: group2, title: 'Bug')
+
+ service.execute(label)
+
+ expect(label1.subscribed?(user)).to eq true
+ expect(label2.subscribed?(user)).to eq true
+ end
+
+ it 'subscribes to label of all projects that have the label' do
+ label1 = create(:global_label, subject: project1, title: 'Bug')
+ label2 = create(:global_label, subject: project2, title: 'Bug')
+
+ service.execute(label)
+
+ expect(label1.subscribed?(user)).to eq true
+ expect(label2.subscribed?(user)).to eq true
+ end
+ end
context 'with a group label' do
- let(:label) { create(:group_label, subject: group, title: 'Bug') }
+ let(:label) { create(:group_label, subject: group1, title: 'Bug') }
- subject(:service) { described_class.new(group, user) }
+ subject(:service) { described_class.new(group1, user) }
it 'subscribes to group label' do
service.execute(label)
@@ -18,7 +59,7 @@ describe Labels::ToggleSubscriptionService, services: true do
expect(label.subscribed?(user)).to eq true
end
- it 'subscribes to labels from all projects inside the group' do
+ it 'subscribes to labels from all projects inside the group that have the label' do
label1 = create(:group_label, subject: project1, title: 'Bug')
label2 = create(:group_label, subject: project2, title: 'Bug')
@@ -27,6 +68,46 @@ describe Labels::ToggleSubscriptionService, services: true do
expect(label1.subscribed?(user)).to eq true
expect(label2.subscribed?(user)).to eq true
end
+
+ context 'inherited from a global label' do
+ it 'subscribes to global label' do
+ label1 = create(:global_label, title: 'Bug')
+ label2 = create(:global_label, subject: group1, title: 'Bug')
+
+ service.execute(label2)
+
+ expect(label1.subscribed?(user)).to eq true
+ end
+
+ it 'subscribes to group label' do
+ label = create(:group_label, subject: group1, title: 'Bug')
+
+ service.execute(label)
+
+ expect(label.subscribed?(user)).to eq true
+ end
+
+ it 'subscribes to label of all groups that have the label' do
+ label1 = create(:global_label, subject: group1, title: 'Bug')
+ label2 = create(:global_label, subject: group2, title: 'Bug')
+
+ service.execute(label1)
+
+ expect(label2.subscribed?(user)).to eq true
+ end
+
+ it 'subscribes to label of all projects that have the label' do
+ project3 = create(:empty_project, group: group2)
+ label1 = create(:global_label, subject: project1, title: 'Bug')
+ label2 = create(:global_label, subject: project2, title: 'Bug')
+ label3 = create(:global_label, subject: project3, title: 'Bug')
+
+ service.execute(label1)
+
+ expect(label2.subscribed?(user)).to eq true
+ expect(label3.subscribed?(user)).to eq true
+ end
+ end
end
context 'with a project label' do
@@ -40,19 +121,53 @@ describe Labels::ToggleSubscriptionService, services: true do
expect(label.subscribed?(user)).to eq true
end
- context 'inherited from a group' do
- let(:label1) { create(:group_label, subject: project1, title: 'Bug') }
+ context 'inherited from a global label' do
+ it 'subscribes to global label' do
+ label1 = create(:global_label, title: 'Bug')
+ label2 = create(:global_label, subject: project1, title: 'Bug')
- it 'subscribes to group label' do
- label2 = create(:group_label, subject: group, title: 'Bug')
+ service.execute(label2)
+
+ expect(label1.subscribed?(user)).to eq true
+ end
+
+ it 'subscribes to project label' do
+ label = create(:global_label, subject: project1, title: 'Bug')
+
+ service.execute(label)
+
+ expect(label.subscribed?(user)).to eq true
+ end
+
+ it 'subscribes to label of all groups that have the label' do
+ label1 = create(:global_label, subject: project1, title: 'Bug')
+ label2 = create(:global_label, subject: group1, title: 'Bug')
+ label3 = create(:global_label, subject: group2, title: 'Bug')
service.execute(label1)
expect(label2.subscribed?(user)).to eq true
+ expect(label3.subscribed?(user)).to eq true
end
- it 'subscribes to labels from all projects inside the group' do
- label2 = create(:group_label, subject: project2, title: 'Bug')
+ it 'subscribes to label of all projects that have the label' do
+ project3 = create(:empty_project, group: group2)
+ label1 = create(:global_label, subject: project1, title: 'Bug')
+ label2 = create(:global_label, subject: project2, title: 'Bug')
+ label3 = create(:global_label, subject: project3, title: 'Bug')
+
+ service.execute(label1)
+
+ expect(label2.subscribed?(user)).to eq true
+ expect(label3.subscribed?(user)).to eq true
+ end
+ end
+
+ context 'inherited from a group' do
+ let(:label1) { create(:group_label, subject: project1, title: 'Bug') }
+
+ it 'subscribes to group label' do
+ label2 = create(:group_label, subject: group1, title: 'Bug')
service.execute(label1)
@@ -64,6 +179,14 @@ describe Labels::ToggleSubscriptionService, services: true do
expect(label1.subscribed?(user)).to eq true
end
+
+ it 'subscribes to labels from all projects inside the group that have the label' do
+ label2 = create(:group_label, subject: project2, title: 'Bug')
+
+ service.execute(label1)
+
+ expect(label2.subscribed?(user)).to eq true
+ end
end
end
end
diff --git a/spec/services/labels/update_service_spec.rb b/spec/services/labels/update_service_spec.rb
index 24123ca22d9..7a4e6778989 100644
--- a/spec/services/labels/update_service_spec.rb
+++ b/spec/services/labels/update_service_spec.rb
@@ -2,9 +2,10 @@ require 'spec_helper'
describe Labels::UpdateService, services: true do
describe '#execute' do
- let!(:group) { create(:group) }
- let!(:project1) { create(:empty_project, group: group) }
- let!(:project2) { create(:empty_project, group: group) }
+ let!(:group1) { create(:group) }
+ let!(:group2) { create(:group) }
+ let!(:project1) { create(:empty_project, group: group1) }
+ let!(:project2) { create(:empty_project, group: group1) }
let(:params) do
{
@@ -14,10 +15,42 @@ describe Labels::UpdateService, services: true do
}
end
+ context 'with a global label' do
+ let(:label) { create(:global_label, title: 'Bug') }
+
+ subject(:service) { described_class.new(nil, double, params) }
+
+ it 'updates the global label' do
+ service.execute(label)
+
+ expect(label).to have_attributes(params)
+ end
+
+ it 'updates the label of all groups that have the label' do
+ label1 = create(:global_label, subject: group1, title: 'Bug')
+ label2 = create(:global_label, subject: group2, title: 'Bug')
+
+ service.execute(label)
+
+ expect(label1.reload).to have_attributes(params)
+ expect(label2.reload).to have_attributes(params)
+ end
+
+ it 'updates the label of all projects that have the label' do
+ label1 = create(:global_label, subject: project1, title: 'Bug')
+ label2 = create(:global_label, subject: project2, title: 'Bug')
+
+ service.execute(label)
+
+ expect(label1.reload).to have_attributes(params)
+ expect(label2.reload).to have_attributes(params)
+ end
+ end
+
context 'with a group label' do
- let(:label) { create(:label, subject: group, title: 'Bug') }
+ let(:label) { create(:group_label, subject: group1, title: 'Bug') }
- subject(:service) { described_class.new(group, double, params) }
+ subject(:service) { described_class.new(group1, double, params) }
it 'updates the group label' do
service.execute(label)
@@ -25,15 +58,55 @@ describe Labels::UpdateService, services: true do
expect(label).to have_attributes(params)
end
- it 'updates the label of all projects inside the group' do
+ it 'updates the label of all projects inside the group that have the label' do
label1 = create(:group_label, subject: project1, title: 'Bug')
label2 = create(:group_label, subject: project2, title: 'Bug')
- service.execute(label1)
+ service.execute(label)
expect(label1.reload).to have_attributes(params)
expect(label2.reload).to have_attributes(params)
end
+
+ context 'inherited from a global label' do
+ it 'updates the global label' do
+ label1 = create(:global_label, title: 'Bug')
+ label2 = create(:global_label, subject: group1, title: 'Bug')
+
+ service.execute(label2)
+
+ expect(label1.reload).to have_attributes(params)
+ end
+
+ it 'updates the group label' do
+ label = create(:group_label, subject: group1, title: 'Bug')
+
+ service.execute(label)
+
+ expect(label.reload).to have_attributes(params)
+ end
+
+ it 'updates the label of all groups that have the label' do
+ label1 = create(:global_label, subject: group1, title: 'Bug')
+ label2 = create(:global_label, subject: group2, title: 'Bug')
+
+ service.execute(label1)
+
+ expect(label2.reload).to have_attributes(params)
+ end
+
+ it 'updates the label of all projects that have the label' do
+ project3 = create(:empty_project, group: group2)
+ label1 = create(:global_label, subject: project1, title: 'Bug')
+ label2 = create(:global_label, subject: project2, title: 'Bug')
+ label3 = create(:global_label, subject: project3, title: 'Bug')
+
+ service.execute(label1)
+
+ expect(label2.reload).to have_attributes(params)
+ expect(label3.reload).to have_attributes(params)
+ end
+ end
end
context 'with a project label' do
@@ -47,24 +120,56 @@ describe Labels::UpdateService, services: true do
expect(label).to have_attributes(params)
end
- context 'inherited from a group' do
- it 'updates the group label' do
- label1 = create(:group_label, subject: group, title: 'Bug')
- label2 = create(:group_label, subject: project1, title: 'Bug')
+ context 'inherited from a global label' do
+ it 'updates the global label' do
+ label1 = create(:global_label, title: 'Bug')
+ label2 = create(:global_label, subject: project1, title: 'Bug')
service.execute(label2)
expect(label1.reload).to have_attributes(params)
end
- it 'updates the label of all projects inside the group' do
- label1 = create(:group_label, subject: project1, title: 'Bug')
- label2 = create(:group_label, subject: project2, title: 'Bug')
+ it 'updates the project label' do
+ label = create(:global_label, subject: project1, title: 'Bug')
+
+ service.execute(label)
+
+ expect(label.reload).to have_attributes(params)
+ end
+
+ it 'updates the label of all groups that have the label' do
+ label1 = create(:global_label, subject: project1, title: 'Bug')
+ label2 = create(:global_label, subject: group1, title: 'Bug')
+ label3 = create(:global_label, subject: group2, title: 'Bug')
service.execute(label1)
- expect(label1.reload).to have_attributes(params)
expect(label2.reload).to have_attributes(params)
+ expect(label3.reload).to have_attributes(params)
+ end
+
+ it 'updates the label of all projects that have the label' do
+ project3 = create(:empty_project, group: group2)
+ label1 = create(:global_label, subject: project1, title: 'Bug')
+ label2 = create(:global_label, subject: project2, title: 'Bug')
+ label3 = create(:global_label, subject: project3, title: 'Bug')
+
+ service.execute(label1)
+
+ expect(label2.reload).to have_attributes(params)
+ expect(label3.reload).to have_attributes(params)
+ end
+ end
+
+ context 'inherited from a group label' do
+ it 'updates the group label' do
+ label1 = create(:group_label, subject: group1, title: 'Bug')
+ label2 = create(:group_label, subject: project1, title: 'Bug')
+
+ service.execute(label2)
+
+ expect(label1.reload).to have_attributes(params)
end
it 'updates the project label' do
@@ -74,6 +179,15 @@ describe Labels::UpdateService, services: true do
expect(label).to have_attributes(params)
end
+
+ it 'updates the label of all projects inside the group that have the label' do
+ label1 = create(:group_label, subject: project1, title: 'Bug')
+ label2 = create(:group_label, subject: project2, title: 'Bug')
+
+ service.execute(label1)
+
+ expect(label2.reload).to have_attributes(params)
+ end
end
end
end