Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/sidebars')
-rw-r--r--spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb42
-rw-r--r--spec/lib/sidebars/admin/menus/admin_overview_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/admin/menus/admin_settings_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/admin/menus/analytics_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/admin/menus/applications_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/admin/menus/ci_cd_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/admin/menus/deploy_keys_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/admin/menus/labels_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/admin/menus/messages_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/admin/menus/system_hooks_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/admin/panel_spec.rb31
-rw-r--r--spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb141
-rw-r--r--spec/lib/sidebars/groups/menus/group_information_menu_spec.rb6
-rw-r--r--spec/lib/sidebars/groups/menus/invite_team_members_menu_spec.rb55
-rw-r--r--spec/lib/sidebars/groups/menus/issues_menu_spec.rb14
-rw-r--r--spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/groups/menus/merge_requests_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/groups/menus/observability_menu_spec.rb60
-rw-r--r--spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb4
-rw-r--r--spec/lib/sidebars/groups/menus/scope_menu_spec.rb16
-rw-r--r--spec/lib/sidebars/groups/menus/settings_menu_spec.rb6
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_menus/analyze_menu_spec.rb28
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_menus/build_menu_spec.rb21
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_menus/manage_menu_spec.rb23
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_menus/monitor_menu_spec.rb22
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_menus/operations_menu_spec.rb24
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_menus/plan_menu_spec.rb30
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_menus/secure_menu_spec.rb25
-rw-r--r--spec/lib/sidebars/groups/super_sidebar_panel_spec.rb55
-rw-r--r--spec/lib/sidebars/menu_item_spec.rb10
-rw-r--r--spec/lib/sidebars/menu_spec.rb132
-rw-r--r--spec/lib/sidebars/panel_spec.rb28
-rw-r--r--spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb16
-rw-r--r--spec/lib/sidebars/projects/menus/confluence_menu_spec.rb9
-rw-r--r--spec/lib/sidebars/projects/menus/deployments_menu_spec.rb8
-rw-r--r--spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb84
-rw-r--r--spec/lib/sidebars/projects/menus/invite_team_members_menu_spec.rb52
-rw-r--r--spec/lib/sidebars/projects/menus/issues_menu_spec.rb25
-rw-r--r--spec/lib/sidebars/projects/menus/merge_requests_menu_spec.rb27
-rw-r--r--spec/lib/sidebars/projects/menus/monitor_menu_spec.rb4
-rw-r--r--spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb29
-rw-r--r--spec/lib/sidebars/projects/menus/project_information_menu_spec.rb6
-rw-r--r--spec/lib/sidebars/projects/menus/repository_menu_spec.rb47
-rw-r--r--spec/lib/sidebars/projects/menus/scope_menu_spec.rb14
-rw-r--r--spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb4
-rw-r--r--spec/lib/sidebars/projects/menus/settings_menu_spec.rb6
-rw-r--r--spec/lib/sidebars/projects/menus/snippets_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/projects/menus/wiki_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/projects/panel_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/analyze_menu_spec.rb30
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/build_menu_spec.rb29
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/code_menu_spec.rb29
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/manage_menu_spec.rb23
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb27
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb27
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb26
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/secure_menu_spec.rb29
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_panel_spec.rb66
-rw-r--r--spec/lib/sidebars/search/panel_spec.rb31
-rw-r--r--spec/lib/sidebars/static_menu_spec.rb44
-rw-r--r--spec/lib/sidebars/uncategorized_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/user_profile/menus/activity_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/user_profile/menus/contributed_projects_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/user_profile/menus/followers_menu_spec.rb14
-rw-r--r--spec/lib/sidebars/user_profile/menus/following_menu_spec.rb14
-rw-r--r--spec/lib/sidebars/user_profile/menus/groups_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/user_profile/menus/overview_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/user_profile/menus/personal_projects_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/user_profile/menus/snippets_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/user_profile/menus/starred_projects_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/user_profile/panel_spec.rb26
-rw-r--r--spec/lib/sidebars/user_settings/menus/access_tokens_menu_spec.rb65
-rw-r--r--spec/lib/sidebars/user_settings/menus/account_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/active_sessions_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/applications_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/authentication_log_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/chat_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/comment_templates_menu_spec.rb65
-rw-r--r--spec/lib/sidebars/user_settings/menus/emails_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/gpg_keys_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/notifications_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/password_menu_spec.rb38
-rw-r--r--spec/lib/sidebars/user_settings/menus/preferences_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/profile_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/menus/ssh_keys_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/panel_spec.rb17
-rw-r--r--spec/lib/sidebars/your_work/panel_spec.rb17
88 files changed, 1964 insertions, 167 deletions
diff --git a/spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb b/spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb
new file mode 100644
index 00000000000..5926852ff57
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::AbuseReportsMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/abuse_reports',
+ title: _('Abuse Reports'),
+ icon: 'slight-frown'
+
+ it_behaves_like 'Admin menu without sub menus', active_routes: { controller: :abuse_reports }
+
+ describe '#pill_count' do
+ let_it_be(:user) { create(:user, :admin) }
+
+ let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
+
+ subject { described_class.new(context) }
+
+ it 'returns zero when there are no abuse reports' 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 abuse reports' do
+ it 'returns the number of abuse reports' do
+ create_list(:abuse_report, 2)
+
+ expect(subject.pill_count).to eq 2
+ end
+ end
+ end
+end
diff --git a/spec/lib/sidebars/admin/menus/admin_overview_menu_spec.rb b/spec/lib/sidebars/admin/menus/admin_overview_menu_spec.rb
new file mode 100644
index 00000000000..d076e73fdd1
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/admin_overview_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::AdminOverviewMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin',
+ title: s_('Admin|Overview'),
+ icon: 'overview'
+
+ it_behaves_like 'Admin menu with sub menus'
+end
diff --git a/spec/lib/sidebars/admin/menus/admin_settings_menu_spec.rb b/spec/lib/sidebars/admin/menus/admin_settings_menu_spec.rb
new file mode 100644
index 00000000000..4c9f603e99f
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/admin_settings_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::AdminSettingsMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/application_settings/general',
+ title: s_('Admin|Settings'),
+ icon: 'settings',
+ separated: true
+
+ it_behaves_like 'Admin menu with sub menus'
+end
diff --git a/spec/lib/sidebars/admin/menus/analytics_menu_spec.rb b/spec/lib/sidebars/admin/menus/analytics_menu_spec.rb
new file mode 100644
index 00000000000..b4aa6e9aeb6
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/analytics_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::AnalyticsMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/dev_ops_reports',
+ title: s_('Admin|Analytics'),
+ icon: 'chart'
+
+ it_behaves_like 'Admin menu with sub menus'
+end
diff --git a/spec/lib/sidebars/admin/menus/applications_menu_spec.rb b/spec/lib/sidebars/admin/menus/applications_menu_spec.rb
new file mode 100644
index 00000000000..0346fa4adfa
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/applications_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::ApplicationsMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/applications',
+ title: s_('Admin|Applications'),
+ icon: 'applications'
+
+ it_behaves_like 'Admin menu without sub menus', active_routes: { controller: :applications }
+end
diff --git a/spec/lib/sidebars/admin/menus/ci_cd_menu_spec.rb b/spec/lib/sidebars/admin/menus/ci_cd_menu_spec.rb
new file mode 100644
index 00000000000..b0d46abbee2
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/ci_cd_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::CiCdMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/runners',
+ title: s_('Admin|CI/CD'),
+ icon: 'rocket'
+
+ it_behaves_like 'Admin menu with sub menus'
+end
diff --git a/spec/lib/sidebars/admin/menus/deploy_keys_menu_spec.rb b/spec/lib/sidebars/admin/menus/deploy_keys_menu_spec.rb
new file mode 100644
index 00000000000..f0ee846fb42
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/deploy_keys_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::DeployKeysMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/deploy_keys',
+ title: s_('Admin|Deploy Keys'),
+ icon: 'key'
+
+ it_behaves_like 'Admin menu without sub menus', active_routes: { controller: :deploy_keys }
+end
diff --git a/spec/lib/sidebars/admin/menus/labels_menu_spec.rb b/spec/lib/sidebars/admin/menus/labels_menu_spec.rb
new file mode 100644
index 00000000000..63e4927ab0d
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/labels_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::LabelsMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/labels',
+ title: s_('Admin|Labels'),
+ icon: 'labels'
+
+ it_behaves_like 'Admin menu without sub menus', active_routes: { controller: :labels }
+end
diff --git a/spec/lib/sidebars/admin/menus/messages_menu_spec.rb b/spec/lib/sidebars/admin/menus/messages_menu_spec.rb
new file mode 100644
index 00000000000..14979b7e47a
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/messages_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::MessagesMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/broadcast_messages',
+ title: s_('Admin|Messages'),
+ icon: 'messages'
+
+ it_behaves_like 'Admin menu without sub menus', active_routes: { controller: :broadcast_messages }
+end
diff --git a/spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb b/spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb
new file mode 100644
index 00000000000..0483159da7a
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::MonitoringMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/system_info',
+ title: s_('Admin|Monitoring'),
+ icon: 'monitor'
+
+ it_behaves_like 'Admin menu with sub menus'
+end
diff --git a/spec/lib/sidebars/admin/menus/system_hooks_menu_spec.rb b/spec/lib/sidebars/admin/menus/system_hooks_menu_spec.rb
new file mode 100644
index 00000000000..a2d0b851091
--- /dev/null
+++ b/spec/lib/sidebars/admin/menus/system_hooks_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Menus::SystemHooksMenu, feature_category: :navigation do
+ it_behaves_like 'Admin menu',
+ link: '/admin/hooks',
+ title: s_('Admin|System Hooks'),
+ icon: 'hook'
+
+ it_behaves_like 'Admin menu without sub menus', active_routes: { controller: :hooks }
+end
diff --git a/spec/lib/sidebars/admin/panel_spec.rb b/spec/lib/sidebars/admin/panel_spec.rb
new file mode 100644
index 00000000000..9c362f527f5
--- /dev/null
+++ b/spec/lib/sidebars/admin/panel_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Admin::Panel, feature_category: :navigation do
+ let_it_be(:user) { build(:admin) }
+
+ let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
+ let(:panel) { described_class.new(context) }
+
+ subject { described_class.new(context) }
+
+ describe '#aria_label' do
+ it 'returns the correct aria label' do
+ expect(panel.aria_label).to eq(_('Admin Area'))
+ end
+ end
+
+ describe '#super_sidebar_context_header' do
+ it 'returns a hash with the correct title and icon' do
+ expected_header = {
+ title: panel.aria_label,
+ icon: 'admin'
+ }
+
+ expect(panel.super_sidebar_context_header).to eq(expected_header)
+ end
+ end
+
+ it_behaves_like 'a panel with uniquely identifiable menu items'
+end
diff --git a/spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb b/spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb
new file mode 100644
index 00000000000..e0c05379a9e
--- /dev/null
+++ b/spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb
@@ -0,0 +1,141 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+RSpec.describe Sidebars::Concerns::SuperSidebarPanel, feature_category: :navigation do
+ let(:menu_class_foo) { Class.new(Sidebars::Menu) }
+ let(:menu_foo) { menu_class_foo.new({}) }
+
+ let(:menu_class_bar) do
+ Class.new(Sidebars::Menu) do
+ def title
+ "Bar"
+ end
+
+ def pick_into_super_sidebar?
+ true
+ end
+ end
+ end
+
+ let(:menu_bar) { menu_class_bar.new({}) }
+
+ subject do
+ Class.new(Sidebars::Panel) do
+ include Sidebars::Concerns::SuperSidebarPanel
+ end.new({})
+ end
+
+ before do
+ allow(menu_foo).to receive(:render?).and_return(true)
+ allow(menu_bar).to receive(:render?).and_return(true)
+ end
+
+ describe '#pick_from_old_menus' do
+ it 'removes items with #pick_into_super_sidebar? from a list and adds them to the panel menus' do
+ old_menus = [menu_foo, menu_bar]
+
+ subject.pick_from_old_menus(old_menus)
+
+ expect(old_menus).to include(menu_foo)
+ expect(subject.renderable_menus).not_to include(menu_foo)
+
+ expect(old_menus).not_to include(menu_bar)
+ expect(subject.renderable_menus).to include(menu_bar)
+ end
+ end
+
+ describe '#transform_old_menus' do
+ let(:uncategorized_menu) { ::Sidebars::UncategorizedMenu.new({}) }
+
+ let(:menu_item) do
+ Sidebars::MenuItem.new(title: 'foo3', link: 'foo3', active_routes: { controller: 'barc' },
+ super_sidebar_parent: menu_class_foo)
+ end
+
+ let(:nil_menu_item) { Sidebars::NilMenuItem.new(item_id: :nil_item) }
+ let(:existing_item) do
+ Sidebars::MenuItem.new(
+ item_id: :exists,
+ title: 'Existing item',
+ link: 'foo2',
+ active_routes: { controller: 'foo2' }
+ )
+ end
+
+ let(:current_menus) { [menu_foo, uncategorized_menu] }
+
+ before do
+ allow(menu_bar).to receive(:serialize_as_menu_item_args).and_return(nil)
+ menu_foo.add_item(existing_item)
+ end
+
+ context 'for Menus with Menu Items' do
+ before do
+ menu_bar.add_item(menu_item)
+ menu_bar.add_item(nil_menu_item)
+ end
+
+ it 'adds Menu Items to defined super_sidebar_parent' do
+ subject.transform_old_menus(current_menus, menu_bar)
+
+ expect(menu_foo.renderable_items).to eq([existing_item, menu_item])
+ expect(uncategorized_menu.renderable_items).to eq([])
+ end
+
+ it 'replaces placeholder Menu Items in the defined super_sidebar_parent' do
+ menu_foo.insert_item_before(:exists, nil_menu_item)
+ allow(menu_item).to receive(:item_id).and_return(:nil_item)
+
+ subject.transform_old_menus(current_menus, menu_bar)
+
+ expect(menu_foo.renderable_items).to eq([menu_item, existing_item])
+ expect(uncategorized_menu.renderable_items).to eq([])
+ end
+
+ it 'considers Menu Items uncategorized if super_sidebar_parent is nil' do
+ allow(menu_item).to receive(:super_sidebar_parent).and_return(nil)
+ subject.transform_old_menus(current_menus, menu_bar)
+
+ expect(menu_foo.renderable_items).to eq([existing_item])
+ expect(uncategorized_menu.renderable_items).to eq([menu_item])
+ end
+
+ it 'considers Menu Items uncategorized if super_sidebar_parent cannot be found' do
+ allow(menu_item).to receive(:super_sidebar_parent).and_return(menu_class_bar)
+ subject.transform_old_menus(current_menus, menu_bar)
+
+ expect(menu_foo.renderable_items).to eq([existing_item])
+ expect(uncategorized_menu.renderable_items).to eq([menu_item])
+ end
+
+ it 'considers Menu Items deleted if super_sidebar_parent is Sidebars::NilMenuItem' do
+ allow(menu_item).to receive(:super_sidebar_parent).and_return(::Sidebars::NilMenuItem)
+ subject.transform_old_menus(current_menus, menu_bar)
+
+ expect(menu_foo.renderable_items).to eq([existing_item])
+ expect(uncategorized_menu.renderable_items).to eq([])
+ end
+ end
+
+ it 'converts "solo" top-level Menu entry to Menu Item' do
+ allow(Sidebars::MenuItem).to receive(:new).and_return(menu_item)
+ allow(menu_bar).to receive(:serialize_as_menu_item_args).and_return({})
+
+ subject.transform_old_menus(current_menus, menu_bar)
+
+ expect(menu_foo.renderable_items).to eq([existing_item, menu_item])
+ expect(uncategorized_menu.renderable_items).to eq([])
+ end
+
+ it 'drops "solo" top-level Menu entries, if they serialize to nil' do
+ allow(Sidebars::MenuItem).to receive(:new).and_return(menu_item)
+ allow(menu_bar).to receive(:serialize_as_menu_item_args).and_return(nil)
+
+ subject.transform_old_menus(current_menus, menu_bar)
+
+ expect(menu_foo.renderable_items).to eq([existing_item])
+ expect(uncategorized_menu.renderable_items).to eq([])
+ end
+ end
+end
diff --git a/spec/lib/sidebars/groups/menus/group_information_menu_spec.rb b/spec/lib/sidebars/groups/menus/group_information_menu_spec.rb
index 1b27db53b6f..4a0301e2f2d 100644
--- a/spec/lib/sidebars/groups/menus/group_information_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/group_information_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Groups::Menus::GroupInformationMenu do
+RSpec.describe Sidebars::Groups::Menus::GroupInformationMenu, feature_category: :navigation do
let_it_be(:owner) { create(:user) }
let_it_be(:root_group) do
build(:group, :private).tap do |g|
@@ -14,6 +14,10 @@ RSpec.describe Sidebars::Groups::Menus::GroupInformationMenu do
let(:user) { owner }
let(:context) { Sidebars::Groups::Context.new(current_user: user, container: group) }
+ it_behaves_like 'not serializable as super_sidebar_menu_args' do
+ let(:menu) { described_class.new(context) }
+ end
+
describe '#title' do
subject { described_class.new(context).title }
diff --git a/spec/lib/sidebars/groups/menus/invite_team_members_menu_spec.rb b/spec/lib/sidebars/groups/menus/invite_team_members_menu_spec.rb
deleted file mode 100644
index a79e5182f45..00000000000
--- a/spec/lib/sidebars/groups/menus/invite_team_members_menu_spec.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Sidebars::Groups::Menus::InviteTeamMembersMenu do
- let_it_be(:owner) { create(:user) }
- let_it_be(:guest) { create(:user) }
- let_it_be(:group) do
- build(:group).tap do |g|
- g.add_owner(owner)
- end
- end
-
- let(:context) { Sidebars::Groups::Context.new(current_user: owner, container: group) }
-
- subject(:invite_menu) { described_class.new(context) }
-
- context 'when the group is viewed by an owner of the group' do
- describe '#render?' do
- it 'renders the Invite team members link' do
- expect(invite_menu.render?).to eq(true)
- end
-
- context 'when the group already has at least 2 members' do
- before do
- group.add_guest(guest)
- end
-
- it 'does not render the link' do
- expect(invite_menu.render?).to eq(false)
- end
- end
- end
-
- describe '#title' do
- it 'displays the correct Invite team members text for the link in the side nav' do
- expect(invite_menu.title).to eq('Invite members')
- end
- end
- end
-
- context 'when the group is viewed by a guest user without admin permissions' do
- let(:context) { Sidebars::Groups::Context.new(current_user: guest, container: group) }
-
- before do
- group.add_guest(guest)
- end
-
- describe '#render?' do
- it 'does not render the link' do
- expect(subject.render?).to eq(false)
- end
- end
- end
-end
diff --git a/spec/lib/sidebars/groups/menus/issues_menu_spec.rb b/spec/lib/sidebars/groups/menus/issues_menu_spec.rb
index 3d55eb3af40..415011e0027 100644
--- a/spec/lib/sidebars/groups/menus/issues_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/issues_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Groups::Menus::IssuesMenu do
+RSpec.describe Sidebars::Groups::Menus::IssuesMenu, feature_category: :navigation do
let_it_be(:owner) { create(:user) }
let_it_be(:group) do
build(:group, :private).tap do |g|
@@ -51,4 +51,16 @@ RSpec.describe Sidebars::Groups::Menus::IssuesMenu do
it_behaves_like 'pill_count formatted results' do
let(:count_service) { ::Groups::OpenIssuesCountService }
end
+
+ it_behaves_like 'serializable as super_sidebar_menu_args' do
+ let(:extra_attrs) do
+ {
+ item_id: :group_issue_list,
+ active_routes: { path: 'groups#issues' },
+ pill_count: menu.pill_count,
+ has_pill: menu.has_pill?,
+ super_sidebar_parent: Sidebars::Groups::SuperSidebarMenus::PlanMenu
+ }
+ end
+ end
end
diff --git a/spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb b/spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb
index 5bf8be9d6e5..8eb9a22e3e1 100644
--- a/spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Groups::Menus::KubernetesMenu, :request_store do
+RSpec.describe Sidebars::Groups::Menus::KubernetesMenu, :request_store, feature_category: :navigation do
let_it_be(:owner) { create(:user) }
let_it_be(:group) do
build(:group, :private).tap do |g|
@@ -14,6 +14,15 @@ RSpec.describe Sidebars::Groups::Menus::KubernetesMenu, :request_store do
let(:context) { Sidebars::Groups::Context.new(current_user: user, container: group) }
let(:menu) { described_class.new(context) }
+ it_behaves_like 'serializable as super_sidebar_menu_args' do
+ let(:extra_attrs) do
+ {
+ super_sidebar_parent: Sidebars::Groups::SuperSidebarMenus::OperationsMenu,
+ item_id: :group_kubernetes_clusters
+ }
+ end
+ end
+
describe '#render?' do
context 'when user can read clusters' do
it 'returns true' do
diff --git a/spec/lib/sidebars/groups/menus/merge_requests_menu_spec.rb b/spec/lib/sidebars/groups/menus/merge_requests_menu_spec.rb
index 3aceff29d6d..a4421226eeb 100644
--- a/spec/lib/sidebars/groups/menus/merge_requests_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/merge_requests_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Groups::Menus::MergeRequestsMenu do
+RSpec.describe Sidebars::Groups::Menus::MergeRequestsMenu, feature_category: :navigation do
let_it_be(:owner) { create(:user) }
let_it_be(:group) do
build(:group, :private).tap do |g|
@@ -33,4 +33,15 @@ RSpec.describe Sidebars::Groups::Menus::MergeRequestsMenu do
it_behaves_like 'pill_count formatted results' do
let(:count_service) { ::Groups::MergeRequestsCountService }
end
+
+ it_behaves_like 'serializable as super_sidebar_menu_args' do
+ let(:extra_attrs) do
+ {
+ item_id: :group_merge_request_list,
+ pill_count: menu.pill_count,
+ has_pill: menu.has_pill?,
+ super_sidebar_parent: Sidebars::Groups::SuperSidebarMenus::CodeMenu
+ }
+ end
+ end
end
diff --git a/spec/lib/sidebars/groups/menus/observability_menu_spec.rb b/spec/lib/sidebars/groups/menus/observability_menu_spec.rb
index 5b993cd6f28..20af8ea00be 100644
--- a/spec/lib/sidebars/groups/menus/observability_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/observability_menu_spec.rb
@@ -20,26 +20,74 @@ RSpec.describe Sidebars::Groups::Menus::ObservabilityMenu do
allow(menu).to receive(:can?).and_call_original
end
- context 'when observability is enabled' do
+ context 'when observability#explore is allowed' do
before do
- allow(Gitlab::Observability).to receive(:observability_enabled?).and_return(true)
+ allow(Gitlab::Observability).to receive(:allowed_for_action?).with(user, group, :explore).and_return(true)
end
it 'returns true' do
expect(menu.render?).to eq true
- expect(Gitlab::Observability).to have_received(:observability_enabled?).with(user, group)
+ expect(Gitlab::Observability).to have_received(:allowed_for_action?).with(user, group, :explore)
end
end
- context 'when observability is disabled' do
+ context 'when observability#explore is not allowed' do
before do
- allow(Gitlab::Observability).to receive(:observability_enabled?).and_return(false)
+ allow(Gitlab::Observability).to receive(:allowed_for_action?).with(user, group, :explore).and_return(false)
end
it 'returns false' do
expect(menu.render?).to eq false
- expect(Gitlab::Observability).to have_received(:observability_enabled?).with(user, group)
+ expect(Gitlab::Observability).to have_received(:allowed_for_action?).with(user, group, :explore)
end
end
end
+
+ describe "Menu items" do
+ before do
+ allow(Gitlab::Observability).to receive(:allowed_for_action?).and_return(false)
+ end
+
+ subject { find_menu(menu, item_id) }
+
+ shared_examples 'observability menu entry' do
+ context 'when action is allowed' do
+ before do
+ allow(Gitlab::Observability).to receive(:allowed_for_action?).with(user, group, item_id).and_return(true)
+ end
+
+ it 'the menu item is added to list of menu items' do
+ is_expected.not_to be_nil
+ end
+ end
+
+ context 'when action is not allowed' do
+ before do
+ allow(Gitlab::Observability).to receive(:allowed_for_action?).with(user, group, item_id).and_return(false)
+ end
+
+ it 'the menu item is added to list of menu items' do
+ is_expected.to be_nil
+ end
+ end
+ end
+
+ describe 'Explore' do
+ it_behaves_like 'observability menu entry' do
+ let(:item_id) { :explore }
+ end
+ end
+
+ describe 'Datasources' do
+ it_behaves_like 'observability menu entry' do
+ let(:item_id) { :datasources }
+ end
+ end
+ end
+
+ private
+
+ def find_menu(menu, item)
+ menu.renderable_items.find { |i| i.item_id == item }
+ end
end
diff --git a/spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb b/spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb
index ce368ad5bd6..382ee07e458 100644
--- a/spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Groups::Menus::PackagesRegistriesMenu do
+RSpec.describe Sidebars::Groups::Menus::PackagesRegistriesMenu, feature_category: :navigation do
let_it_be(:owner) { create(:user) }
let_it_be_with_reload(:group) do
build(:group, :private).tap do |g|
@@ -16,6 +16,8 @@ RSpec.describe Sidebars::Groups::Menus::PackagesRegistriesMenu do
let(:context) { Sidebars::Groups::Context.new(current_user: user, container: group) }
let(:menu) { described_class.new(context) }
+ it_behaves_like 'not serializable as super_sidebar_menu_args'
+
describe '#render?' do
context 'when menu has menu items to show' do
it 'returns true' do
diff --git a/spec/lib/sidebars/groups/menus/scope_menu_spec.rb b/spec/lib/sidebars/groups/menus/scope_menu_spec.rb
index 4b77a09117a..d3aceaf422b 100644
--- a/spec/lib/sidebars/groups/menus/scope_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/scope_menu_spec.rb
@@ -2,14 +2,26 @@
require 'spec_helper'
-RSpec.describe Sidebars::Groups::Menus::ScopeMenu do
+RSpec.describe Sidebars::Groups::Menus::ScopeMenu, feature_category: :navigation do
let(:group) { build(:group) }
let(:user) { group.owner }
let(:context) { Sidebars::Groups::Context.new(current_user: user, container: group) }
+ let(:menu) { described_class.new(context) }
describe '#extra_nav_link_html_options' do
- subject { described_class.new(context).extra_nav_link_html_options }
+ subject { menu.extra_nav_link_html_options }
specify { is_expected.to match(hash_including(class: 'context-header has-tooltip', title: context.group.name)) }
end
+
+ it_behaves_like 'serializable as super_sidebar_menu_args' do
+ let(:extra_attrs) do
+ {
+ sprite_icon: 'group',
+ super_sidebar_parent: ::Sidebars::StaticMenu,
+ title: _('Group overview'),
+ item_id: :group_overview
+ }
+ end
+ end
end
diff --git a/spec/lib/sidebars/groups/menus/settings_menu_spec.rb b/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
index c5246fe93dd..bc30d7628af 100644
--- a/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
@@ -25,6 +25,12 @@ RSpec.describe Sidebars::Groups::Menus::SettingsMenu, :with_license do
end
end
+ describe '#separated?' do
+ it 'returns true' do
+ expect(menu.separated?).to be true
+ end
+ end
+
describe 'Menu items' do
subject { menu.renderable_items.find { |e| e.item_id == item_id } }
diff --git a/spec/lib/sidebars/groups/super_sidebar_menus/analyze_menu_spec.rb b/spec/lib/sidebars/groups/super_sidebar_menus/analyze_menu_spec.rb
new file mode 100644
index 00000000000..3d3d304a5a0
--- /dev/null
+++ b/spec/lib/sidebars/groups/super_sidebar_menus/analyze_menu_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Groups::SuperSidebarMenus::AnalyzeMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Analyze"))
+ expect(subject.sprite_icon).to eq("chart")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :cycle_analytics,
+ :ci_cd_analytics,
+ :contribution_analytics,
+ :devops_adoption,
+ :insights,
+ :issues_analytics,
+ :productivity_analytics,
+ :repository_analytics
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/groups/super_sidebar_menus/build_menu_spec.rb b/spec/lib/sidebars/groups/super_sidebar_menus/build_menu_spec.rb
new file mode 100644
index 00000000000..9437e11c1b6
--- /dev/null
+++ b/spec/lib/sidebars/groups/super_sidebar_menus/build_menu_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Groups::SuperSidebarMenus::BuildMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Build"))
+ expect(subject.sprite_icon).to eq("rocket")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :runners
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/groups/super_sidebar_menus/manage_menu_spec.rb b/spec/lib/sidebars/groups/super_sidebar_menus/manage_menu_spec.rb
new file mode 100644
index 00000000000..916d0942db2
--- /dev/null
+++ b/spec/lib/sidebars/groups/super_sidebar_menus/manage_menu_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Groups::SuperSidebarMenus::ManageMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Manage"))
+ expect(subject.sprite_icon).to eq("users")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :activity,
+ :members,
+ :labels
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/groups/super_sidebar_menus/monitor_menu_spec.rb b/spec/lib/sidebars/groups/super_sidebar_menus/monitor_menu_spec.rb
new file mode 100644
index 00000000000..759975856b8
--- /dev/null
+++ b/spec/lib/sidebars/groups/super_sidebar_menus/monitor_menu_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Groups::SuperSidebarMenus::MonitorMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Monitor"))
+ expect(subject.sprite_icon).to eq("monitor")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :explore,
+ :datasources
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/groups/super_sidebar_menus/operations_menu_spec.rb b/spec/lib/sidebars/groups/super_sidebar_menus/operations_menu_spec.rb
new file mode 100644
index 00000000000..e9c2701021c
--- /dev/null
+++ b/spec/lib/sidebars/groups/super_sidebar_menus/operations_menu_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Groups::SuperSidebarMenus::OperationsMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Operate"))
+ expect(subject.sprite_icon).to eq("deployments")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :dependency_proxy,
+ :packages_registry,
+ :container_registry,
+ :group_kubernetes_clusters
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/groups/super_sidebar_menus/plan_menu_spec.rb b/spec/lib/sidebars/groups/super_sidebar_menus/plan_menu_spec.rb
new file mode 100644
index 00000000000..1ac2cf87236
--- /dev/null
+++ b/spec/lib/sidebars/groups/super_sidebar_menus/plan_menu_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Groups::SuperSidebarMenus::PlanMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Plan"))
+ expect(subject.sprite_icon).to eq("planning")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :group_issue_list,
+ :group_epic_list,
+ :issue_boards,
+ :epic_boards,
+ :roadmap,
+ :milestones,
+ :iterations,
+ :group_wiki,
+ :crm_contacts,
+ :crm_organizations
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/groups/super_sidebar_menus/secure_menu_spec.rb b/spec/lib/sidebars/groups/super_sidebar_menus/secure_menu_spec.rb
new file mode 100644
index 00000000000..9eb81dda462
--- /dev/null
+++ b/spec/lib/sidebars/groups/super_sidebar_menus/secure_menu_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Groups::SuperSidebarMenus::SecureMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Secure"))
+ expect(subject.sprite_icon).to eq("shield")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :security_dashboard,
+ :vulnerability_report,
+ :audit_events,
+ :compliance,
+ :scan_policies
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/groups/super_sidebar_panel_spec.rb b/spec/lib/sidebars/groups/super_sidebar_panel_spec.rb
new file mode 100644
index 00000000000..5035da9c488
--- /dev/null
+++ b/spec/lib/sidebars/groups/super_sidebar_panel_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Groups::SuperSidebarPanel, feature_category: :navigation do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group).tap { |group| group.add_owner(user) } }
+
+ let(:context) do
+ Sidebars::Groups::Context.new(
+ current_user: user,
+ container: group,
+ is_super_sidebar: true,
+ # Turn features off that do not add/remove menu items
+ show_promotions: false,
+ show_discover_group_security: false
+ )
+ end
+
+ subject { described_class.new(context) }
+
+ it 'implements #super_sidebar_context_header' do
+ expect(subject.super_sidebar_context_header).to eq(
+ {
+ title: group.name,
+ avatar: group.avatar_url,
+ id: group.id
+ })
+ end
+
+ describe '#renderable_menus' do
+ let(:category_menu) do
+ [
+ Sidebars::StaticMenu,
+ Sidebars::Groups::SuperSidebarMenus::ManageMenu,
+ Sidebars::Groups::SuperSidebarMenus::PlanMenu,
+ Sidebars::Groups::SuperSidebarMenus::CodeMenu,
+ Sidebars::Groups::SuperSidebarMenus::BuildMenu,
+ Sidebars::Groups::SuperSidebarMenus::SecureMenu,
+ Sidebars::Groups::SuperSidebarMenus::OperationsMenu,
+ Sidebars::Groups::SuperSidebarMenus::MonitorMenu,
+ Sidebars::Groups::SuperSidebarMenus::AnalyzeMenu,
+ Sidebars::UncategorizedMenu,
+ Sidebars::Groups::Menus::SettingsMenu
+ ]
+ end
+
+ it "is exposed as a renderable menu" do
+ expect(subject.instance_variable_get(:@menus).map(&:class)).to eq(category_menu)
+ end
+ end
+
+ it_behaves_like 'a panel with uniquely identifiable menu items'
+ it_behaves_like 'a panel with all menu_items categorized'
+end
diff --git a/spec/lib/sidebars/menu_item_spec.rb b/spec/lib/sidebars/menu_item_spec.rb
index 15804f51934..84bc3430260 100644
--- a/spec/lib/sidebars/menu_item_spec.rb
+++ b/spec/lib/sidebars/menu_item_spec.rb
@@ -18,4 +18,14 @@ RSpec.describe Sidebars::MenuItem do
expect(menu_item.container_html_options).to eq html_options
end
end
+
+ describe "#serialize_for_super_sidebar" do
+ let(:html_options) { { class: 'custom-class' } }
+
+ subject { menu_item.serialize_for_super_sidebar }
+
+ it 'includes custom CSS classes' do
+ expect(subject[:link_classes]).to be('custom-class')
+ end
+ end
end
diff --git a/spec/lib/sidebars/menu_spec.rb b/spec/lib/sidebars/menu_spec.rb
index 53a889c2db8..4f77cb3aed4 100644
--- a/spec/lib/sidebars/menu_spec.rb
+++ b/spec/lib/sidebars/menu_spec.rb
@@ -2,9 +2,10 @@
require 'spec_helper'
-RSpec.describe Sidebars::Menu do
+RSpec.describe Sidebars::Menu, feature_category: :navigation do
let(:menu) { described_class.new(context) }
let(:context) { Sidebars::Context.new(current_user: nil, container: nil) }
+
let(:nil_menu_item) { Sidebars::NilMenuItem.new(item_id: :foo) }
describe '#all_active_routes' do
@@ -21,6 +22,94 @@ RSpec.describe Sidebars::Menu do
end
end
+ describe '#serialize_for_super_sidebar' do
+ before do
+ allow(menu).to receive(:title).and_return('Title')
+ allow(menu).to receive(:active_routes).and_return({ path: 'foo' })
+ end
+
+ it 'returns a tree-like structure of itself and all menu items' do
+ menu.add_item(Sidebars::MenuItem.new(
+ item_id: 'id1',
+ title: 'Is active',
+ link: 'foo2',
+ active_routes: { controller: 'fooc' }
+ ))
+ menu.add_item(Sidebars::MenuItem.new(
+ item_id: 'id2',
+ title: 'Not active',
+ link: 'foo3',
+ active_routes: { controller: 'barc' },
+ has_pill: true,
+ pill_count: 10
+ ))
+ menu.add_item(nil_menu_item)
+
+ allow(context).to receive(:route_is_active).and_return(->(x) { x[:controller] == 'fooc' })
+
+ expect(menu.serialize_for_super_sidebar).to eq(
+ {
+ title: "Title",
+ icon: nil,
+ link: "foo2",
+ is_active: true,
+ pill_count: nil,
+ separated: false,
+ items: [
+ {
+ id: 'id1',
+ title: "Is active",
+ icon: nil,
+ link: "foo2",
+ is_active: true,
+ pill_count: nil,
+ link_classes: nil
+ },
+ {
+ id: 'id2',
+ title: "Not active",
+ icon: nil,
+ link: "foo3",
+ is_active: false,
+ pill_count: 10,
+ link_classes: nil
+ }
+ ]
+ })
+ end
+
+ it 'returns pill data if defined' do
+ allow(menu).to receive(:has_pill?).and_return(true)
+ allow(menu).to receive(:pill_count).and_return('foo')
+ expect(menu.serialize_for_super_sidebar).to eq(
+ {
+ title: "Title",
+ icon: nil,
+ link: nil,
+ is_active: false,
+ pill_count: 'foo',
+ separated: false,
+ items: []
+ })
+ end
+ end
+
+ describe '#serialize_as_menu_item_args' do
+ it 'returns hash of title, link, active_routes, container_html_options' do
+ allow(menu).to receive(:title).and_return('Title')
+ allow(menu).to receive(:active_routes).and_return({ path: 'foo' })
+ allow(menu).to receive(:container_html_options).and_return({ class: 'foo' })
+ allow(menu).to receive(:link).and_return('/link')
+
+ expect(menu.serialize_as_menu_item_args).to eq({
+ title: 'Title',
+ link: '/link',
+ active_routes: { path: 'foo' },
+ container_html_options: { class: 'foo' }
+ })
+ end
+ end
+
describe '#render?' do
context 'when the menus has no items' do
it 'returns false' do
@@ -153,6 +242,47 @@ RSpec.describe Sidebars::Menu do
end
end
+ describe '#replace_placeholder' do
+ let(:item1) { Sidebars::NilMenuItem.new(item_id: :foo1) }
+ let(:item2) { Sidebars::MenuItem.new(item_id: :foo2, title: 'foo2', link: 'foo2', active_routes: {}) }
+ let(:item3) { Sidebars::NilMenuItem.new(item_id: :foo3) }
+
+ subject { menu.instance_variable_get(:@items) }
+
+ before do
+ menu.add_item(item1)
+ menu.add_item(item2)
+ menu.add_item(item3)
+ end
+
+ context 'when a NilMenuItem reference element exists' do
+ it 'replaces the reference element with the provided item' do
+ item = Sidebars::MenuItem.new(item_id: :foo1, title: 'target', active_routes: {}, link: 'target')
+ menu.replace_placeholder(item)
+
+ expect(subject).to eq [item, item2, item3]
+ end
+ end
+
+ context 'when a MenuItem reference element exists' do
+ it 'does not replace the reference element and adds to the end of the list' do
+ item = Sidebars::MenuItem.new(item_id: :foo2, title: 'target', active_routes: {}, link: 'target')
+ menu.replace_placeholder(item)
+
+ expect(subject).to eq [item1, item2, item3, item]
+ end
+ end
+
+ context 'when reference element does not exist' do
+ it 'adds the element to the end of the list' do
+ item = Sidebars::MenuItem.new(item_id: :new_element, title: 'target', active_routes: {}, link: 'target')
+ menu.replace_placeholder(item)
+
+ expect(subject).to eq [item1, item2, item3, item]
+ end
+ end
+ end
+
describe '#remove_element' do
let(:item1) { Sidebars::MenuItem.new(title: 'foo1', link: 'foo1', active_routes: {}, item_id: :foo1) }
let(:item2) { Sidebars::MenuItem.new(title: 'foo2', link: 'foo2', active_routes: {}, item_id: :foo2) }
diff --git a/spec/lib/sidebars/panel_spec.rb b/spec/lib/sidebars/panel_spec.rb
index b70a79361d0..2c1b9c73595 100644
--- a/spec/lib/sidebars/panel_spec.rb
+++ b/spec/lib/sidebars/panel_spec.rb
@@ -2,11 +2,12 @@
require 'spec_helper'
-RSpec.describe Sidebars::Panel do
+RSpec.describe Sidebars::Panel, feature_category: :navigation do
let(:context) { Sidebars::Context.new(current_user: nil, container: nil) }
let(:panel) { Sidebars::Panel.new(context) }
let(:menu1) { Sidebars::Menu.new(context) }
let(:menu2) { Sidebars::Menu.new(context) }
+ let(:menu3) { Sidebars::Menu.new(context) }
describe '#renderable_menus' do
it 'returns only renderable menus' do
@@ -20,6 +21,31 @@ RSpec.describe Sidebars::Panel do
end
end
+ describe '#super_sidebar_menu_items' do
+ it "serializes every renderable menu and returns a flattened result" do
+ panel.add_menu(menu1)
+ panel.add_menu(menu2)
+ panel.add_menu(menu3)
+
+ allow(menu1).to receive(:render?).and_return(true)
+ allow(menu1).to receive(:serialize_for_super_sidebar).and_return("foo")
+
+ allow(menu2).to receive(:render?).and_return(false)
+ allow(menu2).to receive(:serialize_for_super_sidebar).and_return("i-should-not-appear-in-results")
+
+ allow(menu3).to receive(:render?).and_return(true)
+ allow(menu3).to receive(:serialize_for_super_sidebar).and_return(%w[bar baz])
+
+ expect(panel.super_sidebar_menu_items).to eq(%w[foo bar baz])
+ end
+ end
+
+ describe '#super_sidebar_context_header' do
+ it 'raises `NotImplementedError`' do
+ expect { panel.super_sidebar_context_header }.to raise_error(NotImplementedError)
+ end
+ end
+
describe '#has_renderable_menus?' do
it 'returns false when no renderable menus' do
expect(panel.has_renderable_menus?).to be false
diff --git a/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb b/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb
index 2ceb9dcada9..6116fff792a 100644
--- a/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb
@@ -50,20 +50,8 @@ RSpec.describe Sidebars::Projects::Menus::CiCdMenu do
describe 'Artifacts' do
let(:item_id) { :artifacts }
- context 'when feature flag :artifacts_management_page is disabled' do
- it 'does not include artifacts menu item' do
- stub_feature_flags(artifacts_management_page: false)
-
- is_expected.to be_nil
- end
- end
-
- context 'when feature flag :artifacts_management_page is enabled' do
- it 'includes artifacts menu item' do
- stub_feature_flags(artifacts_management_page: true)
-
- is_expected.not_to be_nil
- end
+ it 'includes artifacts menu item' do
+ is_expected.not_to be_nil
end
end
end
diff --git a/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb b/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb
index 836c6d26c6c..55c55b70a43 100644
--- a/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb
@@ -41,4 +41,13 @@ RSpec.describe Sidebars::Projects::Menus::ConfluenceMenu do
end
end
end
+
+ describe 'serialize_as_menu_item_args' do
+ it 'renders as part of the Plan section' do
+ expect(subject.serialize_as_menu_item_args).to include({
+ item_id: :confluence,
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::PlanMenu
+ })
+ end
+ end
end
diff --git a/spec/lib/sidebars/projects/menus/deployments_menu_spec.rb b/spec/lib/sidebars/projects/menus/deployments_menu_spec.rb
index ce971915174..a63acdb5dc2 100644
--- a/spec/lib/sidebars/projects/menus/deployments_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/deployments_menu_spec.rb
@@ -2,12 +2,16 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::DeploymentsMenu do
+RSpec.describe Sidebars::Projects::Menus::DeploymentsMenu, feature_category: :navigation do
let_it_be(:project, reload: true) { create(:project, :repository) }
let(:user) { project.first_owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
+ it_behaves_like 'not serializable as super_sidebar_menu_args' do
+ let(:menu) { described_class.new(context) }
+ end
+
describe '#render?' do
subject { described_class.new(context) }
@@ -47,7 +51,7 @@ RSpec.describe Sidebars::Projects::Menus::DeploymentsMenu do
end
end
- describe 'Feature Flags' do
+ describe 'Feature flags' do
let(:item_id) { :feature_flags }
it_behaves_like 'access rights checks'
diff --git a/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb b/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
index 116948b7cb0..346c681625a 100644
--- a/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
@@ -2,11 +2,15 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::InfrastructureMenu do
+RSpec.describe Sidebars::Projects::Menus::InfrastructureMenu, feature_category: :navigation do
let(:project) { build(:project) }
let(:user) { project.first_owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project, show_cluster_hint: false) }
+ it_behaves_like 'not serializable as super_sidebar_menu_args' do
+ let(:menu) { described_class.new(context) }
+ end
+
describe '#render?' do
subject { described_class.new(context) }
@@ -60,13 +64,13 @@ RSpec.describe Sidebars::Projects::Menus::InfrastructureMenu do
subject.renderable_items.delete(find_menu_item(:kubernetes))
end
- it 'menu link points to Terraform page' do
- expect(subject.link).to eq find_menu_item(:terraform).link
+ it 'menu link points to Terraform states page' do
+ expect(subject.link).to eq find_menu_item(:terraform_states).link
end
- context 'when Terraform menu is not visible' do
+ context 'when Terraform states menu is not visible' do
before do
- subject.renderable_items.delete(find_menu_item(:terraform))
+ subject.renderable_items.delete(find_menu_item(:terraform_states))
end
it 'menu link points to Google Cloud page' do
@@ -99,10 +103,26 @@ RSpec.describe Sidebars::Projects::Menus::InfrastructureMenu do
it_behaves_like 'access rights checks'
end
- describe 'Terraform' do
- let(:item_id) { :terraform }
+ describe 'Terraform states' do
+ let(:item_id) { :terraform_states }
it_behaves_like 'access rights checks'
+
+ context 'if terraform_state.enabled=true' do
+ before do
+ stub_config(terraform_state: { enabled: true })
+ end
+
+ it_behaves_like 'access rights checks'
+ end
+
+ context 'if terraform_state.enabled=false' do
+ before do
+ stub_config(terraform_state: { enabled: false })
+ end
+
+ it { is_expected.to be_nil }
+ end
end
describe 'Google Cloud' do
@@ -141,6 +161,56 @@ RSpec.describe Sidebars::Projects::Menus::InfrastructureMenu do
it_behaves_like 'access rights checks'
end
end
+
+ context 'when instance is not configured for Google OAuth2' do
+ before do
+ stub_feature_flags(incubation_5mp_google_cloud: true)
+ unconfigured_google_oauth2 = Struct.new(:app_id, :app_secret).new('', '')
+ allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for)
+ .with('google_oauth2')
+ .and_return(unconfigured_google_oauth2)
+ end
+
+ it { is_expected.to be_nil }
+ end
+ end
+
+ describe 'AWS' do
+ let(:item_id) { :aws }
+
+ it_behaves_like 'access rights checks'
+
+ context 'when feature flag is turned off globally' do
+ before do
+ stub_feature_flags(cloudseed_aws: false)
+ end
+
+ it { is_expected.to be_nil }
+
+ context 'when feature flag is enabled for specific project' do
+ before do
+ stub_feature_flags(cloudseed_aws: project)
+ end
+
+ it_behaves_like 'access rights checks'
+ end
+
+ context 'when feature flag is enabled for specific group' do
+ before do
+ stub_feature_flags(cloudseed_aws: project.group)
+ end
+
+ it_behaves_like 'access rights checks'
+ end
+
+ context 'when feature flag is enabled for specific project' do
+ before do
+ stub_feature_flags(cloudseed_aws: user)
+ end
+
+ it_behaves_like 'access rights checks'
+ end
+ end
end
end
end
diff --git a/spec/lib/sidebars/projects/menus/invite_team_members_menu_spec.rb b/spec/lib/sidebars/projects/menus/invite_team_members_menu_spec.rb
deleted file mode 100644
index 9838aa8c3e3..00000000000
--- a/spec/lib/sidebars/projects/menus/invite_team_members_menu_spec.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Sidebars::Projects::Menus::InviteTeamMembersMenu do
- let_it_be(:project) { create(:project) }
- let_it_be(:guest) { create(:user) }
-
- let(:context) { Sidebars::Projects::Context.new(current_user: owner, container: project) }
-
- subject(:invite_menu) { described_class.new(context) }
-
- context 'when the project is viewed by an owner of the group' do
- let(:owner) { project.first_owner }
-
- describe '#render?' do
- it 'renders the Invite team members link' do
- expect(invite_menu.render?).to eq(true)
- end
-
- context 'when the project already has at least 2 members' do
- before do
- project.add_guest(guest)
- end
-
- it 'does not render the link' do
- expect(invite_menu.render?).to eq(false)
- end
- end
- end
-
- describe '#title' do
- it 'displays the correct Invite team members text for the link in the side nav' do
- expect(invite_menu.title).to eq('Invite members')
- end
- end
- end
-
- context 'when the project is viewed by a guest user without admin permissions' do
- let(:context) { Sidebars::Projects::Context.new(current_user: guest, container: project) }
-
- before do
- project.add_guest(guest)
- end
-
- describe '#render?' do
- it 'does not render' do
- expect(invite_menu.render?).to eq(false)
- end
- end
- end
-end
diff --git a/spec/lib/sidebars/projects/menus/issues_menu_spec.rb b/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
index 4c0016a77a1..544cbcb956d 100644
--- a/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
@@ -2,13 +2,25 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::IssuesMenu do
+RSpec.describe Sidebars::Projects::Menus::IssuesMenu, feature_category: :navigation do
let(:project) { build(:project) }
let(:user) { project.first_owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
subject { described_class.new(context) }
+ it_behaves_like 'serializable as super_sidebar_menu_args' do
+ let(:menu) { subject }
+ let(:extra_attrs) do
+ {
+ item_id: :project_issue_list,
+ pill_count: menu.pill_count,
+ has_pill: menu.has_pill?,
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::PlanMenu
+ }
+ end
+ end
+
describe '#render?' do
context 'when user can read issues' do
it 'returns true' do
@@ -43,7 +55,7 @@ RSpec.describe Sidebars::Projects::Menus::IssuesMenu do
describe '#pill_count' do
it 'returns zero when there are no open issues' do
- expect(subject.pill_count).to eq 0
+ expect(subject.pill_count).to eq '0'
end
it 'memoizes the query' do
@@ -61,7 +73,14 @@ RSpec.describe Sidebars::Projects::Menus::IssuesMenu do
create_list(:issue, 2, :opened, project: project)
create(:issue, :closed, project: project)
- expect(subject.pill_count).to eq 2
+ expect(subject.pill_count).to eq '2'
+ end
+ end
+
+ describe 'formatting' do
+ it 'returns truncated digits for count value over 1000' do
+ allow(project).to receive(:open_issues_count).and_return 1001
+ expect(subject.pill_count).to eq('1k')
end
end
end
diff --git a/spec/lib/sidebars/projects/menus/merge_requests_menu_spec.rb b/spec/lib/sidebars/projects/menus/merge_requests_menu_spec.rb
index 45c49500e46..08f35b6acd0 100644
--- a/spec/lib/sidebars/projects/menus/merge_requests_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/merge_requests_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::MergeRequestsMenu do
+RSpec.describe Sidebars::Projects::Menus::MergeRequestsMenu, feature_category: :navigation do
let_it_be(:project) { create(:project, :repository) }
let(:user) { project.first_owner }
@@ -10,6 +10,18 @@ RSpec.describe Sidebars::Projects::Menus::MergeRequestsMenu do
subject { described_class.new(context) }
+ it_behaves_like 'serializable as super_sidebar_menu_args' do
+ let(:menu) { subject }
+ let(:extra_attrs) do
+ {
+ item_id: :project_merge_request_list,
+ pill_count: menu.pill_count,
+ has_pill: menu.has_pill?,
+ super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::CodeMenu
+ }
+ end
+ end
+
describe '#render?' do
context 'when repository is not present' do
let(:project) { build(:project) }
@@ -38,7 +50,7 @@ RSpec.describe Sidebars::Projects::Menus::MergeRequestsMenu do
describe '#pill_count' do
it 'returns zero when there are no open merge requests' do
- expect(subject.pill_count).to eq 0
+ expect(subject.pill_count).to eq '0'
end
it 'memoizes the query' do
@@ -56,7 +68,16 @@ RSpec.describe Sidebars::Projects::Menus::MergeRequestsMenu 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
+ expect(subject.pill_count).to eq '2'
+ end
+ end
+
+ describe 'formatting' do
+ it 'returns truncated digits for count value over 1000' do
+ create_list(:merge_request, 1001, :unique_branches, source_project: project, author: user, state: :opened)
+ create(:merge_request, source_project: project, state: :merged)
+
+ expect(subject.pill_count).to eq('1k')
end
end
end
diff --git a/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb b/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
index a1e6ae13e68..aa1e67085cd 100644
--- a/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
@@ -57,6 +57,10 @@ RSpec.describe Sidebars::Projects::Menus::MonitorMenu do
end
context 'Menu items' do
+ before do
+ stub_feature_flags(remove_monitor_metrics: false)
+ end
+
subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } }
shared_examples 'access rights checks' do
diff --git a/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb b/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb
index b03269c424a..860206dc6af 100644
--- a/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do
+RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu, feature_category: :navigation do
let_it_be(:project) { create(:project) }
let_it_be(:harbor_integration) { create(:harbor_integration, project: project) }
@@ -12,6 +12,10 @@ RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do
subject { described_class.new(context) }
+ it_behaves_like 'not serializable as super_sidebar_menu_args' do
+ let(:menu) { subject }
+ end
+
describe '#render?' do
context 'when menu does not have any menu item to show' do
it 'returns false' do
@@ -35,7 +39,7 @@ RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do
before do
stub_container_registry_config(enabled: registry_enabled)
stub_config(packages: { enabled: packages_enabled })
- stub_feature_flags(harbor_registry_integration: false)
+ stub_feature_flags(harbor_registry_integration: false, ml_experiment_tracking: false)
end
context 'when Packages Registry is visible' do
@@ -164,6 +168,7 @@ RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do
stub_feature_flags(harbor_registry_integration: true)
is_expected.not_to be_nil
+ expect(subject.active_routes[:controller]).to eq('projects/harbor/repositories')
end
end
@@ -176,5 +181,25 @@ RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do
end
end
end
+
+ describe 'Model experiments' do
+ let(:item_id) { :model_experiments }
+
+ context 'when :ml_experiment_tracking is enabled' do
+ it 'shows the menu item' do
+ stub_feature_flags(ml_experiment_tracking: true)
+
+ is_expected.not_to be_nil
+ end
+ end
+
+ context 'when :ml_experiment_tracking is disabled' do
+ it 'does not show the menu item' do
+ stub_feature_flags(ml_experiment_tracking: false)
+
+ is_expected.to be_nil
+ end
+ end
+ end
end
end
diff --git a/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb b/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb
index 7ff06ac229e..7547f152b27 100644
--- a/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb
@@ -2,12 +2,16 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::ProjectInformationMenu do
+RSpec.describe Sidebars::Projects::Menus::ProjectInformationMenu, feature_category: :navigation do
let_it_be_with_reload(:project) { create(:project, :repository) }
let(:user) { project.first_owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
+ it_behaves_like 'not serializable as super_sidebar_menu_args' do
+ let(:menu) { described_class.new(context) }
+ end
+
describe '#container_html_options' do
subject { described_class.new(context).container_html_options }
diff --git a/spec/lib/sidebars/projects/menus/repository_menu_spec.rb b/spec/lib/sidebars/projects/menus/repository_menu_spec.rb
index 40ca2107698..1aa0ea30d0a 100644
--- a/spec/lib/sidebars/projects/menus/repository_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/repository_menu_spec.rb
@@ -6,7 +6,11 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou
let_it_be(:project) { create(:project, :repository) }
let(:user) { project.first_owner }
- let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project, current_ref: 'master') }
+ let(:is_super_sidebar) { false }
+ let(:context) do
+ Sidebars::Projects::Context.new(current_user: user, container: project, current_ref: 'master',
+ is_super_sidebar: is_super_sidebar)
+ end
subject { described_class.new(context) }
@@ -36,9 +40,8 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou
end
context 'for menu items' do
- shared_examples_for 'repository menu item link for' do |item_id|
+ shared_examples_for 'repository menu item link for' do
let(:ref) { 'master' }
- let(:item_id) { item_id }
subject { described_class.new(context).renderable_items.find { |e| e.item_id == item_id }.link }
using RSpec::Parameterized::TableSyntax
@@ -77,15 +80,39 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou
end
end
+ shared_examples_for 'repository menu item with different super sidebar title' do |title, super_sidebar_title|
+ subject { described_class.new(context).renderable_items.find { |e| e.item_id == item_id } }
+
+ specify do
+ expect(subject.title).to eq(title)
+ end
+
+ context 'when inside the super sidebar' do
+ let(:is_super_sidebar) { true }
+
+ specify do
+ expect(subject.title).to eq(super_sidebar_title)
+ end
+ end
+ end
+
+ describe 'Files' do
+ let_it_be(:item_id) { :files }
+
+ it_behaves_like 'repository menu item with different super sidebar title',
+ _('Files'),
+ _('Repository')
+ end
+
describe 'Commits' do
let_it_be(:item_id) { :commits }
- it_behaves_like 'repository menu item link for', :commits do
+ it_behaves_like 'repository menu item link for' do
let(:route) { "/#{project.full_path}/-/commits/#{ref}" }
end
end
- describe 'Contributors' do
+ describe 'Contributor statistics' do
let_it_be(:item_id) { :contributors }
context 'when analytics is disabled' do
@@ -103,16 +130,22 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou
project.project_feature.update!(analytics_access_level: ProjectFeature::ENABLED)
end
- it_behaves_like 'repository menu item link for', :contributors do
+ it_behaves_like 'repository menu item link for' do
let(:route) { "/#{project.full_path}/-/graphs/#{ref}" }
end
end
end
describe 'Network' do
- it_behaves_like 'repository menu item link for', :graphs do
+ let_it_be(:item_id) { :graphs }
+
+ it_behaves_like 'repository menu item link for' do
let(:route) { "/#{project.full_path}/-/network/#{ref}" }
end
+
+ it_behaves_like 'repository menu item with different super sidebar title',
+ _('Graph'),
+ _('Repository graph')
end
end
end
diff --git a/spec/lib/sidebars/projects/menus/scope_menu_spec.rb b/spec/lib/sidebars/projects/menus/scope_menu_spec.rb
index 4e87f3b8ead..45464278880 100644
--- a/spec/lib/sidebars/projects/menus/scope_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/scope_menu_spec.rb
@@ -2,11 +2,23 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::ScopeMenu do
+RSpec.describe Sidebars::Projects::Menus::ScopeMenu, feature_category: :navigation do
let(:project) { build(:project) }
let(:user) { project.first_owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
+ it_behaves_like 'serializable as super_sidebar_menu_args' do
+ let(:menu) { described_class.new(context) }
+ let(:extra_attrs) do
+ {
+ title: _('Project overview'),
+ sprite_icon: 'project',
+ super_sidebar_parent: ::Sidebars::StaticMenu,
+ item_id: :project_overview
+ }
+ end
+ end
+
describe '#container_html_options' do
subject { described_class.new(context).container_html_options }
diff --git a/spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb b/spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb
index 41158bd58dc..697359b7941 100644
--- a/spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Sidebars::Projects::Menus::SecurityComplianceMenu do
end
context 'when user is authenticated' do
- context 'when the Security & Compliance is disabled' do
+ context 'when the Security and Compliance is disabled' do
before do
allow(Ability).to receive(:allowed?).with(user, :access_security_and_compliance, project).and_return(false)
end
@@ -28,7 +28,7 @@ RSpec.describe Sidebars::Projects::Menus::SecurityComplianceMenu do
it { is_expected.to be_falsey }
end
- context 'when the Security & Compliance is not disabled' do
+ context 'when the Security and Compliance is not disabled' do
it { is_expected.to be_truthy }
end
end
diff --git a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb
index c7aca0fb97e..4be99892631 100644
--- a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb
@@ -22,6 +22,12 @@ RSpec.describe Sidebars::Projects::Menus::SettingsMenu do
end
end
+ describe '#separated?' do
+ it 'returns true' do
+ expect(subject.separated?).to be true
+ end
+ end
+
describe 'Menu items' do
subject { described_class.new(context).renderable_items.find { |e| e.item_id == item_id } }
diff --git a/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb b/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb
index 04b8c128e3d..9d50eb6f817 100644
--- a/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb
@@ -2,13 +2,23 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::SnippetsMenu do
+RSpec.describe Sidebars::Projects::Menus::SnippetsMenu, feature_category: :navigation do
let(:project) { build(:project) }
let(:user) { project.first_owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
subject { described_class.new(context) }
+ it_behaves_like 'serializable as super_sidebar_menu_args' do
+ let(:menu) { subject }
+ let(:extra_attrs) do
+ {
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::CodeMenu,
+ item_id: :project_snippets
+ }
+ end
+ end
+
describe '#render?' do
context 'when user cannot access snippets' do
let(:user) { nil }
diff --git a/spec/lib/sidebars/projects/menus/wiki_menu_spec.rb b/spec/lib/sidebars/projects/menus/wiki_menu_spec.rb
index 362da3e7b50..64050e3e488 100644
--- a/spec/lib/sidebars/projects/menus/wiki_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/wiki_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::WikiMenu do
+RSpec.describe Sidebars::Projects::Menus::WikiMenu, feature_category: :navigation do
let(:project) { build(:project) }
let(:user) { project.first_owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
@@ -28,4 +28,14 @@ RSpec.describe Sidebars::Projects::Menus::WikiMenu do
end
end
end
+
+ it_behaves_like 'serializable as super_sidebar_menu_args' do
+ let(:menu) { subject }
+ let(:extra_attrs) do
+ {
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::PlanMenu,
+ item_id: :project_wiki
+ }
+ end
+ end
end
diff --git a/spec/lib/sidebars/projects/panel_spec.rb b/spec/lib/sidebars/projects/panel_spec.rb
index ff253eedd08..ec1df438cf1 100644
--- a/spec/lib/sidebars/projects/panel_spec.rb
+++ b/spec/lib/sidebars/projects/panel_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Panel do
+RSpec.describe Sidebars::Projects::Panel, feature_category: :navigation do
let_it_be(:project) { create(:project) }
let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project) }
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/analyze_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/analyze_menu_spec.rb
new file mode 100644
index 00000000000..d459d47c31a
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/analyze_menu_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::AnalyzeMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Analyze"))
+ expect(subject.sprite_icon).to eq("chart")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :dashboards_analytics,
+ :cycle_analytics,
+ :contributors,
+ :ci_cd_analytics,
+ :repository_analytics,
+ :code_review,
+ :merge_request_analytics,
+ :issues,
+ :insights,
+ :model_experiments
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/build_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/build_menu_spec.rb
new file mode 100644
index 00000000000..3f2a40e1c7d
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/build_menu_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::BuildMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Build"))
+ expect(subject.sprite_icon).to eq("rocket")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :pipelines,
+ :jobs,
+ :pipelines_editor,
+ :releases,
+ :environments,
+ :pipeline_schedules,
+ :feature_flags,
+ :test_cases,
+ :artifacts
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/code_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/code_menu_spec.rb
new file mode 100644
index 00000000000..8f69717eb29
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/code_menu_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::CodeMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Code"))
+ expect(subject.sprite_icon).to eq("code")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :project_merge_request_list,
+ :files,
+ :branches,
+ :commits,
+ :tags,
+ :graphs,
+ :compare,
+ :project_snippets,
+ :file_locks
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/manage_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/manage_menu_spec.rb
new file mode 100644
index 00000000000..afcdf2550d7
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/manage_menu_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::ManageMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Manage"))
+ expect(subject.sprite_icon).to eq("users")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :activity,
+ :members,
+ :labels
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb
new file mode 100644
index 00000000000..9344bbc76db
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::MonitorMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Monitor"))
+ expect(subject.sprite_icon).to eq("monitor")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :metrics,
+ :error_tracking,
+ :alert_management,
+ :incidents,
+ :on_call_schedules,
+ :escalation_policies,
+ :service_desk
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb
new file mode 100644
index 00000000000..6ab070c40ae
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::OperationsMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Operate"))
+ expect(subject.sprite_icon).to eq("deployments")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :packages_registry,
+ :container_registry,
+ :kubernetes,
+ :terraform_states,
+ :infrastructure_registry,
+ :google_cloud,
+ :aws
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb
new file mode 100644
index 00000000000..8d61c9d9a0e
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::PlanMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Plan"))
+ expect(subject.sprite_icon).to eq("planning")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :project_issue_list,
+ :boards,
+ :milestones,
+ :iterations,
+ :project_wiki,
+ :requirements
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/secure_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/secure_menu_spec.rb
new file mode 100644
index 00000000000..74ef761332e
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/secure_menu_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::SecureMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Secure"))
+ expect(subject.sprite_icon).to eq("shield")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :discover_project_security,
+ :dashboard,
+ :vulnerability_report,
+ :dependency_list,
+ :license_compliance,
+ :audit_events,
+ :scan_policies,
+ :on_demand_scans,
+ :configuration
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb b/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb
new file mode 100644
index 00000000000..93f0072a111
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarPanel, feature_category: :navigation do
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:user) { project.first_owner }
+ let(:context) do
+ Sidebars::Projects::Context.new(
+ current_user: user,
+ container: project,
+ current_ref: project.repository.root_ref,
+ is_super_sidebar: true,
+ # Turn features on that impact the list of items rendered
+ can_view_pipeline_editor: true,
+ learn_gitlab_enabled: true,
+ show_discover_project_security: true,
+ # Turn features off that do not add/remove items
+ show_cluster_hint: false,
+ show_promotions: false
+ )
+ end
+
+ subject { described_class.new(context) }
+
+ before do
+ # Enable integrations with menu items
+ allow(project).to receive(:external_wiki).and_return(build(:external_wiki_integration, project: project))
+ allow(project).to receive(:external_issue_tracker).and_return(build(:bugzilla_integration, project: project))
+ end
+
+ it 'implements #super_sidebar_context_header' do
+ expect(subject.super_sidebar_context_header).to eq(
+ {
+ title: project.name,
+ avatar: project.avatar_url,
+ id: project.id
+ })
+ end
+
+ describe '#renderable_menus' do
+ let(:category_menu) do
+ [
+ Sidebars::StaticMenu,
+ Sidebars::Projects::SuperSidebarMenus::ManageMenu,
+ Sidebars::Projects::SuperSidebarMenus::PlanMenu,
+ Sidebars::Projects::SuperSidebarMenus::CodeMenu,
+ Sidebars::Projects::SuperSidebarMenus::BuildMenu,
+ Sidebars::Projects::SuperSidebarMenus::SecureMenu,
+ Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
+ Sidebars::Projects::SuperSidebarMenus::MonitorMenu,
+ Sidebars::Projects::SuperSidebarMenus::AnalyzeMenu,
+ Sidebars::UncategorizedMenu,
+ Sidebars::Projects::Menus::SettingsMenu
+ ]
+ end
+
+ it "is exposed as a renderable menu" do
+ expect(subject.instance_variable_get(:@menus).map(&:class)).to eq(category_menu)
+ end
+ end
+
+ it_behaves_like 'a panel with uniquely identifiable menu items'
+ it_behaves_like 'a panel with all menu_items categorized'
+end
diff --git a/spec/lib/sidebars/search/panel_spec.rb b/spec/lib/sidebars/search/panel_spec.rb
new file mode 100644
index 00000000000..30801ff800e
--- /dev/null
+++ b/spec/lib/sidebars/search/panel_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Search::Panel, feature_category: :navigation do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:user) { create(:user) }
+
+ let(:context) { Sidebars::Context.new(current_user: current_user, container: user) }
+ let(:panel) { described_class.new(context) }
+
+ subject { described_class.new(context) }
+
+ it_behaves_like 'a panel with uniquely identifiable menu items'
+
+ describe '#aria_label' do
+ it 'returns the correct aria label' do
+ expect(panel.aria_label).to eq(_('Search results'))
+ end
+ end
+
+ describe '#super_sidebar_context_header' do
+ it 'returns a hash with the correct title and icon' do
+ expected_header = {
+ title: 'Search results',
+ icon: 'search-results'
+ }
+ expect(panel.super_sidebar_context_header).to eq(expected_header)
+ end
+ end
+end
diff --git a/spec/lib/sidebars/static_menu_spec.rb b/spec/lib/sidebars/static_menu_spec.rb
new file mode 100644
index 00000000000..3d9feee0494
--- /dev/null
+++ b/spec/lib/sidebars/static_menu_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::StaticMenu, feature_category: :navigation do
+ let(:context) { {} }
+
+ subject { described_class.new(context) }
+
+ describe '#serialize_for_super_sidebar' do
+ it 'returns flat list of all menu items' do
+ subject.add_item(Sidebars::MenuItem.new(item_id: 'id1', title: 'Is active', link: 'foo2',
+ active_routes: { controller: 'fooc' }))
+ subject.add_item(Sidebars::MenuItem.new(item_id: 'id2', title: 'Not active', link: 'foo3',
+ active_routes: { controller: 'barc' }))
+ subject.add_item(Sidebars::NilMenuItem.new(item_id: 'nil_item'))
+
+ allow(context).to receive(:route_is_active).and_return(->(x) { x[:controller] == 'fooc' })
+
+ expect(subject.serialize_for_super_sidebar).to eq(
+ [
+ {
+ id: 'id1',
+ title: "Is active",
+ icon: nil,
+ link: "foo2",
+ is_active: true,
+ pill_count: nil,
+ link_classes: nil
+ },
+ {
+ id: 'id2',
+ title: "Not active",
+ icon: nil,
+ link: "foo3",
+ is_active: false,
+ pill_count: nil,
+ link_classes: nil
+ }
+ ]
+ )
+ end
+ end
+end
diff --git a/spec/lib/sidebars/uncategorized_menu_spec.rb b/spec/lib/sidebars/uncategorized_menu_spec.rb
new file mode 100644
index 00000000000..45e7c0c87e2
--- /dev/null
+++ b/spec/lib/sidebars/uncategorized_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UncategorizedMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(_("Uncategorized"))
+ expect(subject.sprite_icon).to eq("question")
+ end
+end
diff --git a/spec/lib/sidebars/user_profile/menus/activity_menu_spec.rb b/spec/lib/sidebars/user_profile/menus/activity_menu_spec.rb
new file mode 100644
index 00000000000..6689b8b2da3
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/activity_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Menus::ActivityMenu, feature_category: :navigation do
+ it_behaves_like 'User profile menu',
+ title: s_('UserProfile|Activity'),
+ icon: 'history',
+ active_route: 'users#activity' do
+ let(:link) { "/users/#{user.username}/activity" }
+ end
+end
diff --git a/spec/lib/sidebars/user_profile/menus/contributed_projects_menu_spec.rb b/spec/lib/sidebars/user_profile/menus/contributed_projects_menu_spec.rb
new file mode 100644
index 00000000000..2677851247b
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/contributed_projects_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Menus::ContributedProjectsMenu, feature_category: :navigation do
+ it_behaves_like 'User profile menu',
+ title: s_('UserProfile|Contributed projects'),
+ icon: 'project',
+ active_route: 'users#contributed' do
+ let(:link) { "/users/#{user.username}/contributed" }
+ end
+end
diff --git a/spec/lib/sidebars/user_profile/menus/followers_menu_spec.rb b/spec/lib/sidebars/user_profile/menus/followers_menu_spec.rb
new file mode 100644
index 00000000000..2d3d48f0a8c
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/followers_menu_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Menus::FollowersMenu, feature_category: :navigation do
+ it_behaves_like 'User profile menu',
+ title: s_('UserProfile|Followers'),
+ icon: 'users',
+ active_route: 'users#followers' do
+ let(:link) { "/users/#{user.username}/followers" }
+ end
+
+ it_behaves_like 'Followers/followees counts', :followers
+end
diff --git a/spec/lib/sidebars/user_profile/menus/following_menu_spec.rb b/spec/lib/sidebars/user_profile/menus/following_menu_spec.rb
new file mode 100644
index 00000000000..8d8db2611e6
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/following_menu_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Menus::FollowingMenu, feature_category: :navigation do
+ it_behaves_like 'User profile menu',
+ title: s_('UserProfile|Following'),
+ icon: 'users',
+ active_route: 'users#following' do
+ let(:link) { "/users/#{user.username}/following" }
+ end
+
+ it_behaves_like 'Followers/followees counts', :followees
+end
diff --git a/spec/lib/sidebars/user_profile/menus/groups_menu_spec.rb b/spec/lib/sidebars/user_profile/menus/groups_menu_spec.rb
new file mode 100644
index 00000000000..989cc1ff5ce
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/groups_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Menus::GroupsMenu, feature_category: :navigation do
+ it_behaves_like 'User profile menu',
+ title: s_('UserProfile|Groups'),
+ icon: 'group',
+ active_route: 'users#groups' do
+ let(:link) { "/users/#{user.username}/groups" }
+ end
+end
diff --git a/spec/lib/sidebars/user_profile/menus/overview_menu_spec.rb b/spec/lib/sidebars/user_profile/menus/overview_menu_spec.rb
new file mode 100644
index 00000000000..7cf86676892
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/overview_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Menus::OverviewMenu, feature_category: :navigation do
+ it_behaves_like 'User profile menu',
+ title: s_('UserProfile|Overview'),
+ icon: 'overview',
+ active_route: 'users#show' do
+ let(:link) { "/#{user.username}" }
+ end
+end
diff --git a/spec/lib/sidebars/user_profile/menus/personal_projects_menu_spec.rb b/spec/lib/sidebars/user_profile/menus/personal_projects_menu_spec.rb
new file mode 100644
index 00000000000..3e0bc269a66
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/personal_projects_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Menus::PersonalProjectsMenu, feature_category: :navigation do
+ it_behaves_like 'User profile menu',
+ title: s_('UserProfile|Personal projects'),
+ icon: 'project',
+ active_route: 'users#projects' do
+ let(:link) { "/users/#{user.username}/projects" }
+ end
+end
diff --git a/spec/lib/sidebars/user_profile/menus/snippets_menu_spec.rb b/spec/lib/sidebars/user_profile/menus/snippets_menu_spec.rb
new file mode 100644
index 00000000000..b2363706113
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/snippets_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Menus::SnippetsMenu, feature_category: :navigation do
+ it_behaves_like 'User profile menu',
+ title: s_('UserProfile|Snippets'),
+ icon: 'snippet',
+ active_route: 'users#snippets' do
+ let(:link) { "/users/#{user.username}/snippets" }
+ end
+end
diff --git a/spec/lib/sidebars/user_profile/menus/starred_projects_menu_spec.rb b/spec/lib/sidebars/user_profile/menus/starred_projects_menu_spec.rb
new file mode 100644
index 00000000000..aa6ad0a74e7
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/starred_projects_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Menus::StarredProjectsMenu, feature_category: :navigation do
+ it_behaves_like 'User profile menu',
+ title: s_('UserProfile|Starred projects'),
+ icon: 'star-o',
+ active_route: 'users#starred' do
+ let(:link) { "/users/#{user.username}/starred" }
+ end
+end
diff --git a/spec/lib/sidebars/user_profile/panel_spec.rb b/spec/lib/sidebars/user_profile/panel_spec.rb
new file mode 100644
index 00000000000..c62c7f9fd96
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/panel_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserProfile::Panel, feature_category: :navigation do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:user) { create(:user) }
+
+ let(:context) { Sidebars::Context.new(current_user: current_user, container: user) }
+
+ subject { described_class.new(context) }
+
+ it_behaves_like 'a panel with uniquely identifiable menu items'
+
+ it 'implements #aria_label' do
+ expect(subject.aria_label).to eq(s_('UserProfile|User profile navigation'))
+ end
+
+ it 'implements #super_sidebar_context_header' do
+ expect(subject.super_sidebar_context_header).to eq({
+ title: user.name,
+ avatar: user.avatar_url,
+ avatar_shape: 'circle'
+ })
+ end
+end
diff --git a/spec/lib/sidebars/user_settings/menus/access_tokens_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/access_tokens_menu_spec.rb
new file mode 100644
index 00000000000..fa33e7bedfb
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/access_tokens_menu_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::AccessTokensMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/personal_access_tokens',
+ title: _('Access Tokens'),
+ icon: 'token',
+ active_routes: { controller: :personal_access_tokens }
+
+ describe '#render?' do
+ subject { described_class.new(context) }
+
+ let_it_be(:user) { build(:user) }
+
+ context 'when personal access tokens are disabled' do
+ before do
+ allow(::Gitlab::CurrentSettings).to receive_messages(personal_access_tokens_disabled?: true)
+ end
+
+ context 'when user is logged in' do
+ let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
+
+ it 'does not render' do
+ expect(subject.render?).to be false
+ end
+ end
+
+ context 'when user is not logged in' do
+ let(:context) { Sidebars::Context.new(current_user: nil, container: nil) }
+
+ subject { described_class.new(context) }
+
+ it 'does not render' do
+ expect(subject.render?).to be false
+ end
+ end
+ end
+
+ context 'when personal access tokens are enabled' do
+ before do
+ allow(::Gitlab::CurrentSettings).to receive_messages(personal_access_tokens_disabled?: false)
+ end
+
+ context 'when user is logged in' do
+ let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
+
+ it 'renders' do
+ expect(subject.render?).to be true
+ end
+ end
+
+ context 'when user is not logged in' do
+ let(:context) { Sidebars::Context.new(current_user: nil, container: nil) }
+
+ subject { described_class.new(context) }
+
+ it 'does not render' do
+ expect(subject.render?).to be false
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/sidebars/user_settings/menus/account_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/account_menu_spec.rb
new file mode 100644
index 00000000000..d5810d9c5ae
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/account_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::AccountMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/account',
+ title: _('Account'),
+ icon: 'account',
+ active_routes: { controller: [:accounts, :two_factor_auths] }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/active_sessions_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/active_sessions_menu_spec.rb
new file mode 100644
index 00000000000..be5f826ee58
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/active_sessions_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::ActiveSessionsMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/active_sessions',
+ title: _('Active Sessions'),
+ icon: 'monitor-lines',
+ active_routes: { controller: :active_sessions }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/applications_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/applications_menu_spec.rb
new file mode 100644
index 00000000000..eeda4fb844c
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/applications_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::ApplicationsMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/applications',
+ title: _('Applications'),
+ icon: 'applications',
+ active_routes: { controller: 'oauth/applications' }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/authentication_log_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/authentication_log_menu_spec.rb
new file mode 100644
index 00000000000..33be5050c37
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/authentication_log_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::AuthenticationLogMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/audit_log',
+ title: _('Authentication Log'),
+ icon: 'log',
+ active_routes: { path: 'profiles#audit_log' }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/chat_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/chat_menu_spec.rb
new file mode 100644
index 00000000000..2a0587e2504
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/chat_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::ChatMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/chat',
+ title: _('Chat'),
+ icon: 'comment',
+ active_routes: { controller: :chat_names }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/comment_templates_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/comment_templates_menu_spec.rb
new file mode 100644
index 00000000000..37a383cfd9d
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/comment_templates_menu_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::CommentTemplatesMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/comment_templates',
+ title: _('Comment Templates'),
+ icon: 'comment-lines',
+ active_routes: { controller: :comment_templates }
+
+ describe '#render?' do
+ subject { described_class.new(context) }
+
+ let_it_be(:user) { build(:user) }
+
+ context 'when comment templates are enabled' do
+ before do
+ allow(subject).to receive(:saved_replies_enabled?).and_return(true)
+ end
+
+ context 'when user is logged in' do
+ let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
+
+ it 'does not render' do
+ expect(subject.render?).to be true
+ end
+ end
+
+ context 'when user is not logged in' do
+ let(:context) { Sidebars::Context.new(current_user: nil, container: nil) }
+
+ subject { described_class.new(context) }
+
+ it 'does not render' do
+ expect(subject.render?).to be false
+ end
+ end
+ end
+
+ context 'when comment templates are disabled' do
+ before do
+ allow(subject).to receive(:saved_replies_enabled?).and_return(false)
+ end
+
+ context 'when user is logged in' do
+ let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
+
+ it 'renders' do
+ expect(subject.render?).to be false
+ end
+ end
+
+ context 'when user is not logged in' do
+ let(:context) { Sidebars::Context.new(current_user: nil, container: nil) }
+
+ subject { described_class.new(context) }
+
+ it 'does not render' do
+ expect(subject.render?).to be false
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/sidebars/user_settings/menus/emails_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/emails_menu_spec.rb
new file mode 100644
index 00000000000..2f16c68e601
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/emails_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::EmailsMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/emails',
+ title: _('Emails'),
+ icon: 'mail',
+ active_routes: { controller: :emails }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/gpg_keys_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/gpg_keys_menu_spec.rb
new file mode 100644
index 00000000000..1f4340ad29c
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/gpg_keys_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::GpgKeysMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/gpg_keys',
+ title: _('GPG Keys'),
+ icon: 'key',
+ active_routes: { controller: :gpg_keys }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/notifications_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/notifications_menu_spec.rb
new file mode 100644
index 00000000000..282324056d4
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/notifications_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::NotificationsMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/notifications',
+ title: _('Notifications'),
+ icon: 'notifications',
+ active_routes: { controller: :notifications }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/password_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/password_menu_spec.rb
new file mode 100644
index 00000000000..168019fea5d
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/password_menu_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::PasswordMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/password',
+ title: _('Password'),
+ icon: 'lock',
+ active_routes: { controller: :passwords }
+
+ describe '#render?' do
+ subject { described_class.new(context) }
+
+ let_it_be(:user) { build(:user) }
+ let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
+
+ context 'when password authentication is enabled' do
+ before do
+ allow(user).to receive(:allow_password_authentication?).and_return(true)
+ end
+
+ it 'renders' do
+ expect(subject.render?).to be true
+ end
+ end
+
+ context 'when password authentication is disabled' do
+ before do
+ allow(user).to receive(:allow_password_authentication?).and_return(false)
+ end
+
+ it 'renders' do
+ expect(subject.render?).to be false
+ end
+ end
+ end
+end
diff --git a/spec/lib/sidebars/user_settings/menus/preferences_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/preferences_menu_spec.rb
new file mode 100644
index 00000000000..83a67a40081
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/preferences_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::PreferencesMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/preferences',
+ title: _('Preferences'),
+ icon: 'preferences',
+ active_routes: { controller: :preferences }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/profile_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/profile_menu_spec.rb
new file mode 100644
index 00000000000..8410ba7cfcd
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/profile_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::ProfileMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile',
+ title: _('Profile'),
+ icon: 'profile',
+ active_routes: { path: 'profiles#show' }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/menus/ssh_keys_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/ssh_keys_menu_spec.rb
new file mode 100644
index 00000000000..8c781cc743b
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/ssh_keys_menu_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::SshKeysMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/keys',
+ title: _('SSH Keys'),
+ icon: 'key',
+ active_routes: { controller: :keys }
+
+ it_behaves_like 'User settings menu #render? method'
+end
diff --git a/spec/lib/sidebars/user_settings/panel_spec.rb b/spec/lib/sidebars/user_settings/panel_spec.rb
new file mode 100644
index 00000000000..0c02bf77d0e
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/panel_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Panel, feature_category: :navigation do
+ let_it_be(:user) { create(:user) }
+
+ let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
+
+ subject { described_class.new(context) }
+
+ it_behaves_like 'a panel with uniquely identifiable menu items'
+
+ it 'implements #super_sidebar_context_header' do
+ expect(subject.super_sidebar_context_header).to eq({ title: _('User settings'), avatar: user.avatar_url })
+ end
+end
diff --git a/spec/lib/sidebars/your_work/panel_spec.rb b/spec/lib/sidebars/your_work/panel_spec.rb
new file mode 100644
index 00000000000..ae9c3aa18e6
--- /dev/null
+++ b/spec/lib/sidebars/your_work/panel_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::YourWork::Panel, feature_category: :navigation do
+ let_it_be(:user) { create(:user) }
+
+ let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
+
+ subject { described_class.new(context) }
+
+ it_behaves_like 'a panel with uniquely identifiable menu items'
+
+ it 'implements #super_sidebar_context_header' do
+ expect(subject.super_sidebar_context_header).to eq({ title: 'Your work', icon: 'work' })
+ end
+end