From 8bf89cb4aba188cd9abc41bb9eefb92458cfb75b Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Thu, 20 Jul 2017 22:44:48 +0200 Subject: [PATCH 1/2] Add author_id & assignee_id param to /issues API Allow issues filtering on `author_id` and `assignee_id`. --- app/finders/issuable_finder.rb | 1 + .../unreleased/tc-issue-api-assignee.yml | 4 +++ doc/api/issues.md | 13 ++++++++- lib/api/issues.rb | 5 ++++ spec/requests/api/issues_spec.rb | 27 +++++++++++++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/tc-issue-api-assignee.yml diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index fc63e30c8fb..6fe17a2b99d 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -11,6 +11,7 @@ # group_id: integer # project_id: integer # milestone_title: string +# author_id: integer # assignee_id: integer # search: string # label_name: string diff --git a/changelogs/unreleased/tc-issue-api-assignee.yml b/changelogs/unreleased/tc-issue-api-assignee.yml new file mode 100644 index 00000000000..8d6360d5baf --- /dev/null +++ b/changelogs/unreleased/tc-issue-api-assignee.yml @@ -0,0 +1,4 @@ +--- +title: Add author_id & assignee_id param to /issues API +merge_request: 13004 +author: diff --git a/doc/api/issues.md b/doc/api/issues.md index a00a63bad4b..82c19c8c40a 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -26,7 +26,8 @@ GET /issues?labels=foo,bar&state=opened GET /issues?milestone=1.0.0 GET /issues?milestone=1.0.0&state=opened GET /issues?iids[]=42&iids[]=43 -GET /issues?search=issue+title+or+description +GET /issues?author_id=5 +GET /issues?assignee_id=5 ``` | Attribute | Type | Required | Description | @@ -34,6 +35,8 @@ GET /issues?search=issue+title+or+description | `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 | | `milestone` | string | no | The milestone title | +| `author_id` | integer | no | Returns issues created by the given user `id` (not limited to issues created by the authenticated user) | +| `assignee_id` | integer | no | Returns issues assigned to the given user `id` (not limited to issues created by the authenticated user) | | `iids` | Array[integer] | no | Return only the issues having the given `iid` | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | @@ -117,6 +120,8 @@ GET /groups/:id/issues?milestone=1.0.0 GET /groups/:id/issues?milestone=1.0.0&state=opened GET /groups/:id/issues?iids[]=42&iids[]=43 GET /groups/:id/issues?search=issue+title+or+description +GET /groups/:id/issues?author_id=5 +GET /groups/:id/issues?assignee_id=5 ``` | Attribute | Type | Required | Description | @@ -126,6 +131,8 @@ GET /groups/:id/issues?search=issue+title+or+description | `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 | | `iids` | Array[integer] | no | Return only the issues having the given `iid` | | `milestone` | string | no | The milestone title | +| `author_id` | integer | no | Returns issues created by the given user `id` (not limited to issues created by the authenticated user) | +| `assignee_id` | integer | no | Returns issues assigned to the given user `id` (not limited to issues created by the authenticated user) | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `search` | string | no | Search group issues against their `title` and `description` | @@ -209,6 +216,8 @@ GET /projects/:id/issues?milestone=1.0.0 GET /projects/:id/issues?milestone=1.0.0&state=opened GET /projects/:id/issues?iids[]=42&iids[]=43 GET /projects/:id/issues?search=issue+title+or+description +GET /projects/:id/issues?author_id=5 +GET /projects/:id/issues?assignee_id=5 ``` | Attribute | Type | Required | Description | @@ -218,6 +227,8 @@ GET /projects/:id/issues?search=issue+title+or+description | `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 | | `milestone` | string | no | The milestone title | +| `author_id` | integer | no | Returns issues created by the given user `id` (not limited to issues created by the authenticated user) | +| `assignee_id` | integer | no | Returns issues assigned to the given user `id` (not limited to issues created by the authenticated user) | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `search` | string | no | Search project issues against their `title` and `description` | diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 14b26f28ebf..621539afeaf 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -8,6 +8,9 @@ module API def find_issues(args = {}) args = params.merge(args) + # Do not scope to "authored" when author or assignee id is given + args.delete(:scope) if args[:author_id] || args[:assignee_id] + args.delete(:id) args[:milestone_title] = args.delete(:milestone) args[:label_name] = args.delete(:labels) @@ -29,6 +32,8 @@ module API optional :search, type: String, desc: 'Search issues for text present in the title or description' optional :created_after, type: DateTime, desc: 'Return issues created after the specified time' optional :created_before, type: DateTime, desc: 'Return issues created before the specified time' + optional :author_id, type: Integer, desc: 'Return issues which are authored by the user with the given ID' + optional :assignee_id, type: Integer, desc: 'Return issues which are assigned to the user with the given ID' use :pagination end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index 9837fedb522..dac88ce0b07 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -105,6 +105,33 @@ describe API::Issues do expect(json_response.second['id']).to eq(closed_issue.id) end + it 'returns issues authored by the given author id' do + issue2 = create(:issue, author: user2, project: project) + + get api('/issues', user), author_id: user2.id + + expect_paginated_array_response(size: 1) + expect(first_issue['id']).to eq(issue2.id) + end + + it 'returns issues assigned to the given assignee id' do + issue2 = create(:issue, assignees: [user2], project: project) + + get api('/issues', user), assignee_id: user2.id + + expect_paginated_array_response(size: 1) + expect(first_issue['id']).to eq(issue2.id) + end + + it 'returns issues authored by the given author id and assigned to the given assignee id' do + issue2 = create(:issue, author: user2, assignees: [user2], project: project) + + get api('/issues', user), author_id: user2.id, assignee_id: user2.id + + expect_paginated_array_response(size: 1) + expect(first_issue['id']).to eq(issue2.id) + end + it 'returns issues matching given search string for title' do get api("/issues", user), search: issue.title From d8798c907dfb960856423422a91eb1e6dc8db090 Mon Sep 17 00:00:00 2001 From: Toon Claes Date: Mon, 24 Jul 2017 22:41:33 +0200 Subject: [PATCH 2/2] Allow query param scope for /issues API endpoint --- doc/api/issues.md | 15 +++++++++------ lib/api/issues.rb | 9 +++++---- spec/requests/api/issues_spec.rb | 16 ++++++++++++---- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/doc/api/issues.md b/doc/api/issues.md index 82c19c8c40a..466fea651af 100644 --- a/doc/api/issues.md +++ b/doc/api/issues.md @@ -35,8 +35,9 @@ GET /issues?assignee_id=5 | `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 | | `milestone` | string | no | The milestone title | -| `author_id` | integer | no | Returns issues created by the given user `id` (not limited to issues created by the authenticated user) | -| `assignee_id` | integer | no | Returns issues assigned to the given user `id` (not limited to issues created by the authenticated user) | +| `scope` | string | no | Return issues for the given scope: `created-by-me`, `assigned-to-me` or `all` | +| `author_id` | integer | no | Return issues created by the given user `id`. Combine with `scope=all` or `scope=assigned-to-me`. | +| `assignee_id` | integer | no | Return issues assigned to the given user `id` | | `iids` | Array[integer] | no | Return only the issues having the given `iid` | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | @@ -131,8 +132,9 @@ GET /groups/:id/issues?assignee_id=5 | `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 | | `iids` | Array[integer] | no | Return only the issues having the given `iid` | | `milestone` | string | no | The milestone title | -| `author_id` | integer | no | Returns issues created by the given user `id` (not limited to issues created by the authenticated user) | -| `assignee_id` | integer | no | Returns issues assigned to the given user `id` (not limited to issues created by the authenticated user) | +| `scope` | string | no | Return issues for the given scope: `created-by-me`, `assigned-to-me` or `all` | +| `author_id` | integer | no | Return issues created by the given user `id`. Combine with `scope=all` or `scope=assigned-to-me`. | +| `assignee_id` | integer | no | Return issues assigned to the given user `id` | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `search` | string | no | Search group issues against their `title` and `description` | @@ -227,8 +229,9 @@ GET /projects/:id/issues?assignee_id=5 | `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 | | `milestone` | string | no | The milestone title | -| `author_id` | integer | no | Returns issues created by the given user `id` (not limited to issues created by the authenticated user) | -| `assignee_id` | integer | no | Returns issues assigned to the given user `id` (not limited to issues created by the authenticated user) | +| `scope` | string | no | Return issues for the given scope: `created-by-me`, `assigned-to-me` or `all` | +| `author_id` | integer | no | Return issues created by the given user `id`. Combine with `scope=all` or `scope=assigned-to-me`. | +| `assignee_id` | integer | no | Return issues assigned to the given user `id` | | `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `search` | string | no | Search project issues against their `title` and `description` | diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 621539afeaf..8f8d622fd34 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -8,9 +8,6 @@ module API def find_issues(args = {}) args = params.merge(args) - # Do not scope to "authored" when author or assignee id is given - args.delete(:scope) if args[:author_id] || args[:assignee_id] - args.delete(:id) args[:milestone_title] = args.delete(:milestone) args[:label_name] = args.delete(:labels) @@ -34,6 +31,8 @@ module API optional :created_before, type: DateTime, desc: 'Return issues created before the specified time' optional :author_id, type: Integer, desc: 'Return issues which are authored by the user with the given ID' optional :assignee_id, type: Integer, desc: 'Return issues which are assigned to the user with the given ID' + optional :scope, type: String, values: %w[created-by-me assigned-to-me all], + desc: 'Return merge requests for the given scope: `created-by-me`, `assigned-to-me` or `all`' use :pagination end @@ -60,9 +59,11 @@ module API optional :state, type: String, values: %w[opened closed all], default: 'all', desc: 'Return opened, closed, or all issues' use :issues_params + optional :scope, type: String, values: %w[created-by-me assigned-to-me all], default: 'created-by-me', + desc: 'Return merge requests for the given scope: `created-by-me`, `assigned-to-me` or `all`' end get do - issues = find_issues(scope: 'authored') + issues = find_issues present paginate(issues), with: Entities::IssueBasic, current_user: current_user end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index dac88ce0b07..c8f3267907a 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -71,7 +71,6 @@ describe API::Issues do expect(response).to have_http_status(401) end end - context "when authenticated" do let(:first_issue) { json_response.first } @@ -105,10 +104,19 @@ describe API::Issues do expect(json_response.second['id']).to eq(closed_issue.id) end + it 'returns issues assigned to me' do + issue2 = create(:issue, assignees: [user2], project: project) + + get api('/issues', user2), scope: 'assigned-to-me' + + expect_paginated_array_response(size: 1) + expect(first_issue['id']).to eq(issue2.id) + end + it 'returns issues authored by the given author id' do issue2 = create(:issue, author: user2, project: project) - get api('/issues', user), author_id: user2.id + get api('/issues', user), author_id: user2.id, scope: 'all' expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id) @@ -117,7 +125,7 @@ describe API::Issues do it 'returns issues assigned to the given assignee id' do issue2 = create(:issue, assignees: [user2], project: project) - get api('/issues', user), assignee_id: user2.id + get api('/issues', user), assignee_id: user2.id, scope: 'all' expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id) @@ -126,7 +134,7 @@ describe API::Issues do it 'returns issues authored by the given author id and assigned to the given assignee id' do issue2 = create(:issue, author: user2, assignees: [user2], project: project) - get api('/issues', user), author_id: user2.id, assignee_id: user2.id + get api('/issues', user), author_id: user2.id, assignee_id: user2.id, scope: 'all' expect_paginated_array_response(size: 1) expect(first_issue['id']).to eq(issue2.id)