Commit 9028f616 authored by Arturo Herrero's avatar Arturo Herrero

Merge branch '326429-fj-add-merge_requests-menu' into 'master'

Add Merge Requests and Requirements Menu

See merge request gitlab-org/gitlab!59374
parents 8ed012d0 c2cd4ef6
- if project_nav_tab? :merge_requests
= nav_link(controller: @project.issues_enabled? ? :merge_requests : [:merge_requests, :milestones]) do
= link_to project_merge_requests_path(@project), class: 'shortcuts-merge_requests', data: { qa_selector: 'merge_requests_link' } do
.nav-icon-container
= sprite_icon('git-merge')
%span.nav-item-name#js-onboarding-mr-link
= _('Merge requests')
%span.badge.badge-pill.count.merge_counter.js-merge-counter
= number_with_delimiter(@project.open_merge_requests_count)
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :merge_requests, html_options: { class: "fly-out-top-item" } ) do
= link_to project_merge_requests_path(@project) do
%strong.fly-out-top-item-name
= _('Merge requests')
%span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge
= number_with_delimiter(@project.open_merge_requests_count)
= render_if_exists "layouts/nav/requirements_link", project: @project
- if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts, :test_cases, :pipeline_editor], unless: -> { current_path?('projects/pipelines#charts') }) do
= link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines', data: { qa_selector: 'ci_cd_link' } do
......
- return unless project_nav_tab? :requirements
- refactoring_enabled = Feature.enabled?(:sidebar_refactor, current_user)
= nav_link(path: 'requirements#index') do
= link_to project_requirements_management_requirements_path(project), class: 'qa-project-requirements-link' do
.nav-icon-container
= sprite_icon('requirements')
%span.nav-item-name
= _('Requirements')
%ul.sidebar-sub-level-items{ class: ('is-fly-out-only' if refactoring_enabled) }
= nav_link(path: 'requirements#index', html_options: { class: "fly-out-top-item" } ) do
= link_to project_requirements_management_requirements_path(project) do
%strong.fly-out-top-item-name= _('Requirements')
- if !refactoring_enabled
%li.divider.fly-out-top-item
= nav_link(path: 'requirements#index', html_options: { class: 'home' }) do
= link_to project_requirements_management_requirements_path(project), title: 'List' do
%span= _('List')
- refactoring_enabled = Feature.enabled?(:sidebar_refactor, current_user)
......@@ -13,6 +13,8 @@ module EE
if jira_menu.render?
replace_menu(::Sidebars::Projects::Menus::ExternalIssueTrackerMenu, jira_menu)
end
insert_menu_after(::Sidebars::Projects::Menus::MergeRequestsMenu, ::Sidebars::Projects::Menus::RequirementsMenu.new(context))
end
private
......
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
class RequirementsMenu < ::Sidebars::Menu
override :link
def link
project_requirements_management_requirements_path(context.project)
end
override :configure_menu_items
def configure_menu_items
add_item(list_menu_item)
end
override :render?
def render?
can?(context.current_user, :read_requirement, context.project)
end
override :title
def title
_('Requirements')
end
override :sprite_icon
def sprite_icon
'requirements'
end
override :active_routes
def active_routes
{ path: 'requirements#index' }
end
private
def list_menu_item
return if Feature.enabled?(:sidebar_refactor, context.current_user)
::Sidebars::MenuItem.new(
title: _('List'),
link: project_requirements_management_requirements_path(context.project),
active_routes: { path: 'requirements#index' },
item_id: :requirements_list
)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Sidebars::Projects::Menus::RequirementsMenu do
let(:project) { build(:project) }
let(:user) { project.owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
subject { described_class.new(context) }
before do
stub_licensed_features(requirements: true)
end
describe '#render?' do
context 'when user cannot read requirements' do
let(:user) { nil }
it 'returns false' do
expect(subject.render?).to eq false
end
end
context 'when user can read requirements' do
context 'when feature flag :sidebar_refactor is enabled' do
before do
stub_feature_flags(sidebar_refactor: true)
end
it 'returns true' do
expect(subject.render?).to eq true
end
it 'does not contain any menu item' do
expect(subject.items).to be_empty
end
end
context 'when feature flag :sidebar_refactor is disabled' do
before do
stub_feature_flags(sidebar_refactor: false)
end
it 'returns true' do
expect(subject.render?).to eq true
end
it 'contains list menu item' do
expect(subject.items[0].item_id).to eq :requirements_list
end
end
end
end
end
......@@ -81,6 +81,47 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
describe 'Requirements' do
let(:user) { project.owner }
before do
stub_licensed_features(requirements: true)
allow(view).to receive(:current_user).and_return(user)
end
shared_examples 'has a link to the requirements page' do
specify do
render
expect(rendered).to have_link('Requirements', href: project_requirements_management_requirements_path(project))
end
end
context 'when feature flag :sidebar_refactor is enabled' do
it_behaves_like 'has a link to the requirements page'
it 'does not have a link to the requirement List' do
stub_feature_flags(sidebar_refactor: true)
render
expect(rendered).not_to have_link('List', href: project_requirements_management_requirements_path(project))
end
end
context 'when feature flag :sidebar_refactor is disabled' do
it_behaves_like 'has a link to the requirements page'
it 'has a link to the requirement List' do
stub_feature_flags(sidebar_refactor: false)
render
expect(rendered).to have_link('List', href: project_requirements_management_requirements_path(project))
end
end
end
describe 'Operations main link' do
let(:user) { create(:user) }
......
# frozen_string_literal: true
module Sidebars
module Projects
module Menus
class MergeRequestsMenu < ::Sidebars::Menu
override :link
def link
project_merge_requests_path(context.project)
end
override :extra_container_html_options
def extra_container_html_options
{
class: 'shortcuts-merge_requests'
}
end
override :title
def title
_('Merge requests')
end
override :title_html_options
def title_html_options
{
id: 'js-onboarding-mr-link'
}
end
override :sprite_icon
def sprite_icon
'git-merge'
end
override :render?
def render?
can?(context.current_user, :read_merge_request, context.project) &&
context.project.repo_exists?
end
override :has_pill?
def has_pill?
true
end
override :pill_count
def pill_count
@pill_count ||= context.project.open_merge_requests_count
end
override :pill_html_options
def pill_html_options
{
class: 'merge_counter js-merge-counter'
}
end
override :active_routes
def active_routes
if context.project.issues_enabled?
{ controller: :merge_requests }
else
{ controller: [:merge_requests, :milestones] }
end
end
end
end
end
end
......@@ -13,6 +13,7 @@ module Sidebars
add_menu(Sidebars::Projects::Menus::IssuesMenu.new(context))
add_menu(Sidebars::Projects::Menus::ExternalIssueTrackerMenu.new(context))
add_menu(Sidebars::Projects::Menus::LabelsMenu.new(context))
add_menu(Sidebars::Projects::Menus::MergeRequestsMenu.new(context))
end
override :render_raw_menus_partial
......
......@@ -14,7 +14,6 @@ module QA
include SubMenus::Packages
view 'app/views/layouts/nav/sidebar/_project_menus.html.haml' do
element :merge_requests_link
element :snippets_link
element :members_link
end
......@@ -25,7 +24,7 @@ module QA
def click_merge_requests
within_sidebar do
click_element(:merge_requests_link)
click_element(:sidebar_menu_link, menu_item: 'Merge requests')
end
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Sidebars::Projects::Menus::MergeRequestsMenu do
let_it_be(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
subject { described_class.new(context) }
describe '#render?' do
context 'when repository is not present' do
let(:project) { build(:project) }
it 'returns false' do
expect(subject.render?).to eq false
end
end
context 'when repository is present' do
context 'when user can read merge requests' do
it 'returns true' do
expect(subject.render?).to eq true
end
end
context 'when user cannot read merge requests' do
let(:user) { nil }
it 'returns false' do
expect(subject.render?).to eq false
end
end
end
end
describe '#pill_count' do
it 'returns zero when there are no open merge requests' do
expect(subject.pill_count).to eq 0
end
it 'memoizes the query' do
subject.pill_count
control = ActiveRecord::QueryRecorder.new do
subject.pill_count
end
expect(control.count).to eq 0
end
context 'when there are open merge requests' do
it 'returns the number of open merge requests' do
create_list(:merge_request, 2, :unique_branches, source_project: project, author: user, state: :opened)
create(:merge_request, source_project: project, state: :merged)
expect(subject.pill_count).to eq 2
end
end
end
end
......@@ -243,6 +243,20 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
end
end
describe 'Merge Requests' do
it 'has a link to the merge request list path' do
render
expect(rendered).to have_link('Merge requests', href: project_merge_requests_path(project), class: 'shortcuts-merge_requests')
end
it 'shows pill with the number of merge requests' do
render
expect(rendered).to have_css('span.badge.badge-pill.merge_counter.js-merge-counter')
end
end
describe 'packages tab' do
before do
stub_container_registry_config(enabled: true)
......
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