From 4fdd21685cbbac7fc23e17c531cf28eeecc98577 Mon Sep 17 00:00:00 2001
From: jubianchi <julien.bianchi@pmsipilot.com>
Date: Thu, 14 Aug 2014 12:41:16 +0200
Subject: [PATCH] Filters issues by state via API

---
 CHANGELOG                        |  1 +
 doc/api/issues.md                |  9 +++++++++
 lib/api/issues.rb                | 27 +++++++++++++++++++++++----
 spec/requests/api/issues_spec.rb | 26 ++++++++++++++++++++++++++
 4 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 8ebd4addcbb..a8403f048b4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@ v 7.3.0
   - Store session Redis keys in 'session:gitlab:' namespace
   - Deprecate LDAP account takeover based on partial LDAP email / GitLab username match
   - Keyboard shortcuts for productivity (Robert Schilling)
+  - API: filter issues by state (Julien Bianchi)
 
 v 7.2.0
   - Explore page
diff --git a/doc/api/issues.md b/doc/api/issues.md
index a4b3b3e9918..c12d4528546 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -7,8 +7,14 @@ Get all issues created by authenticated user. This function takes pagination par
 
 ```
 GET /issues
+GET /issues?state=opened
+GET /issues?state=closed
 ```
 
+Parameters:
+
+- `state` (optional) - Return `all` issues or just those that are `opened` or `closed`
+
 ```json
 [
   {
@@ -80,11 +86,14 @@ to return the list of project issues.
 
 ```
 GET /projects/:id/issues
+GET /projects/:id/issues?state=opened
+GET /projects/:id/issues?state=closed
 ```
 
 Parameters:
 
 - `id` (required) - The ID of a project
+- `state` (optional) - Return `all` issues or just those that are `opened` or `closed`
 
 ## Single issue
 
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index eb6a74cd2bc..299fd7e2399 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -3,13 +3,28 @@ module API
   class Issues < Grape::API
     before { authenticate! }
 
+    helpers do
+      def filter_issues_state(issues, state = nil)
+        case state
+          when 'opened' then issues.opened
+          when 'closed' then issues.closed
+          else issues
+        end
+      end
+    end
+
     resource :issues do
       # Get currently authenticated user's issues
       #
-      # Example Request:
+      # Parameters:
+      #   state (optional) - Return "opened" or "closed" issues
+      #
+      # Example Requests:
       #   GET /issues
+      #   GET /issues?state=opened
+      #   GET /issues?state=closed
       get do
-        present paginate(current_user.issues), with: Entities::Issue
+        present paginate(filter_issues_state(current_user.issues, params['state'])), with: Entities::Issue
       end
     end
 
@@ -18,10 +33,14 @@ module API
       #
       # Parameters:
       #   id (required) - The ID of a project
-      # Example Request:
+      #   state (optional) - Return "opened" or "closed" issues
+      #
+      # Example Requests:
       #   GET /projects/:id/issues
+      #   GET /projects/:id/issues?state=opened
+      #   GET /projects/:id/issues?state=closed
       get ":id/issues" do
-        present paginate(user_project.issues), with: Entities::Issue
+        present paginate(filter_issues_state(user_project.issues, params['state'])), with: Entities::Issue
       end
 
       # Get a single project issue
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 08dc94ebdf3..f70b56b194f 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -4,6 +4,7 @@ describe API::API, api: true  do
   include ApiHelpers
   let(:user) { create(:user) }
   let!(:project) { create(:project, namespace: user.namespace ) }
+  let!(:closed_issue) { create(:closed_issue, author: user, assignee: user, project: project, state: :closed) }
   let!(:issue) { create(:issue, author: user, assignee: user, project: project) }
   let!(:label) do
     create(:label, title: 'label', color: '#FFAABB', project: project)
@@ -32,6 +33,31 @@ describe API::API, api: true  do
         response.headers['Link'].should ==
           '<http://www.example.com/api/v3/issues?page=1&per_page=3>; rel="first", <http://www.example.com/api/v3/issues?page=1&per_page=3>; rel="last"'
       end
+
+      it 'should return an array of closed issues' do
+        get api('/issues?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
+
+      it 'should return an array of opened issues' do
+        get api('/issues?state=opened', user)
+        response.status.should == 200
+        json_response.should be_an Array
+        json_response.length.should == 1
+        json_response.first['id'].should == issue.id
+      end
+
+      it 'should return an array of all issues' do
+        get api('/issues?state=all', 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
     end
   end
 
-- 
GitLab