Commit fe8201fe authored by Stan Hu's avatar Stan Hu

Merge branch '273002-full-project-issue-boards-api-on-ce' into 'master'

Make all Project Issue Boards API available even in CE

See merge request gitlab-org/gitlab!46137
parents c7f18e7a a6bae002
---
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)
......
......@@ -42,6 +42,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