Commit 92897d76 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'api-filter-milestone' into 'master'

API: Ability to filter milestones by state

Ability to filter milestones by `active` and `closed` state.

* Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/14931

See merge request !3566
parents 8eae7b10 e6215a9a
...@@ -18,6 +18,7 @@ v 8.7.0 (unreleased) ...@@ -18,6 +18,7 @@ v 8.7.0 (unreleased)
- Handle nil descriptions in Slack issue messages (Stan Hu) - Handle nil descriptions in Slack issue messages (Stan Hu)
- Add default scope to projects to exclude projects pending deletion - Add default scope to projects to exclude projects pending deletion
- Ensure empty recipients are rejected in BuildsEmailService - Ensure empty recipients are rejected in BuildsEmailService
- API: Ability to filter milestones by state `active` and `closed` (Robert Schilling)
- Implement 'Groups View' as an option for dashboard preferences !3379 (Elias W.) - Implement 'Groups View' as an option for dashboard preferences !3379 (Elias W.)
- Implement 'TODOs View' as an option for dashboard preferences !3379 (Elias W.) - Implement 'TODOs View' as an option for dashboard preferences !3379 (Elias W.)
- Gracefully handle notes on deleted commits in merge requests (Stan Hu) - Gracefully handle notes on deleted commits in merge requests (Stan Hu)
......
...@@ -7,8 +7,24 @@ Returns a list of project milestones. ...@@ -7,8 +7,24 @@ Returns a list of project milestones.
``` ```
GET /projects/:id/milestones GET /projects/:id/milestones
GET /projects/:id/milestones?iid=42 GET /projects/:id/milestones?iid=42
GET /projects/:id/milestones?state=active
GET /projects/:id/milestones?state=closed
``` ```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project |
| `iid` | integer | optional | Return only the milestone having the given `iid` |
| `state` | string | optional | Return only `active` or `closed` milestones` |
```bash
curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/milestones
```
Example Response:
```json ```json
[ [
{ {
...@@ -25,10 +41,6 @@ GET /projects/:id/milestones?iid=42 ...@@ -25,10 +41,6 @@ GET /projects/:id/milestones?iid=42
] ]
``` ```
Parameters:
- `id` (required) - The ID of a project
- `iid` (optional) - Return the milestone having the given `iid`
## Get single milestone ## Get single milestone
......
...@@ -3,17 +3,33 @@ module API ...@@ -3,17 +3,33 @@ module API
class Milestones < Grape::API class Milestones < Grape::API
before { authenticate! } before { authenticate! }
helpers do
def filter_milestones_state(milestones, state)
case state
when 'active' then milestones.active
when 'closed' then milestones.closed
else milestones
end
end
end
resource :projects do resource :projects do
# Get a list of project milestones # Get a list of project milestones
# #
# Parameters: # Parameters:
# id (required) - The ID of a project # id (required) - The ID of a project
# state (optional) - Return "active" or "closed" milestones
# Example Request: # Example Request:
# GET /projects/:id/milestones # GET /projects/:id/milestones
# GET /projects/:id/milestones?state=active
# GET /projects/:id/milestones?state=closed
get ":id/milestones" do get ":id/milestones" do
authorize! :read_milestone, user_project authorize! :read_milestone, user_project
present paginate(user_project.milestones), with: Entities::Milestone milestones = user_project.milestones
milestones = filter_milestones_state(milestones, params[:state])
present paginate(milestones), with: Entities::Milestone
end end
# Get a single project milestone # Get a single project milestone
......
...@@ -4,6 +4,7 @@ describe API::API, api: true do ...@@ -4,6 +4,7 @@ describe API::API, api: true do
include ApiHelpers include ApiHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
let!(:project) { create(:project, namespace: user.namespace ) } let!(:project) { create(:project, namespace: user.namespace ) }
let!(:closed_milestone) { create(:closed_milestone, project: project) }
let!(:milestone) { create(:milestone, project: project) } let!(:milestone) { create(:milestone, project: project) }
before { project.team << [user, :developer] } before { project.team << [user, :developer] }
...@@ -20,6 +21,24 @@ describe API::API, api: true do ...@@ -20,6 +21,24 @@ describe API::API, api: true do
get api("/projects/#{project.id}/milestones") get api("/projects/#{project.id}/milestones")
expect(response.status).to eq(401) expect(response.status).to eq(401)
end end
it 'returns an array of active milestones' do
get api("/projects/#{project.id}/milestones?state=active", user)
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(milestone.id)
end
it 'returns an array of closed milestones' do
get api("/projects/#{project.id}/milestones?state=closed", user)
expect(response.status).to eq(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(closed_milestone.id)
end
end end
describe 'GET /projects/:id/milestones/:milestone_id' do describe 'GET /projects/:id/milestones/:milestone_id' 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