Add Todos API
This commit is contained in:
parent
ab81ea1e81
commit
a1f224d3f7
7 changed files with 203 additions and 1 deletions
|
@ -34,6 +34,13 @@ class Todo < ActiveRecord::Base
|
|||
action == BUILD_FAILED
|
||||
end
|
||||
|
||||
def action_name
|
||||
case action
|
||||
when Todo::ASSIGNED then 'assigned you'
|
||||
when Todo::MENTIONED then 'mentioned you on'
|
||||
end
|
||||
end
|
||||
|
||||
def body
|
||||
if note.present?
|
||||
note.note
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
- else
|
||||
(removed)
|
||||
%span.todo-label
|
||||
= todo_action_name(todo)
|
||||
= todo.action_name
|
||||
- if todo.target
|
||||
= todo_target_link(todo)
|
||||
- else
|
||||
|
|
|
@ -58,6 +58,7 @@ module API
|
|||
mount ::API::SystemHooks
|
||||
mount ::API::Tags
|
||||
mount ::API::Templates
|
||||
mount ::API::Todos
|
||||
mount ::API::Triggers
|
||||
mount ::API::Users
|
||||
mount ::API::Variables
|
||||
|
|
|
@ -56,6 +56,10 @@ module API
|
|||
expose :id
|
||||
expose :name, :name_with_namespace
|
||||
expose :path, :path_with_namespace
|
||||
|
||||
expose :web_url do |project, options|
|
||||
Gitlab::Application.routes.url_helpers.namespace_project_url(project.namespace, project)
|
||||
end
|
||||
end
|
||||
|
||||
class Project < Grape::Entity
|
||||
|
@ -272,6 +276,31 @@ module API
|
|||
expose :id, :project_id, :group_id, :group_access
|
||||
end
|
||||
|
||||
class Todo < Grape::Entity
|
||||
expose :id
|
||||
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
|
||||
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?
|
||||
|
||||
Gitlab::Application.routes.url_helpers.public_send(target_url,
|
||||
todo.project.namespace, todo.project, todo.target, anchor: target_anchor)
|
||||
end
|
||||
|
||||
expose :body
|
||||
expose :state
|
||||
expose :created_at
|
||||
end
|
||||
|
||||
class Namespace < Grape::Entity
|
||||
expose :id, :path, :kind
|
||||
end
|
||||
|
|
54
lib/api/todos.rb
Normal file
54
lib/api/todos.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
module API
|
||||
# Todos API
|
||||
class Todos < Grape::API
|
||||
before { authenticate! }
|
||||
|
||||
resource :todos do
|
||||
helpers do
|
||||
def find_todos
|
||||
TodosFinder.new(current_user, params).execute
|
||||
end
|
||||
end
|
||||
|
||||
# Get a todo list
|
||||
#
|
||||
# Example Request:
|
||||
# GET /todos
|
||||
get do
|
||||
@todos = find_todos
|
||||
@todos = paginate @todos
|
||||
|
||||
present @todos, with: Entities::Todo
|
||||
end
|
||||
|
||||
# Mark todo as done
|
||||
#
|
||||
# Parameters:
|
||||
# id: (required) - The ID of the todo being marked as done
|
||||
#
|
||||
# Example Request:
|
||||
#
|
||||
# DELETE /todos/:id
|
||||
#
|
||||
delete ':id' do
|
||||
@todo = current_user.todos.find(params[:id])
|
||||
@todo.done
|
||||
|
||||
present @todo, with: Entities::Todo
|
||||
end
|
||||
|
||||
# Mark all todos as done
|
||||
#
|
||||
# Example Request:
|
||||
#
|
||||
# DELETE /todos
|
||||
#
|
||||
delete do
|
||||
@todos = find_todos
|
||||
@todos.each(&:done)
|
||||
|
||||
present @todos, with: Entities::Todo
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -22,5 +22,9 @@ FactoryGirl.define do
|
|||
trait :build_failed do
|
||||
action { Todo::BUILD_FAILED }
|
||||
end
|
||||
|
||||
trait :done do
|
||||
state :done
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
107
spec/requests/api/todos_spec.rb
Normal file
107
spec/requests/api/todos_spec.rb
Normal file
|
@ -0,0 +1,107 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe API::Todos, api: true do
|
||||
include ApiHelpers
|
||||
|
||||
let(:project_1) { create(:project) }
|
||||
let(:project_2) { create(:project) }
|
||||
let(:author_1) { create(:user) }
|
||||
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_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) }
|
||||
|
||||
describe 'GET /todos' do
|
||||
context 'when unauthenticated' do
|
||||
it 'should return authentication error' do
|
||||
get api('/todos')
|
||||
expect(response.status).to eq(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated' do
|
||||
it 'should return an array of pending todos for current user' do
|
||||
get api('/todos', john_doe)
|
||||
expect(response.status).to eq(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.length).to eq(3)
|
||||
end
|
||||
|
||||
context 'and using the author filter' do
|
||||
it 'should filter based on author_id param' do
|
||||
get api('/todos', john_doe), { author_id: author_2.id }
|
||||
expect(response.status).to eq(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.length).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and using the type filter' do
|
||||
it 'should filter based on type param' do
|
||||
get api('/todos', john_doe), { type: 'MergeRequest' }
|
||||
expect(response.status).to eq(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.length).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and using the state filter' do
|
||||
it 'should filter based on state param' do
|
||||
get api('/todos', john_doe), { state: 'done' }
|
||||
expect(response.status).to eq(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.length).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and using the project filter' do
|
||||
it 'should filter based on project_id param' do
|
||||
project_2.team << [john_doe, :developer]
|
||||
get api('/todos', john_doe), { project_id: project_2.id }
|
||||
expect(response.status).to eq(200)
|
||||
expect(json_response).to be_an Array
|
||||
expect(json_response.length).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE /todos/:id' do
|
||||
context 'when unauthenticated' do
|
||||
it 'should return authentication error' do
|
||||
delete api("/todos/#{pending_1.id}")
|
||||
expect(response.status).to eq(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated' do
|
||||
it 'should mark a todo as done' do
|
||||
delete api("/todos/#{pending_1.id}", john_doe)
|
||||
expect(response.status).to eq(200)
|
||||
expect(pending_1.reload).to be_done
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE /todos' do
|
||||
context 'when unauthenticated' do
|
||||
it 'should return authentication error' do
|
||||
delete api('/todos')
|
||||
expect(response.status).to eq(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated' do
|
||||
it 'should mark all todos as done' do
|
||||
delete api('/todos', john_doe)
|
||||
expect(response.status).to eq(200)
|
||||
expect(pending_1.reload).to be_done
|
||||
expect(pending_2.reload).to be_done
|
||||
expect(pending_3.reload).to be_done
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue