summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru Croitor <acroitor@gitlab.com>2019-05-17 12:46:33 +0300
committerAlexandru Croitor <acroitor@gitlab.com>2019-05-17 13:56:25 +0300
commit9ff6edf690423a284f4d0ad924ff2a9a4285eb50 (patch)
tree9b770e812bd923a664a0c2166935794dcd3dffb3
parentf117c032ac6c414e6c1dfeab98184363c1f61608 (diff)
downloadgitlab-ce-ce-57402-add-issues-statistics-api-endpoints.tar.gz
* 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
-rw-r--r--doc/api/issues.md6
-rw-r--r--doc/api/issues_statistics.md63
-rw-r--r--lib/api/entities.rb20
-rw-r--r--lib/api/helpers/issues_helpers.rb4
-rw-r--r--lib/api/issues.rb22
-rw-r--r--lib/api/validations/check_assignees_count.rb18
-rw-r--r--spec/requests/api/issues/issues_spec.rb51
-rw-r--r--spec/support/shared_examples/requests/api/issues_shared_example_spec.rb6
8 files changed, 93 insertions, 97 deletions
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 936caef7601..4fb3626f637 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -39,7 +39,7 @@ GET /issues?confidential=true
| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `state` | string | no | Return `all` issues or just those that are `opened` or `closed` |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
-| `with_labels_data` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:text_color`. Default is `false`. |
+| `with_labels_details`| Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:text_color`. Default is `false`. |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ |
@@ -170,7 +170,7 @@ GET /groups/:id/issues?confidential=true
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `state` | string | no | Return all issues or just those that are `opened` or `closed` |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
-| `with_labels_data` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:text_color`. Default is `false`. |
+| `with_labels_details`| Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:text_color`. Default is `false`. |
| `iids[]` | Array[integer] | no | Return only the issues having the given `iid` |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
@@ -301,7 +301,7 @@ GET /projects/:id/issues?confidential=true
| `iids[]` | Array[integer] | no | Return only the milestone having the given `iid` |
| `state` | string | no | Return all issues or just those that are `opened` or `closed` |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
-| `with_labels_data` | Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:text_color`. Default is `false`. |
+| `with_labels_details`| Boolean | no | If `true`, response will return more details for each label in labels field: `:name`, `:color`, `:description`, `:text_color`. Default is `false`. |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ |
diff --git a/doc/api/issues_statistics.md b/doc/api/issues_statistics.md
index 1eeb1338104..82bc9c142cc 100644
--- a/doc/api/issues_statistics.md
+++ b/doc/api/issues_statistics.md
@@ -28,14 +28,14 @@ GET /issues_statistics?confidential=true
| Attribute | Type | Required | Description |
| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
+| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
-| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
-| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ |
-| `author_username` | string | no | Return issues created by the given `username`. Simillar to `author_id` and mutually exclusive with `author_id`. |
-| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. _([Introduced][ce-13004] in GitLab 9.5)_ |
-| `assignee_username` | Array[String] | no | Return issues assigned to the given `username`. Simillar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid param error will be returned otherwise. |
-| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced][ce-14016] in GitLab 10.0)_ |
+| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me` |
+| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
+| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
+| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
+| `assignee_username` | Array[String] | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid param error will be returned otherwise. |
+| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `iids[]` | Array[integer] | no | Return only the issues having the given `iid` |
| `search` | string | no | Search issues against their `title` and `description` |
| `in` | string | no | Modify the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description` |
@@ -63,13 +63,9 @@ Example response:
}
```
-**Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API.
+## Get group issues statistics
-**Note**: The `closed_by` attribute was [introduced in GitLab 10.6][ce-17042]. This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
-
-## List group issues
-
-Get a list of a group's issues.
+Gets issues count statistics for given group.
```
GET /groups/:id/issues_statistics
@@ -89,15 +85,15 @@ GET /groups/:id/issues_statistics?confidential=true
| Attribute | Type | Required | Description |
| ------------------- | ---------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
-| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
+| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. |
| `iids[]` | Array[integer] | no | Return only the issues having the given `iid` |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
-| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
-| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ |
-| `author_username` | string | no | Return issues created by the given `username`. Simillar to `author_id` and mutually exclusive with `author_id`. |
-| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. _([Introduced][ce-13004] in GitLab 9.5)_ |
-| `assignee_username` | Array[String] | no | Return issues assigned to the given `username`. Simillar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid param error will be returned otherwise. |
-| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced][ce-14016] in GitLab 10.0)_ |
+| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. |
+| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
+| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
+| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
+| `assignee_username` | Array[String] | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid param error will be returned otherwise. |
+| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `search` | string | no | Search group issues against their `title` and `description` |
| `created_after` | datetime | no | Return issues created on or after the given time |
| `created_before` | datetime | no | Return issues created on or before the given time |
@@ -123,13 +119,9 @@ Example response:
}
```
-**Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API.
-
-**Note**: The `closed_by` attribute was [introduced in GitLab 10.6][ce-17042]. This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
-
-## List project issues
+## Get project issues statistics
-Get a list of a project's issues.
+Gets issues count statistics for given project.
```
GET /projects/:id/issues_statistics
@@ -150,14 +142,14 @@ GET /projects/:id/issues_statistics?confidential=true
| ------------------- | ---------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `iids[]` | Array[integer] | no | Return only the milestone having the given `iid` |
-| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
+| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `None` lists all issues with no labels. `Any` lists all issues with at least one label. |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
-| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`.<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
-| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ |
-| `author_username` | string | no | Return issues created by the given `username`. Simillar to `author_id` and mutually exclusive with `author_id`. |
-| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. _([Introduced][ce-13004] in GitLab 9.5)_ |
-| `assignee_username` | Array[String] | no | Return issues assigned to the given `username`. Simillar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid param error will be returned otherwise. |
-| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced][ce-14016] in GitLab 10.0)_ |
+| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. |
+| `author_id` | integer | no | Return issues created by the given user `id`. Mutually exclusive with `author_username`. Combine with `scope=all` or `scope=assigned_to_me`. |
+| `author_username` | string | no | Return issues created by the given `username`. Similar to `author_id` and mutually exclusive with `author_id`. |
+| `assignee_id` | integer | no | Return issues assigned to the given user `id`. Mutually exclusive with `assignee_username`. `None` returns unassigned issues. `Any` returns issues with an assignee. |
+| `assignee_username` | Array[String] | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid param error will be returned otherwise. |
+| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `search` | string | no | Search project issues against their `title` and `description` |
| `created_after` | datetime | no | Return issues created on or after the given time |
| `created_before` | datetime | no | Return issues created on or before the given time |
@@ -183,8 +175,3 @@ Example response:
}
}
```
-
-**Note**: `assignee` column is deprecated, now we show it as a single-sized array `assignees` to conform to the GitLab EE API.
-
-**Note**: The `closed_by` attribute was [introduced in GitLab 10.6][ce-17042]. This value will only be present for issues which were closed after GitLab 10.6 and when the user account that closed the issue still exists.
-
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
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index 24c53d9c68f..9b9cc778fb3 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -122,25 +122,25 @@ describe API::Issues do
expect_paginated_array_response([issue.id, closed_issue.id])
end
- it 'returns authentication error without any scope' do
- get api('/issues_statistics')
+ context 'issues_statistics' do
+ it 'returns authentication error without any scope' do
+ get api('/issues_statistics')
- expect(response).to have_http_status(401)
- end
+ expect(response).to have_http_status(401)
+ end
- it 'returns authentication error when scope is assigned-to-me' do
- get api('/issues_statistics'), params: { scope: 'assigned-to-me' }
+ it 'returns authentication error when scope is assigned_to_me' do
+ get api('/issues_statistics'), params: { scope: 'assigned_to_me' }
- expect(response).to have_http_status(401)
- end
+ expect(response).to have_http_status(401)
+ end
- it 'returns authentication error when scope is created-by-me' do
- get api('/issues_statistics'), params: { scope: 'created-by-me' }
+ it 'returns authentication error when scope is created_by_me' do
+ get api('/issues_statistics'), params: { scope: 'created_by_me' }
- expect(response).to have_http_status(401)
- end
+ expect(response).to have_http_status(401)
+ end
- context 'issues_statistics' do
context 'no state is treated as all state' do
let(:params) { {} }
let(:counts) { { all: 2, closed: 1, opened: 1 } }
@@ -386,6 +386,31 @@ describe API::Issues do
end
context 'filter by labels or label_name param' do
+ context 'N+1' do
+ let(:label_b) { create(:label, title: 'foo', project: project) }
+ let(:label_c) { create(:label, title: 'bar', project: project) }
+
+ before do
+ create(:label_link, label: label_b, target: issue)
+ create(:label_link, label: label_c, target: issue)
+ end
+ it 'tests N+1' do
+ control = ActiveRecord::QueryRecorder.new do
+ get api('/issues', user), params: { labels: [label.title, label_b.title, label_c.title] }
+ end
+
+ label_d = create(:label, title: 'dar', project: project)
+ label_e = create(:label, title: 'ear', project: project)
+ create(:label_link, label: label_d, target: issue)
+ create(:label_link, label: label_e, target: issue)
+
+ expect do
+ get api('/issues', user), params: { labels: [label.title, label_b.title, label_c.title] }
+ end.not_to exceed_query_limit(control)
+ expect(issue.labels.count).to eq(5)
+ end
+ end
+
it 'returns an array of labeled issues' do
get api('/issues', user), params: { labels: label.title }
diff --git a/spec/support/shared_examples/requests/api/issues_shared_example_spec.rb b/spec/support/shared_examples/requests/api/issues_shared_example_spec.rb
index d1c8e2208a3..1133e95e44e 100644
--- a/spec/support/shared_examples/requests/api/issues_shared_example_spec.rb
+++ b/spec/support/shared_examples/requests/api/issues_shared_example_spec.rb
@@ -28,15 +28,15 @@ shared_examples 'labeled issues with labels and label_name params' do
it_behaves_like 'returns label names'
end
- context 'when with_labels_data provided' do
+ context 'when with_labels_details provided' do
context 'array of labeled issues when all labels match' do
- let(:params) { { labels: "#{label.title},#{label_b.title},#{label_c.title}", with_labels_data: true } }
+ let(:params) { { labels: "#{label.title},#{label_b.title},#{label_c.title}", with_labels_details: true } }
it_behaves_like 'returns basic label entity'
end
context 'array of labeled issues when all labels match with labels param as array' do
- let(:params) { { labels: [label.title, label_b.title, label_c.title], with_labels_data: true } }
+ let(:params) { { labels: [label.title, label_b.title, label_c.title], with_labels_details: true } }
it_behaves_like 'returns basic label entity'
end