Add endpoint to allow users to move issues between lists

parent aff7a2ef
...@@ -10,12 +10,26 @@ class Projects::BoardIssuesController < Projects::ApplicationController ...@@ -10,12 +10,26 @@ class Projects::BoardIssuesController < Projects::ApplicationController
render json: issues.as_json(only: [:id, :title, :confidential], include: { labels: { only: [:id, :title, :color] } }) render json: issues.as_json(only: [:id, :title, :confidential], include: { labels: { only: [:id, :title, :color] } })
end end
def update
service = Boards::Issues::MoveService.new(project, current_user, move_params)
if service.execute
head :ok
else
head :unprocessable_entity
end
end
private private
def filter_params def filter_params
params.permit(:list_id) params.permit(:list_id)
end end
def move_params
params.require(:issue).permit(:from, :to).merge(id: params[:id])
end
def record_not_found(exception) def record_not_found(exception)
render json: { error: exception.message }, status: :not_found render json: { error: exception.message }, status: :not_found
end end
......
...@@ -3,6 +3,7 @@ module Boards ...@@ -3,6 +3,7 @@ module Boards
class MoveService < Boards::BaseService class MoveService < Boards::BaseService
def execute def execute
return false unless issue.present? return false unless issue.present?
return false unless valid_move?
return false unless user.can?(:update_issue, issue) return false unless user.can?(:update_issue, issue)
update_service.execute(issue) update_service.execute(issue)
...@@ -14,16 +15,20 @@ module Boards ...@@ -14,16 +15,20 @@ module Boards
private private
def valid_move?
moving_from.present? && moving_to.present?
end
def issue def issue
@issue ||= project.issues.visible_to_user(user).find_by!(iid: params[:id]) @issue ||= project.issues.visible_to_user(user).find_by!(iid: params[:id])
end end
def moving_from def moving_from
@moving_from ||= board.lists.find(params[:from]) @moving_from ||= board.lists.find_by(id: params[:from])
end end
def moving_to def moving_to
@moving_to ||= board.lists.find(params[:to]) @moving_to ||= board.lists.find_by(id: params[:to])
end end
def close_service def close_service
......
...@@ -857,7 +857,7 @@ Rails.application.routes.draw do ...@@ -857,7 +857,7 @@ Rails.application.routes.draw do
end end
resource :board, only: [:show] do resource :board, only: [:show] do
resources :issues, only: [:index], controller: :board_issues resources :issues, only: [:index, :update], controller: :board_issues
resources :lists, only: [:create, :update, :destroy], controller: :board_lists resources :lists, only: [:create, :update, :destroy], controller: :board_lists
end end
......
...@@ -4,6 +4,12 @@ describe Projects::BoardIssuesController do ...@@ -4,6 +4,12 @@ describe Projects::BoardIssuesController do
let(:project) { create(:project_with_board) } let(:project) { create(:project_with_board) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:planning) { create(:label, project: project, name: 'Planning') }
let(:development) { create(:label, project: project, name: 'Development') }
let!(:list1) { create(:list, board: project.board, label: planning, position: 1) }
let!(:list2) { create(:list, board: project.board, label: development, position: 2) }
before do before do
project.team << [user, :master] project.team << [user, :master]
sign_in(user) sign_in(user)
...@@ -12,19 +18,13 @@ describe Projects::BoardIssuesController do ...@@ -12,19 +18,13 @@ describe Projects::BoardIssuesController do
describe 'GET #index' do describe 'GET #index' do
context 'with valid list id' do context 'with valid list id' do
it 'returns issues that have the list label applied' do it 'returns issues that have the list label applied' do
label1 = create(:label, project: project, name: 'Planning') create(:labeled_issue, project: project, labels: [planning])
label2 = create(:label, project: project, name: 'Development') create(:labeled_issue, project: project, labels: [development])
create(:labeled_issue, project: project, labels: [development])
create(:labeled_issue, project: project, labels: [label1])
create(:labeled_issue, project: project, labels: [label2])
create(:labeled_issue, project: project, labels: [label2])
create(:list, board: project.board, label: label1, position: 1)
development = create(:list, board: project.board, label: label2, position: 2)
get :index, namespace_id: project.namespace.to_param, get :index, namespace_id: project.namespace.to_param,
project_id: project.to_param, project_id: project.to_param,
list_id: development.to_param list_id: list2.to_param
parsed_response = JSON.parse(response.body) parsed_response = JSON.parse(response.body)
...@@ -43,4 +43,44 @@ describe Projects::BoardIssuesController do ...@@ -43,4 +43,44 @@ describe Projects::BoardIssuesController do
end end
end end
end end
describe 'PATCH #update' do
let(:issue) { create(:labeled_issue, project: project, labels: [planning]) }
context 'with valid params' do
it 'returns a successful 200 response' do
move issue: issue, from: list1.id, to: list2.id
expect(response).to have_http_status(200)
end
it 'moves issue to the desired list' do
move issue: issue, from: list1.id, to: list2.id
expect(issue.reload.labels).to contain_exactly(development)
end
end
context 'with invalid params' do
it 'returns a unprocessable entity 422 response for invalid lists' do
move issue: issue, from: nil, to: nil
expect(response).to have_http_status(422)
end
it 'returns a not found 404 response for invalid issue id' do
move issue: 999, from: list1.id, to: list2.id
expect(response).to have_http_status(404)
end
end
def move(issue:, from:, to:)
patch :update, namespace_id: project.namespace.to_param,
project_id: project.to_param,
id: issue.to_param,
issue: { from: from, to: to },
format: :json
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment