From eed79986c9f280ea5ccdc4fd08f127640bd581a0 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Sat, 25 Aug 2018 22:29:27 +0200 Subject: Add subscription API for the group label API --- lib/api/entities.rb | 4 +- lib/api/helpers.rb | 4 +- lib/api/subscriptions.rb | 35 ++++++++----- spec/requests/api/group_labels_spec.rb | 90 +++++++++++++++++++++++++++++++++- 4 files changed, 117 insertions(+), 16 deletions(-) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index fe28cb256e6..8f0dddb55ee 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -1019,12 +1019,12 @@ module API label.open_merge_requests_count(options[:current_user]) end - expose :priority do |label, options| + expose :priority, if: lambda { |_, options| options[:project].is_a?(::Project) } do |label, options| label.priority(options[:project]) end expose :subscribed do |label, options| - label.subscribed?(options[:current_user], options[:parent]) + label.subscribed?(options[:current_user], options[:project]) end end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index fa6c9777824..544736c42f4 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -170,8 +170,8 @@ module API end end - def find_project_label(id) - labels = available_labels_for(user_project) + def find_label(parent, id) + labels = available_labels_for(parent) label = labels.find_by_id(id) || labels.find_by_title(id) label || not_found!('Label') diff --git a/lib/api/subscriptions.rb b/lib/api/subscriptions.rb index 74ad3c35a61..a8d5457efde 100644 --- a/lib/api/subscriptions.rb +++ b/lib/api/subscriptions.rb @@ -4,11 +4,12 @@ module API class Subscriptions < Grape::API before { authenticate! } - subscribable_types = { - 'merge_requests' => proc { |id| find_merge_request_with_access(id, :update_merge_request) }, - 'issues' => proc { |id| find_project_issue(id) }, - 'labels' => proc { |id| find_project_label(id) } - } + subscribables = [ + ['merge_requests', Project, proc { |id| find_merge_request_with_access(id, :update_merge_request) }, proc { user_project }], + ['issues', Project, proc { |id| find_project_issue(id) }, proc { user_project }], + ['labels', Project, proc { |id| find_label(user_project, id) }, proc { user_project }], + ['labels', Group, proc { |id| find_label(user_group, id) }, proc { nil }] + ] params do requires :id, type: String, desc: 'The ID of a project' @@ -19,17 +20,27 @@ module API type_singularized = type.singularize entity_class = Entities.const_get(type_singularized.camelcase) + subscribables.each do |subscribable| + source_type = subscribable[:source].name.underscore + entity_class = Entities.const_get(subscribable[:type].singularize.camelcase) + + params do + requires :id, type: String, desc: "The #{source_type} ID" + requires :subscribable_id, type: String, desc: 'The ID of a resource' + end + resource source_type.pluralize, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do desc 'Subscribe to a resource' do success entity_class end post ":id/#{type}/:subscribable_id/subscribe" do + parent = instance_exec(&parent_ressource) resource = instance_exec(params[:subscribable_id], &finder) - if resource.subscribed?(current_user, user_project) + if resource.subscribed?(current_user, parent) not_modified! else - resource.subscribe(current_user, user_project) - present resource, with: entity_class, current_user: current_user, project: user_project + resource.subscribe(current_user, parent) + present resource, with: entity_class, current_user: current_user, project: parent end end @@ -37,13 +48,15 @@ module API success entity_class end post ":id/#{type}/:subscribable_id/unsubscribe" do + parent = instance_exec(&parent_ressource) resource = instance_exec(params[:subscribable_id], &finder) - if !resource.subscribed?(current_user, user_project) + + if !resource.subscribed?(current_user, parent) not_modified! else - resource.unsubscribe(current_user, user_project) - present resource, with: entity_class, current_user: current_user, project: user_project + resource.unsubscribe(current_user, parent) + present resource, with: entity_class, current_user: current_user, project: parent end end end diff --git a/spec/requests/api/group_labels_spec.rb b/spec/requests/api/group_labels_spec.rb index 09563b1a204..e0411faa186 100644 --- a/spec/requests/api/group_labels_spec.rb +++ b/spec/requests/api/group_labels_spec.rb @@ -209,4 +209,92 @@ describe API::GroupLabels do expect(json_response['message']['color']).to eq(['must be a valid color code']) end end -end \ No newline at end of file + + describe 'POST /groups/:id/labels/:label_id/subscribe' do + context 'when label_id is a label title' do + it 'subscribes to the label' do + post api("/groups/#{group.id}/labels/#{label1.title}/subscribe", user) + + expect(response).to have_gitlab_http_status(201) + expect(json_response['name']).to eq(label1.title) + expect(json_response['subscribed']).to be_truthy + end + end + + context 'when label_id is a label ID' do + it 'subscribes to the label' do + post api("/groups/#{group.id}/labels/#{label1.id}/subscribe", user) + + expect(response).to have_gitlab_http_status(201) + expect(json_response['name']).to eq(label1.title) + expect(json_response['subscribed']).to be_truthy + end + end + + context 'when user is already subscribed to label' do + before do + label1.subscribe(user) + end + + it 'returns 304' do + post api("/groups/#{group.id}/labels/#{label1.id}/subscribe", user) + + expect(response).to have_gitlab_http_status(304) + end + end + + context 'when label ID is not found' do + it 'returns 404 error' do + post api("/groups/#{group.id}/labels/1234/subscribe", user) + + expect(response).to have_gitlab_http_status(404) + end + end + end + + describe 'POST /groups/:id/labels/:label_id/unsubscribe' do + before do + label1.subscribe(user) + end + + context 'when label_id is a label title' do + it 'unsubscribes from the label' do + post api("/groups/#{group.id}/labels/#{label1.title}/unsubscribe", user) + + expect(response).to have_gitlab_http_status(201) + expect(json_response['name']).to eq(label1.title) + expect(json_response['subscribed']).to be_falsey + end + end + + context 'when label_id is a label ID' do + it 'unsubscribes from the label' do + post api("/groups/#{group.id}/labels/#{label1.id}/unsubscribe", user) + + expect(response).to have_gitlab_http_status(201) + expect(json_response['name']).to eq(label1.title) + expect(json_response['subscribed']).to be_falsey + end + end + + context 'when user is already unsubscribed from label' do + before do + label1.unsubscribe(user) + end + + it 'returns 304' do + post api("/groups/#{group.id}/labels/#{label1.id}/unsubscribe", user) + + expect(response).to have_gitlab_http_status(304) + end + end + + context 'when label ID is not found' do + it 'returns 404 error' do + post api("/groups/#{group.id}/labels/1234/unsubscribe", user) + + expect(response).to have_gitlab_http_status(404) + end + end + end +end -- cgit v1.2.1