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/helpers/nav')
-rw-r--r--spec/helpers/nav/new_dropdown_helper_spec.rb320
-rw-r--r--spec/helpers/nav/top_nav_helper_spec.rb235
2 files changed, 524 insertions, 31 deletions
diff --git a/spec/helpers/nav/new_dropdown_helper_spec.rb b/spec/helpers/nav/new_dropdown_helper_spec.rb
new file mode 100644
index 00000000000..dd860ce3180
--- /dev/null
+++ b/spec/helpers/nav/new_dropdown_helper_spec.rb
@@ -0,0 +1,320 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Nav::NewDropdownHelper do
+ describe '#new_dropdown_view_model' do
+ let_it_be(:user) { build_stubbed(:user) }
+
+ let(:current_user) { user }
+ let(:current_project) { nil }
+ let(:current_group) { nil }
+
+ let(:with_can_create_project) { false }
+ let(:with_can_create_group) { false }
+ let(:with_can_create_snippet) { false }
+ let(:with_new_repo_experiment) { :control }
+ let(:with_invite_members_experiment) { false }
+ let(:with_invite_members_experiment_enabled) { false }
+
+ let(:subject) { helper.new_dropdown_view_model(project: current_project, group: current_group) }
+
+ def expected_menu_section(title:, menu_item:)
+ [
+ {
+ title: title,
+ menu_items: [menu_item]
+ }
+ ]
+ end
+
+ before do
+ stub_experiments(new_repo: with_new_repo_experiment)
+ allow(::Gitlab::Experimentation).to receive(:active?).with(:invite_members_new_dropdown) { with_invite_members_experiment }
+ allow(helper).to receive(:experiment_enabled?).with(:invite_members_new_dropdown) { with_invite_members_experiment_enabled }
+ allow(helper).to receive(:tracking_label) { 'test_tracking_label' }
+ allow(helper).to receive(:experiment_tracking_category_and_group) { |x| x }
+
+ allow(helper).to receive(:current_user) { current_user }
+ allow(helper).to receive(:can?) { false }
+
+ allow(user).to receive(:can_create_project?) { with_can_create_project }
+ allow(user).to receive(:can_create_group?) { with_can_create_group }
+ allow(user).to receive(:can?).with(:create_snippet) { with_can_create_snippet }
+ end
+
+ shared_examples 'new repo experiment shared example' do |title|
+ let(:with_new_repo_experiment) { :candidate }
+
+ it 'has experiment project title' do
+ expect(subject[:menu_sections]).to match(
+ expected_menu_section(
+ title: title,
+ menu_item: a_hash_including(title: 'New project/repository')
+ )
+ )
+ end
+ end
+
+ shared_examples 'invite member link shared example' do
+ it 'shows invite member link' do
+ expect(subject[:menu_sections]).to eq(
+ expected_menu_section(
+ title: expected_title,
+ menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'invite',
+ title: 'Invite members',
+ href: expected_href,
+ data: {
+ track_event: 'click_link',
+ track_label: 'test_tracking_label',
+ track_property: :invite_members_new_dropdown
+ }
+ )
+ )
+ )
+ end
+
+ context 'with experiment enabled' do
+ let(:with_invite_members_experiment_enabled) { true }
+
+ it 'shows emoji with invite member link' do
+ expect(subject[:menu_sections]).to match(
+ expected_menu_section(
+ title: expected_title,
+ menu_item: a_hash_including(
+ emoji: 'shaking_hands'
+ )
+ )
+ )
+ end
+ end
+ end
+
+ it 'has title' do
+ expect(subject[:title]).to eq('New...')
+ end
+
+ context 'when current_user is nil (anonymous)' do
+ let(:current_user) { nil }
+
+ it 'is nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'when group and project are nil' do
+ it 'has no menu sections' do
+ expect(subject[:menu_sections]).to eq([])
+ end
+
+ context 'when can create project' do
+ let(:with_can_create_project) { true }
+
+ it 'has project menu item' do
+ expect(subject[:menu_sections]).to eq(
+ expected_menu_section(
+ title: 'GitLab',
+ menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'general_new_project',
+ title: 'New project',
+ href: '/projects/new',
+ data: { track_experiment: 'new_repo', track_event: 'click_link_new_project', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_project_link' }
+ )
+ )
+ )
+ end
+
+ it_behaves_like 'new repo experiment shared example', 'GitLab'
+ end
+
+ context 'when can create group' do
+ let(:with_can_create_group) { true }
+
+ it 'has group menu item' do
+ expect(subject[:menu_sections]).to eq(
+ expected_menu_section(
+ title: 'GitLab',
+ menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'general_new_group',
+ title: 'New group',
+ href: '/groups/new',
+ data: { track_event: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
+ )
+ )
+ )
+ end
+ end
+
+ context 'when can create snippet' do
+ let(:with_can_create_snippet) { true }
+
+ it 'has new snippet menu item' do
+ expect(subject[:menu_sections]).to eq(
+ expected_menu_section(
+ title: 'GitLab',
+ menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'general_new_snippet',
+ title: 'New snippet',
+ href: '/-/snippets/new',
+ data: { track_event: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_snippet_link' }
+ )
+ )
+ )
+ end
+ end
+ end
+
+ context 'with persisted group' do
+ let_it_be(:group) { build_stubbed(:group) }
+
+ let(:current_group) { group }
+ let(:with_can_create_projects_in_group) { false }
+ let(:with_can_create_subgroup_in_group) { false }
+ let(:with_can_admin_in_group) { false }
+
+ before do
+ allow(group).to receive(:persisted?) { true }
+ allow(helper).to receive(:can?).with(current_user, :create_projects, group) { with_can_create_projects_in_group }
+ allow(helper).to receive(:can?).with(current_user, :create_subgroup, group) { with_can_create_subgroup_in_group }
+ allow(helper).to receive(:can?).with(current_user, :admin_group_member, group) { with_can_admin_in_group }
+ end
+
+ it 'has no menu sections' do
+ expect(subject[:menu_sections]).to eq([])
+ end
+
+ context 'when can create projects in group' do
+ let(:with_can_create_projects_in_group) { true }
+
+ it 'has new project menu item' do
+ expect(subject[:menu_sections]).to eq(
+ expected_menu_section(
+ title: 'This group',
+ menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'new_project',
+ title: 'New project',
+ href: "/projects/new?namespace_id=#{group.id}",
+ data: { track_experiment: 'new_repo', track_event: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' }
+ )
+ )
+ )
+ end
+
+ it_behaves_like 'new repo experiment shared example', 'This group'
+ end
+
+ context 'when can create subgroup' do
+ let(:with_can_create_subgroup_in_group) { true }
+
+ it 'has new subgroup menu item' do
+ expect(subject[:menu_sections]).to eq(
+ expected_menu_section(
+ title: 'This group',
+ menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'new_subgroup',
+ title: 'New subgroup',
+ href: "/groups/new?parent_id=#{group.id}",
+ data: { track_event: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' }
+ )
+ )
+ )
+ end
+ end
+
+ context 'when can invite members' do
+ let(:with_can_admin_in_group) { true }
+ let(:with_invite_members_experiment) { true }
+ let(:expected_title) { 'This group' }
+ let(:expected_href) { "/groups/#{group.full_path}/-/group_members" }
+
+ it_behaves_like 'invite member link shared example'
+ end
+ end
+
+ context 'with persisted project' do
+ let_it_be(:project) { build_stubbed(:project) }
+ let_it_be(:merge_project) { build_stubbed(:project) }
+
+ let(:current_project) { project }
+ let(:with_show_new_issue_link) { false }
+ let(:with_merge_project) { nil }
+ let(:with_can_create_snippet_in_project) { false }
+ let(:with_can_import_members) { false }
+
+ before do
+ allow(helper).to receive(:show_new_issue_link?).with(project) { with_show_new_issue_link }
+ allow(helper).to receive(:merge_request_source_project_for_project).with(project) { with_merge_project }
+ allow(helper).to receive(:can?).with(user, :create_snippet, project) { with_can_create_snippet_in_project }
+ allow(helper).to receive(:can_import_members?) { with_can_import_members }
+ end
+
+ it 'has no menu sections' do
+ expect(subject[:menu_sections]).to eq([])
+ end
+
+ context 'with show_new_issue_link?' do
+ let(:with_show_new_issue_link) { true }
+
+ it 'shows new issue menu item' do
+ expect(subject[:menu_sections]).to eq(
+ expected_menu_section(
+ title: 'This project',
+ menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'new_issue',
+ title: 'New issue',
+ href: "/#{project.path_with_namespace}/-/issues/new",
+ data: { track_event: 'click_link_new_issue', track_label: 'plus_menu_dropdown', qa_selector: 'new_issue_link' }
+ )
+ )
+ )
+ end
+ end
+
+ context 'with merge project' do
+ let(:with_merge_project) { merge_project }
+
+ it 'shows merge project' do
+ expect(subject[:menu_sections]).to eq(
+ expected_menu_section(
+ title: 'This project',
+ menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'new_mr',
+ title: 'New merge request',
+ href: "/#{merge_project.path_with_namespace}/-/merge_requests/new",
+ data: { track_event: 'click_link_new_mr', track_label: 'plus_menu_dropdown' }
+ )
+ )
+ )
+ end
+ end
+
+ context 'when can create snippet' do
+ let(:with_can_create_snippet_in_project) { true }
+
+ it 'shows new snippet' do
+ expect(subject[:menu_sections]).to eq(
+ expected_menu_section(
+ title: 'This project',
+ menu_item: ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'new_snippet',
+ title: 'New snippet',
+ href: "/#{project.path_with_namespace}/-/snippets/new",
+ data: { track_event: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' }
+ )
+ )
+ )
+ end
+ end
+
+ context 'when invite members experiment' do
+ let(:with_invite_members_experiment) { true }
+ let(:with_can_import_members) { true }
+ let(:expected_title) { 'This project' }
+ let(:expected_href) { "/#{project.path_with_namespace}/-/project_members" }
+
+ it_behaves_like 'invite member link shared example'
+ end
+ end
+ end
+end
diff --git a/spec/helpers/nav/top_nav_helper_spec.rb b/spec/helpers/nav/top_nav_helper_spec.rb
index 5c9e1e82b01..d87c751c62f 100644
--- a/spec/helpers/nav/top_nav_helper_spec.rb
+++ b/spec/helpers/nav/top_nav_helper_spec.rb
@@ -5,11 +5,17 @@ require 'spec_helper'
RSpec.describe Nav::TopNavHelper do
include ActionView::Helpers::UrlHelper
- describe '#top_nav_view_model' do
- let_it_be(:user) { build_stubbed(:user) }
- let_it_be(:admin) { build_stubbed(:user, :admin) }
+ let_it_be(:user) { build_stubbed(:user) }
+ let_it_be(:admin) { build_stubbed(:user, :admin) }
+ let_it_be(:external_user) { build_stubbed(:user, :external, can_create_group: false) }
+
+ let(:current_user) { nil }
+
+ before do
+ allow(helper).to receive(:current_user) { current_user }
+ end
- let(:current_user) { nil }
+ describe '#top_nav_view_model' do
let(:current_project) { nil }
let(:current_group) { nil }
let(:with_current_settings_admin_mode) { false }
@@ -26,7 +32,6 @@ RSpec.describe Nav::TopNavHelper do
let(:active_title) { 'Menu' }
before do
- allow(helper).to receive(:current_user) { current_user }
allow(Gitlab::CurrentSettings).to receive(:admin_mode) { with_current_settings_admin_mode }
allow(helper).to receive(:header_link?).with(:admin_mode) { with_header_link_admin_mode }
allow(Gitlab::Sherlock).to receive(:enabled?) { with_sherlock_enabled }
@@ -48,30 +53,73 @@ RSpec.describe Nav::TopNavHelper do
context 'when current_user is nil (anonymous)' do
it 'has expected :primary' do
- expected_projects_item = ::Gitlab::Nav::TopNavMenuItem.build(
- href: '/explore',
- icon: 'project',
- id: 'project',
- title: 'Projects'
- )
- expected_groups_item = ::Gitlab::Nav::TopNavMenuItem.build(
- href: '/explore/groups',
- icon: 'group',
- id: 'groups',
- title: 'Groups'
- )
- expected_snippets_item = ::Gitlab::Nav::TopNavMenuItem.build(
- href: '/explore/snippets',
- icon: 'snippet',
- id: 'snippets',
- title: 'Snippets'
- )
- expect(subject[:primary])
- .to eq([
- expected_projects_item,
- expected_groups_item,
- expected_snippets_item
- ])
+ expected_primary = [
+ ::Gitlab::Nav::TopNavMenuItem.build(
+ href: '/explore',
+ icon: 'project',
+ id: 'project',
+ title: 'Projects'
+ ),
+ ::Gitlab::Nav::TopNavMenuItem.build(
+ href: '/explore/groups',
+ icon: 'group',
+ id: 'groups',
+ title: 'Groups'
+ ),
+ ::Gitlab::Nav::TopNavMenuItem.build(
+ href: '/explore/snippets',
+ icon: 'snippet',
+ id: 'snippets',
+ title: 'Snippets'
+ )
+ ]
+ expect(subject[:primary]).to eq(expected_primary)
+ end
+
+ it 'has expected :shortcuts' do
+ expected_shortcuts = [
+ ::Gitlab::Nav::TopNavMenuItem.build(
+ href: '/explore',
+ id: 'project-shortcut',
+ title: 'Projects',
+ css_class: 'dashboard-shortcuts-projects'
+ ),
+ ::Gitlab::Nav::TopNavMenuItem.build(
+ href: '/explore/groups',
+ id: 'groups-shortcut',
+ title: 'Groups',
+ css_class: 'dashboard-shortcuts-groups'
+ ),
+ ::Gitlab::Nav::TopNavMenuItem.build(
+ href: '/explore/snippets',
+ id: 'snippets-shortcut',
+ title: 'Snippets',
+ css_class: 'dashboard-shortcuts-snippets'
+ )
+ ]
+ expect(subject[:shortcuts]).to eq(expected_shortcuts)
+ end
+
+ it 'has expected :secondary' do
+ expected_secondary = [
+ ::Gitlab::Nav::TopNavMenuItem.build(
+ href: '/help',
+ id: 'help',
+ title: 'Help',
+ icon: 'question-o'
+ )
+ ]
+ expect(subject[:secondary]).to eq(expected_secondary)
+ end
+
+ context 'with current nav as project' do
+ before do
+ helper.nav('project')
+ end
+
+ it 'has expected :active' do
+ expect(subject[:primary].detect { |entry| entry[:id] == 'project' }[:active]).to eq(true)
+ end
end
end
@@ -82,6 +130,7 @@ RSpec.describe Nav::TopNavHelper do
expect(subject).to eq({ activeTitle: active_title,
primary: [],
secondary: [],
+ shortcuts: [],
views: {} })
end
@@ -105,6 +154,16 @@ RSpec.describe Nav::TopNavHelper do
expect(subject[:primary]).to eq([expected_primary])
end
+ it 'has expected :shortcuts' do
+ expected_shortcuts = ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'project-shortcut',
+ title: 'Projects',
+ href: '/dashboard/projects',
+ css_class: 'dashboard-shortcuts-projects'
+ )
+ expect(subject[:shortcuts]).to eq([expected_shortcuts])
+ end
+
context 'projects' do
it 'has expected :currentUserName' do
expect(projects_view[:currentUserName]).to eq(current_user.username)
@@ -146,6 +205,16 @@ RSpec.describe Nav::TopNavHelper do
expect(projects_view[:linksSecondary]).to eq(expected_links_secondary)
end
+ context 'with current nav as project' do
+ before do
+ helper.nav('project')
+ end
+
+ it 'has expected :active' do
+ expect(subject[:primary].detect { |entry| entry[:id] == 'project' }[:active]).to eq(true)
+ end
+ end
+
context 'with persisted project' do
let_it_be(:project) { build_stubbed(:project) }
@@ -191,6 +260,16 @@ RSpec.describe Nav::TopNavHelper do
expect(subject[:primary]).to eq([expected_primary])
end
+ it 'has expected :shortcuts' do
+ expected_shortcuts = ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'groups-shortcut',
+ title: 'Groups',
+ href: '/dashboard/groups',
+ css_class: 'dashboard-shortcuts-groups'
+ )
+ expect(subject[:shortcuts]).to eq([expected_shortcuts])
+ end
+
context 'groups' do
it 'has expected :currentUserName' do
expect(groups_view[:currentUserName]).to eq(current_user.username)
@@ -219,7 +298,7 @@ RSpec.describe Nav::TopNavHelper do
it 'has expected :linksSecondary' do
expected_links_secondary = [
::Gitlab::Nav::TopNavMenuItem.build(
- href: '/groups/new#create-group-pane',
+ href: '/groups/new',
id: 'create',
title: 'Create group'
)
@@ -227,6 +306,24 @@ RSpec.describe Nav::TopNavHelper do
expect(groups_view[:linksSecondary]).to eq(expected_links_secondary)
end
+ context 'with external user' do
+ let(:current_user) { external_user }
+
+ it 'does not have create group link' do
+ expect(groups_view[:linksSecondary]).to eq([])
+ end
+ end
+
+ context 'with current nav as group' do
+ before do
+ helper.nav('group')
+ end
+
+ it 'has expected :active' do
+ expect(subject[:primary].detect { |entry| entry[:id] == 'groups' }[:active]).to eq(true)
+ end
+ end
+
context 'with persisted group' do
let_it_be(:group) { build_stubbed(:group) }
@@ -268,6 +365,16 @@ RSpec.describe Nav::TopNavHelper do
)
expect(subject[:primary]).to eq([expected_primary])
end
+
+ it 'has expected :shortcuts' do
+ expected_shortcuts = ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'milestones-shortcut',
+ title: 'Milestones',
+ href: '/dashboard/milestones',
+ css_class: 'dashboard-shortcuts-milestones'
+ )
+ expect(subject[:shortcuts]).to eq([expected_shortcuts])
+ end
end
context 'with snippets' do
@@ -285,6 +392,16 @@ RSpec.describe Nav::TopNavHelper do
)
expect(subject[:primary]).to eq([expected_primary])
end
+
+ it 'has expected :shortcuts' do
+ expected_shortcuts = ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'snippets-shortcut',
+ title: 'Snippets',
+ href: '/dashboard/snippets',
+ css_class: 'dashboard-shortcuts-snippets'
+ )
+ expect(subject[:shortcuts]).to eq([expected_shortcuts])
+ end
end
context 'with activity' do
@@ -302,6 +419,16 @@ RSpec.describe Nav::TopNavHelper do
)
expect(subject[:primary]).to eq([expected_primary])
end
+
+ it 'has expected :shortcuts' do
+ expected_shortcuts = ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'activity-shortcut',
+ title: 'Activity',
+ href: '/dashboard/activity',
+ css_class: 'dashboard-shortcuts-activity'
+ )
+ expect(subject[:shortcuts]).to eq([expected_shortcuts])
+ end
end
context 'when sherlock is enabled' do
@@ -352,7 +479,7 @@ RSpec.describe Nav::TopNavHelper do
title: 'Leave Admin Mode',
icon: 'lock-open',
href: '/admin/session/destroy',
- method: :post
+ data: { method: 'post' }
)
expect(subject[:secondary].last).to eq(expected_leave_admin_mode_item)
end
@@ -373,4 +500,50 @@ RSpec.describe Nav::TopNavHelper do
end
end
end
+
+ describe '#top_nav_responsive_view_model' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:group) { create(:group) }
+
+ let(:with_search) { false }
+ let(:with_new_view_model) { nil }
+
+ let(:subject) { helper.top_nav_responsive_view_model(project: project, group: group) }
+
+ before do
+ allow(helper).to receive(:header_link?).with(:search) { with_search }
+ allow(helper).to receive(:new_dropdown_view_model).with(project: project, group: group) { with_new_view_model }
+ end
+
+ it 'has nil new subview' do
+ expect(subject[:views][:new]).to be_nil
+ end
+
+ it 'has nil search subview' do
+ expect(subject[:views][:search]).to be_nil
+ end
+
+ context 'with search' do
+ let(:with_search) { true }
+
+ it 'has search subview' do
+ expect(subject[:views][:search]).to eq(
+ ::Gitlab::Nav::TopNavMenuItem.build(
+ id: 'search',
+ title: 'Search',
+ icon: 'search',
+ href: search_path
+ )
+ )
+ end
+ end
+
+ context 'with new' do
+ let(:with_new_view_model) { { id: 'test-new-view-model' } }
+
+ it 'has new subview' do
+ expect(subject[:views][:new]).to eq({ id: 'test-new-view-model' })
+ end
+ end
+ end
end