2016-03-11 14:04:42 -05:00
|
|
|
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) }
|
2016-06-22 13:15:09 -04:00
|
|
|
let!(:pending_1) { create(:todo, :mentioned, project: project_1, author: author_1, user: john_doe) }
|
2016-03-11 14:04:42 -05:00
|
|
|
let!(:pending_2) { create(:todo, project: project_2, author: author_2, user: john_doe) }
|
2016-06-28 12:04:44 -04:00
|
|
|
let!(:pending_3) { create(:todo, project: project_1, author: author_2, user: john_doe) }
|
2016-03-11 14:04:42 -05:00
|
|
|
let!(:done) { create(:todo, :done, project: project_1, author: author_1, user: john_doe) }
|
|
|
|
|
2016-06-10 06:24:38 -04:00
|
|
|
before do
|
|
|
|
project_1.team << [john_doe, :developer]
|
|
|
|
project_2.team << [john_doe, :developer]
|
|
|
|
end
|
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
describe 'GET /todos' do
|
|
|
|
context 'when unauthenticated' do
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'returns authentication error' do
|
2016-03-11 14:04:42 -05:00
|
|
|
get api('/todos')
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
expect(response.status).to eq(401)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when authenticated' do
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'returns an array of pending todos for current user' do
|
2016-03-11 14:04:42 -05:00
|
|
|
get api('/todos', john_doe)
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
expect(response.status).to eq(200)
|
|
|
|
expect(json_response).to be_an Array
|
|
|
|
expect(json_response.length).to eq(3)
|
2016-06-10 07:02:41 -04:00
|
|
|
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_type']).to be_present
|
2016-06-22 13:15:09 -04:00
|
|
|
expect(json_response[0]['target']).to be_a Hash
|
2016-06-10 07:02:41 -04:00
|
|
|
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')
|
2016-06-15 07:20:30 -04:00
|
|
|
expect(json_response[0]['action_name']).to eq('assigned')
|
2016-06-10 07:02:41 -04:00
|
|
|
expect(json_response[0]['created_at']).to be_present
|
2016-03-11 14:04:42 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'and using the author filter' do
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'filters based on author_id param' do
|
2016-03-11 14:04:42 -05:00
|
|
|
get api('/todos', john_doe), { author_id: author_2.id }
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
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
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'filters based on type param' do
|
2016-06-28 12:04:44 -04:00
|
|
|
create(:todo, project: project_1, author: author_2, user: john_doe, target: merge_request)
|
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
get api('/todos', john_doe), { type: 'MergeRequest' }
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
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
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'filters based on state param' do
|
2016-03-11 14:04:42 -05:00
|
|
|
get api('/todos', john_doe), { state: 'done' }
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
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
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'filters based on project_id param' do
|
2016-03-11 14:04:42 -05:00
|
|
|
get api('/todos', john_doe), { project_id: project_2.id }
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
expect(response.status).to eq(200)
|
|
|
|
expect(json_response).to be_an Array
|
|
|
|
expect(json_response.length).to eq(1)
|
|
|
|
end
|
|
|
|
end
|
2016-06-22 13:15:09 -04:00
|
|
|
|
|
|
|
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
|
2016-03-11 14:04:42 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'DELETE /todos/:id' do
|
|
|
|
context 'when unauthenticated' do
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'returns authentication error' do
|
2016-03-11 14:04:42 -05:00
|
|
|
delete api("/todos/#{pending_1.id}")
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
expect(response.status).to eq(401)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when authenticated' do
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'marks a todo as done' do
|
2016-03-11 14:04:42 -05:00
|
|
|
delete api("/todos/#{pending_1.id}", john_doe)
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
expect(response.status).to eq(200)
|
|
|
|
expect(pending_1.reload).to be_done
|
|
|
|
end
|
2016-07-08 12:42:47 -04:00
|
|
|
|
|
|
|
it 'updates todos cache' do
|
|
|
|
expect_any_instance_of(User).to receive(:update_todos_count_cache).and_call_original
|
|
|
|
|
|
|
|
delete api("/todos/#{pending_1.id}", john_doe)
|
|
|
|
end
|
2016-03-11 14:04:42 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'DELETE /todos' do
|
|
|
|
context 'when unauthenticated' do
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'returns authentication error' do
|
2016-03-11 14:04:42 -05:00
|
|
|
delete api('/todos')
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
expect(response.status).to eq(401)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when authenticated' do
|
2016-05-20 17:17:13 -04:00
|
|
|
it 'marks all todos as done' do
|
2016-03-11 14:04:42 -05:00
|
|
|
delete api('/todos', john_doe)
|
2016-05-20 17:17:13 -04:00
|
|
|
|
2016-03-11 14:04:42 -05:00
|
|
|
expect(response.status).to eq(200)
|
2016-07-19 07:05:56 -04:00
|
|
|
expect(response.body).to eq('3')
|
2016-03-11 14:04:42 -05:00
|
|
|
expect(pending_1.reload).to be_done
|
|
|
|
expect(pending_2.reload).to be_done
|
|
|
|
expect(pending_3.reload).to be_done
|
|
|
|
end
|
2016-07-08 12:42:47 -04:00
|
|
|
|
|
|
|
it 'updates todos cache' do
|
|
|
|
expect_any_instance_of(User).to receive(:update_todos_count_cache).and_call_original
|
|
|
|
|
|
|
|
delete api("/todos", john_doe)
|
|
|
|
end
|
2016-03-11 14:04:42 -05:00
|
|
|
end
|
|
|
|
end
|
2016-06-28 12:04:44 -04:00
|
|
|
|
|
|
|
shared_examples 'an issuable' do |issuable_type|
|
|
|
|
it 'creates a todo on an issuable' do
|
|
|
|
post api("/projects/#{project_1.id}/#{issuable_type}/#{issuable.id}/todo", john_doe)
|
|
|
|
|
|
|
|
expect(response.status).to eq(201)
|
|
|
|
expect(json_response['project']).to be_a Hash
|
|
|
|
expect(json_response['author']).to be_a Hash
|
|
|
|
expect(json_response['target_type']).to eq(issuable.class.name)
|
|
|
|
expect(json_response['target']).to be_a Hash
|
|
|
|
expect(json_response['target_url']).to be_present
|
|
|
|
expect(json_response['body']).to be_present
|
|
|
|
expect(json_response['state']).to eq('pending')
|
|
|
|
expect(json_response['action_name']).to eq('marked')
|
|
|
|
expect(json_response['created_at']).to be_present
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns 304 there already exist a todo on that issuable' do
|
|
|
|
create(:todo, project: project_1, author: author_1, user: john_doe, target: issuable)
|
|
|
|
|
|
|
|
post api("/projects/#{project_1.id}/#{issuable_type}/#{issuable.id}/todo", john_doe)
|
|
|
|
|
|
|
|
expect(response.status).to eq(304)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns 404 if the issuable is not found' do
|
|
|
|
post api("/projects/#{project_1.id}/#{issuable_type}/123/todo", john_doe)
|
|
|
|
|
|
|
|
expect(response.status).to eq(404)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'POST :id/issuable_type/:issueable_id/todo' do
|
|
|
|
context 'for an issue' do
|
|
|
|
it_behaves_like 'an issuable', 'issues' do
|
|
|
|
let(:issuable) { create(:issue, author: author_1, project: project_1) }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'for a merge request' do
|
|
|
|
it_behaves_like 'an issuable', 'merge_requests' do
|
|
|
|
let(:issuable) { merge_request }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2016-03-11 14:04:42 -05:00
|
|
|
end
|