From 3942621329b20307c1676d60324c8f47ea1e1b37 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Wed, 22 Jun 2016 19:15:09 +0200 Subject: [PATCH] Expose target, filter by state as string --- app/finders/todos_finder.rb | 21 ++ doc/api/todos.md | 447 ++++++++++++++++++++++++-------- lib/api/entities.rb | 8 +- lib/api/todos.rb | 6 +- spec/requests/api/todos_spec.rb | 15 +- 5 files changed, 377 insertions(+), 120 deletions(-) diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb index 58a00f88af7..7806d9e4cc5 100644 --- a/app/finders/todos_finder.rb +++ b/app/finders/todos_finder.rb @@ -25,6 +25,7 @@ class TodosFinder def execute items = current_user.todos items = by_action_id(items) + items = by_action(items) items = by_author(items) items = by_project(items) items = by_state(items) @@ -43,6 +44,18 @@ class TodosFinder params[:action_id] end + def to_action_id + Todo::ACTION_NAMES.key(action.to_sym) + end + + def action? + action.present? && to_action_id + end + + def action + params[:action] + end + def author? params[:author_id].present? end @@ -96,6 +109,14 @@ class TodosFinder params[:type] end + def by_action(items) + if action? + items = items.where(action: to_action_id) + end + + items + end + def by_action_id(items) if action_id? items = items.where(action: action_id) diff --git a/doc/api/todos.md b/doc/api/todos.md index 1d38e4acf13..29e73664410 100644 --- a/doc/api/todos.md +++ b/doc/api/todos.md @@ -5,7 +5,7 @@ ## Get a list of todos Returns a list of todos. When no filter is applied, it returns all pending todos -for the current user. Different filters allow the user to +for the current user. Different filters allow the user to precise the request. ``` GET /todos @@ -15,19 +15,11 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `action_id` | integer | no | The ID of the action of the todo. See the table below for the ID mapping | +| `action` | string | no | The action to be filtered. Can be `assigned`, `mentioned`, `build_failed`, or `marked`. | | `author_id` | integer | no | The ID of an author | | `project_id` | integer | no | The ID of a project | | `state` | string | no | The state of the todo. Can be either `pending` or `done` | -| `type` | string | no | The type of an todo. Can be either `Issue` or `MergeRequest` | - -| `action_id` | Action | -| ----------- | ------ | -| 1 | Issuable assigned | -| 2 | Mentioned in issuable | -| 3 | Build failed | -| 4 | Todo marked for you | - +| `type` | string | no | The type of a todo. Can be either `Issue` or `MergeRequest` | ```bash curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/todos @@ -38,64 +30,158 @@ Example Response: ```json [ { - "id": 130, + "id": 102, "project": { - "id": 1, - "name": "Underscore", - "name_with_namespace": "Documentcloud / Underscore", - "path": "underscore", - "path_with_namespace": "documentcloud/underscore" + "id": 2, + "name": "Gitlab Ce", + "name_with_namespace": "Gitlab Org / Gitlab Ce", + "path": "gitlab-ce", + "path_with_namespace": "gitlab-org/gitlab-ce" }, "author": { - "name": "Juwan Abbott", - "username": "halle", - "id": 8, + "name": "Administrator", + "username": "root", + "id": 1, "state": "active", - "avatar_url": "http://www.gravatar.com/avatar/a0086c7b9e0d73312f32ff745fdcb43e?s=80&d=identicon", - "web_url": "https://gitlab.example.com/u/halle" + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/root" }, - "action_name": "assigned", - "target_id": 71, - "target_type": "Issue", - "target_reference": "#1", - "target_url": "https://gitlab.example.com/documentcloud/underscore/issues/1", - "body": "At voluptas qui nulla soluta qui et.", + "action_name": "marked", + "target_type": "MergeRequest", + "target": { + "id": 34, + "iid": 7, + "project_id": 2, + "title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", + "description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.", + "state": "opened", + "created_at": "2016-06-17T07:49:24.419Z", + "updated_at": "2016-06-17T07:52:43.484Z", + "target_branch": "tutorials_git_tricks", + "source_branch": "DNSBL_docs", + "upvotes": 0, + "downvotes": 0, + "author": { + "name": "Maxie Medhurst", + "username": "craig_rutherford", + "id": 12, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/craig_rutherford" + }, + "assignee": { + "name": "Administrator", + "username": "root", + "id": 1, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/root" + }, + "source_project_id": 2, + "target_project_id": 2, + "labels": [], + "work_in_progress": false, + "milestone": { + "id": 32, + "iid": 2, + "project_id": 2, + "title": "v1.0", + "description": "Assumenda placeat ea voluptatem voluptate qui.", + "state": "active", + "created_at": "2016-06-17T07:47:34.163Z", + "updated_at": "2016-06-17T07:47:34.163Z", + "due_date": null + }, + "merge_when_build_succeeds": false, + "merge_status": "cannot_be_merged", + "subscribed": true, + "user_notes_count": 7 + }, + "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ce/merge_requests/7", + "body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", "state": "pending", - "created_at": "2016-05-20T20:52:00.626Z" + "created_at": "2016-06-17T07:52:35.225Z" }, { - "id": 129, + "id": 98, "project": { - "id": 1, - "name": "Underscore", - "name_with_namespace": "Documentcloud / Underscore", - "path": "underscore", - "path_with_namespace": "documentcloud/underscore" + "id": 2, + "name": "Gitlab Ce", + "name_with_namespace": "Gitlab Org / Gitlab Ce", + "path": "gitlab-ce", + "path_with_namespace": "gitlab-org/gitlab-ce" }, "author": { - "name": "Juwan Abbott", - "username": "halle", - "id": 8, + "name": "Maxie Medhurst", + "username": "craig_rutherford", + "id": 12, "state": "active", - "avatar_url": "http://www.gravatar.com/avatar/a0086c7b9e0d73312f32ff745fdcb43e?s=80&d=identicon", - "web_url": "https://gitlab.example.com/u/halle" + "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/craig_rutherford" }, - "action_name": "mentioned", - "target_id": 79, - "target_type": "Issue", - "target_reference": "#9", - "target_url": "https://gitlab.example.com/documentcloud/underscore/issues/9#note_959", - "body": "@root Fix this shit", + "action_name": "assigned", + "target_type": "MergeRequest", + "target": { + "id": 34, + "iid": 7, + "project_id": 2, + "title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", + "description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.", + "state": "opened", + "created_at": "2016-06-17T07:49:24.419Z", + "updated_at": "2016-06-17T07:52:43.484Z", + "target_branch": "tutorials_git_tricks", + "source_branch": "DNSBL_docs", + "upvotes": 0, + "downvotes": 0, + "author": { + "name": "Maxie Medhurst", + "username": "craig_rutherford", + "id": 12, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/craig_rutherford" + }, + "assignee": { + "name": "Administrator", + "username": "root", + "id": 1, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/root" + }, + "source_project_id": 2, + "target_project_id": 2, + "labels": [], + "work_in_progress": false, + "milestone": { + "id": 32, + "iid": 2, + "project_id": 2, + "title": "v1.0", + "description": "Assumenda placeat ea voluptatem voluptate qui.", + "state": "active", + "created_at": "2016-06-17T07:47:34.163Z", + "updated_at": "2016-06-17T07:47:34.163Z", + "due_date": null + }, + "merge_when_build_succeeds": false, + "merge_status": "cannot_be_merged", + "subscribed": true, + "user_notes_count": 7 + }, + "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ce/merge_requests/7", + "body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", "state": "pending", - "created_at": "2016-05-20T20:51:51.503Z" + "created_at": "2016-06-17T07:49:24.624Z" } ] ``` ## Mark a todo as done -Marks a single pending todo given by its ID for the current user as done. The to -marked as done is returned in the response. +Marks a single pending todo given by its ID for the current user as done. The +todo marked as done is returned in the response. ``` DELETE /todos/:id @@ -115,30 +201,77 @@ Example Response: ```json { - "id": 130, - "project": { - "id": 1, - "name": "Underscore", - "name_with_namespace": "Documentcloud / Underscore", - "path": "underscore", - "path_with_namespace": "documentcloud/underscore" - }, - "author": { - "name": "Juwan Abbott", - "username": "halle", - "id": 8, - "state": "active", - "avatar_url": "http://www.gravatar.com/avatar/a0086c7b9e0d73312f32ff745fdcb43e?s=80&d=identicon", - "web_url": "https://gitlab.example.com/u/halle" - }, - "action_name": "assigned", - "target_id": 71, - "target_type": "Issue", - "target_reference": "#1", - "target_url": "https://gitlab.example.com/documentcloud/underscore/issues/1", - "body": "At voluptas qui nulla soluta qui et.", - "state": "done", - "created_at": "2016-05-20T20:52:00.626Z" + "id": 102, + "project": { + "id": 2, + "name": "Gitlab Ce", + "name_with_namespace": "Gitlab Org / Gitlab Ce", + "path": "gitlab-ce", + "path_with_namespace": "gitlab-org/gitlab-ce" + }, + "author": { + "name": "Administrator", + "username": "root", + "id": 1, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/root" + }, + "action_name": "marked", + "target_type": "MergeRequest", + "target": { + "id": 34, + "iid": 7, + "project_id": 2, + "title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", + "description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.", + "state": "opened", + "created_at": "2016-06-17T07:49:24.419Z", + "updated_at": "2016-06-17T07:52:43.484Z", + "target_branch": "tutorials_git_tricks", + "source_branch": "DNSBL_docs", + "upvotes": 0, + "downvotes": 0, + "author": { + "name": "Maxie Medhurst", + "username": "craig_rutherford", + "id": 12, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/craig_rutherford" + }, + "assignee": { + "name": "Administrator", + "username": "root", + "id": 1, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/root" + }, + "source_project_id": 2, + "target_project_id": 2, + "labels": [], + "work_in_progress": false, + "milestone": { + "id": 32, + "iid": 2, + "project_id": 2, + "title": "v1.0", + "description": "Assumenda placeat ea voluptatem voluptate qui.", + "state": "active", + "created_at": "2016-06-17T07:47:34.163Z", + "updated_at": "2016-06-17T07:47:34.163Z", + "due_date": null + }, + "merge_when_build_succeeds": false, + "merge_status": "cannot_be_merged", + "subscribed": true, + "user_notes_count": 7 + }, + "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ce/merge_requests/7", + "body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", + "state": "done", + "created_at": "2016-06-17T07:52:35.225Z" } ``` @@ -160,57 +293,151 @@ Example Response: ```json [ { - "id": 130, + "id": 102, "project": { - "id": 1, - "name": "Underscore", - "name_with_namespace": "Documentcloud / Underscore", - "path": "underscore", - "path_with_namespace": "documentcloud/underscore" + "id": 2, + "name": "Gitlab Ce", + "name_with_namespace": "Gitlab Org / Gitlab Ce", + "path": "gitlab-ce", + "path_with_namespace": "gitlab-org/gitlab-ce" }, "author": { - "name": "Juwan Abbott", - "username": "halle", - "id": 8, + "name": "Administrator", + "username": "root", + "id": 1, "state": "active", - "avatar_url": "http://www.gravatar.com/avatar/a0086c7b9e0d73312f32ff745fdcb43e?s=80&d=identicon", - "web_url": "https://gitlab.example.com/u/halle" + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/root" }, - "action_name": "assigned", - "target_id": 71, - "target_type": "Issue", - "target_reference": "#1", - "target_url": "https://gitlab.example.com/documentcloud/underscore/issues/1", - "body": "At voluptas qui nulla soluta qui et.", + "action_name": "marked", + "target_type": "MergeRequest", + "target": { + "id": 34, + "iid": 7, + "project_id": 2, + "title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", + "description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.", + "state": "opened", + "created_at": "2016-06-17T07:49:24.419Z", + "updated_at": "2016-06-17T07:52:43.484Z", + "target_branch": "tutorials_git_tricks", + "source_branch": "DNSBL_docs", + "upvotes": 0, + "downvotes": 0, + "author": { + "name": "Maxie Medhurst", + "username": "craig_rutherford", + "id": 12, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/craig_rutherford" + }, + "assignee": { + "name": "Administrator", + "username": "root", + "id": 1, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/root" + }, + "source_project_id": 2, + "target_project_id": 2, + "labels": [], + "work_in_progress": false, + "milestone": { + "id": 32, + "iid": 2, + "project_id": 2, + "title": "v1.0", + "description": "Assumenda placeat ea voluptatem voluptate qui.", + "state": "active", + "created_at": "2016-06-17T07:47:34.163Z", + "updated_at": "2016-06-17T07:47:34.163Z", + "due_date": null + }, + "merge_when_build_succeeds": false, + "merge_status": "cannot_be_merged", + "subscribed": true, + "user_notes_count": 7 + }, + "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ce/merge_requests/7", + "body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", "state": "done", - "created_at": "2016-05-20T20:52:00.626Z" + "created_at": "2016-06-17T07:52:35.225Z" }, { - "id": 129, + "id": 98, "project": { - "id": 1, - "name": "Underscore", - "name_with_namespace": "Documentcloud / Underscore", - "path": "underscore", - "path_with_namespace": "documentcloud/underscore" + "id": 2, + "name": "Gitlab Ce", + "name_with_namespace": "Gitlab Org / Gitlab Ce", + "path": "gitlab-ce", + "path_with_namespace": "gitlab-org/gitlab-ce" }, "author": { - "name": "Juwan Abbott", - "username": "halle", - "id": 8, + "name": "Maxie Medhurst", + "username": "craig_rutherford", + "id": 12, "state": "active", - "avatar_url": "http://www.gravatar.com/avatar/a0086c7b9e0d73312f32ff745fdcb43e?s=80&d=identicon", - "web_url": "https://gitlab.example.com/u/halle" + "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/craig_rutherford" }, - "action_name": "mentioned", - "target_id": 79, - "target_type": "Issue", - "target_reference": "#9", - "target_url": "https://gitlab.example.com/documentcloud/underscore/issues/9#note_959", - "body": "@root Fix this shit", + "action_name": "assigned", + "target_type": "MergeRequest", + "target": { + "id": 34, + "iid": 7, + "project_id": 2, + "title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", + "description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.", + "state": "opened", + "created_at": "2016-06-17T07:49:24.419Z", + "updated_at": "2016-06-17T07:52:43.484Z", + "target_branch": "tutorials_git_tricks", + "source_branch": "DNSBL_docs", + "upvotes": 0, + "downvotes": 0, + "author": { + "name": "Maxie Medhurst", + "username": "craig_rutherford", + "id": 12, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/craig_rutherford" + }, + "assignee": { + "name": "Administrator", + "username": "root", + "id": 1, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "https://gitlab.example.com/u/root" + }, + "source_project_id": 2, + "target_project_id": 2, + "labels": [], + "work_in_progress": false, + "milestone": { + "id": 32, + "iid": 2, + "project_id": 2, + "title": "v1.0", + "description": "Assumenda placeat ea voluptatem voluptate qui.", + "state": "active", + "created_at": "2016-06-17T07:47:34.163Z", + "updated_at": "2016-06-17T07:47:34.163Z", + "due_date": null + }, + "merge_when_build_succeeds": false, + "merge_status": "cannot_be_merged", + "subscribed": true, + "user_notes_count": 7 + }, + "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ce/merge_requests/7", + "body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.", "state": "done", - "created_at": "2016-05-20T20:51:51.503Z" - } + "created_at": "2016-06-17T07:49:24.624Z" + }, ] ``` diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 67d2c396b32..8cc4368b5c2 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -277,16 +277,16 @@ module API expose :project, using: Entities::BasicProjectDetails expose :author, using: Entities::UserBasic expose :action_name - expose :target_id expose :target_type - expose :target_reference do |todo, options| - todo.target.to_reference + + expose :target do |todo, options| + Entities.const_get(todo.target_type).represent(todo.target, options) end expose :target_url do |todo, options| target_type = todo.target_type.underscore target_url = "namespace_project_#{target_type}_url" - target_anchor = "note_#{todo.note_id}" if todo.note.present? + target_anchor = "note_#{todo.note_id}" if todo.note_id? Gitlab::Application.routes.url_helpers.public_send(target_url, todo.project.namespace, todo.project, todo.target, anchor: target_anchor) diff --git a/lib/api/todos.rb b/lib/api/todos.rb index 67714a796c7..8334baad1b9 100644 --- a/lib/api/todos.rb +++ b/lib/api/todos.rb @@ -18,7 +18,7 @@ module API get do todos = find_todos - present paginate(todos), with: Entities::Todo + present paginate(todos), with: Entities::Todo, current_user: current_user end # Mark a todo as done @@ -33,7 +33,7 @@ module API todo = current_user.todos.find(params[:id]) todo.done - present todo, with: Entities::Todo + present todo, with: Entities::Todo, current_user: current_user end # Mark all todos as done @@ -45,7 +45,7 @@ module API todos = find_todos todos.each(&:done) - present paginate(Kaminari.paginate_array(todos)), with: Entities::Todo + present paginate(Kaminari.paginate_array(todos)), with: Entities::Todo, current_user: current_user end end end diff --git a/spec/requests/api/todos_spec.rb b/spec/requests/api/todos_spec.rb index 8d54b4fd3d8..f93f37e3591 100644 --- a/spec/requests/api/todos_spec.rb +++ b/spec/requests/api/todos_spec.rb @@ -9,7 +9,7 @@ describe API::Todos, api: true do let(:author_2) { create(:user) } let(:john_doe) { create(:user, username: 'john_doe') } let(:merge_request) { create(:merge_request, source_project: project_1) } - let!(:pending_1) { create(:todo, project: project_1, author: author_1, user: john_doe) } + let!(:pending_1) { create(:todo, :mentioned, project: project_1, author: author_1, user: john_doe) } let!(:pending_2) { create(:todo, project: project_2, author: author_2, user: john_doe) } let!(:pending_3) { create(:todo, project: project_1, author: author_2, user: john_doe, target: merge_request) } let!(:done) { create(:todo, :done, project: project_1, author: author_1, user: john_doe) } @@ -38,9 +38,8 @@ describe API::Todos, api: true do expect(json_response[0]['id']).to eq(pending_3.id) expect(json_response[0]['project']).to be_a Hash expect(json_response[0]['author']).to be_a Hash - expect(json_response[0]['target_id']).to be_present expect(json_response[0]['target_type']).to be_present - expect(json_response[0]['target_reference']).to be_present + expect(json_response[0]['target']).to be_a Hash expect(json_response[0]['target_url']).to be_present expect(json_response[0]['body']).to be_present expect(json_response[0]['state']).to eq('pending') @@ -87,6 +86,16 @@ describe API::Todos, api: true do expect(json_response.length).to eq(1) end end + + context 'and using the action filter' do + it 'filters based on action param' do + get api('/todos', john_doe), { action: 'mentioned' } + + expect(response.status).to eq(200) + expect(json_response).to be_an Array + expect(json_response.length).to eq(1) + end + end end end