Merge branch 'jubianchi-api/issues-filter-milestone'

This commit is contained in:
Dmitriy Zaporozhets 2014-09-30 12:18:07 +03:00
commit 0c29cb3451
4 changed files with 74 additions and 9 deletions

View file

@ -9,6 +9,7 @@ v 7.4.0
- Do not delete tmp/repositories itself during clean-up, only its contents - Do not delete tmp/repositories itself during clean-up, only its contents
- Support for backup uploads to remote storage - Support for backup uploads to remote storage
- Prevent notes polling when there are not notes - Prevent notes polling when there are not notes
- API: filter project issues by milestone (Julien Bianchi)
v 7.3.1 v 7.3.1
- Fix ref parsing in Gitlab::GitAccess - Fix ref parsing in Gitlab::GitAccess

View file

@ -95,6 +95,8 @@ GET /projects/:id/issues?state=closed
GET /projects/:id/issues?labels=foo GET /projects/:id/issues?labels=foo
GET /projects/:id/issues?labels=foo,bar GET /projects/:id/issues?labels=foo,bar
GET /projects/:id/issues?labels=foo,bar&state=opened GET /projects/:id/issues?labels=foo,bar&state=opened
GET /projects/:id/issues?milestone=1.0.0
GET /projects/:id/issues?milestone=1.0.0&state=opened
``` ```
Parameters: Parameters:
@ -102,6 +104,7 @@ Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID of a project
- `state` (optional) - Return `all` issues or just those that are `opened` or `closed` - `state` (optional) - Return `all` issues or just those that are `opened` or `closed`
- `labels` (optional) - Comma-separated list of label names - `labels` (optional) - Comma-separated list of label names
- `milestone` (optional) - Milestone title
## Single issue ## Single issue

View file

@ -4,7 +4,7 @@ module API
before { authenticate! } before { authenticate! }
helpers do helpers do
def filter_issues_state(issues, state = nil) def filter_issues_state(issues, state)
case state case state
when 'opened' then issues.opened when 'opened' then issues.opened
when 'closed' then issues.closed when 'closed' then issues.closed
@ -13,7 +13,11 @@ module API
end end
def filter_issues_labels(issues, labels) def filter_issues_labels(issues, labels)
issues.includes(:labels).where("labels.title" => labels.split(',')) issues.includes(:labels).where('labels.title' => labels.split(','))
end
def filter_issues_milestone(issues, milestone)
issues.includes(:milestone).where('milestones.title' => milestone)
end end
end end
@ -48,19 +52,24 @@ module API
# id (required) - The ID of a project # id (required) - The ID of a project
# state (optional) - Return "opened" or "closed" issues # state (optional) - Return "opened" or "closed" issues
# labels (optional) - Comma-separated list of label names # labels (optional) - Comma-separated list of label names
# milestone (optional) - Milestone title
# #
# Example Requests: # Example Requests:
# GET /projects/:id/issues # GET /projects/:id/issues
# GET /projects/:id/issues?state=opened # GET /projects/:id/issues?state=opened
# GET /projects/:id/issues?state=closed # GET /projects/:id/issues?state=closed
# GET /projects/:id/issues
# GET /projects/:id/issues?labels=foo # GET /projects/:id/issues?labels=foo
# GET /projects/:id/issues?labels=foo,bar # GET /projects/:id/issues?labels=foo,bar
# GET /projects/:id/issues?labels=foo,bar&state=opened # GET /projects/:id/issues?labels=foo,bar&state=opened
# GET /projects/:id/issues?milestone=1.0.0
# GET /projects/:id/issues?milestone=1.0.0&state=closed
get ":id/issues" do get ":id/issues" do
issues = user_project.issues issues = user_project.issues
issues = filter_issues_state(issues, params[:state]) unless params[:state].nil? issues = filter_issues_state(issues, params[:state]) unless params[:state].nil?
issues = filter_issues_labels(issues, params[:labels]) unless params[:labels].nil? issues = filter_issues_labels(issues, params[:labels]) unless params[:labels].nil?
unless params[:milestone].nil?
issues = filter_issues_milestone(issues, params[:milestone])
end
issues = issues.order('issues.id DESC') issues = issues.order('issues.id DESC')
present paginate(issues), with: Entities::Issue present paginate(issues), with: Entities::Issue

View file

@ -4,12 +4,29 @@ 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_issue) { create(:closed_issue, author: user, assignee: user, project: project, state: :closed) } let!(:closed_issue) do
let!(:issue) { create(:issue, author: user, assignee: user, project: project) } create :closed_issue,
author: user,
assignee: user,
project: project,
state: :closed,
milestone: milestone
end
let!(:issue) do
create :issue,
author: user,
assignee: user,
project: project,
milestone: milestone
end
let!(:label) do let!(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project) create(:label, title: 'label', color: '#FFAABB', project: project)
end end
let!(:label_link) { create(:label_link, label: label, target: issue) } let!(:label_link) { create(:label_link, label: label, target: issue) }
let!(:milestone) { create(:milestone, title: '1.0.0', project: project) }
let!(:empty_milestone) do
create(:milestone, title: '2.0.0', project: project)
end
before { project.team << [user, :reporter] } before { project.team << [user, :reporter] }
@ -102,15 +119,18 @@ describe API::API, api: true do
end end
describe "GET /projects/:id/issues" do describe "GET /projects/:id/issues" do
let(:base_url) { "/projects/#{project.id}" }
let(:title) { milestone.title }
it "should return project issues" do it "should return project issues" do
get api("/projects/#{project.id}/issues", user) get api("#{base_url}/issues", user)
response.status.should == 200 response.status.should == 200
json_response.should be_an Array json_response.should be_an Array
json_response.first['title'].should == issue.title json_response.first['title'].should == issue.title
end end
it 'should return an array of labeled project issues' do it 'should return an array of labeled project issues' do
get api("/projects/#{project.id}/issues?labels=#{label.title}", user) get api("#{base_url}/issues?labels=#{label.title}", user)
response.status.should == 200 response.status.should == 200
json_response.should be_an Array json_response.should be_an Array
json_response.length.should == 1 json_response.length.should == 1
@ -118,7 +138,7 @@ describe API::API, api: true do
end end
it 'should return an array of labeled project issues when at least one label matches' do it 'should return an array of labeled project issues when at least one label matches' do
get api("/projects/#{project.id}/issues?labels=#{label.title},foo,bar", user) get api("#{base_url}/issues?labels=#{label.title},foo,bar", user)
response.status.should == 200 response.status.should == 200
json_response.should be_an Array json_response.should be_an Array
json_response.length.should == 1 json_response.length.should == 1
@ -126,11 +146,43 @@ describe API::API, api: true do
end end
it 'should return an empty array if no project issue matches labels' do it 'should return an empty array if no project issue matches labels' do
get api("/projects/#{project.id}/issues?labels=foo,bar", user) get api("#{base_url}/issues?labels=foo,bar", user)
response.status.should == 200 response.status.should == 200
json_response.should be_an Array json_response.should be_an Array
json_response.length.should == 0 json_response.length.should == 0
end end
it 'should return an empty array if no issue matches milestone' do
get api("#{base_url}/issues?milestone=#{empty_milestone.title}", user)
response.status.should == 200
json_response.should be_an Array
json_response.length.should == 0
end
it 'should return an empty array if milestone does not exist' do
get api("#{base_url}/issues?milestone=foo", user)
response.status.should == 200
json_response.should be_an Array
json_response.length.should == 0
end
it 'should return an array of issues in given milestone' do
get api("#{base_url}/issues?milestone=#{title}", user)
response.status.should == 200
json_response.should be_an Array
json_response.length.should == 2
json_response.first['id'].should == issue.id
json_response.second['id'].should == closed_issue.id
end
it 'should return an array of issues matching state in milestone' do
get api("#{base_url}/issues?milestone=#{milestone.title}"\
'&state=closed', user)
response.status.should == 200
json_response.should be_an Array
json_response.length.should == 1
json_response.first['id'].should == closed_issue.id
end
end end
describe "GET /projects/:id/issues/:issue_id" do describe "GET /projects/:id/issues/:issue_id" do