Commit ae68c1a1 authored by Brett Walker's avatar Brett Walker Committed by Matthias Käppler

Fix labels in API to accept `.` in name/label_id

For example, a label such as `v.1` should
be allowed
parent fb56d1ef
---
title: Allow dots in label names through REST API
merge_request: 52591
author:
type: fixed
...@@ -12,7 +12,7 @@ module API ...@@ -12,7 +12,7 @@ module API
params do params do
requires :id, type: String, desc: 'The ID of a group' requires :id, type: String, desc: 'The ID of a group'
end end
resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :groups, requirements: ::API::Labels::LABEL_ENDPOINT_REQUIREMENTS do
desc 'Get all labels of the group' do desc 'Get all labels of the group' do
detail 'This feature was added in GitLab 11.8' detail 'This feature was added in GitLab 11.8'
success Entities::GroupLabel success Entities::GroupLabel
......
...@@ -9,10 +9,14 @@ module API ...@@ -9,10 +9,14 @@ module API
feature_category :issue_tracking feature_category :issue_tracking
LABEL_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(
name: API::NO_SLASH_URL_PART_REGEX,
label_id: API::NO_SLASH_URL_PART_REGEX)
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, type: String, desc: 'The ID of a project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: LABEL_ENDPOINT_REQUIREMENTS do
desc 'Get all labels of the project' do desc 'Get all labels of the project' do
success Entities::ProjectLabel success Entities::ProjectLabel
end end
......
...@@ -6,6 +6,9 @@ module API ...@@ -6,6 +6,9 @@ module API
before { authenticate! } before { authenticate! }
SUBSCRIBE_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(
subscribable_id: API::NO_SLASH_URL_PART_REGEX)
subscribables = [ subscribables = [
{ {
type: 'merge_requests', type: 'merge_requests',
...@@ -44,7 +47,7 @@ module API ...@@ -44,7 +47,7 @@ module API
requires :id, type: String, desc: "The #{source_type} ID" requires :id, type: String, desc: "The #{source_type} ID"
requires :subscribable_id, type: String, desc: 'The ID of a resource' requires :subscribable_id, type: String, desc: 'The ID of a resource'
end end
resource source_type.pluralize, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource source_type.pluralize, requirements: SUBSCRIBE_ENDPOINT_REQUIREMENTS do
desc 'Subscribe to a resource' do desc 'Subscribe to a resource' do
success subscribable[:entity] success subscribable[:entity]
end end
......
...@@ -3,13 +3,19 @@ ...@@ -3,13 +3,19 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe API::GroupLabels do RSpec.describe API::GroupLabels do
let_it_be(:valid_group_label_title_1) { 'Label foo & bar:subgroup::v.1' }
let_it_be(:valid_group_label_title_1_esc) { ERB::Util.url_encode(valid_group_label_title_1) }
let_it_be(:valid_group_label_title_2) { 'Bar & foo:subgroup::v.2' }
let_it_be(:valid_subgroup_label_title_1) { 'Support label foobar:sub::v.1' }
let_it_be(:valid_new_label_title) { 'New & foo:feature::v.3' }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:group) { create(:group) } let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) } let(:subgroup) { create(:group, parent: group) }
let!(:group_member) { create(:group_member, group: group, user: user) } let!(:group_member) { create(:group_member, group: group, user: user) }
let!(:group_label1) { create(:group_label, title: 'feature-label', group: group) } let!(:group_label1) { create(:group_label, title: valid_group_label_title_1, group: group) }
let!(:group_label2) { create(:group_label, title: 'bug', group: group) } let!(:group_label2) { create(:group_label, title: valid_group_label_title_2, group: group) }
let!(:subgroup_label) { create(:group_label, title: 'support-label', group: subgroup) } let!(:subgroup_label) { create(:group_label, title: valid_subgroup_label_title_1, group: subgroup) }
describe 'GET :id/labels' do describe 'GET :id/labels' do
context 'get current group labels' do context 'get current group labels' do
...@@ -104,7 +110,7 @@ RSpec.describe API::GroupLabels do ...@@ -104,7 +110,7 @@ RSpec.describe API::GroupLabels do
describe 'GET :id/labels/:label_id' do describe 'GET :id/labels/:label_id' do
it 'returns a single label for the group' do it 'returns a single label for the group' do
get api("/groups/#{group.id}/labels/#{group_label1.name}", user) get api("/groups/#{group.id}/labels/#{valid_group_label_title_1_esc}", user)
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(group_label1.name) expect(json_response['name']).to eq(group_label1.name)
...@@ -117,13 +123,13 @@ RSpec.describe API::GroupLabels do ...@@ -117,13 +123,13 @@ RSpec.describe API::GroupLabels do
it 'returns created label when all params are given' do it 'returns created label when all params are given' do
post api("/groups/#{group.id}/labels", user), post api("/groups/#{group.id}/labels", user),
params: { params: {
name: 'Foo', name: valid_new_label_title,
color: '#FFAABB', color: '#FFAABB',
description: 'test' description: 'test'
} }
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq('Foo') expect(json_response['name']).to eq(valid_new_label_title)
expect(json_response['color']).to eq('#FFAABB') expect(json_response['color']).to eq('#FFAABB')
expect(json_response['description']).to eq('test') expect(json_response['description']).to eq('test')
end end
...@@ -131,12 +137,12 @@ RSpec.describe API::GroupLabels do ...@@ -131,12 +137,12 @@ RSpec.describe API::GroupLabels do
it 'returns created label when only required params are given' do it 'returns created label when only required params are given' do
post api("/groups/#{group.id}/labels", user), post api("/groups/#{group.id}/labels", user),
params: { params: {
name: 'Foo & Bar', name: valid_new_label_title,
color: '#FFAABB' color: '#FFAABB'
} }
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq('Foo & Bar') expect(json_response['name']).to eq(valid_new_label_title)
expect(json_response['color']).to eq('#FFAABB') expect(json_response['color']).to eq('#FFAABB')
expect(json_response['description']).to be_nil expect(json_response['description']).to be_nil
end end
...@@ -204,7 +210,7 @@ RSpec.describe API::GroupLabels do ...@@ -204,7 +210,7 @@ RSpec.describe API::GroupLabels do
describe 'DELETE /groups/:id/labels/:label_id' do describe 'DELETE /groups/:id/labels/:label_id' do
it 'returns 204 for existing label' do it 'returns 204 for existing label' do
delete api("/groups/#{group.id}/labels/#{group_label1.name}", user) delete api("/groups/#{group.id}/labels/#{valid_group_label_title_1_esc}", user)
expect(response).to have_gitlab_http_status(:no_content) expect(response).to have_gitlab_http_status(:no_content)
end end
...@@ -228,7 +234,7 @@ RSpec.describe API::GroupLabels do ...@@ -228,7 +234,7 @@ RSpec.describe API::GroupLabels do
end end
it_behaves_like '412 response' do it_behaves_like '412 response' do
let(:request) { api("/groups/#{group.id}/labels/#{group_label1.name}", user) } let(:request) { api("/groups/#{group.id}/labels/#{valid_group_label_title_1_esc}", user) }
end end
end end
...@@ -237,13 +243,13 @@ RSpec.describe API::GroupLabels do ...@@ -237,13 +243,13 @@ RSpec.describe API::GroupLabels do
put api("/groups/#{group.id}/labels", user), put api("/groups/#{group.id}/labels", user),
params: { params: {
name: group_label1.name, name: group_label1.name,
new_name: 'New Label', new_name: valid_new_label_title,
color: '#FFFFFF', color: '#FFFFFF',
description: 'test' description: 'test'
} }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq('New Label') expect(json_response['name']).to eq(valid_new_label_title)
expect(json_response['color']).to eq('#FFFFFF') expect(json_response['color']).to eq('#FFFFFF')
expect(json_response['description']).to eq('test') expect(json_response['description']).to eq('test')
end end
...@@ -255,11 +261,11 @@ RSpec.describe API::GroupLabels do ...@@ -255,11 +261,11 @@ RSpec.describe API::GroupLabels do
put api("/groups/#{subgroup.id}/labels", user), put api("/groups/#{subgroup.id}/labels", user),
params: { params: {
name: subgroup_label.name, name: subgroup_label.name,
new_name: 'New Label' new_name: valid_new_label_title
} }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(subgroup.labels[0].name).to eq('New Label') expect(subgroup.labels[0].name).to eq(valid_new_label_title)
expect(group_label1.name).to eq(group_label1.title) expect(group_label1.name).to eq(group_label1.title)
end end
...@@ -267,7 +273,7 @@ RSpec.describe API::GroupLabels do ...@@ -267,7 +273,7 @@ RSpec.describe API::GroupLabels do
put api("/groups/#{group.id}/labels", user), put api("/groups/#{group.id}/labels", user),
params: { params: {
name: 'not_exists', name: 'not_exists',
new_name: 'label3' new_name: valid_new_label_title
} }
expect(response).to have_gitlab_http_status(:not_found) expect(response).to have_gitlab_http_status(:not_found)
...@@ -291,15 +297,15 @@ RSpec.describe API::GroupLabels do ...@@ -291,15 +297,15 @@ RSpec.describe API::GroupLabels do
describe 'PUT /groups/:id/labels/:label_id' do describe 'PUT /groups/:id/labels/:label_id' do
it 'returns 200 if name and colors and description are changed' do it 'returns 200 if name and colors and description are changed' do
put api("/groups/#{group.id}/labels/#{group_label1.name}", user), put api("/groups/#{group.id}/labels/#{valid_group_label_title_1_esc}", user),
params: { params: {
new_name: 'New Label', new_name: valid_new_label_title,
color: '#FFFFFF', color: '#FFFFFF',
description: 'test' description: 'test'
} }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq('New Label') expect(json_response['name']).to eq(valid_new_label_title)
expect(json_response['color']).to eq('#FFFFFF') expect(json_response['color']).to eq('#FFFFFF')
expect(json_response['description']).to eq('test') expect(json_response['description']).to eq('test')
end end
...@@ -310,25 +316,25 @@ RSpec.describe API::GroupLabels do ...@@ -310,25 +316,25 @@ RSpec.describe API::GroupLabels do
put api("/groups/#{subgroup.id}/labels/#{subgroup_label.name}", user), put api("/groups/#{subgroup.id}/labels/#{subgroup_label.name}", user),
params: { params: {
new_name: 'New Label' new_name: valid_new_label_title
} }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(subgroup.labels[0].name).to eq('New Label') expect(subgroup.labels[0].name).to eq(valid_new_label_title)
expect(group_label1.name).to eq(group_label1.title) expect(group_label1.name).to eq(group_label1.title)
end end
it 'returns 404 if label does not exist' do it 'returns 404 if label does not exist' do
put api("/groups/#{group.id}/labels/not_exists", user), put api("/groups/#{group.id}/labels/not_exists", user),
params: { params: {
new_name: 'label3' new_name: valid_new_label_title
} }
expect(response).to have_gitlab_http_status(:not_found) expect(response).to have_gitlab_http_status(:not_found)
end end
it 'returns 400 if no new parameters given' do it 'returns 400 if no new parameters given' do
put api("/groups/#{group.id}/labels/#{group_label1.name}", user) put api("/groups/#{group.id}/labels/#{valid_group_label_title_1_esc}", user)
expect(response).to have_gitlab_http_status(:bad_request) expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('new_name, color, description are missing, '\ expect(json_response['error']).to eq('new_name, color, description are missing, '\
...@@ -339,7 +345,7 @@ RSpec.describe API::GroupLabels do ...@@ -339,7 +345,7 @@ RSpec.describe API::GroupLabels do
describe 'POST /groups/:id/labels/:label_id/subscribe' do describe 'POST /groups/:id/labels/:label_id/subscribe' do
context 'when label_id is a label title' do context 'when label_id is a label title' do
it 'subscribes to the label' do it 'subscribes to the label' do
post api("/groups/#{group.id}/labels/#{group_label1.title}/subscribe", user) post api("/groups/#{group.id}/labels/#{valid_group_label_title_1_esc}/subscribe", user)
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq(group_label1.title) expect(json_response['name']).to eq(group_label1.title)
...@@ -385,7 +391,7 @@ RSpec.describe API::GroupLabels do ...@@ -385,7 +391,7 @@ RSpec.describe API::GroupLabels do
context 'when label_id is a label title' do context 'when label_id is a label title' do
it 'unsubscribes from the label' do it 'unsubscribes from the label' do
post api("/groups/#{group.id}/labels/#{group_label1.title}/unsubscribe", user) post api("/groups/#{group.id}/labels/#{valid_group_label_title_1_esc}/unsubscribe", user)
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq(group_label1.title) expect(json_response['name']).to eq(group_label1.title)
......
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