Commit b75d28d4 authored by Stan Hu's avatar Stan Hu

Merge branch '53811-issue-boards-to-core-projects-backend-ee' into 'master'

Port Multiple Issue Boards for Projects to Core

See merge request gitlab-org/gitlab-ee!14261
parents a90fe798 b09bf8f2
...@@ -3,8 +3,9 @@ ...@@ -3,8 +3,9 @@
module BoardsResponses module BoardsResponses
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
# Overridden on EE module
def board_params def board_params
params.require(:board).permit(:name, :weight, :milestone_id, :assignee_id, label_ids: []) params.require(:board).permit(:name)
end end
def parent def parent
......
# frozen_string_literal: true
module MultipleBoardsActions
include Gitlab::Utils::StrongMemoize
extend ActiveSupport::Concern
included do
include BoardsActions
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
def recent
recent_visits = ::Boards::VisitsFinder.new(parent, current_user).latest(4)
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.persisted?
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)
respond_to do |format|
format.json do
if service.execute(board)
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? || !latest_visited_board
redirect_to board_path(latest_visited_board.board)
end
def latest_visited_board
@latest_visited_board ||= Boards::VisitsFinder.new(parent, current_user).latest
end
def authorize_create_board!
check_multiple_group_issue_boards_available! if group?
end
def authorize_admin_board!
return render_404 unless can?(current_user, :admin_board, parent)
end
def serializer
BoardSerializer.new(current_user: current_user)
end
def serialize_as_json(resource)
serializer.represent(resource, serializer: 'board', include_full_project_path: board.group_board?)
end
end
# frozen_string_literal: true # frozen_string_literal: true
class Projects::BoardsController < Projects::ApplicationController class Projects::BoardsController < Projects::ApplicationController
include BoardsActions include MultipleBoardsActions
include IssuableCollections include IssuableCollections
before_action :check_issues_available! before_action :check_issues_available!
......
# frozen_string_literal: true
module Boards
class VisitsFinder
attr_accessor :params, :current_user, :parent
def initialize(parent, current_user)
@current_user = current_user
@parent = parent
end
def execute(count = nil)
return unless current_user
recent_visit_model.latest(current_user, parent, count: count)
end
alias_method :latest, :execute
private
def recent_visit_model
parent.is_a?(Group) ? BoardGroupRecentVisit : BoardProjectRecentVisit
end
end
end
...@@ -15,7 +15,8 @@ module BoardsHelper ...@@ -15,7 +15,8 @@ module BoardsHelper
root_path: root_path, root_path: root_path,
bulk_update_path: @bulk_issues_path, bulk_update_path: @bulk_issues_path,
default_avatar: image_path(default_avatar), default_avatar: image_path(default_avatar),
time_tracking_limit_to_hours: Gitlab::CurrentSettings.time_tracking_limit_to_hours.to_s time_tracking_limit_to_hours: Gitlab::CurrentSettings.time_tracking_limit_to_hours.to_s,
recent_boards_endpoint: recent_boards_path
} }
end end
...@@ -87,7 +88,19 @@ module BoardsHelper ...@@ -87,7 +88,19 @@ module BoardsHelper
end end
def boards_link_text def boards_link_text
s_("IssueBoards|Board") if current_board_parent.multiple_issue_boards_available?
s_("IssueBoards|Boards")
else
s_("IssueBoards|Board")
end
end
def recent_boards_path
recent_project_boards_path(@project) if current_board_parent.is_a?(Project)
end
def current_board_json
board.to_json
end end
end end
......
...@@ -1949,9 +1949,8 @@ class Project < ApplicationRecord ...@@ -1949,9 +1949,8 @@ class Project < ApplicationRecord
end end
end end
# Overridden on EE module
def multiple_issue_boards_available? def multiple_issue_boards_available?
false true
end end
def full_path_before_last_save def full_path_before_last_save
......
...@@ -196,6 +196,7 @@ class ProjectPolicy < BasePolicy ...@@ -196,6 +196,7 @@ class ProjectPolicy < BasePolicy
rule { guest & can?(:read_container_image) }.enable :build_read_container_image rule { guest & can?(:read_container_image) }.enable :build_read_container_image
rule { can?(:reporter_access) }.policy do rule { can?(:reporter_access) }.policy do
enable :admin_board
enable :download_code enable :download_code
enable :read_statistics enable :read_statistics
enable :download_wiki_code enable :download_wiki_code
...@@ -240,6 +241,7 @@ class ProjectPolicy < BasePolicy ...@@ -240,6 +241,7 @@ class ProjectPolicy < BasePolicy
rule { can?(:developer_access) & can?(:create_issue) }.enable :import_issues rule { can?(:developer_access) & can?(:create_issue) }.enable :import_issues
rule { can?(:developer_access) }.policy do rule { can?(:developer_access) }.policy do
enable :admin_board
enable :admin_merge_request enable :admin_merge_request
enable :admin_milestone enable :admin_milestone
enable :update_merge_request enable :update_merge_request
...@@ -266,6 +268,7 @@ class ProjectPolicy < BasePolicy ...@@ -266,6 +268,7 @@ class ProjectPolicy < BasePolicy
end end
rule { can?(:maintainer_access) }.policy do rule { can?(:maintainer_access) }.policy do
enable :admin_board
enable :push_to_delete_protected_branch enable :push_to_delete_protected_branch
enable :update_project_snippet enable :update_project_snippet
enable :update_environment enable :update_environment
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
class BoardSimpleEntity < Grape::Entity class BoardSimpleEntity < Grape::Entity
expose :id expose :id
expose :name
end end
BoardSimpleEntity.prepend(EE::BoardSimpleEntity) BoardSimpleEntity.prepend(EE::BoardSimpleEntity)
...@@ -9,7 +9,7 @@ module Boards ...@@ -9,7 +9,7 @@ module Boards
private private
def can_create_board? def can_create_board?
parent.boards.empty? parent.boards.empty? || parent.multiple_issue_boards_available?
end end
def create_board! def create_board!
......
...@@ -3,18 +3,9 @@ ...@@ -3,18 +3,9 @@
module Boards module Boards
class UpdateService < Boards::BaseService class UpdateService < Boards::BaseService
def execute(board) def execute(board)
unless parent.feature_available?(:scoped_issue_board)
params.delete(:milestone_id)
params.delete(:assignee_id)
params.delete(:label_ids)
params.delete(:weight)
end
set_assignee
set_milestone
set_labels
board.update(params) board.update(params)
end end
end end
end end
Boards::UpdateService.prepend(EE::Boards::UpdateService)
# frozen_string_literal: true
module Boards
module Visits
class LatestService < Boards::BaseService
def execute
return unless current_user
recent_visit_model.latest(current_user, parent, count: params[:count])
end
private
def recent_visit_model
parent.is_a?(Group) ? BoardGroupRecentVisit : BoardProjectRecentVisit
end
end
end
end
---
title: Move Multiple Issue Boards for Projects to Core
merge_request:
author:
type: added
...@@ -165,7 +165,11 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -165,7 +165,11 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end end
end end
resources :boards, only: [:index, :show], constraints: { id: /\d+/ } resources :boards, only: [:index, :show, :create, :update, :destroy], constraints: { id: /\d+/ } do
collection do
get :recent
end
end
resources :releases, only: [:index] resources :releases, only: [:index]
resources :forks, only: [:index, :new, :create] resources :forks, only: [:index, :new, :create]
resources :group_links, only: [:index, :create, :update, :destroy], constraints: { id: /\d+/ } resources :group_links, only: [:index, :create, :update, :destroy], constraints: { id: /\d+/ }
......
...@@ -5,90 +5,7 @@ module EE ...@@ -5,90 +5,7 @@ module EE
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
# We need to include the filters as a separate concern since multiple `included` blocks are not allowed include ::MultipleBoardsActions
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 end
end end
...@@ -5,6 +5,11 @@ module EE ...@@ -5,6 +5,11 @@ module EE
extend ActiveSupport::Concern extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
override :board_params
def board_params
params.require(:board).permit(:name, :weight, :milestone_id, :assignee_id, label_ids: [])
end
def authorize_read_parent def authorize_read_parent
authorize_action_for!(board, :read_parent) authorize_action_for!(board, :read_parent)
end end
......
...@@ -17,8 +17,7 @@ module EE ...@@ -17,8 +17,7 @@ module EE
override :board_data override :board_data
def board_data def board_data
show_feature_promotion = (@project && show_promotions? && show_feature_promotion = (@project && show_promotions? &&
(!@project.feature_available?(:multiple_project_issue_boards) || (!@project.feature_available?(:scoped_issue_board) ||
!@project.feature_available?(:scoped_issue_board) ||
!@project.feature_available?(:issue_board_focus_mode))) !@project.feature_available?(:issue_board_focus_mode)))
data = { data = {
......
...@@ -237,11 +237,6 @@ module EE ...@@ -237,11 +237,6 @@ module EE
end end
end end
override :multiple_issue_boards_available?
def multiple_issue_boards_available?
feature_available?(:multiple_project_issue_boards)
end
def multiple_approval_rules_available? def multiple_approval_rules_available?
feature_available?(:multiple_approval_rules) feature_available?(:multiple_approval_rules)
end end
......
...@@ -27,7 +27,6 @@ class License < ApplicationRecord ...@@ -27,7 +27,6 @@ class License < ApplicationRecord
multiple_ldap_servers multiple_ldap_servers
multiple_issue_assignees multiple_issue_assignees
multiple_merge_request_assignees multiple_merge_request_assignees
multiple_project_issue_boards
push_rules push_rules
protected_refs_for_users protected_refs_for_users
related_issues related_issues
...@@ -133,7 +132,6 @@ class License < ApplicationRecord ...@@ -133,7 +132,6 @@ class License < ApplicationRecord
jenkins_integration jenkins_integration
merge_request_approvers merge_request_approvers
multiple_issue_assignees multiple_issue_assignees
multiple_project_issue_boards
multiple_group_issue_boards multiple_group_issue_boards
protected_refs_for_users protected_refs_for_users
push_rules push_rules
......
...@@ -5,11 +5,6 @@ module EE ...@@ -5,11 +5,6 @@ module EE
module CreateService module CreateService
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
override :can_create_board?
def can_create_board?
parent.multiple_issue_boards_available? || super
end
override :create_board! override :create_board!
def create_board! def create_board!
set_assignee set_assignee
......
# frozen_string_literal: true
module EE
module Boards
module UpdateService
extend ::Gitlab::Utils::Override
override :execute
def execute(board)
unless parent.feature_available?(:scoped_issue_board)
params.delete(:milestone_id)
params.delete(:assignee_id)
params.delete(:label_ids)
params.delete(:weight)
end
set_assignee
set_milestone
set_labels
super
end
end
end
end
...@@ -12,12 +12,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -12,12 +12,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
# Begin of the /-/ scope. # Begin of the /-/ scope.
# Use this scope for all new project routes. # Use this scope for all new project routes.
scope '-' do scope '-' do
resources :boards, only: [:create, :update, :destroy] do
collection do
get :recent
end
end
resources :packages, only: [:index, :show, :destroy], module: :packages resources :packages, only: [:index, :show, :destroy], module: :packages
resources :package_files, only: [], module: :packages do resources :package_files, only: [], module: :packages do
member do member do
......
...@@ -13,7 +13,6 @@ describe BoardsResponses do ...@@ -13,7 +13,6 @@ describe BoardsResponses do
before do before do
stub_licensed_features(scoped_issue_board: true) stub_licensed_features(scoped_issue_board: true)
stub_licensed_features(multiple_project_issue_boards: true)
end end
describe '#serialize_as_json' do describe '#serialize_as_json' do
......
...@@ -10,11 +10,13 @@ describe Projects::BoardsController do ...@@ -10,11 +10,13 @@ describe Projects::BoardsController do
end end
describe 'GET index' do describe 'GET index' do
let(:parent) { project }
it 'returns a list of project boards including milestones' do it 'returns a list of project boards including milestones' do
create(:board, project: project, milestone: create(:milestone, project: project)) create(:board, project: project, milestone: create(:milestone, project: project))
create(:board, project: project, milestone_id: Milestone::Upcoming.id) create(:board, project: project, milestone_id: Milestone::Upcoming.id)
list_boards format: :json list_boards
parsed_response = JSON.parse(response.body) parsed_response = JSON.parse(response.body)
...@@ -22,17 +24,7 @@ describe Projects::BoardsController do ...@@ -22,17 +24,7 @@ describe Projects::BoardsController do
expect(parsed_response.length).to eq 2 expect(parsed_response.length).to eq 2
end end
it_behaves_like 'redirects to last visited board' do it_behaves_like 'redirects to last visited board'
let(:parent) { project }
end
def list_boards(format: :html)
get :index, params: {
namespace_id: project.namespace,
project_id: project
},
format: format
end
end end
describe 'GET recent' do describe 'GET recent' do
...@@ -49,10 +41,6 @@ describe Projects::BoardsController do ...@@ -49,10 +41,6 @@ describe Projects::BoardsController do
describe 'POST create' do describe 'POST create' do
context 'with the multiple issue boards available' do context 'with the multiple issue boards available' do
before do
stub_licensed_features(multiple_project_issue_boards: true)
end
context 'with valid params' do context 'with valid params' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:milestone) { create(:milestone, project: project) } let(:milestone) { create(:milestone, project: project) }
...@@ -112,14 +100,6 @@ describe Projects::BoardsController do ...@@ -112,14 +100,6 @@ describe Projects::BoardsController do
end end
end end
it 'renders a 404 when multiple issue boards are not available' do
stub_licensed_features(multiple_project_issue_boards: false)
create_board name: 'Backend'
expect(response).to have_gitlab_http_status(404)
end
def create_board(board_params) def create_board(board_params)
post :create, params: { post :create, params: {
namespace_id: project.namespace.to_param, namespace_id: project.namespace.to_param,
......
...@@ -146,9 +146,9 @@ describe 'Multiple Issue Boards', :js do ...@@ -146,9 +146,9 @@ describe 'Multiple Issue Boards', :js do
end end
end end
# todo: remove these when frontend part is done
context 'with multiple issue boards disabled' do context 'with multiple issue boards disabled' do
before do before do
stub_licensed_features(multiple_project_issue_boards: false)
project.add_maintainer(user) project.add_maintainer(user)
login_as(user) login_as(user)
...@@ -161,8 +161,8 @@ describe 'Multiple Issue Boards', :js do ...@@ -161,8 +161,8 @@ describe 'Multiple Issue Boards', :js do
click_button board.name click_button board.name
page.within(dropdown_selector) do page.within(dropdown_selector) do
expect(page).not_to have_content('Create new board') expect(page).to have_content('Create new board')
expect(page).not_to have_content('Delete board') expect(page).to have_content('Delete board')
end end
expect(page).to have_content('Edit board') expect(page).to have_content('Edit board')
...@@ -176,7 +176,7 @@ describe 'Multiple Issue Boards', :js do ...@@ -176,7 +176,7 @@ describe 'Multiple Issue Boards', :js do
click_button board.name click_button board.name
expect(page).to have_content('Some of your boards are hidden, activate a license to see them again.') expect(page).not_to have_content('Some of your boards are hidden, activate a license to see them again.')
end end
end end
......
...@@ -470,7 +470,7 @@ describe 'Scoped issue boards', :js do ...@@ -470,7 +470,7 @@ describe 'Scoped issue boards', :js do
end end
def create_board_weight(weight) def create_board_weight(weight)
create_board_scope('weight', weight) create_board_scope('weight', weight.to_s)
end end
def create_board_assignee(assignee_name) def create_board_assignee(assignee_name)
...@@ -492,7 +492,7 @@ describe 'Scoped issue boards', :js do ...@@ -492,7 +492,7 @@ describe 'Scoped issue boards', :js do
end end
def update_board_weight(weight) def update_board_weight(weight)
update_board_scope('weight', weight) update_board_scope('weight', weight.to_s)
end end
def create_board_scope(filter, value) def create_board_scope(filter, value)
......
...@@ -66,15 +66,6 @@ describe Boards::CreateService, services: true do ...@@ -66,15 +66,6 @@ describe Boards::CreateService, services: true do
end end
end end
end end
it 'skips creating a second board when the feature is not available' do
stub_licensed_features(multiple_project_issue_boards: false)
service = described_class.new(parent, double)
expect(service.execute).not_to be_nil
expect { service.execute }.not_to change(parent.boards, :count)
end
end end
describe '#execute' do describe '#execute' do
...@@ -84,6 +75,14 @@ describe Boards::CreateService, services: true do ...@@ -84,6 +75,14 @@ describe Boards::CreateService, services: true do
it_behaves_like 'boards create service' do it_behaves_like 'boards create service' do
let(:parent) { create(:group) } let(:parent) { create(:group) }
it 'skips creating a second board when the feature is not available' do
stub_licensed_features(multiple_group_issue_boards: false)
service = described_class.new(parent, double)
expect(service.execute).not_to be_nil
expect { service.execute }.not_to change(parent.boards, :count)
end
end end
it_behaves_like 'board with milestone predefined scope' do it_behaves_like 'board with milestone predefined scope' do
......
...@@ -7,21 +7,11 @@ describe Boards::ListService do ...@@ -7,21 +7,11 @@ describe Boards::ListService do
describe '#execute' do describe '#execute' do
it 'returns all issue boards when multiple issue boards is enabled' do it 'returns all issue boards when multiple issue boards is enabled' do
if parent.is_a?(Group) stub_licensed_features(multiple_group_issue_boards: true)
stub_licensed_features(multiple_group_issue_boards: true)
end
expect(service.execute.size).to eq(3) expect(service.execute.size).to eq(3)
end end
it 'returns the first issue board when multiple issue boards is disabled' do
if parent.is_a?(Project)
stub_licensed_features(multiple_project_issue_boards: false)
end
expect(service.execute.size).to eq(1)
end
it 'returns boards ordered by name' do it 'returns boards ordered by name' do
board_names = ['a-board', 'B-board', 'c-board'].shuffle board_names = ['a-board', 'B-board', 'c-board'].shuffle
boards.each_with_index { |board, i| board.update_column(:name, board_names[i]) } boards.each_with_index { |board, i| board.update_column(:name, board_names[i]) }
...@@ -38,5 +28,11 @@ describe Boards::ListService do ...@@ -38,5 +28,11 @@ describe Boards::ListService do
it_behaves_like 'boards list service' do it_behaves_like 'boards list service' do
let(:parent) { create(:group) } let(:parent) { create(:group) }
it 'returns the first issue board when multiple issue boards is disabled' do
stub_licensed_features(multiple_group_issue_boards: false)
expect(service.execute.size).to eq(1)
end
end end
end end
...@@ -22,7 +22,7 @@ shared_examples 'multiple issue boards show' do ...@@ -22,7 +22,7 @@ shared_examples 'multiple issue boards show' do
context 'when multiple issue boards is disabled' do context 'when multiple issue boards is disabled' do
before do before do
stub_licensed_features(multiple_project_issue_boards: false, multiple_group_issue_boards: false) stub_licensed_features(multiple_group_issue_boards: false)
end end
it 'let user view the default shown board' do it 'let user view the default shown board' do
...@@ -32,10 +32,14 @@ shared_examples 'multiple issue boards show' do ...@@ -32,10 +32,14 @@ shared_examples 'multiple issue boards show' do
expect(assigns(:board)).to eq(board2) expect(assigns(:board)).to eq(board2)
end end
it 'renders 404 when board is not the default' do it 'renders 200 when project board is not the default' do
show(board1) show(board1)
expect(response).to have_gitlab_http_status(404) if parent.is_a?(Project)
expect(response).to have_gitlab_http_status(200)
else
expect(response).to have_gitlab_http_status(404)
end
end end
end end
......
...@@ -38,24 +38,30 @@ shared_examples 'redirects to last visited board' do ...@@ -38,24 +38,30 @@ shared_examples 'redirects to last visited board' do
context 'when multiple boards are disabled' do context 'when multiple boards are disabled' do
before do before do
stub_licensed_features(multiple_project_issue_boards: false, multiple_group_issue_boards: false) stub_licensed_features(multiple_group_issue_boards: false)
end end
it 'renders first board' do it 'renders first board' do
list_boards list_boards(format: :html)
expect(response).to render_template :index if parent.is_a?(Group)
expect(response.content_type).to eq 'text/html' expect(response).to render_template :index
expect(response.content_type).to eq 'text/html'
expect(response).to have_gitlab_http_status(200)
else
expect(response.content_type).to eq 'text/html'
expect(response).to have_gitlab_http_status(302)
end
end end
end end
context 'when multiple boards are enabled' do context 'when multiple boards are enabled' do
before do before do
stub_licensed_features(multiple_project_issue_boards: true, multiple_group_issue_boards: true) stub_licensed_features(multiple_group_issue_boards: true)
end end
it 'redirects to latest visited board' do it 'redirects to latest visited board' do
list_boards list_boards(format: :html)
board_path = if parent.is_a?(Group) board_path = if parent.is_a?(Group)
group_board_path(group_id: parent, id: boards[1].id) group_board_path(group_id: parent, id: boards[1].id)
...@@ -68,7 +74,7 @@ shared_examples 'redirects to last visited board' do ...@@ -68,7 +74,7 @@ shared_examples 'redirects to last visited board' do
end end
end end
def list_boards(recent: false) def list_boards(recent: false, format: :json)
action = recent ? :recent : :index action = recent ? :recent : :index
params = if parent.is_a?(Group) params = if parent.is_a?(Group)
{ group_id: parent } { group_id: parent }
...@@ -76,7 +82,7 @@ def list_boards(recent: false) ...@@ -76,7 +82,7 @@ def list_boards(recent: false)
{ namespace_id: parent.namespace, project_id: parent } { namespace_id: parent.namespace, project_id: parent }
end end
get action, params: params, format: :json get action, params: params, format: format
end end
def visit_board(board, time) def visit_board(board, time)
......
...@@ -4,7 +4,7 @@ shared_examples_for 'multiple and scoped issue boards' do |route_definition| ...@@ -4,7 +4,7 @@ shared_examples_for 'multiple and scoped issue boards' do |route_definition|
context 'multiple issue boards' do context 'multiple issue boards' do
before do before do
board_parent.add_reporter(user) board_parent.add_reporter(user)
stub_licensed_features(multiple_group_issue_boards: true, multiple_project_issue_boards: true) stub_licensed_features(multiple_group_issue_boards: true)
end end
describe "POST #{route_definition}" do describe "POST #{route_definition}" do
......
...@@ -14,14 +14,13 @@ describe 'layouts/nav/sidebar/_project' do ...@@ -14,14 +14,13 @@ describe 'layouts/nav/sidebar/_project' do
end end
describe 'issue boards' do describe 'issue boards' do
it 'has board tab when multiple issue boards is not available' do it 'has boards tab' do
allow(view).to receive(:can?).and_return(true) allow(view).to receive(:can?).and_return(true)
allow(License).to receive(:feature_available?).and_call_original allow(License).to receive(:feature_available?).and_call_original
allow(License).to receive(:feature_available?).with(:multiple_project_issue_boards) { false }
render render
expect(rendered).to have_css('a[title="Board"]') expect(rendered).to have_css('a[title="Boards"]')
end end
end end
......
...@@ -59,7 +59,7 @@ describe Groups::BoardsController do ...@@ -59,7 +59,7 @@ describe Groups::BoardsController do
it 'return an array with one group board' do it 'return an array with one group board' do
create(:board, group: group) create(:board, group: group)
expect(Boards::Visits::LatestService).not_to receive(:new) expect(Boards::VisitsFinder).not_to receive(:new)
list_boards format: :json list_boards format: :json
......
...@@ -65,7 +65,7 @@ describe Projects::BoardsController do ...@@ -65,7 +65,7 @@ describe Projects::BoardsController do
it 'returns a list of project boards' do it 'returns a list of project boards' do
create_list(:board, 2, project: project) create_list(:board, 2, project: project)
expect(Boards::Visits::LatestService).not_to receive(:new) expect(Boards::VisitsFinder).not_to receive(:new)
list_boards format: :json list_boards format: :json
......
...@@ -2,32 +2,32 @@ ...@@ -2,32 +2,32 @@
require 'spec_helper' require 'spec_helper'
describe Boards::Visits::LatestService do describe Boards::VisitsFinder do
describe '#execute' do describe '#latest' do
let(:user) { create(:user) } let(:user) { create(:user) }
context 'when a project board' do context 'when a project board' do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:project_board) { create(:board, project: project) } let(:project_board) { create(:board, project: project) }
subject(:service) { described_class.new(project_board.parent, user) } subject(:finder) { described_class.new(project_board.parent, user) }
it 'returns nil when there is no user' do it 'returns nil when there is no user' do
service.current_user = nil finder.current_user = nil
expect(service.execute).to eq nil expect(finder.execute).to eq nil
end end
it 'queries for most recent visit' do it 'queries for most recent visit' do
expect(BoardProjectRecentVisit).to receive(:latest).once expect(BoardProjectRecentVisit).to receive(:latest).once
service.execute finder.execute
end end
it 'queries for last N visits' do it 'queries for last N visits' do
expect(BoardProjectRecentVisit).to receive(:latest).with(user, project, count: 5).once expect(BoardProjectRecentVisit).to receive(:latest).with(user, project, count: 5).once
described_class.new(project_board.parent, user, count: 5).execute described_class.new(project_board.parent, user).latest(5)
end end
end end
...@@ -35,24 +35,24 @@ describe Boards::Visits::LatestService do ...@@ -35,24 +35,24 @@ describe Boards::Visits::LatestService do
let(:group) { create(:group) } let(:group) { create(:group) }
let(:group_board) { create(:board, group: group) } let(:group_board) { create(:board, group: group) }
subject(:service) { described_class.new(group_board.parent, user) } subject(:finder) { described_class.new(group_board.parent, user) }
it 'returns nil when there is no user' do it 'returns nil when there is no user' do
service.current_user = nil finder.current_user = nil
expect(service.execute).to eq nil expect(finder.execute).to eq nil
end end
it 'queries for most recent visit' do it 'queries for most recent visit' do
expect(BoardGroupRecentVisit).to receive(:latest).once expect(BoardGroupRecentVisit).to receive(:latest).once
service.execute finder.latest
end end
it 'queries for last N visits' do it 'queries for last N visits' do
expect(BoardGroupRecentVisit).to receive(:latest).with(user, group, count: 5).once expect(BoardGroupRecentVisit).to receive(:latest).with(user, group, count: 5).once
described_class.new(group_board.parent, user, count: 5).execute described_class.new(group_board.parent, user).latest(5)
end end
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