From 34b9cc9674554155af49c9a7fe60aaeba72bb23d Mon Sep 17 00:00:00 2001 From: Brent Greeff Date: Fri, 5 Jan 2018 15:21:53 +0000 Subject: [PATCH] API: get participants from merge_requests & issues --- ...86-get-participants-from-issues-mr-api.yml | 5 +++ doc/api/issues.md | 39 +++++++++++++++++++ doc/api/merge_requests.md | 35 +++++++++++++++++ lib/api/issues.rb | 13 +++++++ lib/api/merge_requests.rb | 10 +++++ spec/requests/api/issues_spec.rb | 12 ++++++ spec/requests/api/merge_requests_spec.rb | 6 +++ .../api/issuable_participants_examples.rb | 29 ++++++++++++++ 8 files changed, 149 insertions(+) create mode 100644 changelogs/unreleased/issues-40986-get-participants-from-issues-mr-api.yml create mode 100644 spec/support/shared_examples/requests/api/issuable_participants_examples.rb diff --git a/changelogs/unreleased/issues-40986-get-participants-from-issues-mr-api.yml b/changelogs/unreleased/issues-40986-get-participants-from-issues-mr-api.yml new file mode 100644 index 00000000000..4cac87b0cdb --- /dev/null +++ b/changelogs/unreleased/issues-40986-get-participants-from-issues-mr-api.yml @@ -0,0 +1,5 @@ +--- +title: 'API: get participants from merge_requests & issues' +merge_request: 16187 +author: Brent Greeff +type: added diff --git a/doc/api/issues.md b/doc/api/issues.md index d2fefbe68aa..da89db17cd9 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -1124,6 +1124,45 @@ Example response: ``` +## Participants on issues + +``` +GET /projects/:id/issues/:issue_iid/participants +``` + +| Attribute | Type | Required | Description | +|-------------|---------|----------|--------------------------------------| +| `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 | + +```bash +curl --request GET --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/issues/93/participants +``` + +Example response: + +```json +[ + { + "id": 1, + "name": "John Doe1", + "username": "user1", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/c922747a93b40d1ea88262bf1aebee62?s=80&d=identicon", + "web_url": "http://localhost/user1" + }, + { + "id": 5, + "name": "John Doe5", + "username": "user5", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/4aea8cf834ed91844a2da4ff7ae6b491?s=80&d=identicon", + "web_url": "http://localhost/user5" + } +] +``` + + ## Comments on issues Comments are done via the [notes](notes.md) resource. diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 4d3592e8f71..24afcef9a31 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -308,6 +308,41 @@ Parameters: } ``` +## Get single MR participants + +Get a list of merge request participants. + +``` +GET /projects/:id/merge_requests/:merge_request_iid/participants +``` + +Parameters: + +- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user +- `merge_request_iid` (required) - The internal ID of the merge request + + +```json +[ + { + "id": 1, + "name": "John Doe1", + "username": "user1", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/c922747a93b40d1ea88262bf1aebee62?s=80&d=identicon", + "web_url": "http://localhost/user1" + }, + { + "id": 2, + "name": "John Doe2", + "username": "user2", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/10fc7f102be8de7657fb4d80898bbfe3?s=80&d=identicon", + "web_url": "http://localhost/user2" + }, +] +``` + ## Get single MR commits Get a list of merge request commits. diff --git a/lib/api/issues.rb b/lib/api/issues.rb index b29c5848aef..7aa10631d53 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -277,6 +277,19 @@ module API present paginate(merge_requests), with: Entities::MergeRequestBasic, current_user: current_user, project: user_project end + desc 'List participants for an issue' do + success Entities::UserBasic + end + params do + requires :issue_iid, type: Integer, desc: 'The internal ID of a project issue' + end + get ':id/issues/:issue_iid/participants' do + issue = find_project_issue(params[:issue_iid]) + participants = ::Kaminari.paginate_array(issue.participants) + + present paginate(participants), with: Entities::UserBasic, current_user: current_user, project: user_project + end + desc 'Get the user agent details for an issue' do success Entities::UserAgentDetail end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 02f2b75ab9d..8f665b39fa8 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -185,6 +185,16 @@ module API present merge_request, with: Entities::MergeRequest, current_user: current_user, project: user_project end + desc 'Get the participants of a merge request' do + success Entities::UserBasic + end + get ':id/merge_requests/:merge_request_iid/participants' do + merge_request = find_merge_request_with_access(params[:merge_request_iid]) + participants = ::Kaminari.paginate_array(merge_request.participants) + + present paginate(participants), with: Entities::UserBasic + end + desc 'Get the commits of a merge request' do success Entities::Commit end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index 00d9c795619..320217f2032 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -1582,4 +1582,16 @@ describe API::Issues, :mailer do expect(json_response).to be_an Array expect(json_response.length).to eq(size) if size end + + describe 'GET projects/:id/issues/:issue_iid/participants' do + it_behaves_like 'issuable participants endpoint' do + let(:entity) { issue } + end + + it 'returns 404 if the issue is confidential' do + post api("/projects/#{project.id}/issues/#{confidential_issue.iid}/participants", non_member) + + expect(response).to have_gitlab_http_status(404) + end + end end diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index ef3f610740d..0c9fbb1f187 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -500,6 +500,12 @@ describe API::MergeRequests do end end + describe 'GET /projects/:id/merge_requests/:merge_request_iid/participants' do + it_behaves_like 'issuable participants endpoint' do + let(:entity) { merge_request } + end + end + describe 'GET /projects/:id/merge_requests/:merge_request_iid/commits' do it 'returns a 200 when merge request is valid' do get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/commits", user) diff --git a/spec/support/shared_examples/requests/api/issuable_participants_examples.rb b/spec/support/shared_examples/requests/api/issuable_participants_examples.rb new file mode 100644 index 00000000000..96d59e0c472 --- /dev/null +++ b/spec/support/shared_examples/requests/api/issuable_participants_examples.rb @@ -0,0 +1,29 @@ +shared_examples 'issuable participants endpoint' do + let(:area) { entity.class.name.underscore.pluralize } + + it 'returns participants' do + get api("/projects/#{project.id}/#{area}/#{entity.iid}/participants", user) + + expect(response).to have_gitlab_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.size).to eq(entity.participants.size) + + last_participant = entity.participants.last + expect(json_response.last['id']).to eq(last_participant.id) + expect(json_response.last['name']).to eq(last_participant.name) + expect(json_response.last['username']).to eq(last_participant.username) + end + + it 'returns a 404 when iid does not exist' do + get api("/projects/#{project.id}/#{area}/999/participants", user) + + expect(response).to have_gitlab_http_status(404) + end + + it 'returns a 404 when id is used instead of iid' do + get api("/projects/#{project.id}/#{area}/#{entity.id}/participants", user) + + expect(response).to have_gitlab_http_status(404) + end +end