Commit 79b0e5dd authored by Tan Le's avatar Tan Le

Move audit events nav item and relax permission

This change moves `Audit Events` sub-menu in `Settings` menu within
Projects and Groups to `Security & Compliance`. We also relax the
permission to view this page from being only to administrator to
developer roles.
parent 0bfd480e
......@@ -21,7 +21,6 @@ module GroupsHelper
integrations#edit
ldap_group_links#index
hooks#index
audit_events#index
pipeline_quota#index
]
end
......
......@@ -437,8 +437,6 @@
%span
= _('Pages')
= render_if_exists 'projects/sidebar/settings_audit_events'
= render 'shared/sidebar_toggle_button'
-# Shortcut to Project > Activity
......
......@@ -5,5 +5,20 @@ module AuditEvents
def audit_logs_params
params.permit(:entity_type, :entity_id, :created_before, :created_after, :sort, :author_id)
end
def audit_params
audit_logs_params
.then { |params| transform_author_entity_type(params) }
.then { |params| filter_by_author(params) }
end
# This is an interim change until we have proper API support within Audit Events
def transform_author_entity_type(params)
return params unless params[:entity_type] == 'Author'
params[:author_id] = params[:entity_id]
params.except(:entity_type, :entity_id)
end
end
end
......@@ -8,13 +8,10 @@ class Groups::AuditEventsController < Groups::ApplicationController
include AuditEvents::DateRange
include Analytics::UniqueVisitsHelper
before_action :authorize_admin_group!
before_action :check_audit_events_available!
track_unique_visits :index, target_id: 'g_compliance_audit_events'
layout 'group_settings'
feature_category :audit_events
def index
......@@ -26,6 +23,11 @@ class Groups::AuditEventsController < Groups::ApplicationController
private
def check_audit_events_available!
render_404 unless can?(current_user, :read_group_audit_events, group) &&
group.feature_available?(:audit_events)
end
def events
strong_memoize(:events) do
level = Gitlab::Audit::Levels::Group.new(group: group)
......@@ -39,16 +41,7 @@ class Groups::AuditEventsController < Groups::ApplicationController
end
end
def audit_params
# This is an interim change until we have proper API support within Audit Events
transform_author_entity_type(audit_logs_params)
end
def transform_author_entity_type(params)
return params unless params[:entity_type] == 'Author'
params[:author_id] = params[:entity_id]
params.except(:entity_type, :entity_id)
def filter_by_author(params)
can?(current_user, :admin_group, group) ? params : params.merge(author_id: current_user.id)
end
end
......@@ -8,11 +8,8 @@ class Projects::AuditEventsController < Projects::ApplicationController
include AuditEvents::Sortable
include AuditEvents::DateRange
before_action :authorize_admin_project!
before_action :check_audit_events_available!
layout 'project_settings'
feature_category :audit_events
def index
......@@ -25,7 +22,8 @@ class Projects::AuditEventsController < Projects::ApplicationController
private
def check_audit_events_available!
render_404 unless @project.feature_available?(:audit_events) || LicenseHelper.show_promotions?(current_user)
render_404 unless can?(current_user, :read_project_audit_events, project) &&
(project.feature_available?(:audit_events) || LicenseHelper.show_promotions?(current_user))
end
def events
......@@ -41,16 +39,7 @@ class Projects::AuditEventsController < Projects::ApplicationController
end
end
def audit_params
# This is an interim change until we have proper API support within Audit Events
transform_author_entity_type(audit_logs_params)
end
def transform_author_entity_type(params)
return params unless params[:entity_type] == 'Author'
params[:author_id] = params[:entity_id]
params.except(:entity_type, :entity_id)
def filter_by_author(params)
can?(current_user, :admin_project, project) ? params : params.merge(author_id: current_user.id)
end
end
......@@ -7,7 +7,6 @@ module EE
override :sidebar_settings_paths
def sidebar_settings_paths
super + %w[
audit_events#index
operations#show
]
end
......@@ -177,6 +176,7 @@ module EE
projects/threat_monitoring#show
projects/threat_monitoring#new
projects/threat_monitoring#edit
projects/audit_events#index
]
end
......@@ -279,6 +279,20 @@ module EE
tabs.any? { |tab| project_nav_tab?(tab) }
end
def top_level_link(project)
return project_security_dashboard_index_path(project) if project_nav_tab?(:security)
return project_audit_events_path(project) if project_nav_tab?(:audit_events)
project_dependencies_path(project)
end
def top_level_qa_selector(project)
return 'security_dashboard_link' if project_nav_tab?(:security)
return 'audit_events_settings_link' if project_nav_tab?(:audit_events)
'dependency_list_link'
end
def show_discover_project_security?(project)
!!current_user &&
::Gitlab.com? &&
......@@ -325,9 +339,18 @@ module EE
nav_tabs << :threat_monitoring
end
if show_audit_events?(project)
nav_tabs << :audit_events
end
nav_tabs
end
def show_audit_events?(project)
can?(current_user, :read_project_audit_events, project) &&
(project.feature_available?(:audit_events) || show_promotions?(current_user))
end
def remove_message_data(project)
{
project: project.path,
......
......@@ -27,9 +27,16 @@ module Groups::SecurityFeaturesHelper
group_security_compliance_dashboard_path(group)
elsif group_level_credentials_inventory_available?(group)
group_security_credentials_path(group)
elsif group_level_audit_events_available?(group)
group_audit_events_path(group)
end
end
def group_level_audit_events_available?(group)
group.feature_available?(:audit_events) &&
can?(current_user, :read_group_audit_events, group)
end
def group_level_security_dashboard_data(group)
{
projects_endpoint: expose_url(api_v4_groups_projects_path(id: group.id)),
......
......@@ -24,12 +24,6 @@
%span
Webhooks
- if @group.feature_available?(:audit_events)
= nav_link(path: 'audit_events#index') do
= link_to group_audit_events_path(@group), title: 'Audit Events', data: { qa_selector: 'audit_events_settings_link' } do
%span
Audit Events
- if show_usage_quotas_in_sidebar? && @group.parent.nil? && administration_nav_item_disabled
= nav_link(path: 'usage_quotas#index') do
= link_to group_usage_quotas_path(@group), title: s_('UsageQuota|Usage Quotas') do
......
- main_path = primary_group_level_security_feature_path(@group)
- if main_path.present?
= nav_link(path: %w[dashboard#show vulnerabilities#index compliance_dashboards#show credentials#index]) do
= nav_link(path: %w[dashboard#show vulnerabilities#index compliance_dashboards#show credentials#index audit_events#index]) do
= link_to main_path, data: { qa_selector: 'security_compliance_link' } do
.nav-icon-container
= sprite_icon('shield')
......@@ -27,6 +27,11 @@
= link_to group_security_credentials_path(@group), title: _('Credentials') do
%span= _('Credentials')
- if group_level_audit_events_available?(@group)
= nav_link(path: 'audit_events#index') do
= link_to group_audit_events_path(@group), title: _('Audit Events'), data: { qa_selector: 'audit_events_settings_link' } do
%span= _('Audit Events')
- elsif show_discover_group_security?(@group)
= nav_link(path: group_security_discover_path(@group)) do
= link_to group_security_discover_path(@group) do
......
- if any_project_nav_tab?([:security, :dependencies, :licenses])
- top_level_link = project_nav_tab?(:security) ? project_security_dashboard_index_path(@project) : project_dependencies_path(@project)
- top_level_qa_selector = project_nav_tab?(:security) ? 'security_dashboard_link' : 'dependency_list_link'
- if any_project_nav_tab?([:security, :dependencies, :licenses, :audit_events])
= nav_link(path: sidebar_security_paths) do
= link_to top_level_link, data: { qa_selector: top_level_qa_selector } do
= link_to top_level_link(@project), data: { qa_selector: top_level_qa_selector(@project) } do
.nav-icon-container
= sprite_icon('shield')
%span.nav-item-name
......@@ -11,14 +8,14 @@
%ul.sidebar-sub-level-items
= nav_link(path: sidebar_security_paths, html_options: { class: "fly-out-top-item" } ) do
= link_to top_level_link do
= link_to top_level_link(@project) do
%strong.fly-out-top-item-name
= _('Security & Compliance')
%li.divider.fly-out-top-item
- if project_nav_tab?(:security)
= nav_link(path: 'projects/security/dashboard#index') do
= link_to project_security_dashboard_index_path(@project), title: _('Security Dashboard') do
= link_to project_security_dashboard_index_path(@project), title: _('Security Dashboard'), data: { qa_selector: 'security_dashboard_link' } do
%span= _('Security Dashboard')
= nav_link(path: ['projects/security/vulnerability_report#index', 'projects/security/vulnerabilities#show']) do
......@@ -50,6 +47,11 @@
= link_to project_security_configuration_path(@project), title: _('Configuration'), data: { qa_selector: 'security_configuration_link'} do
%span= _('Configuration')
- if project_nav_tab?(:audit_events)
= nav_link(controller: :audit_events) do
= link_to project_audit_events_path(@project), title: _('Audit Events'), data: { qa_selector: 'audit_events_settings_link' } do
%span= _('Audit Events')
- elsif show_discover_project_security?(@project)
= nav_link(path: project_security_discover_path(@project)) do
= link_to project_security_discover_path(@project) do
......
- return unless @project.feature_available?(:audit_events) || show_promotions?
= nav_link(controller: :audit_events) do
= link_to project_audit_events_path(@project), title: "Audit Events", data: { qa_selector: 'audit_events_settings_link' } do
= _('Audit Events')
---
title: Adjust Audit Events navigation and visibility
merge_request: 49794
author:
type: changed
......@@ -146,6 +146,39 @@ RSpec.describe Groups::AuditEventsController do
end
end
context 'authorized as user without admin group permission' do
let_it_be(:developer) { create(:user) }
let(:audit_logs_params) do
{
group_id: group.to_param, sort: sort,
entity_type: entity_type, entity_id: entity_id,
author_id: owner.id
}
end
let(:request) do
get :index, params: audit_logs_params
end
before do
stub_licensed_features(audit_events: true)
group.add_developer(developer)
sign_in(developer)
end
it 'returns only events by current user' do
developer_event = create(:group_audit_event, entity_id: group.id, author_id: developer.id)
create(:group_audit_event, entity_id: group.id, author_id: owner.id)
request
actual_event_ids = assigns(:events).map { |event| event[:id] }
expect(actual_event_ids).to contain_exactly(developer_event.id)
end
end
context 'unauthorized' do
let(:request) do
get :index, params: { group_id: group.to_param, sort: sort, entity_type: entity_type, entity_id: entity_id }
......
......@@ -151,6 +151,39 @@ RSpec.describe Projects::AuditEventsController do
end
end
context 'authorized as user without admin project permission' do
let_it_be(:developer) { create(:user) }
let(:audit_logs_params) do
{
namespace_id: project.namespace.to_param, project_id: project.to_param,
sort: sort, entity_type: entity_type, entity_id: entity_id,
author_id: maintainer.id
}
end
let(:request) do
get :index, params: audit_logs_params
end
before do
stub_licensed_features(audit_events: true)
project.add_developer(developer)
sign_in(developer)
end
it 'returns only events by current user' do
developer_event = create(:project_audit_event, entity_id: project.id, author_id: developer.id)
create(:project_audit_event, entity_id: project.id, author_id: maintainer.id)
request
actual_event_ids = assigns(:events).map { |event| event[:id] }
expect(actual_event_ids).to contain_exactly(developer_event.id)
end
end
context 'unauthorized' do
before do
stub_licensed_features(audit_events: true)
......
......@@ -29,14 +29,14 @@ RSpec.describe 'Groups > Audit Events', :js do
end
it 'does not have Audit Events button in head nav bar' do
visit edit_group_path(group)
visit group_security_dashboard_path(group)
expect(page).not_to have_link('Audit Events')
end
end
it 'has Audit Events button in head nav bar' do
visit edit_group_path(group)
visit group_security_dashboard_path(group)
expect(page).to have_link('Audit Events')
end
......@@ -52,9 +52,10 @@ RSpec.describe 'Groups > Audit Events', :js do
click_button 'Maintainer'
end
find(:link, text: 'Settings').click
click_link 'Audit Events'
page.within('.qa-group-sidebar') do
find(:link, text: 'Security & Compliance').click
click_link 'Audit Events'
end
page.within('.audit-log-table') do
expect(page).to have_content 'Changed access level from Developer to Maintainer'
......
......@@ -122,23 +122,23 @@ RSpec.describe 'Group navbar' do
end
context 'when security dashboard is available' do
let(:security_and_compliance_nav_item) do
{
nav_item: _('Security & Compliance'),
nav_sub_items: [
_('Security Dashboard'),
_('Vulnerability Report'),
_('Compliance'),
_('Audit Events')
]
}
end
before do
group.add_owner(user)
stub_licensed_features(security_dashboard: true, group_level_compliance_dashboard: true)
insert_after_nav_item(
_('Merge Requests'),
new_nav_item: {
nav_item: _('Security & Compliance'),
nav_sub_items: [
_('Security Dashboard'),
_('Vulnerability Report'),
_('Compliance')
]
}
)
insert_after_nav_item(_('Members'), new_nav_item: settings_nav_item)
insert_after_nav_item(_('Settings'), new_nav_item: administration_nav_item)
......
......@@ -48,8 +48,8 @@ RSpec.describe 'Projects > Audit Events', :js do
expect(reqs.first.status_code).to eq(200)
end
it 'does not have Audit Events button in head nav bar' do
visit edit_project_path(project)
it 'has Audit Events button in head nav bar' do
visit project_audit_events_path(project)
expect(page).to have_link('Audit Events')
end
......@@ -62,7 +62,7 @@ RSpec.describe 'Projects > Audit Events', :js do
end
it 'has Audit Events button in head nav bar' do
visit edit_project_path(project)
visit project_audit_events_path(project)
expect(page).to have_link('Audit Events')
end
......@@ -117,9 +117,10 @@ RSpec.describe 'Projects > Audit Events', :js do
click_link 'Maintainer'
end
find(:link, text: 'Settings').click
click_link 'Audit Events'
page.within('.qa-project-sidebar') do
find(:link, text: 'Security & Compliance').click
click_link 'Audit Events'
end
page.within('.audit-log-table') do
expect(page).to have_content 'Changed access level from Developer to Maintainer'
......@@ -148,7 +149,7 @@ RSpec.describe 'Projects > Audit Events', :js do
end
page.within('.qa-project-sidebar') do
find(:link, text: 'Settings').click
find(:link, text: 'Security & Compliance').click
click_link 'Audit Events'
end
......
......@@ -34,22 +34,22 @@ RSpec.describe 'Project navbar' do
end
context 'when security dashboard is available' do
let(:security_and_compliance_nav_item) do
{
nav_item: _('Security & Compliance'),
nav_sub_items: [
_('Security Dashboard'),
_('Vulnerability Report'),
s_('OnDemandScans|On-demand Scans'),
_('Configuration'),
_('Audit Events')
]
}
end
before do
stub_licensed_features(security_dashboard: true, security_on_demand_scans: true)
insert_after_nav_item(
_('CI / CD'),
new_nav_item: {
nav_item: _('Security & Compliance'),
nav_sub_items: [
_('Security Dashboard'),
_('Vulnerability Report'),
s_('OnDemandScans|On-demand Scans'),
_('Configuration')
]
}
)
visit project_path(project)
end
......
......@@ -10,6 +10,7 @@ RSpec.describe Groups::SecurityFeaturesHelper do
before do
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:can?).and_return(false)
end
describe '#group_level_security_dashboard_available?' do
......@@ -74,6 +75,27 @@ RSpec.describe Groups::SecurityFeaturesHelper do
end
end
describe '#group_level_audit_events_available?' do
where(:audit_events_feature_enabled, :read_group_audit_events_permission, :result) do
true | false | false
true | true | true
false | false | false
false | true | false
end
with_them do
before do
stub_licensed_features(audit_events: audit_events_feature_enabled)
allow(helper).to receive(:can?).with(user, :read_group_audit_events, group)
.and_return(read_group_audit_events_permission)
end
it 'returns the expected result' do
expect(helper.group_level_audit_events_available?(group)).to eq(result)
end
end
end
describe '#primary_group_level_security_feature_path' do
subject { helper.primary_group_level_security_feature_path(group) }
......@@ -107,11 +129,22 @@ RSpec.describe Groups::SecurityFeaturesHelper do
end
end
context 'group_level_audit_events is available' do
before do
allow(helper).to receive(:group_level_audit_events_available?).with(group).and_return(true)
end
it 'returns path to audit events' do
expect(subject).to eq(group_audit_events_path(group))
end
end
context 'when no security features are available' do
before do
allow(helper).to receive(:group_level_security_dashboard_available?).with(group).and_return(false)
allow(helper).to receive(:group_level_compliance_dashboard_available?).with(group).and_return(false)
allow(helper).to receive(:group_level_credentials_inventory_available?).with(group).and_return(false)
allow(helper).to receive(:group_level_audit_events_available?).with(group).and_return(false)
end
it 'returns nil' do
......
......@@ -220,6 +220,7 @@ RSpec.describe ProjectsHelper do
projects/threat_monitoring#show
projects/threat_monitoring#new
projects/threat_monitoring#edit
projects/audit_events#index
]
end
......@@ -276,6 +277,7 @@ RSpec.describe ProjectsHelper do
before do
allow(helper).to receive(:can?) { false }
allow(helper).to receive(:current_user).and_return(user)
end
subject do
......@@ -304,6 +306,64 @@ RSpec.describe ProjectsHelper do
end
end
describe '#top_level_link' do
let(:user) { build(:user) }
subject { helper.top_level_link(project) }
before do
allow(project).to receive(:feature_available?).and_return(false)
allow(helper).to receive(:can?).and_return(false)
allow(helper).to receive(:current_user).and_return(user)
end
it 'shows security/dashboard path' do
allow(helper).to receive(:can?).with(user, :read_project_security_dashboard, project).and_return(true)
is_expected.to eq("/#{project.full_path}/-/security/dashboard")
end
it 'shows audit_events path' do
allow(helper).to receive(:can?).with(user, :read_project_audit_events, project).and_return(true)
allow(project).to receive(:feature_available?).with(:audit_events).and_return(true)
is_expected.to eq("/#{project.full_path}/-/audit_events")
end
it 'shows dependencies path' do
is_expected.to eq("/#{project.full_path}/-/dependencies")
end
end
describe '#top_level_qa_selector' do
let(:user) { build(:user) }
subject { helper.top_level_qa_selector(project) }
before do
allow(project).to receive(:feature_available?).and_return(false)
allow(helper).to receive(:can?).and_return(false)
allow(helper).to receive(:current_user).and_return(user)
end
it 'shows security dashboard selector' do
allow(helper).to receive(:can?).with(user, :read_project_security_dashboard, project).and_return(true)
is_expected.to eq('security_dashboard_link')
end
it 'shows audit events selector' do
allow(helper).to receive(:can?).with(user, :read_project_audit_events, project).and_return(true)
allow(project).to receive(:feature_available?).with(:audit_events).and_return(true)
is_expected.to eq('audit_events_settings_link')
end
it 'shows dependencies selector' do
is_expected.to eq('dependency_list_link')
end
end
describe '#show_discover_project_security?' do
using RSpec::Parameterized::TableSyntax
let(:user) { create(:user) }
......
......@@ -189,6 +189,40 @@ RSpec.describe 'layouts/nav/sidebar/_group' do
end
end
context 'when audit events feature is enabled' do
before do
stub_licensed_features(audit_events: true)
end
context 'when the user does not have access to Audit Events' do
before do
group.add_guest(user)
allow(view).to receive(:current_user).and_return(user)
end
it 'is not visible' do
render
expect(rendered).not_to have_link 'Security & Compliance'
expect(rendered).not_to have_link 'Audit Events'
end
end
context 'when the user has access to Audit Events' do
before do
group.add_owner(user)
allow(view).to receive(:current_user).and_return(user)
end
it 'is visible' do
render
expect(rendered).to have_link 'Security & Compliance'
expect(rendered).to have_link 'Audit Events'
end
end
end
context 'when security dashboard feature is disabled' do
let(:group) { create(:group_with_plan, plan: :bronze_plan) }
......
......@@ -92,12 +92,14 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
before do
allow(view).to receive(:can?).with(nil, :read_dependencies, project).and_return(can_read_dependencies)
allow(view).to receive(:can?).with(nil, :read_project_security_dashboard, project).and_return(can_read_dashboard)
allow(view).to receive(:can?).with(nil, :read_project_audit_events, project).and_return(can_read_project_audit_events)
render
end
describe 'when the user has full permissions' do
let(:can_read_dashboard) { true }
let(:can_read_dependencies) { true }
let(:can_read_project_audit_events) { true }
it 'top level navigation link is visible' do
expect(rendered).to have_link('Security & Compliance', href: project_security_dashboard_index_path(project))
......@@ -114,11 +116,16 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
it 'dependency list link is visible' do
expect(rendered).to have_link('Dependency List', href: project_dependencies_path(project))
end
it 'audit events link is visible' do
expect(rendered).to have_link('Audit Events', href: project_audit_events_path(project))
end
end
describe 'when the user can view only security dashboard' do
let(:can_read_dashboard) { true }
let(:can_read_dependencies) { false }
let(:can_read_project_audit_events) { false }
it 'top level navigation link is visible' do
expect(rendered).to have_link('Security & Compliance', href: project_security_dashboard_index_path(project))
......@@ -135,11 +142,16 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
it 'dependency list link is not visible' do
expect(rendered).not_to have_link('Dependency List', href: project_dependencies_path(project))
end
it 'audit events link is not visible' do
expect(rendered).not_to have_link('Audit Events', href: project_audit_events_path(project))
end
end
describe 'when the user can view only dependency list' do
let(:can_read_dashboard) { false }
let(:can_read_dependencies) { true }
let(:can_read_project_audit_events) { false }
it 'top level navigation link is visible' do
expect(rendered).to have_link('Security & Compliance', href: project_dependencies_path(project))
......@@ -156,11 +168,42 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
it 'dependency list link is visible' do
expect(rendered).to have_link('Dependency List', href: project_dependencies_path(project))
end
it 'audit events link is not visible' do
expect(rendered).not_to have_link('Audit Events', href: project_audit_events_path(project))
end
end
describe 'when the user can view only audit events' do
let(:can_read_dashboard) { false }
let(:can_read_dependencies) { false }
let(:can_read_project_audit_events) { true }
it 'top level navigation link is visible' do
expect(rendered).to have_link('Security & Compliance', href: project_audit_events_path(project))
end
it 'security dashboard link is not visible' do
expect(rendered).not_to have_link('Security Dashboard', href: project_security_dashboard_index_path(project))
end
it 'security configuration link is not visible' do
expect(rendered).not_to have_link('Configuration', href: project_security_configuration_path(project))
end
it 'dependency list link is not visible' do
expect(rendered).not_to have_link('Dependency List', href: project_dependencies_path(project))
end
it 'audit events link is visible' do
expect(rendered).to have_link('Audit Events', href: project_audit_events_path(project))
end
end
describe 'when the user has no permissions' do
let(:can_read_dependencies) { false }
let(:can_read_dashboard) { false }
let(:can_read_project_audit_events) { false }
it 'top level navigation link is visible' do
expect(rendered).not_to have_link('Security & Compliance', href: project_security_dashboard_index_path(project))
......@@ -177,6 +220,10 @@ RSpec.describe 'layouts/nav/sidebar/_project' do
it 'dependency list link is not visible' do
expect(rendered).not_to have_link('Dependency List', href: project_dependencies_path(project))
end
it 'audit events link is not visible' do
expect(rendered).not_to have_link('Audit Events', href: project_audit_events_path(project))
end
end
end
......
......@@ -33,7 +33,6 @@ module QA
view 'ee/app/views/groups/ee/_settings_nav.html.haml' do
element :ldap_synchronization_link
element :audit_events_settings_link
end
view 'ee/app/views/layouts/nav/ee/_epic_link.html.haml' do
element :group_epics_link
......@@ -44,6 +43,7 @@ module QA
element :group_secure_submenu
element :security_dashboard_link
element :vulnerability_report_link
element :audit_events_settings_link
end
view 'ee/app/views/layouts/nav/_group_insights_link.html.haml' do
......@@ -57,8 +57,8 @@ module QA
end
def go_to_audit_events_settings
hover_element(:group_settings_item) do
within_submenu(:group_sidebar_submenu) do
hover_element(:security_compliance_link) do
within_submenu(:group_secure_submenu) do
click_element(:audit_events_settings_link)
end
end
......
......@@ -14,6 +14,7 @@ module QA
element :security_dashboard_link
element :dependency_list_link
element :vulnerability_report_link
element :audit_events_settings_link
end
end
end
......@@ -47,6 +48,14 @@ module QA
yield
end
end
def go_to_audit_events_settings
hover_security_compliance do
within_submenu do
click_element :audit_events_settings_link
end
end
end
end
end
end
......
......@@ -11,18 +11,6 @@ module QA
def self.prepended(base)
base.class_eval do
prepend QA::Page::Project::SubMenus::Common
view 'ee/app/views/projects/sidebar/_settings_audit_events.html.haml' do
element :audit_events_settings_link
end
end
end
def go_to_audit_events_settings
hover_settings do
within_submenu do
click_element :audit_events_settings_link
end
end
end
......
......@@ -33,6 +33,7 @@ RSpec.describe 'Group navbar' do
nav_item: _('Merge Requests'),
nav_sub_items: []
},
(security_and_compliance_nav_item if Gitlab.ee?),
(push_rules_nav_item if Gitlab.ee?),
{
nav_item: _('Kubernetes'),
......
......@@ -416,6 +416,7 @@ RSpec.describe ProjectsHelper do
describe '#get_project_nav_tabs' do
before do
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:can?) { true }
end
......
......@@ -14,6 +14,15 @@ RSpec.shared_context 'project navbar structure' do
}
end
let(:security_and_compliance_nav_item) do
{
nav_item: _('Security & Compliance'),
nav_sub_items: [
_('Audit Events')
]
}
end
let(:structure) do
[
{
......@@ -62,6 +71,7 @@ RSpec.shared_context 'project navbar structure' do
_('Schedules')
]
},
(security_and_compliance_nav_item if Gitlab.ee?),
{
nav_item: _('Operations'),
nav_sub_items: [
......@@ -101,8 +111,7 @@ RSpec.shared_context 'project navbar structure' do
_('Access Tokens'),
_('Repository'),
_('CI / CD'),
_('Operations'),
(_('Audit Events') if Gitlab.ee?)
_('Operations')
].compact
}
].compact
......@@ -128,8 +137,7 @@ RSpec.shared_context 'group navbar structure' do
_('Projects'),
_('Repository'),
_('CI / CD'),
_('Webhooks'),
_('Audit Events')
_('Webhooks')
]
}
end
......@@ -143,6 +151,15 @@ RSpec.shared_context 'group navbar structure' do
}
end
let(:security_and_compliance_nav_item) do
{
nav_item: _('Security & Compliance'),
nav_sub_items: [
_('Audit Events')
]
}
end
let(:push_rules_nav_item) do
{
nav_item: _('Push Rules'),
......@@ -172,6 +189,7 @@ RSpec.shared_context 'group navbar structure' do
nav_item: _('Merge Requests'),
nav_sub_items: []
},
(security_and_compliance_nav_item if Gitlab.ee?),
(push_rules_nav_item if Gitlab.ee?),
{
nav_item: _('Kubernetes'),
......
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