Commit a62c8d04 authored by Winnie Hellmann's avatar Winnie Hellmann Committed by Sean McGivern

Expose epic_iid parameter in issues API

parent 494cb30f
...@@ -615,6 +615,7 @@ POST /projects/:id/issues ...@@ -615,6 +615,7 @@ POST /projects/:id/issues
| `merge_request_to_resolve_discussions_of` | integer | no | The IID of a merge request in which to resolve all issues. This will fill the issue with a default description and mark all discussions as resolved. When passing a description or title, these values will 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 will fill the issue with a default description and mark all discussions as resolved. When passing a description or title, these values will take precedence over the default values.|
| `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. | | `discussion_to_resolve` | string | no | The ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion as resolved. Use in combination with `merge_request_to_resolve_discussions_of`. |
| `weight` **(STARTER)** | integer | no | The weight of the issue. Valid values are greater than or equal to 0. | | `weight` **(STARTER)** | integer | no | The weight of the issue. Valid values are greater than or equal to 0. |
| `epic_iid` **(ULTIMATE)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. |
```bash ```bash
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues?title=Issues%20with%20auth&labels=bug curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues?title=Issues%20with%20auth&labels=bug
...@@ -716,6 +717,7 @@ PUT /projects/:id/issues/:issue_iid ...@@ -716,6 +717,7 @@ PUT /projects/:id/issues/:issue_iid
| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` | | `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` |
| `weight` **(STARTER)** | integer | no | The weight of the issue. Valid values are greater than or equal to 0. 0 | | `weight` **(STARTER)** | integer | no | The weight of the issue. Valid values are greater than or equal to 0. 0 |
| `discussion_locked` | boolean | no | Flag indicating if the issue's discussion is locked. If the discussion is locked only project members can add or edit comments. | | `discussion_locked` | boolean | no | Flag indicating if the issue's discussion is locked. If the discussion is locked only project members can add or edit comments. |
| `epic_iid` **(ULTIMATE)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. |
```bash ```bash
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues/85?state_event=close curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/issues/85?state_event=close
......
...@@ -5,6 +5,18 @@ module EE ...@@ -5,6 +5,18 @@ module EE
module CreateService module CreateService
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
override :filter_params
def filter_params(issue)
epic_iid = params.delete(:epic_iid)
group = issue.project.group
if epic_iid.present? && group && can?(current_user, :admin_epic, group)
finder = EpicsFinder.new(current_user, group_id: group.id)
params[:epic] = finder.find_by!(iid: epic_iid) # rubocop: disable CodeReuse/ActiveRecord
end
super
end
override :before_create override :before_create
def before_create(issue) def before_create(issue)
handle_issue_epic_link(issue) handle_issue_epic_link(issue)
......
...@@ -17,6 +17,18 @@ module EE ...@@ -17,6 +17,18 @@ module EE
result result
end end
override :filter_params
def filter_params(issue)
epic_iid = params.delete(:epic_iid)
group = issue.project.group
if epic_iid.present? && group && can?(current_user, :admin_epic, group)
finder = EpicsFinder.new(current_user, group_id: group.id)
params[:epic] = finder.find_by!(iid: epic_iid) # rubocop: disable CodeReuse/ActiveRecord
end
super
end
private private
def handle_epic(issue) def handle_epic(issue)
......
---
title: Add epic_iid parameter to issues API
merge_request: 15640
author:
type: changed
...@@ -9,6 +9,7 @@ module EE ...@@ -9,6 +9,7 @@ module EE
prepended do prepended do
params :optional_issue_params_ee do params :optional_issue_params_ee do
optional :weight, type: Integer, desc: 'The weight of the issue' optional :weight, type: Integer, desc: 'The weight of the issue'
optional :epic_iid, type: Integer, desc: 'The IID of an epic to associate the issue with'
end end
params :optional_issues_params_ee do params :optional_issues_params_ee do
...@@ -21,7 +22,7 @@ module EE ...@@ -21,7 +22,7 @@ module EE
override :update_params_at_least_one_of override :update_params_at_least_one_of
def update_params_at_least_one_of def update_params_at_least_one_of
[*super, :weight] [*super, :weight, :epic_iid]
end end
override :sort_options override :sort_options
......
...@@ -42,7 +42,7 @@ describe API::Issues, :mailer do ...@@ -42,7 +42,7 @@ describe API::Issues, :mailer do
it 'contains epic_iid in response' do it 'contains epic_iid in response' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:success)
expect(epic_issue_response_for(epic_issue)['epic_iid']).to eq(epic.iid) expect(epic_issue_response_for(epic_issue)['epic_iid']).to eq(epic.iid)
end end
end end
...@@ -55,12 +55,57 @@ describe API::Issues, :mailer do ...@@ -55,12 +55,57 @@ describe API::Issues, :mailer do
it 'does not contain epic_iid in response' do it 'does not contain epic_iid in response' do
subject subject
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(:success)
expect(epic_issue_response_for(epic_issue)).not_to have_key('epic_iid') expect(epic_issue_response_for(epic_issue)).not_to have_key('epic_iid')
end end
end end
end end
shared_examples 'sets epic_iid' do
context 'with epics feature' do
before do
stub_licensed_features(epics: true)
end
it 'sets epic on issue' do
subject
expect(epic_issue.epic).to eq(epic)
end
end
context 'without epics feature' do
before do
stub_licensed_features(epics: false)
end
it 'does not set epic on issue' do
subject
expect(epic_issue.epic).not_to eq(epic)
end
end
end
shared_examples 'ignores epic_iid' do
before do
stub_licensed_features(epics: true)
end
it 'does not contain epic_iid in response' do
subject
expect(response).to have_gitlab_http_status(:success)
expect(epic_issue_response_for(epic_issue)).not_to have_key('epic_iid')
end
it 'does not set epic on issue' do
subject
expect(epic_issue.epic).not_to eq(epic)
end
end
describe "GET /issues" do describe "GET /issues" do
context "when authenticated" do context "when authenticated" do
it 'matches V4 response schema' do it 'matches V4 response schema' do
...@@ -221,6 +266,28 @@ describe API::Issues, :mailer do ...@@ -221,6 +266,28 @@ describe API::Issues, :mailer do
expect(json_response['assignee']['name']).to eq(user2.name) expect(json_response['assignee']['name']).to eq(user2.name)
expect(json_response['assignees'].first['name']).to eq(user2.name) expect(json_response['assignees'].first['name']).to eq(user2.name)
end end
context 'with epic parameter' do
let(:epic_issue) { Issue.last }
let(:params) { { title: 'issue with epic', epic_iid: epic.iid } }
context 'for a group project' do
subject { post api("/projects/#{group_project.id}/issues", user), params: params }
before do
group.add_owner(user)
end
include_examples 'exposes epic_iid'
include_examples 'sets epic_iid'
end
context 'for a user project' do
subject { post api("/projects/#{project.id}/issues", user), params: params }
include_examples 'ignores epic_iid'
end
end
end end
describe 'PUT /projects/:id/issues/:issue_id to update weight' do describe 'PUT /projects/:id/issues/:issue_id to update weight' do
...@@ -271,6 +338,29 @@ describe API::Issues, :mailer do ...@@ -271,6 +338,29 @@ describe API::Issues, :mailer do
end end
end end
describe 'PUT /projects/:id/issues/:issue_id to update epic' do
context 'for a group project' do
let!(:epic_issue) { create(:issue, project: group_project) }
subject { put api("/projects/#{group_project.id}/issues/#{epic_issue.iid}", user), params: { epic_iid: epic.iid } }
before do
group.add_owner(user)
end
include_examples 'exposes epic_iid'
include_examples 'sets epic_iid'
end
context 'for a user project' do
let!(:epic_issue) { create(:issue, project: project) }
subject { put api("/projects/#{project.id}/issues/#{epic_issue.iid}", user), params: { epic_iid: epic.iid } }
include_examples 'ignores epic_iid'
end
end
private private
def epic_issue_response_for(epic_issue) def epic_issue_response_for(epic_issue)
......
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