Commit 6a97e77c authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Move EE boards actions to BoardsActions concern

Previously, `Boards::BoardsController` was prepended to both
`Project::BoardsController` and `Groups::BoardsControllera`.

This is now moved to `EE::BoardsActions` which is prepended to
`BoardsActions` which is already included by both controllers in CE.
parent 92e688f2
......@@ -37,4 +37,4 @@ module BoardsActions
end
end
prepend(EE::BoardsActions)
BoardsActions.prepend(EE::BoardsActions)
# frozen_string_literal: true
module EE
module BoardsActions
extend ActiveSupport::Concern
prepended do
# We need to include the filters as a separate concern since multiple `included` blocks are not allowed
include Filters
end
module Filters
extend ActiveSupport::Concern
included do
before_action :redirect_to_recent_board, only: :index
before_action :authenticate_user!, only: [:recent]
before_action :authorize_create_board!, only: [:create]
before_action :authorize_admin_board!, only: [:create, :update, :destroy]
end
end
def recent
recent_visits = ::Boards::Visits::LatestService.new(parent, current_user, count: 4).execute
recent_boards = recent_visits.map(&:board)
render json: serialize_as_json(recent_boards)
end
def create
board = ::Boards::CreateService.new(parent, current_user, board_params).execute
respond_to do |format|
format.json do
if board.valid?
extra_json = { board_path: board_path(board) }
render json: serialize_as_json(board).merge(extra_json)
else
render json: board.errors, status: :unprocessable_entity
end
end
end
end
def update
service = ::Boards::UpdateService.new(parent, current_user, board_params)
service.execute(board)
respond_to do |format|
format.json do
if board.valid?
extra_json = { board_path: board_path(board) }
render json: serialize_as_json(board).merge(extra_json)
else
render json: board.errors, status: :unprocessable_entity
end
end
end
end
def destroy
service = ::Boards::DestroyService.new(parent, current_user)
service.execute(board)
respond_to do |format|
format.json { head :ok }
format.html { redirect_to boards_path, status: :found }
end
end
private
def redirect_to_recent_board
return if request.format.json? || !parent.multiple_issue_boards_available?
if recently_visited = ::Boards::Visits::LatestService.new(parent, current_user).execute
redirect_to board_path(recently_visited.board)
end
end
def authorize_create_board!
if group?
check_multiple_group_issue_boards_available!
else
check_multiple_project_issue_boards_available!
end
end
def authorize_admin_board!
return render_404 unless can?(current_user, :admin_board, parent)
end
end
end
......@@ -3,6 +3,7 @@
module EE
module BoardsResponses
extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
def authorize_read_parent
authorize_action_for!(board, :read_parent)
......@@ -11,5 +12,15 @@ module EE
def authorize_read_milestone
authorize_action_for!(board, :read_milestone)
end
override :serialize_as_json
def serialize_as_json(resource)
resource.as_json(
only: [:id, :name],
include: {
milestone: { only: [:id, :title] }
}
)
end
end
end
# frozen_string_literal: true
# Shared actions between Groups::BoardsController and Projects::BoardsController
module EE
module Boards
module BoardsController
include ::Gitlab::Utils::StrongMemoize
extend ActiveSupport::Concern
prepended do
before_action :authenticate_user!, only: [:recent]
before_action :authorize_create_board!, only: [:create]
before_action :authorize_admin_board!, only: [:create, :update, :destroy]
end
def recent
recent_visits = ::Boards::Visits::LatestService.new(parent, current_user, count: 4).execute
recent_boards = recent_visits.map(&:board)
render json: serialize_as_json(recent_boards)
end
def create
board = ::Boards::CreateService.new(parent, current_user, board_params).execute
respond_to do |format|
format.json do
if board.valid?
extra_json = { board_path: board_path(board) }
render json: serialize_as_json(board).merge(extra_json)
else
render json: board.errors, status: :unprocessable_entity
end
end
end
end
def update
service = ::Boards::UpdateService.new(parent, current_user, board_params)
service.execute(board)
respond_to do |format|
format.json do
if board.valid?
extra_json = { board_path: board_path(board) }
render json: serialize_as_json(board).merge(extra_json)
else
render json: board.errors, status: :unprocessable_entity
end
end
end
end
def destroy
service = ::Boards::DestroyService.new(parent, current_user)
service.execute(board)
respond_to do |format|
format.json { head :ok }
format.html { redirect_to boards_path, status: :found }
end
end
private
def board
strong_memoize(:board) do
parent.boards.find(params[:id])
end
end
def authorize_create_board!
if group?
check_multiple_group_issue_boards_available!
else
check_multiple_project_issue_boards_available!
end
end
def authorize_admin_board!
return render_404 unless can?(current_user, :admin_board, parent)
end
def serialize_as_json(resource)
resource.as_json(
only: [:id, :name],
include: {
milestone: { only: [:id, :title] }
}
)
end
end
end
end
......@@ -47,6 +47,10 @@ describe Groups::BoardsController do
subject { list_boards }
end
it_behaves_like 'redirects to last visited board' do
let(:parent) { group }
end
def list_boards(format: :html)
get :index, params: { group_id: group }, format: format
end
......
......@@ -29,6 +29,10 @@ describe Projects::BoardsController do
subject { list_boards }
end
it_behaves_like 'redirects to last visited board' do
let(:parent) { project }
end
def list_boards(format: :html)
get :index, params: {
namespace_id: project.namespace,
......
......@@ -5,13 +5,18 @@ shared_examples 'multiple issue boards show' do
let!(:board2) { create(:board, parent: parent, name: 'a') }
context 'when multiple issue boards is enabled' do
it 'let user view any board from parent' do
[board1, board2].each do |board|
show(board)
it 'lets user view board1' do
show(board1)
expect(response).to have_gitlab_http_status(200)
expect(assigns(:board)).to eq(board1)
end
expect(response).to have_gitlab_http_status(200)
expect(assigns(:board)).to eq(board)
end
it 'lets user view board2' do
show(board2)
expect(response).to have_gitlab_http_status(200)
expect(assigns(:board)).to eq(board2)
end
end
......
......@@ -9,7 +9,7 @@ shared_examples 'returns recently visited boards' do
it 'returns a 401' do
sign_out(user)
get_recent_boards
list_boards(recent: true)
expect(response).to have_gitlab_http_status(401)
end
......@@ -20,27 +20,69 @@ shared_examples 'returns recently visited boards' do
visit_board(boards[board_index], Time.now + i.minutes)
end
get_recent_boards
list_boards(recent: true)
expect(json_response.length).to eq(4)
expect(json_response.map { |b| b['id'] }).to eq([1, 7, 3, 5].map { |i| boards[i].id })
end
end
shared_examples 'redirects to last visited board' do
let(:boards) { create_list(:board, 3, parent: parent) }
def visit_board(board, time)
if parent.is_a?(Group)
create(:board_group_recent_visit, group: parent, board: board, user: user, updated_at: time)
else
create(:board_project_recent_visit, project: parent, board: board, user: user, updated_at: time)
before do
visit_board(boards[2], Time.now + 1.minute)
visit_board(boards[0], Time.now + 2.minutes)
visit_board(boards[1], Time.now + 5.minutes)
end
context 'when multiple boards are disabled' do
before do
stub_licensed_features(multiple_project_issue_boards: false, multiple_group_issue_boards: false)
end
it 'renders first board' do
list_boards
expect(response).to render_template :index
expect(response.content_type).to eq 'text/html'
end
end
def get_recent_boards
params = if parent.is_a?(Group)
{ group_id: parent }
else
{ namespace_id: parent.namespace, project_id: parent }
end
context 'when multiple boards are enabled' do
before do
stub_licensed_features(multiple_project_issue_boards: true, multiple_group_issue_boards: true)
end
it 'redirects to latest visited board' do
list_boards
board_path = if parent.is_a?(Group)
group_board_path(group_id: parent, id: boards[1].id)
else
namespace_project_board_path(namespace_id: parent.namespace, project_id: parent, id: boards[1].id)
end
expect(response).to redirect_to(board_path)
end
end
end
def list_boards(recent: false)
action = recent ? :recent : :index
params = if parent.is_a?(Group)
{ group_id: parent }
else
{ namespace_id: parent.namespace, project_id: parent }
end
get action, params: params, format: :json
end
get :recent, params: params, format: :json
def visit_board(board, time)
if parent.is_a?(Group)
create(:board_group_recent_visit, group: parent, board: board, user: user, updated_at: time)
else
create(:board_project_recent_visit, project: parent, board: board, user: user, updated_at: time)
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