From 5ec28dc387fb4adc3c5b65ac47819a8663186954 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Mon, 8 Apr 2019 14:17:22 +0300 Subject: Changes to issues api When issues_controller endpoint was used for search, the parameters passed to the controller were slightly different then the ones passed to API. Because the searchbar UI is reused in different places and builds the parameters passed to request in same way we need to account for old parameter names. Add issues_statistics api endpoints Adds issue_statistics api endpoints for issue lists and returns counts of issues for all, closed and opened states. Expose more label attributes based on a param When requesting issues list through API expose more attributes for labels, like color, description if with_labels_data param is being passed, avoiding this way to change response schema for users that already use API. https://gitlab.com/gitlab-org/gitlab-ce/issues/57402 --- lib/api/entities.rb | 10 ++++- lib/api/helpers/issues_helpers.rb | 37 +++++++++++++++++++ lib/api/issues.rb | 78 ++++++++++++++++++++++++++------------- 3 files changed, 97 insertions(+), 28 deletions(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 296688ba25b..a57c7e9f851 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -542,9 +542,13 @@ module API class IssueBasic < ProjectEntity expose :closed_at expose :closed_by, using: Entities::UserBasic - expose :labels do |issue| + expose :labels do |issue, options| # Avoids an N+1 query since labels are preloaded - issue.labels.map(&:title).sort + if options[:with_labels_data] + ::API::Entities::LabelBasic.represent(issue.labels.sort_by(&:title)) + else + issue.labels.map(&:title).sort + end end expose :milestone, using: Entities::Milestone expose :assignees, :author, using: Entities::UserBasic @@ -560,6 +564,8 @@ module API expose :due_date expose :confidential expose :discussion_locked + expose(:has_tasks) {|issue, _| !issue.task_list_items.empty? } + expose :task_status, if: -> (issue, _) { !issue.task_list_items.empty? } expose :web_url do |issue| Gitlab::UrlBuilder.build(issue) diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb index f6762910b0c..00aaf5243b7 100644 --- a/lib/api/helpers/issues_helpers.rb +++ b/lib/api/helpers/issues_helpers.rb @@ -18,6 +18,43 @@ module API :title ] end + + def issue_finder(args = {}) + args = declared_params.merge(args) + + args.delete(:id) + args[:milestone_title] ||= args.delete(:milestone) + args[:milestone_title] ||= args.delete(:milestone_title) + args[:label_name] ||= args.delete(:labels) + args[:scope] = args[:scope].underscore if args[:scope] + + IssuesFinder.new(current_user, args) + end + + def find_issues(args = {}) + # rubocop: disable CodeReuse/ActiveRecord + finder = issue_finder(args) + issues = finder.execute.with_api_entity_associations + order_by = declared_params[:sort].present? && %w(asc desc).include?(declared_params[:sort].downcase) + issues = issues.reorder(order_options_with_tie_breaker) if order_by + issues + # rubocop: enable CodeReuse/ActiveRecord + end + + def issues_statistics(args = {}) + finder = issue_finder(args) + counter = Gitlab::IssuablesCountForState.new(finder) + + { + statistics: { + counts: { + all: counter[:all], + closed: counter[:closed], + opened: counter[:opened] + } + } + } + end end end end diff --git a/lib/api/issues.rb b/lib/api/issues.rb index d0a93b77951..67da1c46480 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -3,27 +3,12 @@ module API class Issues < Grape::API include PaginationParams + helpers Helpers::IssuesHelpers + helpers ::Gitlab::IssuableMetadata before { authenticate_non_get! } - helpers ::Gitlab::IssuableMetadata - helpers do - # rubocop: disable CodeReuse/ActiveRecord - def find_issues(args = {}) - args = declared_params.merge(args) - - args.delete(:id) - args[:milestone_title] = args.delete(:milestone) - args[:label_name] = args.delete(:labels) - args[:scope] = args[:scope].underscore if args[:scope] - - issues = IssuesFinder.new(current_user, args).execute - .with_api_entity_associations - issues.reorder(order_options_with_tie_breaker) - end - # rubocop: enable CodeReuse/ActiveRecord - if Gitlab.ee? params :issues_params_ee do optional :weight, types: [Integer, String], integer_none_any: true, desc: 'The weight of the issue' @@ -35,13 +20,14 @@ module API end params :issues_params do - optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names' + optional :labels, :label_name, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names' + optional :with_labels_data, type: Boolean, desc: 'Return more label data than just lable title', default: false optional :milestone, type: String, desc: 'Milestone title' optional :order_by, type: String, values: %w[created_at updated_at], default: 'created_at', desc: 'Return issues ordered by `created_at` or `updated_at` fields.' - optional :sort, type: String, values: %w[asc desc], default: 'desc', + optional :sort, type: String, default: 'desc', desc: 'Return issues sorted in `asc` or `desc` order.' - optional :milestone, type: String, desc: 'Return issues for a specific milestone' + optional :milestone, :milestone_title, type: String, desc: 'Return issues for a specific milestone' optional :iids, type: Array[Integer], desc: 'The IID array of issues' optional :search, type: String, desc: 'Search issues for text present in the title, description, or any combination of these' optional :in, type: String, desc: '`title`, `description`, or a string joining them with comma' @@ -50,12 +36,17 @@ module API optional :updated_after, type: DateTime, desc: 'Return issues updated after the specified time' optional :updated_before, type: DateTime, desc: 'Return issues updated before the specified time' optional :author_id, type: Integer, desc: 'Return issues which are authored by the user with the given ID' + optional :author_username, type: String, desc: 'Return issues which are authored by the user with the given username' optional :assignee_id, types: [Integer, String], integer_none_any: true, desc: 'Return issues which are assigned to the user with the given ID' + optional :assignee_username, type: Array[String], + desc: 'Return issues which are assigned to the user with the given username' optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], desc: 'Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`' optional :my_reaction_emoji, type: String, desc: 'Return issues reacted by the authenticated user by the given emoji' optional :confidential, type: Boolean, desc: 'Filter confidential or public issues' + optional :state, type: String, values: %w[opened closed all], default: 'all', + desc: 'Return opened, closed, or all issues' use :pagination use :issues_params_ee if Gitlab.ee? @@ -75,13 +66,25 @@ module API end end + desc "Get currently authenticated user's issues statistics" + params do + use :issues_params + optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], default: 'created_by_me', + desc: 'Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`' + end + get '/issues_statistics' do + authenticate! unless params[:scope] == 'all' + + stats = issues_statistics + + present stats, with: Grape::Presenters::Presenter + end + resource :issues do desc "Get currently authenticated user's issues" do success Entities::IssueBasic end params do - optional :state, type: String, values: %w[opened closed all], default: 'all', - desc: 'Return opened, closed, or all issues' use :issues_params optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], default: 'created_by_me', desc: 'Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`' @@ -92,6 +95,7 @@ module API options = { with: Entities::IssueBasic, + with_labels_data: declared_params[:with_labels_data], current_user: current_user, issuable_metadata: issuable_meta_data(issues, 'Issue') } @@ -108,8 +112,6 @@ module API success Entities::IssueBasic end params do - optional :state, type: String, values: %w[opened closed all], default: 'all', - desc: 'Return opened, closed, or all issues' use :issues_params end get ":id/issues" do @@ -119,12 +121,25 @@ module API options = { with: Entities::IssueBasic, + with_labels_data: declared_params[:with_labels_data], current_user: current_user, issuable_metadata: issuable_meta_data(issues, 'Issue') } present issues, options end + + desc 'Get statistics for the list of group issues' + params do + use :issues_params + end + get ":id/issues_statistics" do + group = find_group!(params[:id]) + + stats = issues_statistics(group_id: group.id, include_subgroups: true) + + present stats, with: Grape::Presenters::Presenter + end end params do @@ -137,8 +152,6 @@ module API success Entities::IssueBasic end params do - optional :state, type: String, values: %w[opened closed all], default: 'all', - desc: 'Return opened, closed, or all issues' use :issues_params end get ":id/issues" do @@ -148,6 +161,7 @@ module API options = { with: Entities::IssueBasic, + with_labels_data: declared_params[:with_labels_data], current_user: current_user, project: user_project, issuable_metadata: issuable_meta_data(issues, 'Issue') @@ -156,6 +170,18 @@ module API present issues, options end + desc 'Get statistics for the list of project issues' + params do + use :issues_params + end + get ":id/issues_statistics" do + project = find_project!(params[:id]) + + stats = issues_statistics(project_id: project.id) + + present stats, with: Grape::Presenters::Presenter + end + desc 'Get a single project issue' do success Entities::Issue end -- cgit v1.2.3 From a4fbf39eca4518598e893f6f1b81b8b69927c6f9 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Fri, 19 Apr 2019 10:55:36 +0300 Subject: Move issue details to from IssueBasic to Issue entity Cleanup IssueBasic entity to keep it basic and move extra attributes to Issue entity which contains more details --- lib/api/entities.rb | 27 +++++++++++++++++++-------- lib/api/helpers/issues_helpers.rb | 1 + lib/api/issues.rb | 12 ++++++------ 3 files changed, 26 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index a57c7e9f851..1f10dc6c0fc 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -542,13 +542,9 @@ module API class IssueBasic < ProjectEntity expose :closed_at expose :closed_by, using: Entities::UserBasic - expose :labels do |issue, options| + expose :labels do |issue| # Avoids an N+1 query since labels are preloaded - if options[:with_labels_data] - ::API::Entities::LabelBasic.represent(issue.labels.sort_by(&:title)) - else - issue.labels.map(&:title).sort - end + issue.labels.map(&:title).sort end expose :milestone, using: Entities::Milestone expose :assignees, :author, using: Entities::UserBasic @@ -564,8 +560,6 @@ module API expose :due_date expose :confidential expose :discussion_locked - expose(:has_tasks) {|issue, _| !issue.task_list_items.empty? } - expose :task_status, if: -> (issue, _) { !issue.task_list_items.empty? } expose :web_url do |issue| Gitlab::UrlBuilder.build(issue) @@ -579,6 +573,23 @@ module API class Issue < IssueBasic include ::API::Helpers::RelatedResourcesHelpers + expose :labels do |issue, options| + # Avoids an N+1 query since labels are preloaded + if options[:with_labels_data] + ::API::Entities::LabelBasic.represent(issue.labels.sort_by(&:title)) + else + issue.labels.map(&:title).sort + end + end + + expose(:has_tasks) do |issue, _| + !issue.task_list_items.empty? + end + + expose :task_status, if: -> (issue, _) do + !issue.task_list_items.empty? + end + expose :_links do expose :self do |issue| expose_url(api_v4_project_issue_path(id: issue.project_id, issue_iid: issue.iid)) diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb index 00aaf5243b7..12bbc598532 100644 --- a/lib/api/helpers/issues_helpers.rb +++ b/lib/api/helpers/issues_helpers.rb @@ -37,6 +37,7 @@ module API issues = finder.execute.with_api_entity_associations order_by = declared_params[:sort].present? && %w(asc desc).include?(declared_params[:sort].downcase) issues = issues.reorder(order_options_with_tie_breaker) if order_by + issues # rubocop: enable CodeReuse/ActiveRecord end diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 67da1c46480..6977657e356 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -82,7 +82,7 @@ module API resource :issues do desc "Get currently authenticated user's issues" do - success Entities::IssueBasic + success Entities::Issue end params do use :issues_params @@ -94,7 +94,7 @@ module API issues = paginate(find_issues) options = { - with: Entities::IssueBasic, + with: Entities::Issue, with_labels_data: declared_params[:with_labels_data], current_user: current_user, issuable_metadata: issuable_meta_data(issues, 'Issue') @@ -109,7 +109,7 @@ module API end resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do desc 'Get a list of group issues' do - success Entities::IssueBasic + success Entities::Issue end params do use :issues_params @@ -120,7 +120,7 @@ module API issues = paginate(find_issues(group_id: group.id, include_subgroups: true)) options = { - with: Entities::IssueBasic, + with: Entities::Issue, with_labels_data: declared_params[:with_labels_data], current_user: current_user, issuable_metadata: issuable_meta_data(issues, 'Issue') @@ -149,7 +149,7 @@ module API include TimeTrackingEndpoints desc 'Get a list of project issues' do - success Entities::IssueBasic + success Entities::Issue end params do use :issues_params @@ -160,7 +160,7 @@ module API issues = paginate(find_issues(project_id: project.id)) options = { - with: Entities::IssueBasic, + with: Entities::Issue, with_labels_data: declared_params[:with_labels_data], current_user: current_user, project: user_project, -- cgit v1.2.3 From f117c032ac6c414e6c1dfeab98184363c1f61608 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Wed, 24 Apr 2019 16:08:14 +0300 Subject: Add params validations and remove extra params support Remove label_name and milestone_title params support Add mutually_exclusive validation for author_id and author_username Add mutually_exclusive validation for assignee_id and assignee_username Add validation to allow single value for asignee_username on CE Add separate issue_stats_params helper for statistics params and reuse in issues_params. --- lib/api/helpers/issues_helpers.rb | 5 +--- lib/api/issues.rb | 41 ++++++++++++++++++---------- lib/api/validations/check_assignees_count.rb | 36 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 lib/api/validations/check_assignees_count.rb (limited to 'lib') diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb index 12bbc598532..fb791691069 100644 --- a/lib/api/helpers/issues_helpers.rb +++ b/lib/api/helpers/issues_helpers.rb @@ -24,7 +24,6 @@ module API args.delete(:id) args[:milestone_title] ||= args.delete(:milestone) - args[:milestone_title] ||= args.delete(:milestone_title) args[:label_name] ||= args.delete(:labels) args[:scope] = args[:scope].underscore if args[:scope] @@ -35,10 +34,8 @@ module API # rubocop: disable CodeReuse/ActiveRecord finder = issue_finder(args) issues = finder.execute.with_api_entity_associations - order_by = declared_params[:sort].present? && %w(asc desc).include?(declared_params[:sort].downcase) - issues = issues.reorder(order_options_with_tie_breaker) if order_by - issues + issues.reorder(order_options_with_tie_breaker) # rubocop: enable CodeReuse/ActiveRecord end diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 6977657e356..9fd2d959c22 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -19,15 +19,10 @@ module API end end - params :issues_params do - optional :labels, :label_name, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names' - optional :with_labels_data, type: Boolean, desc: 'Return more label data than just lable title', default: false + params :issues_stats_params do + optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names' optional :milestone, type: String, desc: 'Milestone title' - optional :order_by, type: String, values: %w[created_at updated_at], default: 'created_at', - desc: 'Return issues ordered by `created_at` or `updated_at` fields.' - optional :sort, type: String, default: 'desc', - desc: 'Return issues sorted in `asc` or `desc` order.' - optional :milestone, :milestone_title, type: String, desc: 'Return issues for a specific milestone' + optional :milestone, type: String, desc: 'Return issues for a specific milestone' optional :iids, type: Array[Integer], desc: 'The IID array of issues' optional :search, type: String, desc: 'Search issues for text present in the title, description, or any combination of these' optional :in, type: String, desc: '`title`, `description`, or a string joining them with comma' @@ -35,23 +30,39 @@ module API optional :created_before, type: DateTime, desc: 'Return issues created before the specified time' optional :updated_after, type: DateTime, desc: 'Return issues updated after the specified time' optional :updated_before, type: DateTime, desc: 'Return issues updated before the specified time' + optional :author_id, type: Integer, desc: 'Return issues which are authored by the user with the given ID' optional :author_username, type: String, desc: 'Return issues which are authored by the user with the given username' + mutually_exclusive :author_id, :author_username + optional :assignee_id, types: [Integer, String], integer_none_any: true, desc: 'Return issues which are assigned to the user with the given ID' - optional :assignee_username, type: Array[String], + optional :assignee_username, type: Array[String], check_assignees_count: true, + coerce_with: Validations::CheckAssigneesCount.coerce, desc: 'Return issues which are assigned to the user with the given username' + mutually_exclusive :assignee_id, :assignee_username + optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], desc: 'Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`' optional :my_reaction_emoji, type: String, desc: 'Return issues reacted by the authenticated user by the given emoji' optional :confidential, type: Boolean, desc: 'Filter confidential or public issues' - optional :state, type: String, values: %w[opened closed all], default: 'all', - desc: 'Return opened, closed, or all issues' - use :pagination use :issues_params_ee if Gitlab.ee? end + params :issues_params do + optional :with_labels_data, type: Boolean, desc: 'Return more label data than just lable title', default: false + optional :state, type: String, values: %w[opened closed all], default: 'all', + desc: 'Return opened, closed, or all issues' + optional :order_by, type: String, values: %w[created_at updated_at], default: 'created_at', + desc: 'Return issues ordered by `created_at` or `updated_at` fields.' + optional :sort, type: String, values: %w[asc desc], default: 'desc', + desc: 'Return issues sorted in `asc` or `desc` order.' + + use :issues_stats_params + use :pagination + end + params :issue_params do optional :description, type: String, desc: 'The description of an issue' optional :assignee_ids, type: Array[Integer], desc: 'The array of user IDs to assign issue' @@ -68,7 +79,7 @@ module API desc "Get currently authenticated user's issues statistics" params do - use :issues_params + use :issues_stats_params optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], default: 'created_by_me', desc: 'Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`' end @@ -131,7 +142,7 @@ module API desc 'Get statistics for the list of group issues' params do - use :issues_params + use :issues_stats_params end get ":id/issues_statistics" do group = find_group!(params[:id]) @@ -172,7 +183,7 @@ module API desc 'Get statistics for the list of project issues' params do - use :issues_params + use :issues_stats_params end get ":id/issues_statistics" do project = find_project!(params[:id]) diff --git a/lib/api/validations/check_assignees_count.rb b/lib/api/validations/check_assignees_count.rb new file mode 100644 index 00000000000..e19c88e97b1 --- /dev/null +++ b/lib/api/validations/check_assignees_count.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module API + module Validations + class CheckAssigneesCount < Grape::Validations::Base + def self.coerce + lambda do |value| + case value + when String + [value] + when Array + value + when CheckAssigneesCount + value + else + [] + end + end + end + + def validate_param!(attr_name, params) + unless param_allowed?(attr_name, params) + raise Grape::Exceptions::Validation, + params: [@scope.full_name(attr_name)], + message: "allows one value, but found #{params[attr_name].size}: #{params[attr_name].join(", ")}" + end + end + + private + + def param_allowed?(attr_name, params) + params[attr_name].size <= 1 + end + end + end +end -- cgit v1.2.3 From 9ff6edf690423a284f4d0ad924ff2a9a4285eb50 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Fri, 17 May 2019 12:46:33 +0300 Subject: Review updates and cleanup * Cleaned issues and issues_statistics docs * Renamed param with_labels_data to with_labels_details * Added spec for N+1 check when retrieving labels from issue * Refactoed CheckAssigneesCount validation class --- lib/api/entities.rb | 20 ++++++++------------ lib/api/helpers/issues_helpers.rb | 4 +--- lib/api/issues.rb | 22 ++++++++-------------- lib/api/validations/check_assignees_count.rb | 18 +++++++----------- 4 files changed, 24 insertions(+), 40 deletions(-) (limited to 'lib') diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 1f10dc6c0fc..625fada4f08 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -542,10 +542,15 @@ module API class IssueBasic < ProjectEntity expose :closed_at expose :closed_by, using: Entities::UserBasic - expose :labels do |issue| - # Avoids an N+1 query since labels are preloaded - issue.labels.map(&:title).sort + + expose :labels do |issue, options| + if options[:with_labels_details] + ::API::Entities::LabelBasic.represent(issue.labels.sort_by(&:title)) + else + issue.labels.map(&:title).sort + end end + expose :milestone, using: Entities::Milestone expose :assignees, :author, using: Entities::UserBasic @@ -573,15 +578,6 @@ module API class Issue < IssueBasic include ::API::Helpers::RelatedResourcesHelpers - expose :labels do |issue, options| - # Avoids an N+1 query since labels are preloaded - if options[:with_labels_data] - ::API::Entities::LabelBasic.represent(issue.labels.sort_by(&:title)) - else - issue.labels.map(&:title).sort - end - end - expose(:has_tasks) do |issue, _| !issue.task_list_items.empty? end diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb index fb791691069..fc66cec5341 100644 --- a/lib/api/helpers/issues_helpers.rb +++ b/lib/api/helpers/issues_helpers.rb @@ -31,12 +31,10 @@ module API end def find_issues(args = {}) - # rubocop: disable CodeReuse/ActiveRecord finder = issue_finder(args) issues = finder.execute.with_api_entity_associations - issues.reorder(order_options_with_tie_breaker) - # rubocop: enable CodeReuse/ActiveRecord + issues.reorder(order_options_with_tie_breaker) # rubocop: disable CodeReuse/ActiveRecord end def issues_statistics(args = {}) diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 9fd2d959c22..0b4da01f3c8 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -51,7 +51,7 @@ module API end params :issues_params do - optional :with_labels_data, type: Boolean, desc: 'Return more label data than just lable title', default: false + optional :with_labels_details, type: Boolean, desc: 'Return more label data than just lable title', default: false optional :state, type: String, values: %w[opened closed all], default: 'all', desc: 'Return opened, closed, or all issues' optional :order_by, type: String, values: %w[created_at updated_at], default: 'created_at', @@ -80,15 +80,13 @@ module API desc "Get currently authenticated user's issues statistics" params do use :issues_stats_params - optional :scope, type: String, values: %w[created-by-me assigned-to-me created_by_me assigned_to_me all], default: 'created_by_me', + optional :scope, type: String, values: %w[created_by_me assigned_to_me all], default: 'created_by_me', desc: 'Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`' end get '/issues_statistics' do authenticate! unless params[:scope] == 'all' - stats = issues_statistics - - present stats, with: Grape::Presenters::Presenter + present issues_statistics, with: Grape::Presenters::Presenter end resource :issues do @@ -106,7 +104,7 @@ module API options = { with: Entities::Issue, - with_labels_data: declared_params[:with_labels_data], + with_labels_details: declared_params[:with_labels_details], current_user: current_user, issuable_metadata: issuable_meta_data(issues, 'Issue') } @@ -132,7 +130,7 @@ module API options = { with: Entities::Issue, - with_labels_data: declared_params[:with_labels_data], + with_labels_details: declared_params[:with_labels_details], current_user: current_user, issuable_metadata: issuable_meta_data(issues, 'Issue') } @@ -147,9 +145,7 @@ module API get ":id/issues_statistics" do group = find_group!(params[:id]) - stats = issues_statistics(group_id: group.id, include_subgroups: true) - - present stats, with: Grape::Presenters::Presenter + present issues_statistics(group_id: group.id, include_subgroups: true), with: Grape::Presenters::Presenter end end @@ -172,7 +168,7 @@ module API options = { with: Entities::Issue, - with_labels_data: declared_params[:with_labels_data], + with_labels_details: declared_params[:with_labels_details], current_user: current_user, project: user_project, issuable_metadata: issuable_meta_data(issues, 'Issue') @@ -188,9 +184,7 @@ module API get ":id/issues_statistics" do project = find_project!(params[:id]) - stats = issues_statistics(project_id: project.id) - - present stats, with: Grape::Presenters::Presenter + present issues_statistics(project_id: project.id), with: Grape::Presenters::Presenter end desc 'Get a single project issue' do diff --git a/lib/api/validations/check_assignees_count.rb b/lib/api/validations/check_assignees_count.rb index e19c88e97b1..836ec936b31 100644 --- a/lib/api/validations/check_assignees_count.rb +++ b/lib/api/validations/check_assignees_count.rb @@ -6,12 +6,8 @@ module API def self.coerce lambda do |value| case value - when String - [value] - when Array - value - when CheckAssigneesCount - value + when String, Array + Array.wrap(value) else [] end @@ -19,11 +15,11 @@ module API end def validate_param!(attr_name, params) - unless param_allowed?(attr_name, params) - raise Grape::Exceptions::Validation, - params: [@scope.full_name(attr_name)], - message: "allows one value, but found #{params[attr_name].size}: #{params[attr_name].join(", ")}" - end + return if param_allowed?(attr_name, params) + + raise Grape::Exceptions::Validation, + params: [@scope.full_name(attr_name)], + message: "allows one value, but found #{params[attr_name].size}: #{params[attr_name].join(", ")}" end private -- cgit v1.2.3