diff options
Diffstat (limited to 'spec/helpers')
30 files changed, 561 insertions, 341 deletions
diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb index 0304aac18ae..1703727db21 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -46,6 +46,10 @@ RSpec.describe ApplicationSettingsHelper do expect(helper.visible_attributes).to include(:deactivate_dormant_users) end + it 'contains :deactivate_dormant_users_period' do + expect(helper.visible_attributes).to include(:deactivate_dormant_users_period) + end + it 'contains rate limit parameters' do expect(helper.visible_attributes).to include(*%i( issues_create_limit notes_create_limit project_export_limit @@ -63,6 +67,10 @@ RSpec.describe ApplicationSettingsHelper do it 'does not contain :deactivate_dormant_users' do expect(helper.visible_attributes).not_to include(:deactivate_dormant_users) end + + it 'does not contain :deactivate_dormant_users_period' do + expect(helper.visible_attributes).not_to include(:deactivate_dormant_users_period) + end end end @@ -289,6 +297,66 @@ RSpec.describe ApplicationSettingsHelper do end end + describe '.spam_check_endpoint_enabled?' do + subject { helper.spam_check_endpoint_enabled? } + + context 'when spam check endpoint is enabled' do + before do + stub_application_setting(spam_check_endpoint_enabled: true) + end + + it { is_expected.to be true } + end + + context 'when spam check endpoint is disabled' do + before do + stub_application_setting(spam_check_endpoint_enabled: false) + end + + it { is_expected.to be false } + end + end + + describe '.anti_spam_service_enabled?' do + subject { helper.anti_spam_service_enabled? } + + context 'when akismet is enabled and spam check endpoint is disabled' do + before do + stub_application_setting(spam_check_endpoint_enabled: false) + stub_application_setting(akismet_enabled: true) + end + + it { is_expected.to be true } + end + + context 'when akismet is disabled and spam check endpoint is enabled' do + before do + stub_application_setting(spam_check_endpoint_enabled: true) + stub_application_setting(akismet_enabled: false) + end + + it { is_expected.to be true } + end + + context 'when akismet and spam check endpoint are both enabled' do + before do + stub_application_setting(spam_check_endpoint_enabled: true) + stub_application_setting(akismet_enabled: true) + end + + it { is_expected.to be true } + end + + context 'when akismet and spam check endpoint are both disabled' do + before do + stub_application_setting(spam_check_endpoint_enabled: false) + stub_application_setting(akismet_enabled: false) + end + + it { is_expected.to be false } + end + end + describe '#sidekiq_job_limiter_modes_for_select' do subject { helper.sidekiq_job_limiter_modes_for_select } @@ -305,7 +373,7 @@ RSpec.describe ApplicationSettingsHelper do allow(helper).to receive(:can?).with(user, :read_cluster, instance_of(Clusters::Instance)).and_return(true) end - it { is_expected.to be_truthy} + it { is_expected.to be_truthy } context ':certificate_based_clusters feature flag is disabled' do before do diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index 65e46b61882..fe652e905cc 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -357,7 +357,7 @@ RSpec.describe BlobHelper do describe '#ide_merge_request_path' do let_it_be(:project) { create(:project, :repository) } - let_it_be(:merge_request) { create(:merge_request, source_project: project)} + let_it_be(:merge_request) { create(:merge_request, source_project: project) } it 'returns IDE path for the given MR if MR is not merged' do expect(helper.ide_merge_request_path(merge_request)).to eq("/-/ide/project/#{project.full_path}/merge_requests/#{merge_request.iid}") diff --git a/spec/helpers/ci/builds_helper_spec.rb b/spec/helpers/ci/builds_helper_spec.rb index ea3b5aac4ea..c215d7b4a78 100644 --- a/spec/helpers/ci/builds_helper_spec.rb +++ b/spec/helpers/ci/builds_helper_spec.rb @@ -80,7 +80,7 @@ RSpec.describe Ci::BuildsHelper do expect(subject).to eq({ page_path: project_job_path(project, ci_build), build_status: ci_build.status, - build_stage: ci_build.stage, + build_stage: ci_build.stage_name, log_state: '' }) end @@ -106,7 +106,7 @@ RSpec.describe Ci::BuildsHelper do expect(subject).to eq([{ id: failed_build.id, failure: failed_build.present.callout_failure_message, - failure_summary: helper.build_summary(failed_build) + failure_summary: helper.build_summary(failed_build) }].to_json) end end diff --git a/spec/helpers/ci/runners_helper_spec.rb b/spec/helpers/ci/runners_helper_spec.rb index 3b18572ad64..1b1edde8faf 100644 --- a/spec/helpers/ci/runners_helper_spec.rb +++ b/spec/helpers/ci/runners_helper_spec.rb @@ -131,17 +131,32 @@ RSpec.describe Ci::RunnersHelper do describe '#group_runners_data_attributes' do let(:group) { create(:group) } - it 'returns group data to render a runner list' do - expect(helper.group_runners_data_attributes(group)).to include( - registration_token: group.runners_token, - group_id: group.id, - group_full_path: group.full_path, - runner_install_help_page: 'https://docs.gitlab.com/runner/install/', - online_contact_timeout_secs: 7200, - stale_timeout_secs: 7889238, - empty_state_svg_path: start_with('/assets/illustrations/pipelines_empty'), - empty_state_filtered_svg_path: start_with('/assets/illustrations/magnifying-glass') - ) + context 'when user can register group runners' do + before do + allow(helper).to receive(:can?).with(user, :register_group_runners, group).and_return(true) + end + + it 'returns group data to render a runner list' do + expect(helper.group_runners_data_attributes(group)).to include( + group_id: group.id, + group_full_path: group.full_path, + runner_install_help_page: 'https://docs.gitlab.com/runner/install/', + online_contact_timeout_secs: 7200, + stale_timeout_secs: 7889238, + empty_state_svg_path: start_with('/assets/illustrations/pipelines_empty'), + empty_state_filtered_svg_path: start_with('/assets/illustrations/magnifying-glass') + ) + end + end + + context 'when user cannot register group runners' do + before do + allow(helper).to receive(:can?).with(user, :register_group_runners, group).and_return(false) + end + + it 'returns empty registration token' do + expect(helper.group_runners_data_attributes(group)).not_to include(registration_token: group.runners_token) + end end end diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb index 010100769d4..0cc53da98b2 100644 --- a/spec/helpers/commits_helper_spec.rb +++ b/spec/helpers/commits_helper_spec.rb @@ -329,7 +329,7 @@ RSpec.describe CommitsHelper do it { is_expected.to include(commit.author) } it { is_expected.to include(ref) } - it do + specify do is_expected.to include( { merge_request: merge_request.cache_key, diff --git a/spec/helpers/gitlab_script_tag_helper_spec.rb b/spec/helpers/gitlab_script_tag_helper_spec.rb index 9d71e25286e..cfe7b349cec 100644 --- a/spec/helpers/gitlab_script_tag_helper_spec.rb +++ b/spec/helpers/gitlab_script_tag_helper_spec.rb @@ -27,8 +27,8 @@ RSpec.describe GitlabScriptTagHelper do end describe 'inline script tag' do - let(:tag_with_nonce) {"<script nonce=\"noncevalue\">\n//<![CDATA[\nalert(1)\n//]]>\n</script>"} - let(:tag_with_nonce_and_type) {"<script type=\"application/javascript\" nonce=\"noncevalue\">\n//<![CDATA[\nalert(1)\n//]]>\n</script>"} + let(:tag_with_nonce) { "<script nonce=\"noncevalue\">\n//<![CDATA[\nalert(1)\n//]]>\n</script>" } + let(:tag_with_nonce_and_type) { "<script type=\"application/javascript\" nonce=\"noncevalue\">\n//<![CDATA[\nalert(1)\n//]]>\n</script>" } it 'returns a script tag with a nonce using block syntax' do expect(helper.javascript_tag { 'alert(1)' }.to_s).to eq tag_with_nonce diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index 2c1061d2f1b..00e620832b3 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -520,6 +520,29 @@ RSpec.describe GroupsHelper do end end + describe '#group_overview_tabs_app_data' do + let_it_be(:group) { create(:group) } + let_it_be(:user) { create(:user) } + + before do + allow(helper).to receive(:current_user).and_return(user) + + allow(helper).to receive(:can?).with(user, :create_subgroup, group) { true } + allow(helper).to receive(:can?).with(user, :create_projects, group) { true } + end + + it 'returns expected hash' do + expect(helper.group_overview_tabs_app_data(group)).to match( + { + subgroups_and_projects_endpoint: including("/groups/#{group.path}/-/children.json"), + shared_projects_endpoint: including("/groups/#{group.path}/-/shared_projects.json"), + archived_projects_endpoint: including("/groups/#{group.path}/-/children.json?archived=only"), + current_group_visibility: group.visibility + }.merge(helper.group_overview_tabs_app_data(group)) + ) + end + end + describe "#enabled_git_access_protocol_options_for_group" do subject { helper.enabled_git_access_protocol_options_for_group } diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 069465c2fec..18a21b59409 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -448,7 +448,7 @@ RSpec.describe IssuablesHelper do allow(merge_request).to receive(:can_be_merged_by?).and_return(can_merge) end - it { is_expected.to include({ can_merge: can_merge })} + it { is_expected.to include({ can_merge: can_merge }) } end end end @@ -480,7 +480,7 @@ RSpec.describe IssuablesHelper do allow(merge_request).to receive(:can_be_merged_by?).and_return(can_merge) end - it { is_expected.to include({ can_merge: can_merge })} + it { is_expected.to include({ can_merge: can_merge }) } end end end diff --git a/spec/helpers/jira_connect_helper_spec.rb b/spec/helpers/jira_connect_helper_spec.rb index 4d2fc3d9ee6..97e37023c2d 100644 --- a/spec/helpers/jira_connect_helper_spec.rb +++ b/spec/helpers/jira_connect_helper_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe JiraConnectHelper do describe '#jira_connect_app_data' do + let_it_be(:installation) { create(:jira_connect_installation) } let_it_be(:subscription) { create(:jira_connect_subscription) } let(:user) { create(:user) } @@ -13,11 +14,12 @@ RSpec.describe JiraConnectHelper do stub_application_setting(jira_connect_application_key: client_id) end - subject { helper.jira_connect_app_data([subscription]) } + subject { helper.jira_connect_app_data([subscription], installation) } context 'user is not logged in' do before do allow(view).to receive(:current_user).and_return(nil) + allow(Gitlab).to receive_message_chain('config.gitlab.url') { 'http://test.host' } end it 'includes Jira Connect app attributes' do @@ -36,14 +38,14 @@ RSpec.describe JiraConnectHelper do end context 'with oauth_metadata' do - let(:oauth_metadata) { helper.jira_connect_app_data([subscription])[:oauth_metadata] } + let(:oauth_metadata) { helper.jira_connect_app_data([subscription], installation)[:oauth_metadata] } subject(:parsed_oauth_metadata) { Gitlab::Json.parse(oauth_metadata).deep_symbolize_keys } it 'assigns oauth_metadata' do expect(parsed_oauth_metadata).to include( oauth_authorize_url: start_with('http://test.host/oauth/authorize?'), - oauth_token_url: 'http://test.host/oauth/token', + oauth_token_path: '/oauth/token', state: %r/[a-z0-9.]{32}/, oauth_token_payload: hash_including( grant_type: 'authorization_code', @@ -74,6 +76,30 @@ RSpec.describe JiraConnectHelper do expect(oauth_metadata).to be_nil end end + + context 'with self-managed instance' do + let_it_be(:installation) { create(:jira_connect_installation, instance_url: 'https://gitlab.example.com') } + + it 'points urls to the self-managed instance' do + expect(parsed_oauth_metadata).to include( + oauth_authorize_url: start_with('https://gitlab.example.com/oauth/authorize?'), + oauth_token_path: '/oauth/token' + ) + end + + context 'and jira_connect_oauth_self_managed feature is disabled' do + before do + stub_feature_flags(jira_connect_oauth_self_managed: false) + end + + it 'does not point urls to the self-managed instance' do + expect(parsed_oauth_metadata).not_to include( + oauth_authorize_url: start_with('https://gitlab.example.com/oauth/authorize?'), + oauth_token_path: 'https://gitlab.example.com/oauth/token' + ) + end + end + end end it 'passes group as "skip_groups" param' do diff --git a/spec/helpers/learn_gitlab_helper_spec.rb b/spec/helpers/learn_gitlab_helper_spec.rb index 7c9dfd6b5be..0d4f1965d92 100644 --- a/spec/helpers/learn_gitlab_helper_spec.rb +++ b/spec/helpers/learn_gitlab_helper_spec.rb @@ -7,16 +7,16 @@ RSpec.describe LearnGitlabHelper do include Devise::Test::ControllerHelpers let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME, namespace: user.namespace) } + let_it_be(:project) { create(:project, name: Onboarding::LearnGitlab::PROJECT_NAME, namespace: user.namespace) } let_it_be(:namespace) { project.namespace } before do - allow_next_instance_of(LearnGitlab::Project) do |learn_gitlab| + allow_next_instance_of(Onboarding::LearnGitlab) do |learn_gitlab| allow(learn_gitlab).to receive(:project).and_return(project) end - OnboardingProgress.onboard(namespace) - OnboardingProgress.register(namespace, :git_write) + Onboarding::Progress.onboard(namespace) + Onboarding::Progress.register(namespace, :git_write) end describe '#learn_gitlab_enabled?' do @@ -37,8 +37,8 @@ RSpec.describe LearnGitlabHelper do with_them do before do - allow(OnboardingProgress).to receive(:onboarding?).with(project.namespace).and_return(onboarding) - allow_next(LearnGitlab::Project, user).to receive(:available?).and_return(learn_gitlab_available) + allow(Onboarding::Progress).to receive(:onboarding?).with(project.namespace).and_return(onboarding) + allow_next(Onboarding::LearnGitlab, user).to receive(:available?).and_return(learn_gitlab_available) end context 'when signed in' do @@ -81,7 +81,7 @@ RSpec.describe LearnGitlabHelper do it 'has all section data', :aggregate_failures do expect(onboarding_sections_data.keys).to contain_exactly(:deploy, :plan, :workspace) - expect(onboarding_sections_data.values.map { |section| section.keys }).to match_array([[:svg]] * 3) + expect(onboarding_sections_data.values.map(&:keys)).to match_array([[:svg]] * 3) end it 'has all project data', :aggregate_failures do diff --git a/spec/helpers/members_helper_spec.rb b/spec/helpers/members_helper_spec.rb index 4a3a623ce77..005fce1730f 100644 --- a/spec/helpers/members_helper_spec.rb +++ b/spec/helpers/members_helper_spec.rb @@ -6,12 +6,12 @@ RSpec.describe MembersHelper do describe '#remove_member_message' do let(:requester) { create(:user) } let(:project) { create(:project, :public) } - let(:project_member) { build(:project_member, project: project) } - let(:project_member_invite) { build(:project_member, project: project).tap { |m| m.generate_invite_token! } } + let(:project_member) { create(:project_member, project: project) } + let(:project_member_invite) { create(:project_member, project: project).tap { |m| m.generate_invite_token! } } let(:project_member_request) { project.request_access(requester) } let(:group) { create(:group) } - let(:group_member) { build(:group_member, group: group) } - let(:group_member_invite) { build(:group_member, group: group).tap { |m| m.generate_invite_token! } } + let(:group_member) { create(:group_member, group: group) } + let(:group_member_invite) { create(:group_member, group: group).tap { |m| m.generate_invite_token! } } let(:group_member_request) { group.request_access(requester) } it { expect(remove_member_message(project_member)).to eq "Are you sure you want to remove #{project_member.user.name} from the #{project.full_name} project?" } diff --git a/spec/helpers/nav/new_dropdown_helper_spec.rb b/spec/helpers/nav/new_dropdown_helper_spec.rb index 45664a7e0bd..3a65131aab0 100644 --- a/spec/helpers/nav/new_dropdown_helper_spec.rb +++ b/spec/helpers/nav/new_dropdown_helper_spec.rb @@ -100,7 +100,7 @@ RSpec.describe Nav::NewDropdownHelper do id: 'general_new_group', title: 'New group', href: '/groups/new', - data: { track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown' } + data: { qa_selector: 'global_new_group_link', track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown' } ) ) ) diff --git a/spec/helpers/nav/top_nav_helper_spec.rb b/spec/helpers/nav/top_nav_helper_spec.rb index e4fa503b5ee..9c396d6bf25 100644 --- a/spec/helpers/nav/top_nav_helper_spec.rb +++ b/spec/helpers/nav/top_nav_helper_spec.rb @@ -27,9 +27,11 @@ RSpec.describe Nav::TopNavHelper do let(:subject) { helper.top_nav_view_model(project: current_project, group: current_group) } - let(:active_title) { 'Menu' } + let(:menu_title) { 'Menu' } before do + stub_feature_flags(new_navbar_layout: false) + 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 } @@ -44,12 +46,15 @@ RSpec.describe Nav::TopNavHelper do allow(helper).to receive(:dashboard_nav_link?).with(:activity) { with_activity } end - it 'has :activeTitle' do - expect(subject[:activeTitle]).to eq(active_title) + it 'has :menuTitle' do + expect(subject[:menuTitle]).to eq(menu_title) end context 'when current_user is nil (anonymous)' do it 'has expected :primary' do + expected_header = ::Gitlab::Nav::TopNavMenuHeader.build( + title: 'Explore' + ) expected_primary = [ { href: '/explore', icon: 'project', id: 'project', title: 'Projects' }, { href: '/explore/groups', icon: 'group', id: 'groups', title: 'Groups' }, @@ -58,7 +63,7 @@ RSpec.describe Nav::TopNavHelper do ::Gitlab::Nav::TopNavMenuItem.build(**item) end - expect(subject[:primary]).to eq(expected_primary) + expect(subject[:primary]).to eq([expected_header, *expected_primary]) end it 'has expected :shortcuts' do @@ -103,7 +108,7 @@ RSpec.describe Nav::TopNavHelper do let(:current_user) { user } it 'has no menu items or views by default' do - expect(subject).to eq({ activeTitle: active_title, + expect(subject).to eq({ menuTitle: menu_title, primary: [], secondary: [], shortcuts: [], @@ -115,6 +120,9 @@ RSpec.describe Nav::TopNavHelper do let(:projects_view) { subject[:views][:projects] } it 'has expected :primary' do + expected_header = ::Gitlab::Nav::TopNavMenuHeader.build( + title: 'Switch to' + ) expected_primary = ::Gitlab::Nav::TopNavMenuItem.build( css_class: 'qa-projects-dropdown', data: { @@ -126,7 +134,7 @@ RSpec.describe Nav::TopNavHelper do title: 'Projects', view: 'projects' ) - expect(subject[:primary]).to eq([expected_primary]) + expect(subject[:primary]).to eq([expected_header, expected_primary]) end it 'has expected :shortcuts' do @@ -153,61 +161,87 @@ RSpec.describe Nav::TopNavHelper do ::Gitlab::Nav::TopNavMenuItem.build( data: { qa_selector: 'menu_item_link', - qa_title: 'Your projects', - **menu_data_tracking_attrs('your_projects') + qa_title: 'View all projects', + **menu_data_tracking_attrs('view_all_projects') }, href: '/dashboard/projects', id: 'your', - title: 'Your projects' - ), - ::Gitlab::Nav::TopNavMenuItem.build( - data: { - qa_selector: 'menu_item_link', - qa_title: 'Starred projects', - **menu_data_tracking_attrs('starred_projects') - }, - href: '/dashboard/projects/starred', - id: 'starred', - title: 'Starred projects' - ), - ::Gitlab::Nav::TopNavMenuItem.build( - data: { - qa_selector: 'menu_item_link', - qa_title: 'Explore projects', - **menu_data_tracking_attrs('explore_projects') - }, - href: '/explore', - id: 'explore', - title: 'Explore projects' - ), - ::Gitlab::Nav::TopNavMenuItem.build( - data: { - qa_selector: 'menu_item_link', - qa_title: 'Explore topics', - **menu_data_tracking_attrs('explore_topics') - }, - href: '/explore/projects/topics', - id: 'topics', - title: 'Explore topics' + title: 'View all projects' ) ] expect(projects_view[:linksPrimary]).to eq(expected_links_primary) end - it 'has expected :linksSecondary' do - expected_links_secondary = [ - ::Gitlab::Nav::TopNavMenuItem.build( - data: { - qa_selector: 'menu_item_link', - qa_title: 'Create new project', - **menu_data_tracking_attrs('create_new_project') - }, - href: '/projects/new', - id: 'create', - title: 'Create new project' - ) - ] - expect(projects_view[:linksSecondary]).to eq(expected_links_secondary) + it 'does not have any :linksSecondary' do + expect(projects_view[:linksSecondary]).to eq([]) + end + + context 'when extra submenu options are not hidden' do + before do + stub_feature_flags(remove_extra_primary_submenu_options: false) + end + + it 'has expected :linksPrimary' do + expected_links_primary = [ + ::Gitlab::Nav::TopNavMenuItem.build( + data: { + qa_selector: 'menu_item_link', + qa_title: 'Your projects', + **menu_data_tracking_attrs('your_projects') + }, + href: '/dashboard/projects', + id: 'your', + title: 'Your projects' + ), + ::Gitlab::Nav::TopNavMenuItem.build( + data: { + qa_selector: 'menu_item_link', + qa_title: 'Starred projects', + **menu_data_tracking_attrs('starred_projects') + }, + href: '/dashboard/projects/starred', + id: 'starred', + title: 'Starred projects' + ), + ::Gitlab::Nav::TopNavMenuItem.build( + data: { + qa_selector: 'menu_item_link', + qa_title: 'Explore projects', + **menu_data_tracking_attrs('explore_projects') + }, + href: '/explore', + id: 'explore', + title: 'Explore projects' + ), + ::Gitlab::Nav::TopNavMenuItem.build( + data: { + qa_selector: 'menu_item_link', + qa_title: 'Explore topics', + **menu_data_tracking_attrs('explore_topics') + }, + href: '/explore/projects/topics', + id: 'topics', + title: 'Explore topics' + ) + ] + expect(projects_view[:linksPrimary]).to eq(expected_links_primary) + end + + it 'has expected :linksSecondary' do + expected_links_secondary = [ + ::Gitlab::Nav::TopNavMenuItem.build( + data: { + qa_selector: 'menu_item_link', + qa_title: 'Create new project', + **menu_data_tracking_attrs('create_new_project') + }, + href: '/projects/new', + id: 'create', + title: 'Create new project' + ) + ] + expect(projects_view[:linksSecondary]).to eq(expected_links_secondary) + end end context 'with current nav as project' do @@ -251,6 +285,9 @@ RSpec.describe Nav::TopNavHelper do let(:groups_view) { subject[:views][:groups] } it 'has expected :primary' do + expected_header = ::Gitlab::Nav::TopNavMenuHeader.build( + title: 'Switch to' + ) expected_primary = ::Gitlab::Nav::TopNavMenuItem.build( css_class: 'qa-groups-dropdown', data: { @@ -262,7 +299,7 @@ RSpec.describe Nav::TopNavHelper do title: 'Groups', view: 'groups' ) - expect(subject[:primary]).to eq([expected_primary]) + expect(subject[:primary]).to eq([expected_header, expected_primary]) end it 'has expected :shortcuts' do @@ -289,41 +326,67 @@ RSpec.describe Nav::TopNavHelper do ::Gitlab::Nav::TopNavMenuItem.build( data: { qa_selector: 'menu_item_link', - qa_title: 'Your groups', - **menu_data_tracking_attrs('your_groups') + qa_title: 'View all groups', + **menu_data_tracking_attrs('view_all_groups') }, href: '/dashboard/groups', id: 'your', - title: 'Your groups' - ), - ::Gitlab::Nav::TopNavMenuItem.build( - data: { - qa_selector: 'menu_item_link', - qa_title: 'Explore groups', - **menu_data_tracking_attrs('explore_groups') - }, - href: '/explore/groups', - id: 'explore', - title: 'Explore groups' + title: 'View all groups' ) ] expect(groups_view[:linksPrimary]).to eq(expected_links_primary) end - it 'has expected :linksSecondary' do - expected_links_secondary = [ - ::Gitlab::Nav::TopNavMenuItem.build( - data: { - qa_selector: 'menu_item_link', - qa_title: 'Create group', - **menu_data_tracking_attrs('create_group') - }, - href: '/groups/new', - id: 'create', - title: 'Create group' - ) - ] - expect(groups_view[:linksSecondary]).to eq(expected_links_secondary) + it 'does not have any :linksSecondary' do + expect(groups_view[:linksSecondary]).to eq([]) + end + + context 'when extra submenu options are not hidden' do + before do + stub_feature_flags(remove_extra_primary_submenu_options: false) + end + + it 'has expected :linksPrimary' do + expected_links_primary = [ + ::Gitlab::Nav::TopNavMenuItem.build( + data: { + qa_selector: 'menu_item_link', + qa_title: 'Your groups', + **menu_data_tracking_attrs('your_groups') + }, + href: '/dashboard/groups', + id: 'your', + title: 'Your groups' + ), + ::Gitlab::Nav::TopNavMenuItem.build( + data: { + qa_selector: 'menu_item_link', + qa_title: 'Explore groups', + **menu_data_tracking_attrs('explore_groups') + }, + href: '/explore/groups', + id: 'explore', + title: 'Explore groups' + ) + ] + expect(groups_view[:linksPrimary]).to eq(expected_links_primary) + end + + it 'has expected :linksSecondary' do + expected_links_secondary = [ + ::Gitlab::Nav::TopNavMenuItem.build( + data: { + qa_selector: 'menu_item_link', + qa_title: 'Create group', + **menu_data_tracking_attrs('create_group') + }, + href: '/groups/new', + id: 'create', + title: 'Create group' + ) + ] + expect(groups_view[:linksSecondary]).to eq(expected_links_secondary) + end end context 'with external user' do @@ -374,6 +437,9 @@ RSpec.describe Nav::TopNavHelper do let(:with_milestones) { true } it 'has expected :primary' do + expected_header = ::Gitlab::Nav::TopNavMenuHeader.build( + title: 'Explore' + ) expected_primary = ::Gitlab::Nav::TopNavMenuItem.build( data: { qa_selector: 'milestones_link', @@ -384,7 +450,7 @@ RSpec.describe Nav::TopNavHelper do id: 'milestones', title: 'Milestones' ) - expect(subject[:primary]).to eq([expected_primary]) + expect(subject[:primary]).to eq([expected_header, expected_primary]) end it 'has expected :shortcuts' do @@ -402,6 +468,9 @@ RSpec.describe Nav::TopNavHelper do let(:with_snippets) { true } it 'has expected :primary' do + expected_header = ::Gitlab::Nav::TopNavMenuHeader.build( + title: 'Explore' + ) expected_primary = ::Gitlab::Nav::TopNavMenuItem.build( data: { qa_selector: 'snippets_link', @@ -412,7 +481,7 @@ RSpec.describe Nav::TopNavHelper do id: 'snippets', title: 'Snippets' ) - expect(subject[:primary]).to eq([expected_primary]) + expect(subject[:primary]).to eq([expected_header, expected_primary]) end it 'has expected :shortcuts' do @@ -430,6 +499,9 @@ RSpec.describe Nav::TopNavHelper do let(:with_activity) { true } it 'has expected :primary' do + expected_header = ::Gitlab::Nav::TopNavMenuHeader.build( + title: 'Explore' + ) expected_primary = ::Gitlab::Nav::TopNavMenuItem.build( data: { qa_selector: 'activity_link', @@ -440,7 +512,7 @@ RSpec.describe Nav::TopNavHelper do id: 'activity', title: 'Activity' ) - expect(subject[:primary]).to eq([expected_primary]) + expect(subject[:primary]).to eq([expected_header, expected_primary]) end it 'has expected :shortcuts' do diff --git a/spec/helpers/notify_helper_spec.rb b/spec/helpers/notify_helper_spec.rb index 654fb9bb3f8..09da2b89dff 100644 --- a/spec/helpers/notify_helper_spec.rb +++ b/spec/helpers/notify_helper_spec.rb @@ -51,6 +51,33 @@ RSpec.describe NotifyHelper do end end + describe '#merge_request_hash_param' do + let(:merge_request) { create(:merge_request) } + let(:reviewer) { create(:user) } + let(:avatar_icon_for_user) { 'avatar_icon_for_user' } + + before do + allow(helper).to receive(:avatar_icon_for_user).and_return(avatar_icon_for_user) + end + + it 'returns MR approved description' do + mr_link_style = "font-weight: 600;color:#3777b0;text-decoration:none" + reviewer_avatar_style = "border-radius:12px;margin:-7px 0 -7px 3px;" + mr_link = link_to(merge_request.to_reference, merge_request_url(merge_request), style: mr_link_style).html_safe + reviewer_avatar = content_tag(:img, nil, height: "24", src: avatar_icon_for_user, style: reviewer_avatar_style, \ + width: "24", alt: "Avatar", class: "avatar").html_safe + reviewer_link = link_to(reviewer.name, user_url(reviewer), style: "color:#333333;text-decoration:none;", \ + class: "muted").html_safe + result = helper.merge_request_hash_param(merge_request, reviewer) + expect(result[:mr_highlight]).to eq '<span style="font-weight: 600;color:#333333;">'.html_safe + expect(result[:highlight_end]).to eq '</span>'.html_safe + expect(result[:mr_link]).to eq mr_link + expect(result[:reviewer_highlight]).to eq '<span>'.html_safe + expect(result[:reviewer_avatar]).to eq reviewer_avatar + expect(result[:reviewer_link]).to eq reviewer_link + end + end + def reference_link(entity, url) "<a href=\"#{url}\">#{entity.to_reference}</a>" end diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb index d0d399ad10f..1e16d969744 100644 --- a/spec/helpers/page_layout_helper_spec.rb +++ b/spec/helpers/page_layout_helper_spec.rb @@ -222,6 +222,22 @@ RSpec.describe PageLayoutHelper do end end + describe '#full_content_class' do + before do + allow(helper).to receive(:current_user).and_return(build(:user)) + end + + it 'has a content_class set' do + assign(:content_class, '_content_class_') + + expect(helper.full_content_class).to eq 'container-fluid container-limited _content_class_' + end + + it 'has no content_class set' do + expect(helper.full_content_class).to eq 'container-fluid container-limited ' + end + end + describe '#user_status_properties' do let(:user) { build(:user) } diff --git a/spec/helpers/profiles_helper_spec.rb b/spec/helpers/profiles_helper_spec.rb index 63641e65942..7de8ca89d3d 100644 --- a/spec/helpers/profiles_helper_spec.rb +++ b/spec/helpers/profiles_helper_spec.rb @@ -99,7 +99,7 @@ RSpec.describe ProfilesHelper do describe "#ssh_key_expires_field_description" do subject { helper.ssh_key_expires_field_description } - it { is_expected.to eq('Key becomes invalid on this date.') } + it { is_expected.to eq(s_('Profiles|Optional but recommended. If set, key becomes invalid on the specified date.')) } end describe '#middle_dot_divider_classes' do diff --git a/spec/helpers/projects/google_cloud/cloudsql_helper_spec.rb b/spec/helpers/projects/google_cloud/cloudsql_helper_spec.rb new file mode 100644 index 00000000000..6b82518592f --- /dev/null +++ b/spec/helpers/projects/google_cloud/cloudsql_helper_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::GoogleCloud::CloudsqlHelper do + describe '#TIERS' do + it 'is an array' do + expect(described_class::TIERS).to be_an_instance_of(Array) + end + end + + describe '#VERSIONS' do + it 'returns versions for :postgres' do + expect(described_class::VERSIONS[:postgres]).to be_an_instance_of(Array) + end + + it 'returns versions for :mysql' do + expect(described_class::VERSIONS[:mysql]).to be_an_instance_of(Array) + end + + it 'returns versions for :sqlserver' do + expect(described_class::VERSIONS[:sqlserver]).to be_an_instance_of(Array) + end + end +end diff --git a/spec/helpers/projects/pages_helper_spec.rb b/spec/helpers/projects/pages_helper_spec.rb new file mode 100644 index 00000000000..4a4cebc9d70 --- /dev/null +++ b/spec/helpers/projects/pages_helper_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::PagesHelper do + let(:user) { create(:user) } + let(:project) { create(:project) } + + before do + stub_config(pages: { + access_control: true, + external_http: true, + external_https: true, + host: "new.domain.com" + }) + end + + context 'when the user have permission' do + before do + project.add_maintainer(user) + end + + context 'on custom domain' do + using RSpec::Parameterized::TableSyntax + + where(:external_http, :external_https, :can_create) do + false | false | false + false | true | true + true | false | true + true | true | true + end + + with_them do + it do + stub_config(pages: { external_http: external_http, external_https: external_https }) + + expect(can_create_pages_custom_domains?(user, project)).to be can_create + end + end + end + + context 'on domain limit' do + it 'can create new domains when the limit is 0' do + Gitlab::CurrentSettings.update!(max_pages_custom_domains_per_project: 0) + + expect(can_create_pages_custom_domains?(user, project)).to be true + end + + it 'validates custom domain creation is only allowed upto max value' do + Gitlab::CurrentSettings.update!(max_pages_custom_domains_per_project: 1) + + expect(can_create_pages_custom_domains?(user, project)).to be true + create(:pages_domain, project: project) + expect(can_create_pages_custom_domains?(user, project)).to be false + end + end + end + + context 'when the user does not have permission' do + before do + project.add_guest(user) + end + + it 'validates user cannot create domain' do + expect(can_create_pages_custom_domains?(user, project)).to be false + end + end +end diff --git a/spec/helpers/projects/pipeline_helper_spec.rb b/spec/helpers/projects/pipeline_helper_spec.rb index 8ce4e9f5293..a70544ace1a 100644 --- a/spec/helpers/projects/pipeline_helper_spec.rb +++ b/spec/helpers/projects/pipeline_helper_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Projects::PipelineHelper do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :repository) } let_it_be(:raw_pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } - let_it_be(:pipeline) { Ci::PipelinePresenter.new(raw_pipeline, current_user: user)} + let_it_be(:pipeline) { Ci::PipelinePresenter.new(raw_pipeline, current_user: user) } describe '#js_pipeline_tabs_data' do before do @@ -19,7 +19,6 @@ RSpec.describe Projects::PipelineHelper do it 'returns pipeline tabs data' do expect(pipeline_tabs_data).to include({ - can_generate_codequality_reports: pipeline.can_generate_codequality_reports?.to_json, failed_jobs_count: pipeline.failed_builds.count, failed_jobs_summary: prepare_failed_jobs_summary_data(pipeline.failed_builds), full_path: project.full_path, @@ -31,9 +30,10 @@ RSpec.describe Projects::PipelineHelper do summary_endpoint: summary_project_pipeline_tests_path(project, pipeline, format: :json), suite_endpoint: project_pipeline_test_path(project, pipeline, suite_name: 'suite', format: :json), blob_path: project_blob_path(project, pipeline.sha), - has_test_report: pipeline.has_reports?(Ci::JobArtifact.test_reports), + has_test_report: pipeline.complete_and_has_reports?(Ci::JobArtifact.of_report_type(:test)), empty_state_image_path: match_asset_path('illustrations/empty-state/empty-test-cases-lg.svg'), - artifacts_expired_image_path: match_asset_path('illustrations/pipeline.svg') + artifacts_expired_image_path: match_asset_path('illustrations/pipeline.svg'), + tests_count: pipeline.test_report_summary.total[:count] }) end end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 04c066986b7..a9db2a1c008 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -1147,37 +1147,23 @@ RSpec.describe ProjectsHelper do context 'with the setting enabled' do before do stub_application_setting(delete_inactive_projects: true) + stub_application_setting(inactive_projects_min_size_mb: 0) + stub_application_setting(inactive_projects_send_warning_email_after_months: 1) end - context 'with the feature flag disabled' do - before do - stub_feature_flags(inactive_projects_deletion: false) - end - + context 'with an active project' do it_behaves_like 'does not show the banner' end - context 'with the feature flag enabled' do + context 'with an inactive project' do before do - stub_feature_flags(inactive_projects_deletion: true) - stub_application_setting(inactive_projects_min_size_mb: 0) - stub_application_setting(inactive_projects_send_warning_email_after_months: 1) + project.statistics.storage_size = 1.megabyte + project.last_activity_at = 1.year.ago + project.save! end - context 'with an active project' do - it_behaves_like 'does not show the banner' - end - - context 'with an inactive project' do - before do - project.statistics.storage_size = 1.megabyte - project.last_activity_at = 1.year.ago - project.save! - end - - it 'shows the banner' do - expect(helper.show_inactive_project_deletion_banner?(project)).to be(true) - end + it 'shows the banner' do + expect(helper.show_inactive_project_deletion_banner?(project)).to be(true) end end end @@ -1304,7 +1290,7 @@ RSpec.describe ProjectsHelper do let_it_be(:has_active_license) { true } it 'displays the correct messagee' do - expect(subject).to eq(s_('Clusters|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd} or reach out to GitLab support.')) + expect(subject).to eq(s_('Clusters|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of February 2023. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd} or reach out to GitLab support.')) end end @@ -1312,7 +1298,7 @@ RSpec.describe ProjectsHelper do let_it_be(:has_active_license) { false } it 'displays the correct message' do - expect(subject).to eq(s_('Clusters|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of November 2022. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd}.')) + expect(subject).to eq(s_('Clusters|The certificate-based Kubernetes integration has been deprecated and will be turned off at the end of February 2023. Please %{linkStart}migrate to the GitLab agent for Kubernetes%{linkEnd}.')) end end end diff --git a/spec/helpers/routing/pseudonymization_helper_spec.rb b/spec/helpers/routing/pseudonymization_helper_spec.rb index dd4cc55ed2b..eb2cb548f35 100644 --- a/spec/helpers/routing/pseudonymization_helper_spec.rb +++ b/spec/helpers/routing/pseudonymization_helper_spec.rb @@ -70,7 +70,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do end context 'with controller for groups with subgroups and project' do - let(:masked_url) { "http://localhost/namespace#{subgroup.id}/project#{subproject.id}"} + let(:masked_url) { "http://localhost/namespace#{subgroup.id}/project#{subproject.id}" } let(:group) { subgroup } let(:project) { subproject } let(:request) do @@ -94,7 +94,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do end context 'with controller for groups and subgroups' do - let(:masked_url) { "http://localhost/groups/namespace#{subgroup.id}/-/shared"} + let(:masked_url) { "http://localhost/groups/namespace#{subgroup.id}/-/shared" } let(:group) { subgroup } let(:request) do double(:Request, diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index 513e2865ee3..ad0705e4fbf 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -625,7 +625,7 @@ RSpec.describe SearchHelper do false | false end - let(:params) {{ confidential: confidential }} + let(:params) { { confidential: confidential } } with_them do it 'transforms confidentiality param' do diff --git a/spec/helpers/sorting_helper_spec.rb b/spec/helpers/sorting_helper_spec.rb index 1ee920d1c95..3e555301325 100644 --- a/spec/helpers/sorting_helper_spec.rb +++ b/spec/helpers/sorting_helper_spec.rb @@ -74,11 +74,11 @@ RSpec.describe SortingHelper do def project_common_options { - sort_value_latest_activity => sort_title_latest_activity, + sort_value_latest_activity => sort_title_latest_activity, sort_value_recently_created => sort_title_created_date, - sort_value_name => sort_title_name, - sort_value_name_desc => sort_title_name_desc, - sort_value_stars_desc => sort_title_stars + sort_value_name => sort_title_name, + sort_value_name_desc => sort_title_name_desc, + sort_value_stars_desc => sort_title_stars } end @@ -90,11 +90,11 @@ RSpec.describe SortingHelper do describe '#projects_sort_options_hash' do it 'returns a hash of available sorting options' do admin_options = project_common_options.merge({ - sort_value_oldest_activity => sort_title_oldest_activity, - sort_value_oldest_created => sort_title_oldest_created, + sort_value_oldest_activity => sort_title_oldest_activity, + sort_value_oldest_created => sort_title_oldest_created, sort_value_recently_created => sort_title_recently_created, - sort_value_stars_desc => sort_title_most_stars, - sort_value_largest_repo => sort_title_largest_repo + sort_value_stars_desc => sort_title_most_stars, + sort_value_largest_repo => sort_title_largest_repo }) expect(projects_sort_options_hash).to eq(admin_options) @@ -180,10 +180,10 @@ RSpec.describe SortingHelper do describe '#projects_sort_option_titles' do it 'returns a hash of titles for the sorting options' do options = project_common_options.merge({ - sort_value_oldest_activity => sort_title_latest_activity, - sort_value_oldest_created => sort_title_created_date, - sort_value_name_desc => sort_title_name, - sort_value_stars_asc => sort_title_stars + sort_value_oldest_activity => sort_title_latest_activity, + sort_value_oldest_created => sort_title_created_date, + sort_value_name_desc => sort_title_name, + sort_value_stars_asc => sort_title_stars }) expect(projects_sort_option_titles).to eq(options) @@ -198,10 +198,10 @@ RSpec.describe SortingHelper do describe '#projects_sort_options_hash' do it 'returns a hash of available sorting options' do options = project_common_options.merge({ - sort_value_oldest_activity => sort_title_oldest_activity, - sort_value_oldest_created => sort_title_oldest_created, + sort_value_oldest_activity => sort_title_oldest_activity, + sort_value_oldest_created => sort_title_oldest_created, sort_value_recently_created => sort_title_recently_created, - sort_value_stars_desc => sort_title_most_stars + sort_value_stars_desc => sort_title_most_stars }) expect(projects_sort_options_hash).to eq(options) @@ -210,6 +210,18 @@ RSpec.describe SortingHelper do end end + describe '#tags_sort_options_hash' do + it 'returns a hash of available sorting options' do + expect(tags_sort_options_hash).to include({ + sort_value_name => sort_title_name, + sort_value_oldest_updated => sort_title_oldest_updated, + sort_value_recently_updated => sort_title_recently_updated, + sort_value_version_desc => sort_title_version_desc, + sort_value_version_asc => sort_title_version_asc + }) + end + end + describe 'with `forks` controller' do before do stub_controller_path 'forks' @@ -219,9 +231,9 @@ RSpec.describe SortingHelper do it 'returns a hash of available sorting options' do expect(forks_sort_options_hash).to include({ sort_value_recently_created => sort_title_created_date, - sort_value_oldest_created => sort_title_created_date, - sort_value_latest_activity => sort_title_latest_activity, - sort_value_oldest_activity => sort_title_latest_activity + sort_value_oldest_created => sort_title_created_date, + sort_value_latest_activity => sort_title_latest_activity, + sort_value_oldest_activity => sort_title_latest_activity }) end end diff --git a/spec/helpers/storage_helper_spec.rb b/spec/helpers/storage_helper_spec.rb index 6c3556c874b..6c0f1034d65 100644 --- a/spec/helpers/storage_helper_spec.rb +++ b/spec/helpers/storage_helper_spec.rb @@ -27,15 +27,15 @@ RSpec.describe StorageHelper do create(:project, namespace: namespace, statistics: build(:project_statistics, - namespace: namespace, - repository_size: 10.kilobytes, - wiki_size: 10.bytes, - lfs_objects_size: 20.gigabytes, - build_artifacts_size: 30.megabytes, + namespace: namespace, + repository_size: 10.kilobytes, + wiki_size: 10.bytes, + lfs_objects_size: 20.gigabytes, + build_artifacts_size: 30.megabytes, pipeline_artifacts_size: 11.megabytes, - snippets_size: 40.megabytes, - packages_size: 12.megabytes, - uploads_size: 15.megabytes)) + snippets_size: 40.megabytes, + packages_size: 12.megabytes, + uploads_size: 15.megabytes)) end let(:message) { 'Repository: 10 KB / Wikis: 10 Bytes / Build Artifacts: 30 MB / Pipeline Artifacts: 11 MB / LFS: 20 GB / Snippets: 40 MB / Packages: 12 MB / Uploads: 15 MB' } @@ -50,147 +50,4 @@ RSpec.describe StorageHelper do expect(helper.storage_counters_details(namespace_stats)).to eq(message) end end - - describe "storage_enforcement_banner" do - let_it_be_with_refind(:current_user) { create(:user) } - let_it_be(:free_group) { create(:group) } - let_it_be(:paid_group) { create(:group) } - - before do - allow(helper).to receive(:can?).with(current_user, :maintainer_access, free_group).and_return(true) - allow(helper).to receive(:can?).with(current_user, :maintainer_access, paid_group).and_return(true) - allow(helper).to receive(:current_user) { current_user } - allow(paid_group).to receive(:paid?).and_return(true) - - stub_feature_flags(namespace_storage_limit_bypass_date_check: false) - end - - describe "#storage_enforcement_banner_info" do - it 'returns nil when namespace is not free' do - expect(helper.storage_enforcement_banner_info(paid_group)).to be(nil) - end - - it 'returns nil when storage_enforcement_date is not set' do - allow(free_group).to receive(:storage_enforcement_date).and_return(nil) - - expect(helper.storage_enforcement_banner_info(free_group)).to be(nil) - end - - describe 'when storage_enforcement_date is set' do - let_it_be(:storage_enforcement_date) { Date.today + 30 } - - before do - allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date) - end - - it 'returns nil when current_user do not have access usage quotas page' do - allow(helper).to receive(:can?).with(current_user, :maintainer_access, free_group).and_return(false) - - expect(helper.storage_enforcement_banner_info(free_group)).to be(nil) - end - - it 'returns nil when namespace_storage_limit_show_preenforcement_banner FF is disabled' do - stub_feature_flags(namespace_storage_limit_show_preenforcement_banner: false) - - expect(helper.storage_enforcement_banner_info(free_group)).to be(nil) - end - - context 'when current_user can access the usage quotas page' do - it 'returns a hash' do - used_storage = helper.storage_counter(free_group.root_storage_statistics&.storage_size || 0) - - expect(helper.storage_enforcement_banner_info(free_group)).to eql({ - text_paragraph_1: "Effective #{storage_enforcement_date}, namespace storage limits will apply to the <strong>#{free_group.name}</strong> namespace. View the <a href=\"/help/user/usage_quotas#namespace-storage-limit-enforcement-schedule\" >rollout schedule for this change</a>.", - text_paragraph_2: "The namespace is currently using <strong>#{used_storage}</strong> of namespace storage. Group owners can view namespace storage usage and purchase more from <strong>Group settings > Usage quotas</strong>. <a href=\"/help/user/usage_quotas#manage-your-storage-usage\" >Learn more.</a>", - text_paragraph_3: "See our <a href=\"https://about.gitlab.com/pricing/faq-efficient-free-tier/#storage-limits-on-gitlab-saas-free-tier\" >FAQ</a> for more information.", - variant: 'warning', - namespace_id: free_group.id, - callouts_feature_name: 'storage_enforcement_banner_second_enforcement_threshold', - callouts_path: '/-/users/group_callouts' - }) - end - - context 'when namespace has used storage' do - before do - create(:namespace_root_storage_statistics, namespace: free_group, storage_size: 102400) - end - - it 'returns a hash with the correct storage size text' do - expect(helper.storage_enforcement_banner_info(free_group)[:text_paragraph_2]).to eql("The namespace is currently using <strong>100 KB</strong> of namespace storage. Group owners can view namespace storage usage and purchase more from <strong>Group settings > Usage quotas</strong>. <a href=\"/help/user/usage_quotas#manage-your-storage-usage\" >Learn more.</a>") - end - end - - context 'when the given group is a sub-group' do - let_it_be(:sub_group) { build(:group) } - - before do - allow(helper).to receive(:can?).with(current_user, :maintainer_access, sub_group).and_return(true) - allow(sub_group).to receive(:root_ancestor).and_return(free_group) - end - - it 'returns the banner hash' do - expect(helper.storage_enforcement_banner_info(sub_group).keys).to match_array(%i(text_paragraph_1 text_paragraph_2 text_paragraph_3 variant namespace_id callouts_feature_name callouts_path)) - end - end - end - end - - context 'when the :storage_banner_bypass_date_check is enabled', :freeze_time do - before do - stub_feature_flags(namespace_storage_limit_bypass_date_check: true) - end - - it 'returns the enforcement info' do - puts helper.storage_enforcement_banner_info(free_group)[:text_paragraph_1] - expect(helper.storage_enforcement_banner_info(free_group)[:text_paragraph_1]).to include("Effective #{Date.current}, namespace storage limits will apply") - end - end - - context 'when storage_enforcement_date is set and dismissed callout exists' do - before do - create(:group_callout, - user: current_user, - group_id: free_group.id, - feature_name: 'storage_enforcement_banner_second_enforcement_threshold') - storage_enforcement_date = Date.today + 30 - allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date) - end - - it { expect(helper.storage_enforcement_banner_info(free_group)).to be(nil) } - end - - context 'callouts_feature_name' do - let(:days_from_now) { 45 } - - subject do - storage_enforcement_date = Date.today + days_from_now - allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date) - - helper.storage_enforcement_banner_info(free_group)[:callouts_feature_name] - end - - it 'returns first callouts_feature_name' do - is_expected.to eq('storage_enforcement_banner_first_enforcement_threshold') - end - - context 'returns second callouts_feature_name' do - let(:days_from_now) { 20 } - - it { is_expected.to eq('storage_enforcement_banner_second_enforcement_threshold') } - end - - context 'returns third callouts_feature_name' do - let(:days_from_now) { 13 } - - it { is_expected.to eq('storage_enforcement_banner_third_enforcement_threshold') } - end - - context 'returns fourth callouts_feature_name' do - let(:days_from_now) { 3 } - - it { is_expected.to eq('storage_enforcement_banner_fourth_enforcement_threshold') } - end - end - end - end end diff --git a/spec/helpers/tab_helper_spec.rb b/spec/helpers/tab_helper_spec.rb index dd5707e2aff..80a1224abbb 100644 --- a/spec/helpers/tab_helper_spec.rb +++ b/spec/helpers/tab_helper_spec.rb @@ -182,7 +182,7 @@ RSpec.describe TabHelper do context 'with data attributes' do it 'creates a tab counter badge with the data attributes' do expect(helper.gl_tab_counter_badge(1, { data: { some_attribute: 'foo' } })).to eq( - '<span data-some-attribute="foo" class="gl-badge badge badge-pill badge-muted sm gl-tab-counter-badge">1</span>' + '<span class="gl-badge badge badge-pill badge-muted sm gl-tab-counter-badge" data-some-attribute="foo">1</span>' ) end end diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb index bbabfedc3ee..a8945424877 100644 --- a/spec/helpers/todos_helper_spec.rb +++ b/spec/helpers/todos_helper_spec.rb @@ -258,6 +258,21 @@ RSpec.describe TodosHelper do end end + describe '#no_todos_messages' do + context 'when getting todos messsages' do + it 'return these sentences' do + expected_sentences = [ + s_('Todos|Good job! Looks like you don\'t have anything left on your To-Do List'), + s_('Todos|Isn\'t an empty To-Do List beautiful?'), + s_('Todos|Give yourself a pat on the back!'), + s_('Todos|Nothing left to do. High five!'), + s_('Todos|Henceforth, you shall be known as "To-Do Destroyer"') + ] + expect(helper.no_todos_messages).to eq(expected_sentences) + end + end + end + describe '#todo_author_display?' do using RSpec::Parameterized::TableSyntax diff --git a/spec/helpers/users/callouts_helper_spec.rb b/spec/helpers/users/callouts_helper_spec.rb index 2c148aabead..170ae098a2f 100644 --- a/spec/helpers/users/callouts_helper_spec.rb +++ b/spec/helpers/users/callouts_helper_spec.rb @@ -241,10 +241,10 @@ RSpec.describe Users::CalloutsHelper do context 'the web-hook failure callout has been dismissed', :freeze_time do before do - create(:namespace_callout, + create(:project_callout, feature_name: described_class::WEB_HOOK_DISABLED, user: user, - namespace: project.namespace, + project: project, dismissed_at: 1.week.ago) end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 78a15f52be5..617a796781e 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -136,7 +136,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(blocked_user) - expect(filter_ee_badges(badges)).to match_array([text: "Blocked", variant: "danger"]) + expect(filter_ee_badges(badges)).to match_array([text: s_("AdminUsers|Blocked"), variant: "danger"]) end end @@ -146,7 +146,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(blocked_pending_approval_user) - expect(filter_ee_badges(badges)).to match_array([text: 'Pending approval', variant: 'info']) + expect(filter_ee_badges(badges)).to match_array([text: s_('AdminUsers|Pending approval'), variant: 'info']) end end @@ -156,7 +156,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(banned_user) - expect(filter_ee_badges(badges)).to match_array([text: 'Banned', variant: 'danger']) + expect(filter_ee_badges(badges)).to match_array([text: s_('AdminUsers|Banned'), variant: 'danger']) end end @@ -166,7 +166,17 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(admin_user) - expect(filter_ee_badges(badges)).to match_array([text: "Admin", variant: "success"]) + expect(filter_ee_badges(badges)).to match_array([text: s_("AdminUsers|Admin"), variant: "success"]) + end + end + + context 'with a bot' do + it "returns the bot badge" do + bot = create(:user, :bot) + + badges = helper.user_badges_in_admin_section(bot) + + expect(filter_ee_badges(badges)).to match_array([text: s_('AdminUsers|Bot'), variant: "muted"]) end end @@ -176,7 +186,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(external_user) - expect(filter_ee_badges(badges)).to match_array([text: "External", variant: "secondary"]) + expect(filter_ee_badges(badges)).to match_array([text: s_("AdminUsers|External"), variant: "secondary"]) end end @@ -184,7 +194,7 @@ RSpec.describe UsersHelper do it 'returns the "It\'s You" badge' do badges = helper.user_badges_in_admin_section(user) - expect(filter_ee_badges(badges)).to match_array([text: "It's you!", variant: "muted"]) + expect(filter_ee_badges(badges)).to match_array([text: s_("AdminUsers|It's you!"), variant: "muted"]) end end @@ -195,9 +205,9 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(user) expect(badges).to match_array([ - { text: "Blocked", variant: "danger" }, - { text: "Admin", variant: "success" }, - { text: "External", variant: "secondary" } + { text: s_("AdminUsers|Blocked"), variant: "danger" }, + { text: s_("AdminUsers|Admin"), variant: "success" }, + { text: s_("AdminUsers|External"), variant: "secondary" } ]) end end @@ -208,7 +218,7 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(locked_user) - expect(filter_ee_badges(badges)).to match_array([text: "Locked", variant: "warning"]) + expect(filter_ee_badges(badges)).to match_array([text: s_("AdminUsers|Locked"), variant: "warning"]) end end @@ -435,7 +445,7 @@ RSpec.describe UsersHelper do it 'contains resend confirmation e-mail text' do expect(user_email_help_text).to include _('Resend confirmation e-mail') - expect(user_email_help_text).to include _('Please click the link in the confirmation email before continuing. It was sent to ') + expect(user_email_help_text).to match /Please click the link in the confirmation email before continuing. It was sent to.*#{user.unconfirmed_email}/ end end end diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb index 5adcbe3334d..75128d758f9 100644 --- a/spec/helpers/wiki_helper_spec.rb +++ b/spec/helpers/wiki_helper_spec.rb @@ -132,11 +132,11 @@ RSpec.describe WikiHelper do it 'returns the tracking context' do expect(subject).to eq( - 'wiki-format' => :markdown, - 'wiki-title-size' => 9, - 'wiki-content-size' => 4, + 'wiki-format' => :markdown, + 'wiki-title-size' => 9, + 'wiki-content-size' => 4, 'wiki-directory-nest-level' => 2, - 'wiki-container-type' => 'Project' + 'wiki-container-type' => 'Project' ) end diff --git a/spec/helpers/wiki_page_version_helper_spec.rb b/spec/helpers/wiki_page_version_helper_spec.rb index bc500c28c5a..a792e5df035 100644 --- a/spec/helpers/wiki_page_version_helper_spec.rb +++ b/spec/helpers/wiki_page_version_helper_spec.rb @@ -6,8 +6,8 @@ RSpec.describe WikiPageVersionHelper do let_it_be(:project) { create(:project, :public, :repository) } let_it_be(:user) { create(:user, username: 'foo') } - let(:commit_with_user) { create(:commit, project: project, author: user)} - let(:commit_without_user) { create(:commit, project: project, author_name: 'Foo', author_email: 'foo@example.com')} + let(:commit_with_user) { create(:commit, project: project, author: user) } + let(:commit_without_user) { create(:commit, project: project, author_name: 'Foo', author_email: 'foo@example.com') } let(:wiki_page_version) { Gitlab::Git::WikiPageVersion.new(commit, nil) } describe '#wiki_page_version_author_url' do |