Commit a6bae002 authored by Takuya Noguchi's avatar Takuya Noguchi

Make all Project Issue Boards API available even in CE

This change moves all project issue boards API to EE to CE, but
filtering by milestons, assignees, and/or weights remains in EE.

This change includes specs for creating, updating, and deleting
project issue board APIs.
Signed-off-by: default avatarTakuya Noguchi <takninnovationresearch@gmail.com>
parent ee8e6fa5
---
title: Make all Project Issue Boards API available even in CE
merge_request: 46137
author: Takuya Noguchi
type: changed
......@@ -8,7 +8,6 @@ module EE
prepended do
use ::Gitlab::Middleware::IpRestrictor
mount ::EE::API::Boards
mount ::EE::API::GroupBoards
mount ::API::AuditEvents
......
# frozen_string_literal: true
module EE
module API
class Boards < ::API::Base
include ::API::PaginationParams
include ::API::BoardsResponses
prepend EE::API::BoardsResponses # rubocop: disable Cop/InjectEnterpriseEditionModule
before { authenticate! }
helpers do
def board_parent
user_project
end
end
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
segment ':id/boards' do
desc 'Create a project board' do
detail 'This feature was introduced in 10.4'
success ::API::Entities::Board
end
params do
requires :name, type: String, desc: 'The board name'
end
post '/' do
authorize!(:admin_board, board_parent)
create_board
end
desc 'Update a project board' do
detail 'This feature was introduced in 11.0'
success ::API::Entities::Board
end
params do
use :update_params
end
put '/:board_id' do
authorize!(:admin_board, board_parent)
update_board
end
desc 'Delete a project board' do
detail 'This feature was introduced in 10.4'
success ::API::Entities::Board
end
delete '/:board_id' do
authorize!(:admin_board, board_parent)
delete_board
end
end
end
end
end
end
......@@ -7,35 +7,7 @@ module EE
prepended do
helpers do
def create_board
forbidden! unless board_parent.multiple_issue_boards_available?
response =
::Boards::CreateService.new(board_parent, current_user, { name: params[:name] }).execute
present response.payload, with: ::API::Entities::Board
end
def update_board
service = ::Boards::UpdateService.new(board_parent, current_user, declared_params(include_missing: false))
service.execute(board)
if board.valid?
present board, with: ::API::Entities::Board
else
bad_request!("Failed to save board #{board.errors.messages}")
end
end
def delete_board
forbidden! unless board_parent.multiple_issue_boards_available?
destroy_conditionally!(board) do |board|
service = ::Boards::DestroyService.new(board_parent, current_user)
service.execute(board)
end
end
# Overrides API::BoardsResponses create_list_params
def create_list_params
params.slice(:label_id, :milestone_id, :assignee_id)
end
......@@ -73,6 +45,7 @@ module EE
exactly_one_of :label_id, :milestone_id, :assignee_id
end
# Overrides API::BoardsResponses update_params
params :update_params do
optional :name, type: String, desc: 'The board name'
optional :assignee_id, type: Integer, desc: 'The ID of a user to associate with board'
......
......@@ -7,11 +7,10 @@ module EE
extend ActiveSupport::Concern
prepended do
# Default filtering configuration
expose :name
expose :group, using: ::API::Entities::BasicGroupDetails
with_options if: ->(board, _) { board.resource_parent.feature_available?(:scoped_issue_board) } do
# Default filtering configuration
expose :milestone do |board|
if board.milestone.is_a?(Milestone)
::API::Entities::Milestone.represent(board.milestone)
......
......@@ -40,6 +40,43 @@ module API
authorize!(:read_board, user_project)
present board, with: Entities::Board
end
desc 'Create a project board' do
detail 'This feature was introduced in 10.4'
success Entities::Board
end
params do
requires :name, type: String, desc: 'The board name'
end
post '/' do
authorize!(:admin_board, board_parent)
create_board
end
desc 'Update a project board' do
detail 'This feature was introduced in 11.0'
success Entities::Board
end
params do
use :update_params
end
put '/:board_id' do
authorize!(:admin_board, board_parent)
update_board
end
desc 'Delete a project board' do
detail 'This feature was introduced in 10.4'
success Entities::Board
end
delete '/:board_id' do
authorize!(:admin_board, board_parent)
delete_board
end
end
params do
......
......@@ -10,6 +10,35 @@ module API
board_parent.boards.find(params[:board_id])
end
def create_board
forbidden! unless board_parent.multiple_issue_boards_available?
response =
::Boards::CreateService.new(board_parent, current_user, { name: params[:name] }).execute
present response.payload, with: Entities::Board
end
def update_board
service = ::Boards::UpdateService.new(board_parent, current_user, declared_params(include_missing: false))
service.execute(board)
if board.valid?
present board, with: Entities::Board
else
bad_request!("Failed to save board #{board.errors.messages}")
end
end
def delete_board
forbidden! unless board_parent.multiple_issue_boards_available?
destroy_conditionally!(board) do |board|
service = ::Boards::DestroyService.new(board_parent, current_user)
service.execute(board)
end
end
def board_lists
board.destroyable_lists
end
......@@ -62,6 +91,12 @@ module API
params :list_creation_params do
requires :label_id, type: Integer, desc: 'The ID of an existing label'
end
params :update_params do
# Configurable issue boards are not available in CE/EE Core.
# https://docs.gitlab.com/ee/user/project/issue_board.html#configurable-issue-boards
optional :name, type: String, desc: 'The board name'
end
end
end
end
......
......@@ -4,6 +4,7 @@ module API
module Entities
class Board < Grape::Entity
expose :id
expose :name
expose :project, using: Entities::BasicProjectDetails
expose :lists, using: Entities::List do |board|
......
......@@ -35,7 +35,46 @@ RSpec.describe API::Boards do
it_behaves_like 'group and project boards', "/projects/:id/boards"
describe "POST /projects/:id/boards/lists" do
describe "POST /projects/:id/boards" do
let(:url) { "/projects/#{board_parent.id}/boards" }
it 'creates a new issue board' do
post api(url, user), params: { name: 'foo' }
expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq('foo')
end
it 'fails to create a new board' do
post api(url, user), params: { some_name: 'foo' }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('name is missing')
end
end
describe "PUT /projects/:id/boards/:board_id" do
let(:url) { "/projects/#{board_parent.id}/boards/#{board.id}" }
it 'updates the issue board' do
put api(url, user), params: { name: 'changed board name' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq('changed board name')
end
end
describe "DELETE /projects/:id/boards/:board_id" do
let(:url) { "/projects/#{board_parent.id}/boards/#{board.id}" }
it 'delete the issue board' do
delete api(url, user)
expect(response).to have_gitlab_http_status(:no_content)
end
end
describe "POST /projects/:id/boards/:board_id/lists" do
let(:url) { "/projects/#{board_parent.id}/boards/#{board.id}/lists" }
it 'creates a new issue board list for group labels' do
......@@ -65,7 +104,7 @@ RSpec.describe API::Boards do
end
end
describe "POST /groups/:id/boards/lists" do
describe "POST /groups/:id/boards/:board_id/lists" do
let_it_be(:group) { create(:group) }
let_it_be(:board_parent) { create(:group, parent: group ) }
let(:url) { "/groups/#{board_parent.id}/boards/#{board.id}/lists" }
......
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