From 61baf3528d2f39ffc8f7aa07eddf3df0cec3508b Mon Sep 17 00:00:00 2001 From: Mark Fletcher Date: Tue, 28 Feb 2017 17:53:40 +0530 Subject: [PATCH] Enable filtering milestones by search criteria in the API - Also remove a redundant test --- ...rch-for-milestone-by-title-in-rest-api.yml | 4 ++++ doc/api/milestones.md | 6 ++++-- lib/api/helpers.rb | 4 ++++ lib/api/milestones.rb | 2 ++ spec/requests/api/milestones_spec.rb | 21 ++++++++++++++----- 5 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 changelogs/unreleased/28807-search-for-milestone-by-title-in-rest-api.yml diff --git a/changelogs/unreleased/28807-search-for-milestone-by-title-in-rest-api.yml b/changelogs/unreleased/28807-search-for-milestone-by-title-in-rest-api.yml new file mode 100644 index 00000000000..0016253e32e --- /dev/null +++ b/changelogs/unreleased/28807-search-for-milestone-by-title-in-rest-api.yml @@ -0,0 +1,4 @@ +--- +title: Enable filtering milestones by search criteria in the API +merge_request: 9606 +author: diff --git a/doc/api/milestones.md b/doc/api/milestones.md index bf7dcc008e9..1d6749201e2 100644 --- a/doc/api/milestones.md +++ b/doc/api/milestones.md @@ -10,6 +10,7 @@ GET /projects/:id/milestones?iid=42 GET /projects/:id/milestones?iid[]=42&iid[]=43 GET /projects/:id/milestones?state=active GET /projects/:id/milestones?state=closed +GET /projects/:id/milestones?search=version ``` Parameters: @@ -18,7 +19,8 @@ Parameters: | --------- | ---- | -------- | ----------- | | `id` | integer | yes | The ID of a project | | `iid` | Array[integer] | optional | Return only the milestone having the given `iid` | -| `state` | string | optional | Return only `active` or `closed` milestones` | +| `state` | string | optional | Return only `active` or `closed` milestones` | +| `search` | string | optional | Return only milestones with a title or description matching the provided string | ```bash curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/5/milestones @@ -115,4 +117,4 @@ GET /projects/:id/milestones/:milestone_id/merge_requests Parameters: - `id` (required) - The ID of a project -- `milestone_id` (required) - The ID of a project milestone \ No newline at end of file +- `milestone_id` (required) - The ID of a project milestone diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 72d2b320077..4600abc7dc7 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -164,6 +164,10 @@ module API items.where(iid: iid) end + def filter_by_search(items, text) + items.search(text) + end + # error helpers def forbidden!(reason = nil) diff --git a/lib/api/milestones.rb b/lib/api/milestones.rb index 0b4ed76b35c..44bdaea7fa4 100644 --- a/lib/api/milestones.rb +++ b/lib/api/milestones.rb @@ -31,6 +31,7 @@ module API optional :state, type: String, values: %w[active closed all], default: 'all', desc: 'Return "active", "closed", or "all" milestones' optional :iid, type: Array[Integer], desc: 'The IID of the milestone' + optional :search, type: String, desc: 'The search criteria for the title or description of the milestone' use :pagination end get ":id/milestones" do @@ -39,6 +40,7 @@ module API milestones = user_project.milestones milestones = filter_milestones_state(milestones, params[:state]) milestones = filter_by_iid(milestones, params[:iid]) if params[:iid].present? + milestones = filter_by_search(milestones, params[:search]) if params[:search] present paginate(milestones), with: Entities::Milestone end diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb index 418bf5a507c..570651165ea 100644 --- a/spec/requests/api/milestones_spec.rb +++ b/spec/requests/api/milestones_spec.rb @@ -4,8 +4,8 @@ describe API::Milestones, api: true do include ApiHelpers let(:user) { create(:user) } let!(:project) { create(:empty_project, namespace: user.namespace ) } - let!(:closed_milestone) { create(:closed_milestone, project: project) } - let!(:milestone) { create(:milestone, project: project) } + let!(:closed_milestone) { create(:closed_milestone, project: project, title: 'version1', description: 'closed milestone') } + let!(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') } before { project.team << [user, :developer] } @@ -60,17 +60,28 @@ describe API::Milestones, api: true do get api("/projects/#{project.id}/milestones", user), iid: [milestone.iid, closed_milestone.iid] expect(response).to have_http_status(200) + expect(response).to include_pagination_headers expect(json_response.size).to eq(2) expect(json_response.first['title']).to eq milestone.title expect(json_response.first['id']).to eq milestone.id end - it 'returns a project milestone by iid array' do - get api("/projects/#{project.id}/milestones", user), iid: [milestone.iid, closed_milestone.iid] + it 'returns a project milestone by searching for title' do + get api("/projects/#{project.id}/milestones", user), search: 'version2' expect(response).to have_http_status(200) expect(response).to include_pagination_headers - expect(json_response.size).to eq(2) + expect(json_response.size).to eq(1) + expect(json_response.first['title']).to eq milestone.title + expect(json_response.first['id']).to eq milestone.id + end + + it 'returns a project milestones by searching for description' do + get api("/projects/#{project.id}/milestones", user), search: 'open' + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response.size).to eq(1) expect(json_response.first['title']).to eq milestone.title expect(json_response.first['id']).to eq milestone.id end