Commit 703575f7 authored by David Kim's avatar David Kim Committed by Dmytro Zaporozhets (DZ)

Filter by reviewer in MergeRequest List API

parent 5824d80f
...@@ -14,6 +14,7 @@ type: reference, api ...@@ -14,6 +14,7 @@ type: reference, api
> - `author_username` and `author_username` were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10. > - `author_username` and `author_username` were [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 12.10.
> - `reference` was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354) in GitLab 12.10 in favour of `references`. > - `reference` was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20354) in GitLab 12.10 in favour of `references`.
> - `with_merge_status_recheck` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0. > - `with_merge_status_recheck` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31890) in GitLab 13.0.
> - `reviewer_username` and `reviewer_id` were [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49341) in GitLab 13.8.
Every API call to merge requests must be authenticated. Every API call to merge requests must be authenticated.
...@@ -92,13 +93,15 @@ Parameters: ...@@ -92,13 +93,15 @@ Parameters:
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. | | `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. |
| `approver_ids` **(STARTER)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. | | `approver_ids` **(STARTER)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. |
| `approved_by_ids` **(STARTER)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. | | `approved_by_ids` **(STARTER)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. |
| `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. |
| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. |
| `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. | | `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `source_branch` | string | no | Return merge requests with the given source branch. | | `source_branch` | string | no | Return merge requests with the given source branch. |
| `target_branch` | string | no | Return merge requests with the given target branch. | | `target_branch` | string | no | Return merge requests with the given target branch. |
| `search` | string | no | Search merge requests against their `title` and `description`. | | `search` | string | no | Search merge requests 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`. | | `in` | string | no | Modify the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description`. |
| `wip` | string | no | Filter merge requests against their `wip` status. `yes` to return *only* WIP merge requests, `no` to return *non* WIP merge requests. | | `wip` | string | no | Filter merge requests against their `wip` status. `yes` to return *only* WIP merge requests, `no` to return *non* WIP merge requests. |
| `not` | Hash | no | Return merge requests that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `my_reaction_emoji`. | | `not` | Hash | no | Return merge requests that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `reviewer_id`, `reviewer_username`, `my_reaction_emoji`. |
| `environment` | string | no | Returns merge requests deployed to the given environment. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `environment` | string | no | Returns merge requests deployed to the given environment. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `deployed_before` | datetime | no | Return merge requests deployed before the given date/time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `deployed_before` | datetime | no | Return merge requests deployed before the given date/time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `deployed_after` | datetime | no | Return merge requests deployed after the given date/time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) | | `deployed_after` | datetime | no | Return merge requests deployed after the given date/time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
...@@ -153,6 +156,14 @@ Parameters: ...@@ -153,6 +156,14 @@ Parameters:
"avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon", "avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon",
"web_url": "https://gitlab.example.com/axel.block" "web_url": "https://gitlab.example.com/axel.block"
}], }],
"reviewers": [{
"id": 2,
"name": "Sam Bauch",
"username": "kenyatta_oconnell",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/956c92487c6f6f7616b536927e22c9a0?s=80&d=identicon",
"web_url": "http://gitlab.example.com//kenyatta_oconnell"
}],
"source_project_id": 2, "source_project_id": 2,
"target_project_id": 3, "target_project_id": 3,
"labels": [ "labels": [
...@@ -268,11 +279,15 @@ Parameters: ...@@ -268,11 +279,15 @@ Parameters:
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. | | `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. |
| `approver_ids` **(STARTER)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. | | `approver_ids` **(STARTER)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. |
| `approved_by_ids` **(STARTER)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. | | `approved_by_ids` **(STARTER)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. |
| `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. |
| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#reviewer) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. |
| `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. | | `my_reaction_emoji` | string | no | Return merge requests reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. |
| `source_branch` | string | no | Return merge requests with the given source branch. | | `source_branch` | string | no | Return merge requests with the given source branch. |
| `target_branch` | string | no | Return merge requests with the given target branch. | | `target_branch` | string | no | Return merge requests with the given target branch. |
| `search` | string | no | Search merge requests against their `title` and `description`. | | `search` | string | no | Search merge requests against their `title` and `description`. |
| `wip` | string | no | Filter merge requests against their `wip` status. `yes` to return *only* WIP merge requests, `no` to return *non* WIP merge requests. | | `wip` | string | no | Filter merge requests against their `wip` status. `yes` to return *only* WIP merge requests, `no` to return *non* WIP merge requests. |
| `not` | Hash | no | Return merge requests that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `reviewer_id`, `reviewer_username`, `my_reaction_emoji`. |
```json ```json
[ [
...@@ -324,6 +339,14 @@ Parameters: ...@@ -324,6 +339,14 @@ Parameters:
"avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon", "avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon",
"web_url": "https://gitlab.example.com/axel.block" "web_url": "https://gitlab.example.com/axel.block"
}], }],
"reviewers": [{
"id": 2,
"name": "Sam Bauch",
"username": "kenyatta_oconnell",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/956c92487c6f6f7616b536927e22c9a0?s=80&d=identicon",
"web_url": "http://gitlab.example.com//kenyatta_oconnell"
}],
"source_project_id": 2, "source_project_id": 2,
"target_project_id": 3, "target_project_id": 3,
"labels": [ "labels": [
...@@ -432,11 +455,14 @@ Parameters: ...@@ -432,11 +455,14 @@ Parameters:
| `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 9.5)_. | | `assignee_id` | integer | no | Returns merge requests assigned to the given user `id`. `None` returns unassigned merge requests. `Any` returns merge requests with an assignee. _([Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/13060) in GitLab 9.5)_. |
| `approver_ids` **(STARTER)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. | | `approver_ids` **(STARTER)** | integer array | no | Returns merge requests which have specified all the users with the given `id`s as individual approvers. `None` returns merge requests without approvers. `Any` returns merge requests with an approver. |
| `approved_by_ids` **(STARTER)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. | | `approved_by_ids` **(STARTER)** | integer array | no | Returns merge requests which have been approved by all the users with the given `id`s (Max: 5). `None` returns merge requests with no approvals. `Any` returns merge requests with an approval. |
| `reviewer_id` | integer | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#enable-or-disable-merge-request-reviewers) with the given user `id`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_username`. |
| `reviewer_username` | string | no | Returns merge requests which have the user as a [reviewer](../user/project/merge_requests/getting_started.md#enable-or-disable-merge-request-reviewers) with the given `username`. `None` returns merge requests with no reviewers. `Any` returns merge requests with any reviewer. Mutually exclusive with `reviewer_id`. |
| `my_reaction_emoji` | string | no | Return merge requests 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](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_. | | `my_reaction_emoji` | string | no | Return merge requests 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](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14016) in GitLab 10.0)_. |
| `source_branch` | string | no | Return merge requests with the given source branch. | | `source_branch` | string | no | Return merge requests with the given source branch. |
| `target_branch` | string | no | Return merge requests with the given target branch. | | `target_branch` | string | no | Return merge requests with the given target branch. |
| `search` | string | no | Search merge requests against their `title` and `description`. | | `search` | string | no | Search merge requests against their `title` and `description`. |
| `non_archived` | boolean | no | Return merge requests from non archived projects only. Default is true. _(Introduced in [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23809))_. | | `non_archived` | boolean | no | Return merge requests from non archived projects only. Default is true. _(Introduced in [GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23809))_. |
| `not` | Hash | no | Return merge requests that do not match the parameters supplied. Accepts: `labels`, `milestone`, `author_id`, `author_username`, `assignee_id`, `assignee_username`, `reviewer_id`, `reviewer_username`, `my_reaction_emoji`. |
```json ```json
[ [
...@@ -488,6 +514,14 @@ Parameters: ...@@ -488,6 +514,14 @@ Parameters:
"avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon", "avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon",
"web_url": "https://gitlab.example.com/axel.block" "web_url": "https://gitlab.example.com/axel.block"
}], }],
"reviewers": [{
"id": 2,
"name": "Sam Bauch",
"username": "kenyatta_oconnell",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/956c92487c6f6f7616b536927e22c9a0?s=80&d=identicon",
"web_url": "http://gitlab.example.com//kenyatta_oconnell"
}],
"source_project_id": 2, "source_project_id": 2,
"target_project_id": 3, "target_project_id": 3,
"labels": [ "labels": [
...@@ -618,6 +652,14 @@ Parameters: ...@@ -618,6 +652,14 @@ Parameters:
"avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon", "avatar_url": "http://www.gravatar.com/avatar/46f6f7dc858ada7be1853f7fb96e81da?s=80&d=identicon",
"web_url": "https://gitlab.example.com/axel.block" "web_url": "https://gitlab.example.com/axel.block"
}], }],
"reviewers": [{
"id": 2,
"name": "Sam Bauch",
"username": "kenyatta_oconnell",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/956c92487c6f6f7616b536927e22c9a0?s=80&d=identicon",
"web_url": "http://gitlab.example.com//kenyatta_oconnell"
}],
"source_project_id": 2, "source_project_id": 2,
"target_project_id": 3, "target_project_id": 3,
"labels": [ "labels": [
......
...@@ -21,6 +21,9 @@ module API ...@@ -21,6 +21,9 @@ module API
coerce_with: Validations::Validators::CheckAssigneesCount.coerce, coerce_with: Validations::Validators::CheckAssigneesCount.coerce,
desc: 'Return merge requests which are assigned to the user with the given username' desc: 'Return merge requests which are assigned to the user with the given username'
mutually_exclusive :assignee_id, :assignee_username mutually_exclusive :assignee_id, :assignee_username
optional :reviewer_username,
type: String,
desc: 'Return merge requests which have the user as a reviewer with the given username'
optional :labels, optional :labels,
type: Array[String], type: Array[String],
...@@ -32,6 +35,11 @@ module API ...@@ -32,6 +35,11 @@ module API
params :merge_requests_base_params do params :merge_requests_base_params do
use :merge_requests_negatable_params use :merge_requests_negatable_params
optional :reviewer_id,
types: [Integer, String],
integer_none_any: true,
desc: 'Return merge requests which have the user as a reviewer with the given ID'
mutually_exclusive :reviewer_id, :reviewer_username
optional :state, optional :state,
type: String, type: String,
values: %w[opened closed locked merged all], values: %w[opened closed locked merged all],
...@@ -72,6 +80,10 @@ module API ...@@ -72,6 +80,10 @@ module API
optional :wip, type: String, values: %w[yes no], desc: 'Search merge requests for WIP in the title' optional :wip, type: String, values: %w[yes no], desc: 'Search merge requests for WIP in the title'
optional :not, type: Hash, desc: 'Parameters to negate' do optional :not, type: Hash, desc: 'Parameters to negate' do
use :merge_requests_negatable_params use :merge_requests_negatable_params
optional :reviewer_id,
types: Integer,
desc: 'Return merge requests which have the user as a reviewer with the given ID'
mutually_exclusive :reviewer_id, :reviewer_username
end end
optional :deployed_before, optional :deployed_before,
......
...@@ -440,6 +440,7 @@ RSpec.describe API::MergeRequests do ...@@ -440,6 +440,7 @@ RSpec.describe API::MergeRequests do
milestone: milestone, milestone: milestone,
author: user, author: user,
assignees: [user], assignees: [user],
reviewers: [user2],
source_project: project, source_project: project,
target_project: project, target_project: project,
source_branch: 'what', source_branch: 'what',
...@@ -498,6 +499,71 @@ RSpec.describe API::MergeRequests do ...@@ -498,6 +499,71 @@ RSpec.describe API::MergeRequests do
expect(mr['assignee']['id']).not_to eq(user2.id) expect(mr['assignee']['id']).not_to eq(user2.id)
end end
end end
context 'filter by reviewer' do
context 'with reviewer_id' do
context 'with an id' do
let(:params) { { not: { reviewer_id: user2.id } } }
it 'returns merge requests that do not have the given reviewer' do
get api(endpoint_path, user), params: { not: { reviewer_id: user2.id } }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an(Array)
expect(json_response.length).to eq(4)
expect(json_response.map { |mr| mr['id'] }).not_to include(merge_request2)
end
end
context 'with Any' do
let(:params) { { not: { reviewer_id: 'Any' } } }
it 'returns a 400' do
# Any is not supported for negated filter
get api(endpoint_path, user), params: params
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('not[reviewer_id] is invalid')
end
end
context 'with None' do
let(:params) { { not: { reviewer_id: 'None' } } }
it 'returns a 400' do
# None is not supported for negated filter
get api(endpoint_path, user), params: params
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('not[reviewer_id] is invalid')
end
end
end
context 'with reviewer_username' do
let(:params) { { not: { reviewer_username: user2.username } } }
it 'returns merge requests that do not have the given reviewer' do
get api(endpoint_path, user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an(Array)
expect(json_response.length).to eq(4)
expect(json_response.map { |mr| mr['id'] }).not_to include(merge_request2)
end
end
context 'when both reviewer_id and reviewer_username' do
let(:params) { { not: { reviewer_id: user2.id, reviewer_username: user2.username } } }
it 'returns a 400' do
get api('/merge_requests', user), params: params
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('not[reviewer_id], not[reviewer_username] are mutually exclusive')
end
end
end
end end
context 'source_branch param' do context 'source_branch param' do
...@@ -666,6 +732,79 @@ RSpec.describe API::MergeRequests do ...@@ -666,6 +732,79 @@ RSpec.describe API::MergeRequests do
end end
end end
context 'filter by reviewer' do
let_it_be(:review_requested_mr1) do
create(:merge_request, :unique_branches, author: user, reviewers: [user2], source_project: project2, target_project: project2)
end
let_it_be(:review_requested_mr2) do
create(:merge_request, :unique_branches, author: user2, reviewers: [user], source_project: project2, target_project: project2)
end
let(:params) { { scope: :all } }
context 'with reviewer_id' do
let(:params) { super().merge(reviewer_id: reviewer_id) }
context 'with an id' do
let(:reviewer_id) { user2.id }
it 'returns review requested merge requests for the given user' do
get api('/merge_requests', user), params: params
expect_response_contain_exactly(review_requested_mr1.id)
end
end
context 'with Any' do
let(:reviewer_id) { 'Any' }
it 'returns review requested merge requests for any user' do
get api('/merge_requests', user), params: params
expect_response_contain_exactly(review_requested_mr1.id, review_requested_mr2.id)
end
end
context 'with None' do
let(:reviewer_id) { 'None' }
it 'returns merge requests that has no assigned reviewers' do
get api('/merge_requests', user), params: params
expect_response_contain_exactly(
merge_request.id,
merge_request_closed.id,
merge_request_merged.id,
merge_request_locked.id,
merge_request2.id
)
end
end
end
context 'with reviewer_username' do
let(:params) { super().merge(reviewer_username: user2.username) }
it 'returns review requested merge requests for the given user' do
get api('/merge_requests', user), params: params
expect_response_contain_exactly(review_requested_mr1.id)
end
end
context 'with both reviewer_id and reviewer_username' do
let(:params) { super().merge(reviewer_id: user2.id, reviewer_username: user2.username) }
it 'returns a 400' do
get api('/merge_requests', user), params: params
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('reviewer_id, reviewer_username are mutually exclusive')
end
end
end
it 'returns an array of merge requests assigned to the given user' do it 'returns an array of merge requests assigned to the given user' do
merge_request3 = create(:merge_request, :simple, author: user, assignees: [user2], source_project: project2, target_project: project2, source_branch: 'other-branch') merge_request3 = create(:merge_request, :simple, author: user, assignees: [user2], source_project: project2, target_project: project2, source_branch: 'other-branch')
......
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