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/concerns/super_sidebar_panel_spec.rb139
-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.rb15
-rw-r--r--spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/groups/menus/merge_requests_menu_spec.rb14
-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/super_sidebar_panel_spec.rb44
-rw-r--r--spec/lib/sidebars/menu_spec.rb79
-rw-r--r--spec/lib/sidebars/panel_spec.rb28
-rw-r--r--spec/lib/sidebars/projects/menus/deployments_menu_spec.rb6
-rw-r--r--spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb72
-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.rb15
-rw-r--r--spec/lib/sidebars/projects/menus/merge_requests_menu_spec.rb15
-rw-r--r--spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb6
-rw-r--r--spec/lib/sidebars/projects/menus/project_information_menu_spec.rb6
-rw-r--r--spec/lib/sidebars/projects/menus/repository_menu_spec.rb2
-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/snippets_menu_spec.rb13
-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/operations_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_panel_spec.rb45
-rw-r--r--spec/lib/sidebars/static_menu_spec.rb38
-rw-r--r--spec/lib/sidebars/uncategorized_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/user_profile/menus/activity_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/user_profile/menus/contributed_projects_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/user_profile/menus/followers_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_profile/menus/following_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_profile/menus/groups_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/user_profile/menus/overview_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/user_profile/menus/personal_projects_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/user_profile/menus/snippets_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/user_profile/menus/starred_projects_menu_spec.rb11
-rw-r--r--spec/lib/sidebars/user_profile/panel_spec.rb24
-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/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/saved_replies_menu_spec.rb65
-rw-r--r--spec/lib/sidebars/user_settings/menus/ssh_keys_menu_spec.rb13
-rw-r--r--spec/lib/sidebars/user_settings/panel_spec.rb15
-rw-r--r--spec/lib/sidebars/your_work/panel_spec.rb15
56 files changed, 1142 insertions, 135 deletions
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..f33cb4ab7f6
--- /dev/null
+++ b/spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb
@@ -0,0 +1,139 @@
+# 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 'adds Menu Items to defined super_sidebar_parent, before super_sidebar_before' do
+ allow(menu_item).to receive(:super_sidebar_before).and_return(:exists)
+ 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..ceeda4a7ac3 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,17 @@ 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' },
+ sprite_icon: 'issues',
+ pill_count: menu.pill_count,
+ has_pill: menu.has_pill?,
+ super_sidebar_parent: ::Sidebars::StaticMenu
+ }
+ 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..72f85f7930a 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,16 @@ 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,
+ sprite_icon: 'git-merge',
+ pill_count: menu.pill_count,
+ has_pill: menu.has_pill?,
+ super_sidebar_parent: ::Sidebars::StaticMenu
+ }
+ 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/super_sidebar_panel_spec.rb b/spec/lib/sidebars/groups/super_sidebar_panel_spec.rb
new file mode 100644
index 00000000000..beaf3875f1c
--- /dev/null
+++ b/spec/lib/sidebars/groups/super_sidebar_panel_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Groups::SuperSidebarPanel, feature_category: :navigation do
+ let_it_be(:group) { create(:group) }
+
+ let(:user) { group.first_owner }
+
+ let(:context) do
+ double("Stubbed context", current_user: user, container: group, group: group).as_null_object # rubocop:disable RSpec/VerifiedDoubles
+ 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::PlanMenu,
+ Sidebars::Groups::Menus::CiCdMenu,
+ (Sidebars::Groups::Menus::SecurityComplianceMenu if Gitlab.ee?),
+ Sidebars::Groups::SuperSidebarMenus::OperationsMenu,
+ Sidebars::Groups::Menus::ObservabilityMenu,
+ (Sidebars::Groups::Menus::AnalyticsMenu if Gitlab.ee?),
+ Sidebars::UncategorizedMenu,
+ Sidebars::Groups::Menus::SettingsMenu
+ ].compact
+ end
+
+ it "is exposed as a renderable menu" do
+ expect(subject.instance_variable_get(:@menus).map(&:class)).to eq(category_menu)
+ end
+ end
+end
diff --git a/spec/lib/sidebars/menu_spec.rb b/spec/lib/sidebars/menu_spec.rb
index 53a889c2db8..641f1c6e7e6 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,82 @@ 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(title: 'Is active', link: 'foo2', active_routes: { controller: 'fooc' }))
+ menu.add_item(Sidebars::MenuItem.new(
+ 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,
+ items: [
+ {
+ title: "Is active",
+ icon: nil,
+ link: "foo2",
+ is_active: true,
+ pill_count: nil
+ },
+ {
+ title: "Not active",
+ icon: nil,
+ link: "foo3",
+ is_active: false,
+ pill_count: 10
+ }
+ ]
+ })
+ 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',
+ 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
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/deployments_menu_spec.rb b/spec/lib/sidebars/projects/menus/deployments_menu_spec.rb
index ce971915174..5065c261cf8 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) }
diff --git a/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb b/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
index 116948b7cb0..7f0e02892e4 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) }
@@ -103,6 +107,22 @@ RSpec.describe Sidebars::Projects::Menus::InfrastructureMenu do
let(:item_id) { :terraform }
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..c7ff846bc95 100644
--- a/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
@@ -2,13 +2,26 @@
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,
+ sprite_icon: 'issues',
+ pill_count: menu.pill_count,
+ has_pill: menu.has_pill?,
+ super_sidebar_parent: ::Sidebars::StaticMenu
+ }
+ end
+ end
+
describe '#render?' do
context 'when user can read issues' do
it 'returns true' do
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..a19df559b58 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,19 @@ 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,
+ sprite_icon: 'git-merge',
+ pill_count: menu.pill_count,
+ has_pill: menu.has_pill?,
+ super_sidebar_parent: ::Sidebars::StaticMenu
+ }
+ end
+ end
+
describe '#render?' do
context 'when repository is not present' do
let(:project) { build(:project) }
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..554bc763345 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
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..b0631aacdb9 100644
--- a/spec/lib/sidebars/projects/menus/repository_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/repository_menu_spec.rb
@@ -85,7 +85,7 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou
end
end
- describe 'Contributors' do
+ describe 'Contributor statistics' do
let_it_be(:item_id) { :contributors }
context 'when analytics is disabled' do
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/snippets_menu_spec.rb b/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb
index 04b8c128e3d..c5fd407dae9 100644
--- a/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb
@@ -2,13 +2,24 @@
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::Menus::RepositoryMenu,
+ super_sidebar_before: :contributors,
+ 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/operations_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb
new file mode 100644
index 00000000000..df3f7e6cdab
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::OperationsMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(_("Operations"))
+ expect(subject.sprite_icon).to eq("deployments")
+ 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..3917d26f6f2
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::PlanMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(_("Plan"))
+ expect(subject.sprite_icon).to eq("planning")
+ 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..d6fc3fd8fe1
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb
@@ -0,0 +1,45 @@
+# 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
+ double("Stubbed context", current_user: user, container: project, project: project, current_ref: 'master').as_null_object # rubocop:disable RSpec/VerifiedDoubles
+ end
+
+ subject { described_class.new(context) }
+
+ 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::PlanMenu,
+ Sidebars::Projects::Menus::RepositoryMenu,
+ Sidebars::Projects::Menus::CiCdMenu,
+ Sidebars::Projects::Menus::SecurityComplianceMenu,
+ Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
+ Sidebars::Projects::Menus::MonitorMenu,
+ Sidebars::Projects::Menus::AnalyticsMenu,
+ 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
+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..086eb332a15
--- /dev/null
+++ b/spec/lib/sidebars/static_menu_spec.rb
@@ -0,0 +1,38 @@
+# 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(title: 'Is active', link: 'foo2', active_routes: { controller: 'fooc' }))
+ subject.add_item(Sidebars::MenuItem.new(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(
+ [
+ {
+ title: "Is active",
+ icon: nil,
+ link: "foo2",
+ is_active: true,
+ pill_count: nil
+ },
+ {
+ title: "Not active",
+ icon: nil,
+ link: "foo3",
+ is_active: false,
+ pill_count: 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..44492380f11
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/activity_menu_spec.rb
@@ -0,0 +1,11 @@
+# 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'),
+ 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..a5371c36fd3
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/contributed_projects_menu_spec.rb
@@ -0,0 +1,11 @@
+# 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'),
+ 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..1b3efbf4ceb
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/followers_menu_spec.rb
@@ -0,0 +1,13 @@
+# 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'),
+ 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..167961f085e
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/following_menu_spec.rb
@@ -0,0 +1,13 @@
+# 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'),
+ 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..6c48ad2e8d0
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/groups_menu_spec.rb
@@ -0,0 +1,11 @@
+# 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'),
+ 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..e34f59cddf0
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/overview_menu_spec.rb
@@ -0,0 +1,11 @@
+# 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'),
+ 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..ba2c3d11b88
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/personal_projects_menu_spec.rb
@@ -0,0 +1,11 @@
+# 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'),
+ 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..2760d172a51
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/snippets_menu_spec.rb
@@ -0,0 +1,11 @@
+# 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'),
+ 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..e205d1f5492
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/menus/starred_projects_menu_spec.rb
@@ -0,0 +1,11 @@
+# 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'),
+ 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..af261dce3f3
--- /dev/null
+++ b/spec/lib/sidebars/user_profile/panel_spec.rb
@@ -0,0 +1,24 @@
+# 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 '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/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/saved_replies_menu_spec.rb b/spec/lib/sidebars/user_settings/menus/saved_replies_menu_spec.rb
new file mode 100644
index 00000000000..ea1a2a3539f
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/menus/saved_replies_menu_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::UserSettings::Menus::SavedRepliesMenu, feature_category: :navigation do
+ it_behaves_like 'User settings menu',
+ link: '/-/profile/saved_replies',
+ title: _('Saved Replies'),
+ icon: 'symlink',
+ active_routes: { controller: :saved_replies }
+
+ describe '#render?' do
+ subject { described_class.new(context) }
+
+ let_it_be(:user) { build(:user) }
+
+ context 'when saved replies 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 saved replies 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/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..aa05d99912a
--- /dev/null
+++ b/spec/lib/sidebars/user_settings/panel_spec.rb
@@ -0,0 +1,15 @@
+# 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 '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..97da94e4114
--- /dev/null
+++ b/spec/lib/sidebars/your_work/panel_spec.rb
@@ -0,0 +1,15 @@
+# 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 'implements #super_sidebar_context_header' do
+ expect(subject.super_sidebar_context_header).to eq({ title: 'Your work', icon: 'work' })
+ end
+end