diff options
Diffstat (limited to 'spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb')
-rw-r--r-- | spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb | 1169 |
1 files changed, 1022 insertions, 147 deletions
diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb index bc5b3b7bfc6..7cb49f635af 100644 --- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb +++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb @@ -19,20 +19,41 @@ RSpec.describe 'layouts/nav/sidebar/_project' do it_behaves_like 'has nav sidebar' - describe 'Project Overview' do + describe 'Project information' do it 'has a link to the project path' do render - expect(rendered).to have_link('Project overview', href: project_path(project), class: %w(shortcuts-project rspec-project-link)) - expect(rendered).to have_selector('[aria-label="Project overview"]') + expect(rendered).to have_link('Project information', href: project_path(project), class: %w(shortcuts-project rspec-project-link)) + expect(rendered).to have_selector('[aria-label="Project information"]') + end + + context 'when feature flag :sidebar_refactor is disabled' do + it 'has a link to the project path' do + stub_feature_flags(sidebar_refactor: false) + + render + + expect(rendered).to have_link('Project overview', href: project_path(project), class: %w(shortcuts-project rspec-project-link)) + expect(rendered).to have_selector('[aria-label="Project overview"]') + end end describe 'Details' do - it 'has a link to the projects path' do + it 'does not have a link to the details menu' do render - expect(rendered).to have_link('Details', href: project_path(project), class: 'shortcuts-project') - expect(rendered).to have_selector('[aria-label="Project details"]') + expect(rendered).not_to have_link('Details', href: project_path(project)) + end + + context 'when feature flag :sidebar_refactor is disabled' do + it 'has a link to the projects path' do + stub_feature_flags(sidebar_refactor: false) + + render + + expect(rendered).to have_link('Details', href: project_path(project), class: 'shortcuts-project') + expect(rendered).to have_selector('[aria-label="Project details"]') + end end end @@ -45,10 +66,62 @@ RSpec.describe 'layouts/nav/sidebar/_project' do end describe 'Releases' do - it 'has a link to the project releases path' do + it 'does not have a link to the project releases path' do + render + + expect(rendered).not_to have_link('Releases', href: project_releases_path(project), class: 'shortcuts-project-releases') + end + + context 'when feature flag :sidebar refactor is disabled' do + it 'has a link to the project releases path' do + stub_feature_flags(sidebar_refactor: false) + + render + + expect(rendered).to have_link('Releases', href: project_releases_path(project), class: 'shortcuts-project-releases') + end + end + end + + describe 'Labels' do + let(:page) { Nokogiri::HTML.parse(rendered) } + + it 'has a link to the labels path' do render - expect(rendered).to have_link('Releases', href: project_releases_path(project), class: 'shortcuts-project-releases') + expect(page.at_css('.shortcuts-project').parent.css('[aria-label="Labels"]')).not_to be_empty + expect(rendered).to have_link('Labels', href: project_labels_path(project)) + end + + context 'when feature flag :sidebar_refactor is disabled' do + it 'does not have the labels menu item' do + stub_feature_flags(sidebar_refactor: false) + + render + + expect(page.at_css('.shortcuts-project').parent.css('[aria-label="Labels"]')).to be_empty + end + end + end + + describe 'Members' do + let(:page) { Nokogiri::HTML.parse(rendered) } + + it 'has a link to the members page' do + render + + expect(page.at_css('.shortcuts-project').parent.css('[aria-label="Members"]')).not_to be_empty + expect(rendered).to have_link('Members', href: project_project_members_path(project)) + end + + context 'when feature flag :sidebar_refactor is disabled' do + it 'does not have a link to the members page' do + stub_feature_flags(sidebar_refactor: false) + + render + + expect(page.at_css('.shortcuts-project').parent.css('[aria-label="Members"]')).to be_empty + end end end end @@ -56,6 +129,9 @@ RSpec.describe 'layouts/nav/sidebar/_project' do describe 'Learn GitLab' do it 'has a link to the learn GitLab experiment' do allow(view).to receive(:learn_gitlab_experiment_enabled?).and_return(true) + allow_next_instance_of(LearnGitlab::Onboarding) do |onboarding| + expect(onboarding).to receive(:completed_percentage).and_return(20) + end render @@ -127,145 +203,797 @@ RSpec.describe 'layouts/nav/sidebar/_project' do end end - describe 'issue boards' do - it 'has board tab' do + describe 'Issues' do + it 'has a link to the issue list path' do + render + + expect(rendered).to have_link('Issues', href: project_issues_path(project)) + end + + it 'shows pill with the number of open issues' do render - expect(rendered).to have_css('a[title="Boards"]') + expect(rendered).to have_css('span.badge.badge-pill.issue_counter') + end + + describe 'Issue List' do + it 'has a link to the issue list path' do + render + + expect(rendered).to have_link('List', href: project_issues_path(project)) + end + end + + describe 'Issue Boards' do + it 'has a link to the issue boards path' do + render + + expect(rendered).to have_link('Boards', href: project_boards_path(project)) + end + end + + describe 'Labels' do + let(:page) { Nokogiri::HTML.parse(rendered) } + + it 'does not have a link to the labels page' do + render + + expect(page.at_css('.shortcuts-issues').parent.css('[aria-label="Labels"]')).to be_empty + end + + context 'when feature flag :sidebar_refactor is disabled' do + it 'has a link to the labels page' do + stub_feature_flags(sidebar_refactor: false) + + render + + expect(page.at_css('.shortcuts-issues').parent.css('[aria-label="Labels"]')).not_to be_empty + expect(rendered).to have_link('Labels', href: project_labels_path(project)) + end + end + end + + describe 'Service Desk' do + it 'has a link to the service desk path' do + render + + expect(rendered).to have_link('Service Desk', href: service_desk_project_issues_path(project)) + end + end + + describe 'Milestones' do + it 'has a link to the milestones path' do + render + + expect(rendered).to have_link('Milestones', href: project_milestones_path(project)) + end end end - describe 'packages tab' do - before do - stub_container_registry_config(enabled: true) + describe 'External Issue Tracker' do + let_it_be_with_refind(:project) { create(:project, has_external_issue_tracker: true) } + + context 'with custom external issue tracker' do + let(:external_issue_tracker_url) { 'http://test.com' } + + let!(:external_issue_tracker) do + create(:custom_issue_tracker_service, active: external_issue_tracker_active, project: project, project_url: external_issue_tracker_url) + end + + context 'when external issue tracker is configured and active' do + let(:external_issue_tracker_active) { true } + + it 'has a link to the external issue tracker' do + render + + expect(rendered).to have_link(external_issue_tracker.title, href: external_issue_tracker_url) + end + end + + context 'when external issue tracker is not configured and active' do + let(:external_issue_tracker_active) { false } + + it 'does not have a link to the external issue tracker' do + render + + expect(rendered).not_to have_link(external_issue_tracker.title) + end + end + end + + context 'with Jira issue tracker' do + let_it_be(:jira) { create(:jira_service, project: project, issues_enabled: false) } + + it 'has a link to the Jira issue tracker' do + render - allow(controller).to receive(:controller_name) - .and_return('repositories') - allow(controller).to receive(:controller_path) - .and_return('projects/registry/repositories') + expect(rendered).to have_link('Jira', href: project.external_issue_tracker.issue_tracker_path) + end end + end + + describe 'Labels' do + it 'does not show the labels menu' do + project.project_feature.update!(issues_access_level: ProjectFeature::DISABLED) - it 'highlights sidebar item and flyout' do render - expect(rendered).to have_css('.sidebar-top-level-items > li.active', count: 1) - expect(rendered).to have_css('.sidebar-sub-level-items > li.fly-out-top-item.active', count: 1) + expect(rendered).not_to have_link('Labels', href: project_labels_path(project), class: 'shortcuts-labels') end - it 'highlights container registry tab' do + context 'when feature flag :sidebar_refactor is disabled' do + before do + stub_feature_flags(sidebar_refactor: false) + end + + context 'when issues are not enabled' do + it 'has a link to the labels path' do + project.project_feature.update!(issues_access_level: ProjectFeature::DISABLED) + + render + + expect(rendered).to have_link('Labels', href: project_labels_path(project), class: 'shortcuts-labels') + end + end + + context 'when issues are enabled' do + it 'does not have a link to the labels path' do + render + + expect(rendered).not_to have_link('Labels', href: project_labels_path(project), class: 'shortcuts-labels') + end + end + end + end + + describe 'Merge Requests' do + it 'has a link to the merge request list path' do + render + + expect(rendered).to have_link('Merge requests', href: project_merge_requests_path(project), class: 'shortcuts-merge_requests') + end + + it 'shows pill with the number of merge requests' do render - expect(rendered).to have_css('.sidebar-sub-level-items > li:not(.fly-out-top-item).active', text: 'Container Registry') + expect(rendered).to have_css('span.badge.badge-pill.merge_counter.js-merge-counter') end end - describe 'Packages' do - let_it_be(:user) { create(:user) } + describe 'CI/CD' do + it 'has a link to pipelines page' do + render - let_it_be(:package_menu_name) { 'Packages & Registries' } - let_it_be(:package_entry_name) { 'Package Registry' } + expect(rendered).to have_link('CI/CD', href: project_pipelines_path(project)) + end - before do - project.team.add_developer(user) - sign_in(user) - stub_container_registry_config(enabled: true) + describe 'Artifacts' do + it 'has a link to the artifacts page' do + render + + expect(rendered).to have_link('Artifacts', href: project_artifacts_path(project)) + end end - context 'when packages is enabled' do - it 'packages link is visible' do + describe 'Jobs' do + it 'has a link to the jobs page' do render - expect(rendered).to have_link(package_menu_name, href: project_packages_path(project)) + expect(rendered).to have_link('Jobs', href: project_jobs_path(project)) end + end - it 'packages list link is visible' do + describe 'Pipeline Schedules' do + it 'has a link to the pipeline schedules page' do render - expect(rendered).to have_link(package_entry_name, href: project_packages_path(project)) + expect(rendered).to have_link('Schedules', href: pipeline_schedules_path(project)) end + end - it 'container registry link is visible' do + describe 'Pipelines' do + it 'has a link to the pipelines page' do render - expect(rendered).to have_link('Container Registry', href: project_container_registry_index_path(project)) + expect(rendered).to have_link('Pipelines', href: project_pipelines_path(project)) + end + end + + describe 'Pipeline Editor' do + it 'has a link to the pipeline editor' do + render + + expect(rendered).to have_link('Editor', href: project_ci_pipeline_editor_path(project)) + end + + context 'when user cannot access pipeline editor' do + it 'does not has a link to the pipeline editor' do + allow(view).to receive(:can_view_pipeline_editor?).and_return(false) + + render + + expect(rendered).not_to have_link('Editor', href: project_ci_pipeline_editor_path(project)) + end + end + end + end + + describe 'Security and Compliance' do + describe 'when user does not have permissions' do + before do + allow(view).to receive(:current_user).and_return(nil) + end + + it 'top level navigation link is not visible' do + render + + expect(rendered).not_to have_link('Security & Compliance') end end - context 'when container registry is disabled' do + context 'when user has permissions' do before do - stub_container_registry_config(enabled: false) + allow(view).to receive(:current_user).and_return(user) + + render + end + + it 'top level navigation link is visible' do + expect(rendered).to have_link('Security & Compliance') + end + + it 'security configuration link is visible' do + expect(rendered).to have_link('Configuration', href: project_security_configuration_path(project)) end + end + end - it 'packages top level and list link are visible' do + describe 'Deployments' do + let(:page) { Nokogiri::HTML.parse(rendered) } + + describe 'Feature Flags' do + it 'has a link to the feature flags page' do render - expect(rendered).to have_link(package_menu_name, href: project_packages_path(project)) - expect(rendered).to have_link(package_entry_name, href: project_packages_path(project)) + expect(page.at_css('.shortcuts-deployments').parent.css('[aria-label="Feature Flags"]')).not_to be_empty + expect(rendered).to have_link('Feature Flags', href: project_feature_flags_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the feature flags page' do + render + + expect(rendered).not_to have_link('Feature Flags') + end + end + + context 'when feature flag :sidebar_refactor is disabled' do + it 'does not have a Feature Flags menu item' do + stub_feature_flags(sidebar_refactor: false) + + render + + expect(rendered).not_to have_selector('.shortcuts-deployments') + end end + end - it 'container registry link is not visible' do + describe 'Environments' do + it 'has a link to the environments page' do render - expect(rendered).not_to have_link('Container Registry', href: project_container_registry_index_path(project)) + expect(page.at_css('.shortcuts-deployments').parent.css('[aria-label="Environments"]')).not_to be_empty + expect(rendered).to have_link('Environments', href: project_environments_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the environments page' do + render + + expect(rendered).not_to have_link('Environments') + end + end + + context 'when feature flag :sidebar_refactor is disabled' do + it 'does not have a Environments menu item' do + stub_feature_flags(sidebar_refactor: false) + + render + + expect(rendered).not_to have_selector('.shortcuts-deployments') + end + end + end + + describe 'Releases' do + it 'has a link to the project releases path' do + render + + expect(rendered).to have_link('Releases', href: project_releases_path(project), class: 'shortcuts-deployments-releases') + end + + context 'when feature flag :sidebar refactor is disabled' do + it 'does not have a link to the project releases path' do + stub_feature_flags(sidebar_refactor: false) + + render + + expect(rendered).not_to have_link('Releases', href: project_releases_path(project), class: 'shortcuts-deployments-releases') + end end end end - describe 'wiki entry tab' do - let(:can_read_wiki) { true } + describe 'Monitor' do + it 'top level navigation link is visible for user with permissions' do + render - before do - allow(view).to receive(:can?).with(user, :read_wiki, project).and_return(can_read_wiki) + expect(rendered).to have_link('Monitor') end - describe 'when wiki is enabled' do - it 'shows the wiki tab with the wiki internal link' do + describe 'Metrics Dashboard' do + it 'has a link to the metrics dashboard page' do render - expect(rendered).to have_link('Wiki', href: wiki_path(project.wiki)) + expect(rendered).to have_link('Metrics', href: project_metrics_dashboard_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the metrics page' do + render + + expect(rendered).not_to have_link('Metrics') + end end end - describe 'when wiki is disabled' do - let(:can_read_wiki) { false } + describe 'Logs' do + it 'has a link to the pod logs page' do + render + + expect(rendered).to have_link('Logs', href: project_logs_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the pod logs page' do + render + + expect(rendered).not_to have_link('Logs') + end + end + end - it 'does not show the wiki tab' do + describe 'Tracing' do + it 'has a link to the tracing page' do render - expect(rendered).not_to have_link('Wiki') + expect(rendered).to have_link('Tracing', href: project_tracing_path(project)) + end + + context 'without project.tracing_external_url' do + it 'has a link to the tracing page' do + render + + expect(rendered).to have_link('Tracing', href: project_tracing_path(project)) + end + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the tracing page' do + render + + expect(rendered).not_to have_text 'Tracing' + end + end + end + + describe 'Error Tracking' do + it 'has a link to the error tracking page' do + render + + expect(rendered).to have_link('Error Tracking', href: project_error_tracking_index_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the error tracking page' do + render + + expect(rendered).not_to have_link('Error Tracking') + end + end + end + + describe 'Alert Management' do + it 'has a link to the alert management page' do + render + + expect(rendered).to have_link('Alerts', href: project_alert_management_index_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the alert management page' do + render + + expect(rendered).not_to have_link('Alerts') + end + end + end + + describe 'Incidents' do + it 'has a link to the incidents page' do + render + + expect(rendered).to have_link('Incidents', href: project_incidents_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the incidents page' do + render + + expect(rendered).not_to have_link('Incidents') + end + end + end + + context 'when feature flag :sidebar_refactor is disabled' do + before do + stub_feature_flags(sidebar_refactor: false) + end + + describe 'Serverless' do + it 'has a link to the serverless page' do + render + + page = Nokogiri::HTML.parse(rendered) + + expect(page.at_css('.shortcuts-operations').parent.css('[aria-label="Serverless"]')).not_to be_empty + expect(rendered).to have_link('Serverless', href: project_serverless_functions_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the serverless page' do + render + + expect(rendered).not_to have_link('Serverless') + end + end + end + + describe 'Terraform' do + it 'has a link to the terraform page' do + render + + page = Nokogiri::HTML.parse(rendered) + + expect(page.at_css('.shortcuts-operations').parent.css('[aria-label="Terraform"]')).not_to be_empty + expect(rendered).to have_link('Terraform', href: project_terraform_index_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the terraform page' do + render + + expect(rendered).not_to have_link('Terraform') + end + end + end + + describe 'Kubernetes' do + it 'has a link to the kubernetes page' do + render + + page = Nokogiri::HTML.parse(rendered) + + expect(page.at_css('.shortcuts-operations').parent.css('[aria-label="Kubernetes"]')).not_to be_empty + expect(rendered).to have_link('Kubernetes', href: project_clusters_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the kubernetes page' do + render + + expect(rendered).not_to have_link('Kubernetes') + end + end + end + end + + describe 'Environments' do + let(:page) { Nokogiri::HTML.parse(rendered) } + + it 'does not have a link to the environments page' do + render + + expect(page.at_css('.shortcuts-monitor').parent.css('[aria-label="Environments"]')).to be_empty + end + + context 'when feature flag :sidebar_refactor is disabled' do + before do + stub_feature_flags(sidebar_refactor: false) + end + + it 'has a link to the environments page' do + render + + expect(page.at_css('.shortcuts-operations').parent.css('[aria-label="Environments"]')).not_to be_empty + expect(rendered).to have_link('Environments', href: project_environments_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the environments page' do + render + + expect(rendered).not_to have_link('Environments') + end + end + end + end + + describe 'Feature Flags' do + let(:page) { Nokogiri::HTML.parse(rendered) } + + it 'does not have a link to the feature flags page' do + render + + expect(page.at_css('.shortcuts-monitor').parent.css('[aria-label="Feature Flags"]')).to be_empty + end + + context 'when feature flag :sidebar_refactor is disabled' do + before do + stub_feature_flags(sidebar_refactor: false) + end + + it 'has a link to the feature flags page' do + render + + expect(page.at_css('.shortcuts-operations').parent.css('[aria-label="Feature Flags"]')).not_to be_empty + expect(rendered).to have_link('Feature Flags', href: project_feature_flags_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the feature flags page' do + render + + expect(rendered).not_to have_link('Feature Flags') + end + end + end + end + + describe 'Product Analytics' do + it 'has a link to the product analytics page' do + render + + expect(rendered).to have_link('Product Analytics', href: project_product_analytics_path(project)) + end + + describe 'when feature flag :product_analytics is disabled' do + it 'does not have a link to the feature flags page' do + stub_feature_flags(product_analytics: false) + + render + + expect(rendered).not_to have_link('Product Analytics') + end end end end - describe 'external wiki entry tab' do - let(:properties) { { 'external_wiki_url' => 'https://gitlab.com' } } - let(:service_status) { true } + describe 'Infrastructure' do + describe 'Serverless platform' do + it 'has a link to the serverless page' do + render + + expect(rendered).to have_link('Serverless platform', href: project_serverless_functions_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the serverless page' do + render + + expect(rendered).not_to have_link('Serverless platform') + end + end + end + + describe 'Terraform' do + it 'has a link to the terraform page' do + render + + expect(rendered).to have_link('Terraform', href: project_terraform_index_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the terraform page' do + render + + expect(rendered).not_to have_link('Terraform') + end + end + end + + describe 'Kubernetes clusters' do + it 'has a link to the kubernetes page' do + render + + expect(rendered).to have_link('Kubernetes clusters', href: project_clusters_path(project)) + end + + describe 'when the user does not have access' do + let(:user) { nil } + + it 'does not have a link to the kubernetes page' do + render + + expect(rendered).not_to have_link('Kubernetes clusters') + end + end + end + end + + describe 'Packages and Registries' do + let(:registry_enabled) { true } + let(:packages_enabled) { true } before do - project.create_external_wiki_service(active: service_status, properties: properties) - project.reload + stub_container_registry_config(enabled: registry_enabled) + stub_config(packages: { enabled: packages_enabled }) end - context 'when it is active' do - it 'shows the external wiki tab with the external wiki service link' do + it 'top level navigation link is visible and points to package registry page' do + render + + expect(rendered).to have_link('Packages & Registries', href: project_packages_path(project)) + end + + describe 'Packages Registry' do + it 'shows link to package registry page' do render - expect(rendered).to have_link('External wiki', href: properties['external_wiki_url']) + expect(rendered).to have_link('Package Registry', href: project_packages_path(project)) + end + + context 'when packages config setting is not enabled' do + let(:packages_enabled) { false } + + it 'does not show link to package registry page' do + render + + expect(rendered).not_to have_link('Package Registry', href: project_packages_path(project)) + end end end - context 'when it is disabled' do - let(:service_status) { false } + describe 'Container Registry' do + it 'shows link to container registry page' do + render - it 'does not show the external wiki tab' do + expect(rendered).to have_link('Container Registry', href: project_container_registry_index_path(project)) + end + + context 'when container config setting is not enabled' do + let(:registry_enabled) { false } + + it 'does not show link to package registry page' do + render + + expect(rendered).not_to have_link('Container Registry', href: project_container_registry_index_path(project)) + end + end + end + + describe 'Infrastructure Registry' do + it 'shows link to infrastructure registry page' do render - expect(rendered).not_to have_link('External wiki') + expect(rendered).to have_link('Infrastructure Registry', href: project_infrastructure_registry_index_path(project)) + end + + context 'when feature flag :infrastructure_registry_page is disabled' do + it 'does not show link to package registry page' do + stub_feature_flags(infrastructure_registry_page: false) + + render + + expect(rendered).not_to have_link('Infrastructure Registry', href: project_infrastructure_registry_index_path(project)) + end end end end - describe 'confluence tab' do + describe 'Analytics' do + it 'top level navigation link is visible points to the value stream page' do + render + + expect(rendered).to have_link('Analytics', href: project_cycle_analytics_path(project)) + end + + describe 'CI/CD' do + it 'has a link to the CI/CD analytics page' do + render + + expect(rendered).to have_link('CI/CD', href: charts_project_pipelines_path(project)) + end + + context 'when user does not have access' do + let(:user) { nil } + + it 'does not have a link to the CI/CD analytics page' do + render + + expect(rendered).not_to have_link('CI/CD', href: charts_project_pipelines_path(project)) + end + end + end + + describe 'Repository' do + it 'has a link to the repository analytics page' do + render + + expect(rendered).to have_link('Repository', href: charts_project_graph_path(project, 'master')) + end + + context 'when user does not have access' do + let(:user) { nil } + + it 'does not have a link to the repository analytics page' do + render + + expect(rendered).not_to have_link('Repository', href: charts_project_graph_path(project, 'master')) + end + end + end + + describe 'Value Stream' do + it 'has a link to the value stream page' do + render + + expect(rendered).to have_link('Value Stream', href: project_cycle_analytics_path(project)) + end + + context 'when user does not have access' do + let(:user) { nil } + + it 'does not have a link to the value stream page' do + render + + expect(rendered).not_to have_link('Value Stream', href: project_cycle_analytics_path(project)) + end + end + end + end + + describe 'Confluence' do let!(:service) { create(:confluence_service, project: project, active: active) } before do @@ -275,11 +1003,11 @@ RSpec.describe 'layouts/nav/sidebar/_project' do context 'when the Confluence integration is active' do let(:active) { true } - it 'shows the Confluence tab' do + it 'shows the Confluence link' do expect(rendered).to have_link('Confluence', href: project_wikis_confluence_path(project)) end - it 'does not show the GitLab wiki tab' do + it 'does not show the GitLab wiki link' do expect(rendered).not_to have_link('Wiki') end end @@ -287,167 +1015,314 @@ RSpec.describe 'layouts/nav/sidebar/_project' do context 'when it is disabled' do let(:active) { false } - it 'does not show the Confluence tab' do + it 'does not show the Confluence link' do expect(rendered).not_to have_link('Confluence') end - it 'shows the GitLab wiki tab' do + it 'shows the GitLab wiki link' do expect(rendered).to have_link('Wiki', href: wiki_path(project.wiki)) end end end - describe 'ci/cd settings tab' do - before do - project.update!(archived: project_archived) + describe 'Wiki' do + describe 'when wiki is enabled' do + it 'shows the wiki tab with the wiki internal link' do + render + + expect(rendered).to have_link('Wiki', href: wiki_path(project.wiki)) + end end - context 'when project is archived' do - let(:project_archived) { true } + describe 'when wiki is disabled' do + let(:user) { nil } - it 'does not show the ci/cd settings tab' do + it 'does not show the wiki link' do render - expect(rendered).not_to have_link('CI/CD', href: project_settings_ci_cd_path(project)) + expect(rendered).not_to have_link('Wiki') end end + end - context 'when project is active' do - let(:project_archived) { false } + describe 'External Wiki' do + let(:properties) { { 'external_wiki_url' => 'https://gitlab.com' } } + let(:service_status) { true } + + before do + project.create_external_wiki_service(active: service_status, properties: properties) + project.reload + end - it 'shows the ci/cd settings tab' do + context 'when it is active' do + it 'shows the external wiki tab with the external wiki service link' do render - expect(rendered).to have_link('CI/CD', href: project_settings_ci_cd_path(project)) + expect(rendered).to have_link('External wiki', href: properties['external_wiki_url']) + end + end + + context 'when it is disabled' do + let(:service_status) { false } + + it 'does not show the external wiki link' do + render + + expect(rendered).not_to have_link('External wiki') end end end - describe 'pipeline editor link' do - it 'shows the pipeline editor link' do + describe 'Snippets' do + before do render - - expect(rendered).to have_link('Editor', href: project_ci_pipeline_editor_path(project)) end - it 'does not show the pipeline editor link' do - allow(view).to receive(:can_view_pipeline_editor?).and_return(false) + context 'when user can access snippets' do + it 'shows Snippets link' do + expect(rendered).to have_link('Snippets', href: project_snippets_path(project)) + end + end - render + context 'when user cannot access snippets' do + let(:user) { nil } - expect(rendered).not_to have_link('Editor', href: project_ci_pipeline_editor_path(project)) + it 'does not show Snippets link' do + expect(rendered).not_to have_link('Snippets') + end end end - describe 'operations settings tab' do - describe 'archive projects' do - before do - project.update!(archived: project_archived) - end + describe 'Members' do + it 'does not show the Member menu item' do + expect(rendered).not_to have_selector('.sidebar-top-level-items > li > a[aria-label="Members"]') + end - context 'when project is archived' do - let(:project_archived) { true } + context 'when feature flag :sidebar_refactor is disabled' do + before do + stub_feature_flags(sidebar_refactor: false) - it 'does not show the operations settings tab' do - render + render + end - expect(rendered).not_to have_link('Operations', href: project_settings_operations_path(project)) + context 'when user can access members' do + it 'show Members link' do + expect(rendered).to have_selector('.sidebar-top-level-items > li > a[aria-label="Members"]') + expect(rendered).to have_link('Members', href: project_project_members_path(project)) end end - context 'when project is active' do - let(:project_archived) { false } + context 'when user cannot access members' do + let(:user) { nil } - it 'shows the operations settings tab' do - render - - expect(rendered).to have_link('Operations', href: project_settings_operations_path(project)) + it 'show Members link' do + expect(rendered).not_to have_link('Members') end end end + end - describe 'Tracing' do - it 'is not visible to unauthorized user' do - allow(view).to receive(:can?).and_return(false) + describe 'Settings' do + describe 'General' do + it 'has a link to the General settings' do + render + expect(rendered).to have_link('General', href: edit_project_path(project)) + end + end + + describe 'Integrations' do + it 'has a link to the Integrations settings' do render - expect(rendered).not_to have_text 'Tracing' + expect(rendered).to have_link('Integrations', href: project_settings_integrations_path(project)) end + end - it 'links to Tracing page' do + describe 'WebHooks' do + it 'has a link to the WebHooks settings' do render - expect(rendered).to have_link('Tracing', href: project_tracing_path(project)) + expect(rendered).to have_link('Webhooks', href: project_hooks_path(project)) end + end - context 'without project.tracing_external_url' do - it 'links to Tracing page' do + describe 'Access Tokens' do + context 'self-managed instance' do + before do + allow(Gitlab).to receive(:com?).and_return(false) + end + + it 'has a link to the Access Tokens settings' do render - expect(rendered).to have_link('Tracing', href: project_tracing_path(project)) + expect(rendered).to have_link('Access Tokens', href: project_settings_access_tokens_path(project)) + end + end + + context 'gitlab.com' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + it 'has a link to the Access Tokens settings' do + render + + expect(rendered).to have_link('Access Tokens', href: project_settings_access_tokens_path(project)) end end end - describe 'Alert Management' do - it 'shows the Alerts sidebar entry' do + describe 'Repository' do + it 'has a link to the Repository settings' do render - expect(rendered).to have_css('a[title="Alerts"]') + expect(rendered).to have_link('Repository', href: project_settings_repository_path(project)) end end - end - describe 'value stream analytics entry' do - let(:read_cycle_analytics) { true } + describe 'CI/CD' do + context 'when project is archived' do + before do + project.update!(archived: true) + end - before do - allow(view).to receive(:can?).with(user, :read_cycle_analytics, project).and_return(read_cycle_analytics) - end + it 'does not have a link to the CI/CD settings' do + render - describe 'when value stream analytics is enabled' do - it 'shows the value stream analytics entry' do - render + expect(rendered).not_to have_link('CI/CD', href: project_settings_ci_cd_path(project)) + end + end - expect(rendered).to have_link('Value Stream', href: project_cycle_analytics_path(project)) + context 'when project is not archived' do + it 'has a link to the CI/CD settings' do + render + + expect(rendered).to have_link('CI/CD', href: project_settings_ci_cd_path(project)) + end end end - describe 'when value stream analytics is disabled' do - let(:read_cycle_analytics) { false } + describe 'Monitor' do + context 'when project is archived' do + before do + project.update!(archived: true) + end - it 'does not show the value stream analytics entry' do - render + it 'does not have a link to the Monitor settings' do + render - expect(rendered).not_to have_link('Value Stream', href: project_cycle_analytics_path(project)) + expect(rendered).not_to have_link('Monitor', href: project_settings_operations_path(project)) + end + end + + context 'when project is not archived active' do + it 'has a link to the Monitor settings' do + render + + expect(rendered).to have_link('Monitor', href: project_settings_operations_path(project)) + end end end - end - describe 'project access tokens' do - context 'self-managed instance' do + describe 'Pages' do before do - allow(Gitlab).to receive(:com?).and_return(false) + stub_config(pages: { enabled: pages_enabled }) end - it 'displays "Access Tokens" nav item' do - render + context 'when pages are enabled' do + let(:pages_enabled) { true } + + it 'has a link to the Pages settings' do + render - expect(rendered).to have_link('Access Tokens', href: project_settings_access_tokens_path(project)) + expect(rendered).to have_link('Pages', href: project_pages_path(project)) + end + end + + context 'when pages are not enabled' do + let(:pages_enabled) { false } + + it 'does not have a link to the Pages settings' do + render + + expect(rendered).not_to have_link('Pages', href: project_pages_path(project)) + end end end - context 'gitlab.com' do + describe 'Packages & Registries' do before do - allow(Gitlab).to receive(:com?).and_return(true) + stub_container_registry_config(enabled: registry_enabled) end - it 'displays "Access Tokens" nav item' do - render + context 'when registry is enabled' do + let(:registry_enabled) { true } + + it 'has a link to the Packages & Registries settings' do + render + + expect(rendered).to have_link('Packages & Registries', href: project_settings_packages_and_registries_path(project)) + end + + context 'when feature flag :sidebar_refactor is disabled' do + it 'does not have a link to the Packages & Registries settings' do + stub_feature_flags(sidebar_refactor: false) + + render - expect(rendered).to have_link('Access Tokens', href: project_settings_access_tokens_path(project)) + expect(rendered).not_to have_link('Packages & Registries', href: project_settings_packages_and_registries_path(project)) + end + end end + + context 'when registry is not enabled' do + let(:registry_enabled) { false } + + it 'does not have a link to the Packages & Registries settings' do + render + + expect(rendered).not_to have_link('Packages & Registries', href: project_settings_packages_and_registries_path(project)) + end + end + end + end + + describe 'Hidden menus' do + it 'has a link to the Activity page' do + render + + expect(rendered).to have_link('Activity', href: activity_project_path(project), class: 'shortcuts-project-activity', visible: false) + end + + it 'has a link to the Graph page' do + render + + expect(rendered).to have_link('Graph', href: project_network_path(project, current_ref), class: 'shortcuts-network', visible: false) + end + + it 'has a link to the New Issue page' do + render + + expect(rendered).to have_link('Create a new issue', href: new_project_issue_path(project), class: 'shortcuts-new-issue', visible: false) + end + + it 'has a link to the Jobs page' do + render + + expect(rendered).to have_link('Jobs', href: project_jobs_path(project), class: 'shortcuts-builds', visible: false) + end + + it 'has a link to the Commits page' do + render + + expect(rendered).to have_link('Commits', href: project_commits_path(project), class: 'shortcuts-commits', visible: false) + end + + it 'has a link to the Issue Boards page' do + render + + expect(rendered).to have_link('Issue Boards', href: project_boards_path(project), class: 'shortcuts-issue-boards', visible: false) end end |