Commit a135c5eb authored by Jan Provaznik's avatar Jan Provaznik

Extend Epics API - searching and sorting

In API allow searching epics by title and description and sort
epics by created_at and updated_at attributes.

created_at and updated_at attributes are also exposed in epic API - if
we allow sorting by these attributes it also makes sense to include them
in API response.

Close #4732
parent e8a37e6a
---
title: Add basic searching and sorting to Epics API
merge_request:
author:
type: added
......@@ -16,11 +16,16 @@ Gets all epics of the requested group and its subgroups.
```
GET /groups/:id/-/epics
GET /groups/:id/-/epics?author_id=5
```
| Attribute | Type | Required | Description |
| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `author_id` | integer | no | Return epics created by the given user `id` |
| `order_by` | string | no | Return epics ordered by `created_at` or `updated_at` fields. Default is `created_at` |
| `sort` | string | no | Return epics sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Search epics against their `title` and `description` |
```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/1/-/epics
......@@ -45,7 +50,9 @@ Example response:
"web_url": "http://localhost:3001/kam"
},
"start_date": null,
"end_date": null
"end_date": null,
"created_at": "2018-01-21T06:21:13.165Z",
"updated_at": "2018-01-22T12:41:41.166Z"
}
]
```
......@@ -85,7 +92,9 @@ Example response:
"web_url": "http://localhost:3001/arnita"
},
"start_date": null,
"end_date": null
"end_date": null,
"created_at": "2018-01-21T06:21:13.165Z",
"updated_at": "2018-01-22T12:41:41.166Z"
}
```
......@@ -127,7 +136,9 @@ Example response:
"username" : "eileen.lowe"
},
"start_date": null,
"end_date": null
"end_date": null,
"created_at": "2018-01-21T06:21:13.165Z",
"updated_at": "2018-01-22T12:41:41.166Z"
}
```
......@@ -170,7 +181,9 @@ Example response:
"username" : "eileen.lowe"
},
"start_date": null,
"end_date": null
"end_date": null,
"created_at": "2018-01-21T06:21:13.165Z",
"updated_at": "2018-01-22T12:41:41.166Z"
}
```
......
......@@ -29,6 +29,14 @@ module API
def epic
@epic ||= user_group.epics.find_by(iid: params[:epic_iid])
end
def find_epics(args = {})
args = declared_params.merge(args)
epics = EpicsFinder.new(current_user, args).execute
epics.reorder(args[:order_by] => args[:sort])
end
end
params do
......@@ -39,8 +47,16 @@ module API
desc 'Get epics for the group' do
success Entities::Epic
end
params do
optional :order_by, type: String, values: %w[created_at updated_at], default: 'created_at',
desc: 'Return epics ordered by `created_at` or `updated_at` fields.'
optional :sort, type: String, values: %w[asc desc], default: 'desc',
desc: 'Return epics sorted in `asc` or `desc` order.'
optional :search, type: String, desc: 'Search epics for text present in the title or description'
optional :author_id, type: Integer, desc: 'Return epics which are authored by the user with the given ID'
end
get ':id/-/epics' do
present EpicsFinder.new(current_user, group_id: user_group.id).execute, with: Entities::Epic
present find_epics(group_id: user_group.id), with: Entities::Epic
end
desc 'Get details of an epic' do
......
......@@ -19,7 +19,9 @@
"additionalProperties": false
},
"start_date": { "type": ["string", "null"] },
"end_date": { "type": ["string", "null"] }
"end_date": { "type": ["string", "null"] },
"created_at": { "type": ["string", "null"] },
"updated_at": { "type": ["string", "null"] }
},
"required": [
"id", "iid", "group_id", "title"
......
......@@ -19,7 +19,9 @@
"description": { "type": ["string", "null"] },
"author": { "type": ["object", "null"] },
"start_date": { "type": ["string", "null"] },
"end_date": { "type": ["string", "null"] }
"end_date": { "type": ["string", "null"] },
"created_at": { "type": ["string", "null"] },
"updated_at": { "type": ["string", "null"] }
},
"additionalProperties": false
},
......
......@@ -60,6 +60,77 @@ describe API::Epics do
expect(response).to match_response_schema('public_api/v4/epics', dir: 'ee')
end
end
context 'with multiple epics' do
let(:user2) { create(:user) }
let!(:epic) do
create(:epic,
group: group,
created_at: 3.days.ago,
updated_at: 2.days.ago)
end
let!(:epic2) do
create(:epic,
author: user2,
group: group,
title: 'foo',
description: 'bar',
created_at: 2.days.ago,
updated_at: 3.days.ago)
end
before do
stub_licensed_features(epics: true)
end
def expect_array_response(expected)
items = json_response.map { |i| i['id'] }
expect(items).to eq(expected)
end
it 'returns epics authored by the given author id' do
get api(url, user), author_id: user2.id
expect_array_response([epic2.id])
end
it 'returns epics matching given search string for title' do
get api(url, user), search: epic2.title
expect_array_response([epic2.id])
end
it 'returns epics matching given search string for description' do
get api(url, user), search: epic2.description
expect_array_response([epic2.id])
end
it 'sorts by created_at descending by default' do
get api(url, user)
expect_array_response([epic2.id, epic.id])
end
it 'sorts ascending when requested' do
get api(url, user), sort: :asc
expect_array_response([epic.id, epic2.id])
end
it 'sorts by updated_at descending when requested' do
get api(url, user), order_by: :updated_at
expect_array_response([epic.id, epic2.id])
end
it 'sorts by updated_at ascending when requested' do
get api(url, user), order_by: :updated_at, sort: :asc
expect_array_response([epic2.id, epic.id])
end
end
end
describe 'GET /groups/:id/-/epics/:epic_iid' do
......
......@@ -506,6 +506,8 @@ module API
expose :author, using: Entities::UserBasic
expose :start_date
expose :end_date
expose :created_at
expose :updated_at
end
class EpicIssue < 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