Commit 20d38fed authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch '62322-add-optional-id-to-label-api-put-delete-pd' into 'master'

Add label_id parameter to label API for PUT and DELETE

Closes #62322

See merge request gitlab-org/gitlab-ce!31804
parents e8492290 f1e24d4d
---
title: Add optional label_id parameter to label API for PUT and DELETE
merge_request: 31804
author:
type: changed
...@@ -138,7 +138,8 @@ DELETE /projects/:id/labels ...@@ -138,7 +138,8 @@ DELETE /projects/:id/labels
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- | | --------- | ------- | -------- | --------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | The name of the label | | `label_id` | integer | yes (or `name`) | The id of the existing label |
| `name` | string | yes (or `label_id`) | The name of the existing label |
```bash ```bash
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/labels?name=bug" curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/labels?name=bug"
...@@ -156,7 +157,8 @@ PUT /projects/:id/labels ...@@ -156,7 +157,8 @@ PUT /projects/:id/labels
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------------- | ------- | --------------------------------- | ------------------------------- | | --------------- | ------- | --------------------------------- | ------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | The name of the existing label | | `label_id` | integer | yes (or `name`) | The id of the existing label |
| `name` | string | yes (or `label_id`) | The name of the existing label |
| `new_name` | string | yes if `color` is not provided | The new name of the label | | `new_name` | string | yes if `color` is not provided | The new name of the label |
| `color` | string | yes if `new_name` is not provided | The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) | | `color` | string | yes if `new_name` is not provided | The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) |
| `description` | string | no | The new description of the label | | `description` | string | no | The new description of the label |
......
...@@ -11,9 +11,9 @@ module API ...@@ -11,9 +11,9 @@ module API
optional :description, type: String, desc: 'The description of label to be created' optional :description, type: String, desc: 'The description of label to be created'
end end
def find_label(parent, id, include_ancestor_groups: true) def find_label(parent, id_or_title, include_ancestor_groups: true)
labels = available_labels_for(parent, include_ancestor_groups: include_ancestor_groups) labels = available_labels_for(parent, include_ancestor_groups: include_ancestor_groups)
label = labels.find_by_id(id) || labels.find_by_title(id) label = labels.find_by_id(id_or_title) || labels.find_by_title(id_or_title)
label || not_found!('Label') label || not_found!('Label')
end end
...@@ -35,12 +35,7 @@ module API ...@@ -35,12 +35,7 @@ module API
priority = params.delete(:priority) priority = params.delete(:priority)
label_params = declared_params(include_missing: false) label_params = declared_params(include_missing: false)
label = label = ::Labels::CreateService.new(label_params).execute(create_service_params(parent))
if parent.is_a?(Project)
::Labels::CreateService.new(label_params).execute(project: parent)
else
::Labels::CreateService.new(label_params).execute(group: parent)
end
if label.persisted? if label.persisted?
if parent.is_a?(Project) if parent.is_a?(Project)
...@@ -56,10 +51,13 @@ module API ...@@ -56,10 +51,13 @@ module API
def update_label(parent, entity) def update_label(parent, entity)
authorize! :admin_label, parent authorize! :admin_label, parent
label = find_label(parent, params[:name], include_ancestor_groups: false) label = find_label(parent, params_id_or_title, include_ancestor_groups: false)
update_priority = params.key?(:priority) update_priority = params.key?(:priority)
priority = params.delete(:priority) priority = params.delete(:priority)
# params is used to update the label so we need to remove this field here
params.delete(:label_id)
label = ::Labels::UpdateService.new(declared_params(include_missing: false)).execute(label) label = ::Labels::UpdateService.new(declared_params(include_missing: false)).execute(label)
render_validation_error!(label) unless label.valid? render_validation_error!(label) unless label.valid?
...@@ -77,10 +75,24 @@ module API ...@@ -77,10 +75,24 @@ module API
def delete_label(parent) def delete_label(parent)
authorize! :admin_label, parent authorize! :admin_label, parent
label = find_label(parent, params[:name], include_ancestor_groups: false) label = find_label(parent, params_id_or_title, include_ancestor_groups: false)
destroy_conditionally!(label) destroy_conditionally!(label)
end end
def params_id_or_title
@params_id_or_title ||= params[:label_id] || params[:name]
end
def create_service_params(parent)
if parent.is_a?(Project)
{ project: parent }
elsif parent.is_a?(Group)
{ group: parent }
else
raise TypeError, 'Parent type is not supported'
end
end
end end
end end
end end
...@@ -38,11 +38,13 @@ module API ...@@ -38,11 +38,13 @@ module API
success Entities::ProjectLabel success Entities::ProjectLabel
end end
params do params do
requires :name, type: String, desc: 'The name of the label to be updated' optional :label_id, type: Integer, desc: 'The id of the label to be updated'
optional :name, type: String, desc: 'The name of the label to be updated'
optional :new_name, type: String, desc: 'The new name of the label' optional :new_name, type: String, desc: 'The new name of the label'
optional :color, type: String, desc: "The new color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the allowed CSS color names" optional :color, type: String, desc: "The new color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the allowed CSS color names"
optional :description, type: String, desc: 'The new description of label' optional :description, type: String, desc: 'The new description of label'
optional :priority, type: Integer, desc: 'The priority of the label', allow_blank: true optional :priority, type: Integer, desc: 'The priority of the label', allow_blank: true
exactly_one_of :label_id, :name
at_least_one_of :new_name, :color, :description, :priority at_least_one_of :new_name, :color, :description, :priority
end end
put ':id/labels' do put ':id/labels' do
...@@ -53,7 +55,9 @@ module API ...@@ -53,7 +55,9 @@ module API
success Entities::ProjectLabel success Entities::ProjectLabel
end end
params do params do
requires :name, type: String, desc: 'The name of the label to be deleted' optional :label_id, type: Integer, desc: 'The id of the label to be deleted'
optional :name, type: String, desc: 'The name of the label to be deleted'
exactly_one_of :label_id, :name
end end
delete ':id/labels' do delete ':id/labels' do
delete_label(user_project) delete_label(user_project)
......
# frozen_string_literal: true
require 'spec_helper'
describe API::Helpers::LabelHelpers do
describe 'create_service_params' do
let(:label_helper) do
Class.new do
include API::Helpers::LabelHelpers
end.new
end
context 'when a project is given' do
it 'returns the expected params' do
project = create(:project)
expect(label_helper.create_service_params(project)).to eq({ project: project })
end
end
context 'when a group is given' do
it 'returns the expected params' do
group = create(:group)
expect(label_helper.create_service_params(group)).to eq({ group: group })
end
end
context 'when something else is given' do
it 'raises a type error' do
expect { label_helper.create_service_params(Class.new) }.to raise_error(TypeError)
end
end
end
end
This diff is collapsed.
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