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 ...@@ -37,4 +37,4 @@ module BoardsActions
end end
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 @@ ...@@ -3,6 +3,7 @@
module EE module EE
module BoardsResponses module BoardsResponses
extend ActiveSupport::Concern extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
def authorize_read_parent def authorize_read_parent
authorize_action_for!(board, :read_parent) authorize_action_for!(board, :read_parent)
...@@ -11,5 +12,15 @@ module EE ...@@ -11,5 +12,15 @@ module EE
def authorize_read_milestone def authorize_read_milestone
authorize_action_for!(board, :read_milestone) authorize_action_for!(board, :read_milestone)
end end
override :serialize_as_json
def serialize_as_json(resource)
resource.as_json(
only: [:id, :name],
include: {
milestone: { only: [:id, :title] }
}
)
end
end 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 ...@@ -47,6 +47,10 @@ describe Groups::BoardsController do
subject { list_boards } subject { list_boards }
end end
it_behaves_like 'redirects to last visited board' do
let(:parent) { group }
end
def list_boards(format: :html) def list_boards(format: :html)
get :index, params: { group_id: group }, format: format get :index, params: { group_id: group }, format: format
end end
......
...@@ -29,6 +29,10 @@ describe Projects::BoardsController do ...@@ -29,6 +29,10 @@ describe Projects::BoardsController do
subject { list_boards } subject { list_boards }
end end
it_behaves_like 'redirects to last visited board' do
let(:parent) { project }
end
def list_boards(format: :html) def list_boards(format: :html)
get :index, params: { get :index, params: {
namespace_id: project.namespace, namespace_id: project.namespace,
......
...@@ -5,13 +5,18 @@ shared_examples 'multiple issue boards show' do ...@@ -5,13 +5,18 @@ shared_examples 'multiple issue boards show' do
let!(:board2) { create(:board, parent: parent, name: 'a') } let!(:board2) { create(:board, parent: parent, name: 'a') }
context 'when multiple issue boards is enabled' do context 'when multiple issue boards is enabled' do
it 'let user view any board from parent' do it 'lets user view board1' do
[board1, board2].each do |board| show(board1)
show(board)
expect(response).to have_gitlab_http_status(200)
expect(assigns(:board)).to eq(board1)
end
expect(response).to have_gitlab_http_status(200) it 'lets user view board2' do
expect(assigns(:board)).to eq(board) show(board2)
end
expect(response).to have_gitlab_http_status(200)
expect(assigns(:board)).to eq(board2)
end end
end end
......
...@@ -9,7 +9,7 @@ shared_examples 'returns recently visited boards' do ...@@ -9,7 +9,7 @@ shared_examples 'returns recently visited boards' do
it 'returns a 401' do it 'returns a 401' do
sign_out(user) sign_out(user)
get_recent_boards list_boards(recent: true)
expect(response).to have_gitlab_http_status(401) expect(response).to have_gitlab_http_status(401)
end end
...@@ -20,27 +20,69 @@ shared_examples 'returns recently visited boards' do ...@@ -20,27 +20,69 @@ shared_examples 'returns recently visited boards' do
visit_board(boards[board_index], Time.now + i.minutes) visit_board(boards[board_index], Time.now + i.minutes)
end end
get_recent_boards list_boards(recent: true)
expect(json_response.length).to eq(4) 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 }) expect(json_response.map { |b| b['id'] }).to eq([1, 7, 3, 5].map { |i| boards[i].id })
end end
end
shared_examples 'redirects to last visited board' do
let(:boards) { create_list(:board, 3, parent: parent) }
def visit_board(board, time) before do
if parent.is_a?(Group) visit_board(boards[2], Time.now + 1.minute)
create(:board_group_recent_visit, group: parent, board: board, user: user, updated_at: time) visit_board(boards[0], Time.now + 2.minutes)
else visit_board(boards[1], Time.now + 5.minutes)
create(:board_project_recent_visit, project: parent, board: board, user: user, updated_at: time) 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
end end
def get_recent_boards context 'when multiple boards are enabled' do
params = if parent.is_a?(Group) before do
{ group_id: parent } stub_licensed_features(multiple_project_issue_boards: true, multiple_group_issue_boards: true)
else end
{ namespace_id: parent.namespace, project_id: parent }
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
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