Commit 1e9003f4 authored by Douwe Maan's avatar Douwe Maan

Merge branch '51748-filter-any-milestone-via-api' into 'master'

Allows to filter issues by `Any milestone` in the API

Closes #51748

See merge request gitlab-org/gitlab-ce!22080
parents 3c8ccd2e a1c3d407
...@@ -428,6 +428,10 @@ class IssuableFinder ...@@ -428,6 +428,10 @@ class IssuableFinder
params[:milestone_title] == Milestone::Upcoming.name params[:milestone_title] == Milestone::Upcoming.name
end end
def filter_by_any_milestone?
params[:milestone_title] == Milestone::Any.title
end
def filter_by_started_milestone? def filter_by_started_milestone?
params[:milestone_title] == Milestone::Started.name params[:milestone_title] == Milestone::Started.name
end end
...@@ -437,6 +441,8 @@ class IssuableFinder ...@@ -437,6 +441,8 @@ class IssuableFinder
if milestones? if milestones?
if filter_by_no_milestone? if filter_by_no_milestone?
items = items.left_joins_milestones.where(milestone_id: [-1, nil]) items = items.left_joins_milestones.where(milestone_id: [-1, nil])
elsif filter_by_any_milestone?
items = items.any_milestone
elsif filter_by_upcoming_milestone? elsif filter_by_upcoming_milestone?
upcoming_ids = Milestone.upcoming_ids_by_projects(projects(items)) upcoming_ids = Milestone.upcoming_ids_by_projects(projects(items))
items = items.left_joins_milestones.where(milestone_id: upcoming_ids) items = items.left_joins_milestones.where(milestone_id: upcoming_ids)
......
...@@ -76,6 +76,7 @@ module Issuable ...@@ -76,6 +76,7 @@ module Issuable
scope :recent, -> { reorder(id: :desc) } scope :recent, -> { reorder(id: :desc) }
scope :of_projects, ->(ids) { where(project_id: ids) } scope :of_projects, ->(ids) { where(project_id: ids) }
scope :of_milestones, ->(ids) { where(milestone_id: ids) } scope :of_milestones, ->(ids) { where(milestone_id: ids) }
scope :any_milestone, -> { where('milestone_id IS NOT NULL') }
scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) } scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) }
scope :opened, -> { with_state(:opened) } scope :opened, -> { with_state(:opened) }
scope :only_opened, -> { with_state(:opened) } scope :only_opened, -> { with_state(:opened) }
......
---
title: Allows to filter issues by Any milestone in the API
merge_request: 22080
author: Jacopo Beschi @jacopo-beschi
type: added
...@@ -37,7 +37,7 @@ GET /issues?my_reaction_emoji=star ...@@ -37,7 +37,7 @@ GET /issues?my_reaction_emoji=star
| ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | ------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `state` | string | no | Return all issues or just those that are `opened` or `closed` | | `state` | string | no | Return all issues or just those that are `opened` or `closed` |
| `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels | | `labels` | string | no | Comma-separated list of label names, issues must have all labels to be returned. `No+Label` lists all issues with no labels |
| `milestone` | string | no | The milestone title. `No+Milestone` lists all issues with no milestone | | `milestone` | string | no | The milestone title. `No+Milestone` lists all issues with no milestone. `Any+Milestone` lists all issues that have an assigned milestone |
| `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ | | `scope` | string | no | Return issues for the given scope: `created_by_me`, `assigned_to_me` or `all`. Defaults to `created_by_me`<br> For versions before 11.0, use the now deprecated `created-by-me` or `assigned-to-me` scopes instead.<br> _([Introduced][ce-13004] in GitLab 9.5. [Changed to snake_case][ce-18935] in GitLab 11.0)_ |
| `author_id` | integer | no | Return issues created by the given user `id`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ | | `author_id` | integer | no | Return issues created by the given user `id`. Combine with `scope=all` or `scope=assigned_to_me`. _([Introduced][ce-13004] in GitLab 9.5)_ |
| `assignee_id` | integer | no | Return issues assigned to the given user `id` _([Introduced][ce-13004] in GitLab 9.5)_ | | `assignee_id` | integer | no | Return issues assigned to the given user `id` _([Introduced][ce-13004] in GitLab 9.5)_ |
......
...@@ -125,6 +125,14 @@ describe IssuesFinder do ...@@ -125,6 +125,14 @@ describe IssuesFinder do
end end
end end
context 'filtering by any milestone' do
let(:params) { { milestone_title: Milestone::Any.title } }
it 'returns issues with any assigned milestone' do
expect(issues).to contain_exactly(issue1)
end
end
context 'filtering by upcoming milestone' do context 'filtering by upcoming milestone' do
let(:params) { { milestone_title: Milestone::Upcoming.name } } let(:params) { { milestone_title: Milestone::Upcoming.name } }
......
...@@ -56,6 +56,7 @@ describe API::Issues do ...@@ -56,6 +56,7 @@ describe API::Issues do
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) } let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
let(:no_milestone_title) { URI.escape(Milestone::None.title) } let(:no_milestone_title) { URI.escape(Milestone::None.title) }
let(:any_milestone_title) { URI.escape(Milestone::Any.title) }
before(:all) do before(:all) do
project.add_reporter(user) project.add_reporter(user)
...@@ -811,6 +812,15 @@ describe API::Issues do ...@@ -811,6 +812,15 @@ describe API::Issues do
expect(json_response.first['id']).to eq(confidential_issue.id) expect(json_response.first['id']).to eq(confidential_issue.id)
end end
it 'returns an array of issues with any milestone' do
get api("#{base_url}/issues?milestone=#{any_milestone_title}", user)
response_ids = json_response.map { |issue| issue['id'] }
expect_paginated_array_response(size: 2)
expect(response_ids).to contain_exactly(closed_issue.id, issue.id)
end
it 'sorts by created_at descending by default' do it 'sorts by created_at descending by default' do
get api("#{base_url}/issues", user) get api("#{base_url}/issues", user)
......
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