Commit d12901d0 authored by Max Woolf's avatar Max Woolf

Merge branch 'sy-create-incidents-via-api' into 'master'

Add issue_type support for REST API

See merge request gitlab-org/gitlab!60687
parents 90dcc626 d847e797
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
# updated_after: datetime # updated_after: datetime
# updated_before: datetime # updated_before: datetime
# confidential: boolean # confidential: boolean
# issue_type: array of strings (one of Issue.issue_types) # issue_types: array of strings (one of Issue.issue_types)
# #
class IssuesFinder < IssuableFinder class IssuesFinder < IssuableFinder
CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::REPORTER CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::REPORTER
......
---
title: Add support for create, updating, and filtering issues based on issue type
in REST API
merge_request: 60687
author:
type: added
...@@ -62,6 +62,7 @@ GET /issues?state=opened ...@@ -62,6 +62,7 @@ GET /issues?state=opened
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ | | `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ |
| `iids[]` | integer array | no | Return only the issues having the given `iid` | | `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `in` | string | no | Modify the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description` | | `in` | string | no | Modify the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description` |
| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _(Introduced in [GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/260375))_ |
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ | | `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ | | `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. | | `milestone` | string | no | The milestone title. `None` lists all issues with no milestone. `Any` lists all issues that have an assigned milestone. |
...@@ -158,6 +159,7 @@ Example response: ...@@ -158,6 +159,7 @@ Example response:
"task_status": "10 of 15 tasks completed", "task_status": "10 of 15 tasks completed",
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"_links":{ "_links":{
"self":"http://gitlab.example.com/api/v4/projects/1/issues/76", "self":"http://gitlab.example.com/api/v4/projects/1/issues/76",
"notes":"http://gitlab.example.com/api/v4/projects/1/issues/76/notes", "notes":"http://gitlab.example.com/api/v4/projects/1/issues/76/notes",
...@@ -267,6 +269,7 @@ GET /groups/:id/issues?state=opened ...@@ -267,6 +269,7 @@ GET /groups/:id/issues?state=opened
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ | | `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user | | `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `iids[]` | integer array | no | Return only the issues having the given `iid` | | `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _(Introduced in [GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/260375))_ |
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ | | `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ | | `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `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. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
...@@ -361,6 +364,7 @@ Example response: ...@@ -361,6 +364,7 @@ Example response:
"task_status": "10 of 15 tasks completed", "task_status": "10 of 15 tasks completed",
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"_links":{ "_links":{
"self":"http://gitlab.example.com/api/v4/projects/4/issues/41", "self":"http://gitlab.example.com/api/v4/projects/4/issues/41",
"notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes", "notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes",
...@@ -469,6 +473,7 @@ GET /projects/:id/issues?state=opened ...@@ -469,6 +473,7 @@ GET /projects/:id/issues?state=opened
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ | | `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. _(Introduced in [GitLab 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/233420))_ |
| `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 |
| `iids[]` | integer array | no | Return only the issues having the given `iid` | | `iids[]` | integer array | no | Return only the issues having the given `iid` |
| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _(Introduced in [GitLab 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/260375))_ |
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ | | `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ | | `iteration_title` **(PREMIUM)** | string | no | Return issues assigned to the iteration with the given title. Similar to `iteration_id` and mutually exclusive with `iteration_id`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
| `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. `No+Label` (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. |
...@@ -569,6 +574,7 @@ Example response: ...@@ -569,6 +574,7 @@ Example response:
"task_status": "10 of 15 tasks completed", "task_status": "10 of 15 tasks completed",
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"_links":{ "_links":{
"self":"http://gitlab.example.com/api/v4/projects/4/issues/41", "self":"http://gitlab.example.com/api/v4/projects/4/issues/41",
"notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes", "notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes",
...@@ -729,6 +735,7 @@ Example response: ...@@ -729,6 +735,7 @@ Example response:
}, },
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"task_completion_status": { "task_completion_status": {
"count": 0, "count": 0,
"completed_count": 0 "completed_count": 0
...@@ -895,6 +902,7 @@ Example response: ...@@ -895,6 +902,7 @@ Example response:
}, },
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"_links": { "_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2", "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes", "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
...@@ -985,6 +993,7 @@ POST /projects/:id/issues ...@@ -985,6 +993,7 @@ POST /projects/:id/issues
| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) | | `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) |
| `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 |
| `iid` | integer/string | no | The internal ID of the project's issue (requires administrator or project owner rights) | | `iid` | integer/string | no | The internal ID of the project's issue (requires administrator or project owner rights) |
| `issue_type` | string | no | The type of issue. One of `issue`, `incident`, or `test_case`. Default is `issue`. |
| `labels` | string | no | Comma-separated label names for an issue | | `labels` | string | no | Comma-separated label names for an issue |
| `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This fills out the issue with a default description and mark all discussions as resolved. When passing a description or title, these values take precedence over the default values.| | `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This fills out the issue with a default description and mark all discussions as resolved. When passing a description or title, these values take precedence over the default values.|
| `milestone_id` | integer | no | The global ID of a milestone to assign issue | | `milestone_id` | integer | no | The global ID of a milestone to assign issue |
...@@ -1044,6 +1053,7 @@ Example response: ...@@ -1044,6 +1053,7 @@ Example response:
}, },
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"_links": { "_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2", "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes", "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
...@@ -1131,6 +1141,7 @@ At least one of the following parameters is required for the request to be succe ...@@ -1131,6 +1141,7 @@ At least one of the following parameters is required for the request to be succe
- `:description` - `:description`
- `:discussion_locked` - `:discussion_locked`
- `:due_date` - `:due_date`
- `:issue_type`
- `:labels` - `:labels`
- `:milestone_id` - `:milestone_id`
- `:state_event` - `:state_event`
...@@ -1152,6 +1163,7 @@ PUT /projects/:id/issues/:issue_iid ...@@ -1152,6 +1163,7 @@ PUT /projects/:id/issues/:issue_iid
| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) | | `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal in API version 5](https://gitlab.com/gitlab-org/gitlab/-/issues/35157)) |
| `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 |
| `issue_iid` | integer | yes | The internal ID of a project's issue | | `issue_iid` | integer | yes | The internal ID of a project's issue |
| `issue_type` | string | no | Updates the type of issue. One of `issue`, `incident`, or `test_case`. |
| `labels` | string | no | Comma-separated label names for an issue. Set to an empty string to unassign all labels. | | `labels` | string | no | Comma-separated label names for an issue. Set to an empty string to unassign all labels. |
| `milestone_id` | integer | no | The global ID of a milestone to assign the issue to. Set to `0` or provide an empty value to unassign a milestone.| | `milestone_id` | integer | no | The global ID of a milestone to assign the issue to. Set to `0` or provide an empty value to unassign a milestone.|
| `remove_labels`| string | no | Comma-separated label names to remove from an issue. | | `remove_labels`| string | no | Comma-separated label names to remove from an issue. |
...@@ -1219,6 +1231,7 @@ Example response: ...@@ -1219,6 +1231,7 @@ Example response:
}, },
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"_links": { "_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2", "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes", "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
...@@ -1405,6 +1418,7 @@ Example response: ...@@ -1405,6 +1418,7 @@ Example response:
}, },
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"_links": { "_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2", "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes", "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
...@@ -1549,6 +1563,7 @@ Example response: ...@@ -1549,6 +1563,7 @@ Example response:
}, },
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"_links": { "_links": {
"self": "http://gitlab.example.com/api/v4/projects/1/issues/2", "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
"notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes", "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
...@@ -1680,6 +1695,7 @@ Example response: ...@@ -1680,6 +1695,7 @@ Example response:
}, },
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"task_completion_status":{ "task_completion_status":{
"count":0, "count":0,
"completed_count":0 "completed_count":0
...@@ -1788,6 +1804,7 @@ Example response: ...@@ -1788,6 +1804,7 @@ Example response:
}, },
"confidential": false, "confidential": false,
"discussion_locked": false, "discussion_locked": false,
"issue_type": "issue",
"task_completion_status":{ "task_completion_status":{
"count":0, "count":0,
"completed_count":0 "completed_count":0
...@@ -2013,7 +2030,7 @@ If the project is private or the issue is confidential, you need to provide cred ...@@ -2013,7 +2030,7 @@ If the project is private or the issue is confidential, you need to provide cred
The preferred way to do this, is by using [personal access tokens](../user/profile/personal_access_tokens.md). The preferred way to do this, is by using [personal access tokens](../user/profile/personal_access_tokens.md).
```plaintext ```plaintext
GET /projects/:id/issues/:issue_id/related_merge_requests GET /projects/:id/issues/:issue_iid/related_merge_requests
``` ```
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
......
...@@ -471,7 +471,7 @@ RSpec.describe API::Issues, :mailer do ...@@ -471,7 +471,7 @@ RSpec.describe API::Issues, :mailer do
end end
end end
describe 'PUT /projects/:id/issues/:issue_id to update weight' do describe 'PUT /projects/:id/issues/:issue_iid to update weight' do
let!(:issue) { create :issue, author: user, project: project } let!(:issue) { create :issue, author: user, project: project }
it 'updates an issue with no weight' do it 'updates an issue with no weight' do
...@@ -531,14 +531,14 @@ RSpec.describe API::Issues, :mailer do ...@@ -531,14 +531,14 @@ RSpec.describe API::Issues, :mailer do
end end
end end
describe 'PUT /projects/:id/issues/:issue_id to update epic' do describe 'PUT /projects/:id/issues/:issue_iid to update epic' do
it_behaves_like 'with epic parameter' do it_behaves_like 'with epic parameter' do
let(:issue_with_epic) { create(:issue, project: target_project) } let(:issue_with_epic) { create(:issue, project: target_project) }
let(:request) { put api("/projects/#{target_project.id}/issues/#{issue_with_epic.iid}", user), params: params } let(:request) { put api("/projects/#{target_project.id}/issues/#{issue_with_epic.iid}", user), params: params }
end end
end end
describe 'POST /projects/:id/issues/:issue_id/metric_images' do describe 'POST /projects/:id/issues/:issue_iid/metric_images' do
include WorkhorseHelpers include WorkhorseHelpers
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
...@@ -643,7 +643,7 @@ RSpec.describe API::Issues, :mailer do ...@@ -643,7 +643,7 @@ RSpec.describe API::Issues, :mailer do
end end
end end
describe 'GET /projects/:id/issues/:issue_id/metric_images' do describe 'GET /projects/:id/issues/:issue_iid/metric_images' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
let_it_be(:project) do let_it_be(:project) do
...@@ -701,7 +701,7 @@ RSpec.describe API::Issues, :mailer do ...@@ -701,7 +701,7 @@ RSpec.describe API::Issues, :mailer do
end end
end end
describe 'DELETE /projects/:id/issues/:issue_id/metric_images/:metric_image_id' do describe 'DELETE /projects/:id/issues/:issue_iid/metric_images/:metric_image_id' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
let_it_be(:project) do let_it_be(:project) do
......
...@@ -36,6 +36,7 @@ module API ...@@ -36,6 +36,7 @@ module API
expose :due_date expose :due_date
expose :confidential expose :confidential
expose :discussion_locked expose :discussion_locked
expose :issue_type
expose :web_url do |issue| expose :web_url do |issue|
Gitlab::UrlBuilder.build(issue) Gitlab::UrlBuilder.build(issue)
......
...@@ -28,7 +28,8 @@ module API ...@@ -28,7 +28,8 @@ module API
:remove_labels, :remove_labels,
:milestone_id, :milestone_id,
:state_event, :state_event,
:title :title,
:issue_type
] ]
end end
...@@ -47,6 +48,7 @@ module API ...@@ -47,6 +48,7 @@ module API
args[:not][:label_name] ||= args[:not]&.delete(:labels) args[:not][:label_name] ||= args[:not]&.delete(:labels)
args[:scope] = args[:scope].underscore if args[:scope] args[:scope] = args[:scope].underscore if args[:scope]
args[:sort] = "#{args[:order_by]}_#{args[:sort]}" args[:sort] = "#{args[:order_by]}_#{args[:sort]}"
args[:issue_types] ||= args.delete(:issue_type)
IssuesFinder.new(current_user, args) IssuesFinder.new(current_user, args)
end end
......
...@@ -74,6 +74,7 @@ module API ...@@ -74,6 +74,7 @@ module API
desc: 'Return issues sorted in `asc` or `desc` order.' desc: 'Return issues sorted in `asc` or `desc` order.'
optional :due_date, type: String, values: %w[0 overdue week month next_month_and_previous_two_weeks] << '', optional :due_date, type: String, values: %w[0 overdue week month next_month_and_previous_two_weeks] << '',
desc: 'Return issues that have no due date (`0`), or whose due date is this week, this month, between two weeks ago and next month, or which are overdue. Accepts: `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`, `0`' desc: 'Return issues that have no due date (`0`), or whose due date is this week, this month, between two weeks ago and next month, or which are overdue. Accepts: `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`, `0`'
optional :issue_type, type: String, values: Issue.issue_types.keys, desc: "The type of the issue. Accepts: #{Issue.issue_types.keys.join(', ')}"
use :issues_stats_params use :issues_stats_params
use :pagination use :pagination
...@@ -90,6 +91,7 @@ module API ...@@ -90,6 +91,7 @@ module API
optional :due_date, type: String, desc: 'Date string in the format YEAR-MONTH-DAY' optional :due_date, type: String, desc: 'Date string in the format YEAR-MONTH-DAY'
optional :confidential, type: Boolean, desc: 'Boolean parameter if the issue should be confidential' optional :confidential, type: Boolean, desc: 'Boolean parameter if the issue should be confidential'
optional :discussion_locked, type: Boolean, desc: " Boolean parameter indicating if the issue's discussion is locked" optional :discussion_locked, type: Boolean, desc: " Boolean parameter indicating if the issue's discussion is locked"
optional :issue_type, type: String, values: Issue.issue_types.keys, desc: "The type of the issue. Accepts: #{Issue.issue_types.keys.join(', ')}"
use :optional_issue_params_ee use :optional_issue_params_ee
end end
......
...@@ -115,6 +115,7 @@ RSpec.describe API::Issues do ...@@ -115,6 +115,7 @@ RSpec.describe API::Issues do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response.dig('author', 'id')).to eq(issue.author.id) expect(json_response.dig('author', 'id')).to eq(issue.author.id)
expect(json_response['description']).to eq(issue.description) expect(json_response['description']).to eq(issue.description)
expect(json_response['issue_type']).to eq('issue')
end end
end end
...@@ -378,6 +379,14 @@ RSpec.describe API::Issues do ...@@ -378,6 +379,14 @@ RSpec.describe API::Issues do
expect_paginated_array_response([issue.id, closed_issue.id]) expect_paginated_array_response([issue.id, closed_issue.id])
end end
it 'returns issues with a given issue_type' do
issue2 = create(:incident, project: project)
get api('/issues', user), params: { issue_type: 'incident' }
expect_paginated_array_response(issue2.id)
end
it 'returns issues matching given search string for title' do it 'returns issues matching given search string for title' do
get api('/issues', user), params: { search: issue.title } get api('/issues', user), params: { search: issue.title }
...@@ -939,7 +948,17 @@ RSpec.describe API::Issues do ...@@ -939,7 +948,17 @@ RSpec.describe API::Issues do
end end
end end
describe 'PUT /projects/:id/issues/:issue_id' do describe "POST /projects/:id/issues" do
it 'creates a new project issue' do
post api("/projects/#{project.id}/issues", user), params: { title: 'new issue' }
expect(response).to have_gitlab_http_status(:created)
expect(json_response['title']).to eq('new issue')
expect(json_response['issue_type']).to eq('issue')
end
end
describe 'PUT /projects/:id/issues/:issue_iid' do
it_behaves_like 'issuable update endpoint' do it_behaves_like 'issuable update endpoint' do
let(:entity) { issue } let(:entity) { issue }
end end
...@@ -971,6 +990,14 @@ RSpec.describe API::Issues do ...@@ -971,6 +990,14 @@ RSpec.describe API::Issues do
expect(ResourceLabelEvent.last.created_at).to be_like_time(fixed_time) expect(ResourceLabelEvent.last.created_at).to be_like_time(fixed_time)
end end
end end
describe 'issue_type param' do
it 'allows issue type to be converted' do
put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { issue_type: 'incident' }
expect(issue.reload.incident?).to be(true)
end
end
end end
describe 'DELETE /projects/:id/issues/:issue_iid' do describe 'DELETE /projects/:id/issues/:issue_iid' do
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
RSpec.shared_examples 'issuable update endpoint' do RSpec.shared_examples 'issuable update endpoint' do
let(:area) { entity.class.name.underscore.pluralize } let(:area) { entity.class.name.underscore.pluralize }
describe 'PUT /projects/:id/issues/:issue_id' do describe 'PUT /projects/:id/issues/:issue_iid' do
let(:url) { "/projects/#{project.id}/#{area}/#{entity.iid}" } let(:url) { "/projects/#{project.id}/#{area}/#{entity.iid}" }
it 'clears labels when labels param is nil' do it 'clears labels when labels param is nil' do
......
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