Add Todos API

This commit is contained in:
Douglas Barbosa Alexandre 2016-03-11 16:04:42 -03:00 committed by Robert Schilling
parent ab81ea1e81
commit a1f224d3f7
7 changed files with 203 additions and 1 deletions

View file

@ -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

View file

@ -11,7 +11,7 @@
- else
(removed)
%span.todo-label
= todo_action_name(todo)
= todo.action_name
- if todo.target
= todo_target_link(todo)
- else

View file

@ -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

View file

@ -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
View 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

View file

@ -22,5 +22,9 @@ FactoryGirl.define do
trait :build_failed do
action { Todo::BUILD_FAILED }
end
trait :done do
state :done
end
end
end

View 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