diff options
Diffstat (limited to 'spec/helpers')
30 files changed, 781 insertions, 703 deletions
diff --git a/spec/helpers/admin/user_actions_helper_spec.rb b/spec/helpers/admin/user_actions_helper_spec.rb index 3bc380fbc99..87d2308690c 100644 --- a/spec/helpers/admin/user_actions_helper_spec.rb +++ b/spec/helpers/admin/user_actions_helper_spec.rb @@ -114,23 +114,5 @@ RSpec.describe Admin::UserActionsHelper do it { is_expected.to match_array([]) } end - - context 'when `ban_user_feature_flag` is disabled' do - before do - stub_feature_flags(ban_user_feature_flag: false) - end - - context 'the user is a standard user' do - let_it_be(:user) { create(:user) } - - it { is_expected.not_to include("ban") } - end - - context 'the user is banned' do - let_it_be(:user) { create(:user, :banned) } - - it { is_expected.not_to include("unban") } - end - end end end diff --git a/spec/helpers/appearances_helper_spec.rb b/spec/helpers/appearances_helper_spec.rb index 8673353996e..2b0192d24b3 100644 --- a/spec/helpers/appearances_helper_spec.rb +++ b/spec/helpers/appearances_helper_spec.rb @@ -10,17 +10,90 @@ RSpec.describe AppearancesHelper do allow(helper).to receive(:current_user).and_return(user) end - describe '#appearance_short_name' do + describe 'pwa icon scaled' do + before do + stub_config_setting(relative_url_root: '/relative_root') + end + + shared_examples 'gets icon path' do |width| + let!(:width) { width } + + it 'returns path of icon' do + expect(helper.appearance_pwa_icon_path_scaled(width)).to match(result) + end + end + + context 'with custom icon' do + let!(:appearance) { create(:appearance, :with_pwa_icon) } + let!(:result) { "/relative_root/uploads/-/system/appearance/pwa_icon/#{appearance.id}/dk.png?width=#{width}" } + + it_behaves_like 'gets icon path', 192 + it_behaves_like 'gets icon path', 512 + end + + context 'with default icon' do + let!(:result) { "/relative_root/-/pwa-icons/logo-#{width}.png" } + + it_behaves_like 'gets icon path', 192 + it_behaves_like 'gets icon path', 512 + end + + it 'returns path of maskable logo' do + expect(helper.appearance_maskable_logo).to match('/relative_root/-/pwa-icons/maskable-logo.png') + end + + context 'with wrong input' do + let!(:result) { nil } + + it_behaves_like 'gets icon path', 19200 + end + + context 'when path is append to root' do + it 'appends root and path' do + expect(helper.append_root_path('/works_just_fine')).to match('/relative_root/works_just_fine') + end + end + end + + describe '#appearance_pwa_name' do it 'returns the default value' do create(:appearance) - expect(helper.appearance_short_name).to match('GitLab') + expect(helper.appearance_pwa_name).to match('GitLab') + end + + it 'returns the customized value' do + create(:appearance, pwa_name: 'GitLab as PWA') + + expect(helper.appearance_pwa_name).to match('GitLab as PWA') + end + end + + describe '#appearance_pwa_short_name' do + it 'returns the default value' do + create(:appearance) + + expect(helper.appearance_pwa_short_name).to match('GitLab') end it 'returns the customized value' do create(:appearance, pwa_short_name: 'Short') - expect(helper.appearance_short_name).to match('Short') + expect(helper.appearance_pwa_short_name).to match('Short') + end + end + + describe '#appearance_pwa_description' do + it 'returns the default value' do + create(:appearance) + + expect(helper.appearance_pwa_description).to include('The complete DevOps platform.') + end + + it 'returns the customized value' do + create(:appearance, pwa_description: 'This is a description') + + expect(helper.appearance_pwa_description).to match('This is a description') end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index a8514c373db..bb1a4d57cc0 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -211,7 +211,7 @@ RSpec.describe ApplicationHelper do describe '#support_url' do context 'when alternate support url is specified' do - let(:alternate_url) { 'http://company.example.com/getting-help' } + let(:alternate_url) { 'http://company.example.com/get-help' } it 'returns the alternate support url' do stub_application_setting(help_page_support_url: alternate_url) @@ -222,7 +222,7 @@ RSpec.describe ApplicationHelper do context 'when alternate support url is not specified' do it 'builds the support url from the promo_url' do - expect(helper.support_url).to eq(helper.promo_url + '/getting-help/') + expect(helper.support_url).to eq(helper.promo_url + '/get-help/') end end end @@ -540,6 +540,23 @@ RSpec.describe ApplicationHelper do end end + describe '#profile_social_links' do + context 'when discord is set' do + let_it_be(:user) { build(:user) } + let(:discord) { discord_url(user) } + + it 'returns an empty string if discord is not set' do + expect(discord).to eq('') + end + + it 'returns discord url when discord id is set' do + user.discord = '1234567890123456789' + + expect(discord).to eq('https://discord.com/users/1234567890123456789') + end + end + end + describe '#gitlab_ui_form_for' do let_it_be(:user) { build(:user) } @@ -689,28 +706,4 @@ RSpec.describe ApplicationHelper do expect(helper.stylesheet_link_tag_defer('test')).to eq( '<link rel="stylesheet" media="screen" href="/stylesheets/test.css" />') end end - - describe '#use_new_fonts?' do - subject { helper.use_new_fonts? } - - it { is_expected.to eq true } - - context 'when the feature flag is disabled' do - before do - stub_feature_flags(new_fonts: false) - end - - it { is_expected.to eq false } - - context 'with special request param' do - let(:request) { instance_double(ActionController::TestRequest, params: { new_fonts: true }) } - - before do - allow(helper).to receive(:request).and_return(request) - end - - it { is_expected.to eq true } - end - end - end end diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb index 914c866c464..19cb970553b 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -3,6 +3,14 @@ require 'spec_helper' RSpec.describe ApplicationSettingsHelper do + include Devise::Test::ControllerHelpers + + let_it_be(:current_user) { create(:admin) } + + before do + allow(helper).to receive(:current_user).and_return(current_user) + end + context 'when all protocols in use' do before do stub_application_setting(enabled_git_access_protocol: '') @@ -360,13 +368,10 @@ RSpec.describe ApplicationSettingsHelper do end describe '#instance_clusters_enabled?', :request_store do - let_it_be(:user) { create(:user) } - subject { helper.instance_clusters_enabled? } before do - allow(helper).to receive(:current_user).and_return(user) - allow(helper).to receive(:can?).with(user, :read_cluster, instance_of(Clusters::Instance)).and_return(true) + allow(helper).to receive(:can?).with(current_user, :read_cluster, instance_of(Clusters::Instance)).and_return(true) end it { is_expected.to be_truthy } @@ -379,4 +384,52 @@ RSpec.describe ApplicationSettingsHelper do it { is_expected.to be_falsey } end end + + describe '#restricted_level_checkboxes' do + let_it_be(:application_setting) { create(:application_setting) } + + before do + allow(current_user).to receive(:can_admin_all_resources?).and_return(true) + stub_application_setting( + restricted_visibility_levels: [ + Gitlab::VisibilityLevel::PUBLIC, + Gitlab::VisibilityLevel::INTERNAL, + Gitlab::VisibilityLevel::PRIVATE + ] + ) + end + + it 'returns restricted level checkboxes with correct label, description, and HTML attributes' do + helper.gitlab_ui_form_for(application_setting, url: '/admin/application_settings/general') do |form| + result = helper.restricted_level_checkboxes(form) + + expect(result[0]).to have_checked_field(s_('VisibilityLevel|Private'), with: Gitlab::VisibilityLevel::PRIVATE) + expect(result[0]).to have_selector('[data-testid="lock-icon"]') + expect(result[0]).to have_content( + s_( + 'AdminSettings|If selected, only administrators are able to create private groups, projects, and ' \ + 'snippets.' + ) + ) + + expect(result[1]).to have_checked_field(s_('VisibilityLevel|Internal'), with: Gitlab::VisibilityLevel::INTERNAL) + expect(result[1]).to have_selector('[data-testid="shield-icon"]') + expect(result[1]).to have_content( + s_( + 'AdminSettings|If selected, only administrators are able to create internal groups, projects, and ' \ + 'snippets.' + ) + ) + + expect(result[2]).to have_checked_field(s_('VisibilityLevel|Public'), with: Gitlab::VisibilityLevel::PUBLIC) + expect(result[2]).to have_selector('[data-testid="earth-icon"]') + expect(result[2]).to have_content( + s_( + 'AdminSettings|If selected, only administrators are able to create public groups, projects, ' \ + 'and snippets. Also, profiles are only visible to authenticated users.' + ) + ) + end + end + end end diff --git a/spec/helpers/artifacts_helper_spec.rb b/spec/helpers/artifacts_helper_spec.rb new file mode 100644 index 00000000000..cf48f0ecc39 --- /dev/null +++ b/spec/helpers/artifacts_helper_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe ArtifactsHelper, feature_category: :build_artifacts do + let_it_be(:user) { build_stubbed(:user) } + let_it_be(:project) { build_stubbed(:project) } + + describe '#artifacts_app_data' do + before do + allow(helper).to receive(:current_user) { user } + allow(helper).to receive(:can?).with(user, :destroy_artifacts, project).and_return(false) + end + + subject { helper.artifacts_app_data(project) } + + it 'returns expected data' do + expect(subject).to include({ + project_path: project.full_path, + artifacts_management_feedback_image_path: match_asset_path('illustrations/chat-bubble-sm.svg') + }) + end + + describe 'can_destroy_artifacts' do + it 'returns false without permission' do + expect(subject[:can_destroy_artifacts]).to eq('false') + end + + it 'returns true when user has permission' do + allow(helper).to receive(:can?).with(user, :destroy_artifacts, project).and_return(true) + + expect(subject[:can_destroy_artifacts]).to eq('true') + end + end + end +end diff --git a/spec/helpers/bizible_helper_spec.rb b/spec/helpers/bizible_helper_spec.rb index b82211d51ec..c1b79a8e1e2 100644 --- a/spec/helpers/bizible_helper_spec.rb +++ b/spec/helpers/bizible_helper_spec.rb @@ -4,43 +4,43 @@ require "spec_helper" RSpec.describe BizibleHelper do describe '#bizible_enabled?' do - before do - stub_config(extra: { bizible: SecureRandom.uuid }) - end - - context 'when bizible is disabled' do + context 'when bizible config is not true' do before do - allow(helper).to receive(:bizible_enabled?).and_return(false) + stub_config(extra: { bizible: false }) end - it { is_expected.to be_falsey } + it { expect(helper.bizible_enabled?).to be_falsy } end - context 'when bizible is enabled' do + context 'when bizible config is enabled' do before do - allow(helper).to receive(:bizible_enabled?).and_return(true) + stub_config(extra: { bizible: true }) end - it { is_expected.to be_truthy } - end + it { expect(helper.bizible_enabled?).to be_truthy } - subject(:bizible_enabled?) { helper.bizible_enabled? } + context 'with ecomm_instrumentation feature flag disabled' do + before do + stub_feature_flags(ecomm_instrumentation: false) + end - context 'with ecomm_instrumentation feature flag disabled' do - before do - stub_feature_flags(ecomm_instrumentation: false) + it { expect(helper.bizible_enabled?).to be_falsey } end - it { is_expected.to be_falsey } - end + context 'with ecomm_instrumentation feature flag enabled' do + before do + stub_feature_flags(ecomm_instrumentation: true) + end + + it { expect(helper.bizible_enabled?).to be_truthy } + end - context 'with ecomm_instrumentation feature flag enabled' do - context 'when no id is set' do + context 'with invite_email present' do before do - stub_config(extra: {}) + stub_feature_flags(ecomm_instrumentation: true) end - it { is_expected.to be_falsey } + it { expect(helper.bizible_enabled?('test@test.com')).to be_falsy } end end end diff --git a/spec/helpers/ci/variables_helper_spec.rb b/spec/helpers/ci/variables_helper_spec.rb new file mode 100644 index 00000000000..d032e7f9087 --- /dev/null +++ b/spec/helpers/ci/variables_helper_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::VariablesHelper, feature_category: :pipeline_authoring do + describe '#ci_variable_maskable_raw_regex' do + it 'converts to a javascript regex' do + expect(helper.ci_variable_maskable_raw_regex).to eq("^\\S{8,}$") + end + end +end diff --git a/spec/helpers/emails_helper_spec.rb b/spec/helpers/emails_helper_spec.rb index 1f7400983da..dbc6bd2eb28 100644 --- a/spec/helpers/emails_helper_spec.rb +++ b/spec/helpers/emails_helper_spec.rb @@ -385,7 +385,7 @@ RSpec.describe EmailsHelper do context 'with no html tag' do let(:expected_output) do - 'John was added as a reviewer.<br>' + 'John was added as a reviewer.' end it 'returns the expected output' do @@ -395,7 +395,7 @@ RSpec.describe EmailsHelper do context 'with <strong> tag' do let(:expected_output) do - '<strong>John</strong> was added as a reviewer.<br>' + '<strong>John</strong> was added as a reviewer.' end it 'returns the expected output' do @@ -410,7 +410,7 @@ RSpec.describe EmailsHelper do context 'with no html tag' do let(:expected_output) do - 'Ted was added as a reviewer.<br>John and Mary were removed from reviewers.' + "Ted was added as a reviewer.\nJohn and Mary were removed from reviewers." end it 'returns the expected output' do @@ -460,7 +460,7 @@ RSpec.describe EmailsHelper do let(:fishy_user) { build(:user, name: "<script>alert('hi')</script>") } let(:expected_output) do - '<strong><script>alert('hi')</script></strong> was added as a reviewer.<br>' + '<strong><script>alert('hi')</script></strong> was added as a reviewer.' end it 'escapes the html tag' do @@ -476,7 +476,7 @@ RSpec.describe EmailsHelper do let(:fishy_user) { build(:user, name: "example.com") } let(:expected_output) do - 'example_com was added as a reviewer.<br>' + 'example_com was added as a reviewer.' end it "sanitizes user's name" do diff --git a/spec/helpers/form_helper_spec.rb b/spec/helpers/form_helper_spec.rb index 7c8c59be409..83b08e5fcec 100644 --- a/spec/helpers/form_helper_spec.rb +++ b/spec/helpers/form_helper_spec.rb @@ -6,38 +6,15 @@ RSpec.describe FormHelper do include Devise::Test::ControllerHelpers describe '#dropdown_max_select' do - let(:feature_flag) { :limit_reviewer_and_assignee_size } - - context "with the :limit_reviewer_and_assignee_size feature flag on" do - before do - stub_feature_flags(feature_flag => true) - end - - it 'correctly returns the max amount of reviewers or assignees to allow' do - max = Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS - - expect(helper.dropdown_max_select({}, feature_flag)) - .to eq(max) - expect(helper.dropdown_max_select({ 'max-select'.to_sym => 5 }, feature_flag)) - .to eq(5) - expect(helper.dropdown_max_select({ 'max-select'.to_sym => max + 5 }, feature_flag)) - .to eq(max) - end - end - - context "with the :limit_reviewer_and_assignee_size feature flag off" do - before do - stub_feature_flags(feature_flag => false) - end - - it 'correctly returns the max amount of reviewers or assignees to allow' do - expect(helper.dropdown_max_select({}, feature_flag)) - .to eq(nil) - expect(helper.dropdown_max_select({ 'max-select'.to_sym => 5 }, feature_flag)) - .to eq(5) - expect(helper.dropdown_max_select({ 'max-select'.to_sym => 120 }, feature_flag)) - .to eq(120) - end + it 'correctly returns the max amount of reviewers or assignees to allow' do + max = Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS + + expect(helper.dropdown_max_select({})) + .to eq(max) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => 5 })) + .to eq(5) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => max + 5 })) + .to eq(max) end end @@ -64,43 +41,19 @@ RSpec.describe FormHelper do describe '#reviewers_dropdown_options' do let(:merge_request) { build(:merge_request) } - context "with the :limit_reviewer_and_assignee_size feature flag on" do - context "with multiple reviewers" do - it 'correctly returns the max amount of reviewers or assignees to allow' do - allow(helper).to receive(:merge_request_supports_multiple_reviewers?).and_return(true) - - expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) - .to eq(Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS) - end - end + context "with multiple reviewers" do + it 'correctly returns the max amount of reviewers or assignees to allow' do + allow(helper).to receive(:merge_request_supports_multiple_reviewers?).and_return(true) - context "with only 1 reviewer" do - it 'correctly returns the max amount of reviewers or assignees to allow' do - expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) - .to eq(1) - end + expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) + .to eq(Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS) end end - context "with the :limit_reviewer_and_assignee_size feature flag off" do - before do - stub_feature_flags(limit_reviewer_and_assignee_size: false) - end - - context "with multiple reviewers" do - it 'correctly returns the max amount of reviewers or assignees to allow' do - allow(helper).to receive(:merge_request_supports_multiple_reviewers?).and_return(true) - - expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) - .to eq(nil) - end - end - - context "with only 1 reviewer" do - it 'correctly returns the max amount of reviewers or assignees to allow' do - expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) - .to eq(1) - end + context "with only 1 reviewer" do + it 'correctly returns the max amount of reviewers or assignees to allow' do + expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) + .to eq(1) end end end diff --git a/spec/helpers/hooks_helper_spec.rb b/spec/helpers/hooks_helper_spec.rb index 98a1f77b414..a6cfbfe86ca 100644 --- a/spec/helpers/hooks_helper_spec.rb +++ b/spec/helpers/hooks_helper_spec.rb @@ -32,17 +32,34 @@ RSpec.describe HooksHelper do end end - describe '#link_to_test_hook' do + describe '#webhook_test_items' do + let(:triggers) { [:push_events, :note_events] } + + it 'returns test items for disclosure' do + expect(helper.webhook_test_items(project_hook, triggers)).to eq([ + { + href: test_hook_path(project_hook, triggers[0]), + text: 'Push events' + }, + { + href: test_hook_path(project_hook, triggers[1]), + text: 'Comments' + } + ]) + end + end + + describe '#test_hook_path' do let(:trigger) { 'push_events' } it 'returns project namespaced link' do - expect(helper.link_to_test_hook(project_hook, trigger)) - .to include("href=\"#{test_project_hook_path(project, project_hook, trigger: trigger)}\"") + expect(helper.test_hook_path(project_hook, trigger)) + .to eq(test_project_hook_path(project, project_hook, trigger: trigger)) end it 'returns admin namespaced link' do - expect(helper.link_to_test_hook(system_hook, trigger)) - .to include("href=\"#{test_admin_hook_path(system_hook, trigger: trigger)}\"") + expect(helper.test_hook_path(system_hook, trigger)) + .to eq(test_admin_hook_path(system_hook, trigger: trigger)) end end diff --git a/spec/helpers/ide_helper_spec.rb b/spec/helpers/ide_helper_spec.rb index 29b2784412e..e2ee4f33eee 100644 --- a/spec/helpers/ide_helper_spec.rb +++ b/spec/helpers/ide_helper_spec.rb @@ -15,16 +15,12 @@ RSpec.describe IdeHelper, feature_category: :web_ide do context 'with vscode_web_ide=true and instance vars set' do before do stub_feature_flags(vscode_web_ide: true) - - self.instance_variable_set(:@branch, 'master') - self.instance_variable_set(:@project, project) - self.instance_variable_set(:@path, 'foo/README.md') - self.instance_variable_set(:@merge_request, '7') end it 'returns hash' do - expect(helper.ide_data) - .to eq( + expect(helper.ide_data(project: project, branch: 'master', path: 'foo/README.md', merge_request: '7', +fork_info: nil)) + .to match( 'can-use-new-web-ide' => 'true', 'use-new-web-ide' => 'true', 'user-preferences-path' => profile_preferences_path, @@ -35,6 +31,9 @@ RSpec.describe IdeHelper, feature_category: :web_ide do 'csp-nonce' => 'test-csp-nonce', 'ide-remote-path' => ide_remote_path(remote_host: ':remote_host', remote_path: ':remote_path'), 'file-path' => 'foo/README.md', + 'editor-font-family' => 'JetBrains Mono', + 'editor-font-format' => 'woff2', + 'editor-font-src-url' => a_string_matching(%r{jetbrains-mono/JetBrainsMono}), 'merge-request' => '7', 'fork-info' => nil ) @@ -43,7 +42,8 @@ RSpec.describe IdeHelper, feature_category: :web_ide do it 'does not use new web ide if user.use_legacy_web_ide' do allow(user).to receive(:use_legacy_web_ide).and_return(true) - expect(helper.ide_data).to include('use-new-web-ide' => 'false') + expect(helper.ide_data(project: project, branch: nil, path: nil, merge_request: nil, +fork_info: nil)).to include('use-new-web-ide' => 'false') end end @@ -52,9 +52,9 @@ RSpec.describe IdeHelper, feature_category: :web_ide do stub_feature_flags(vscode_web_ide: false) end - context 'when instance vars are not set' do + context 'when instance vars and parameters are not set' do it 'returns instance data in the hash as nil' do - expect(helper.ide_data) + expect(helper.ide_data(project: nil, branch: nil, path: nil, merge_request: nil, fork_info: nil)) .to include( 'can-use-new-web-ide' => 'false', 'use-new-web-ide' => 'false', @@ -73,15 +73,10 @@ RSpec.describe IdeHelper, feature_category: :web_ide do it 'returns instance data in the hash' do fork_info = { ide_path: '/test/ide/path' } - self.instance_variable_set(:@branch, 'master') - self.instance_variable_set(:@path, 'foo/bar') - self.instance_variable_set(:@merge_request, '1') - self.instance_variable_set(:@fork_info, fork_info) - self.instance_variable_set(:@project, project) - serialized_project = API::Entities::Project.represent(project, current_user: project.creator).to_json - expect(helper.ide_data) + expect(helper.ide_data(project: project, branch: 'master', path: 'foo/bar', merge_request: '1', +fork_info: fork_info)) .to include( 'branch-name' => 'master', 'file-path' => 'foo/bar', @@ -96,12 +91,12 @@ RSpec.describe IdeHelper, feature_category: :web_ide do context 'environments guidance experiment', :experiment do before do stub_experiments(in_product_guidance_environments_webide: :candidate) - self.instance_variable_set(:@project, project) end context 'when project has no enviornments' do it 'enables environment guidance' do - expect(helper.ide_data).to include('enable-environments-guidance' => 'true') + expect(helper.ide_data(project: project, branch: nil, path: nil, merge_request: nil, +fork_info: nil)).to include('enable-environments-guidance' => 'true') end context 'and the callout has been dismissed' do @@ -109,7 +104,8 @@ RSpec.describe IdeHelper, feature_category: :web_ide do callout = create(:callout, feature_name: :web_ide_ci_environments_guidance, user: project.creator) callout.update!(dismissed_at: Time.now - 1.week) allow(helper).to receive(:current_user).and_return(User.find(project.creator.id)) - expect(helper.ide_data).to include('enable-environments-guidance' => 'false') + expect(helper.ide_data(project: project, branch: nil, path: nil, merge_request: nil, +fork_info: nil)).to include('enable-environments-guidance' => 'false') end end end @@ -118,7 +114,8 @@ RSpec.describe IdeHelper, feature_category: :web_ide do it 'disables environment guidance' do create(:environment, project: project) - expect(helper.ide_data).to include('enable-environments-guidance' => 'false') + expect(helper.ide_data(project: project, branch: nil, path: nil, merge_request: nil, +fork_info: nil)).to include('enable-environments-guidance' => 'false') end end end diff --git a/spec/helpers/invite_members_helper_spec.rb b/spec/helpers/invite_members_helper_spec.rb index 48e94ec7e98..abf8b65dc1e 100644 --- a/spec/helpers/invite_members_helper_spec.rb +++ b/spec/helpers/invite_members_helper_spec.rb @@ -36,7 +36,8 @@ RSpec.describe InviteMembersHelper do end it 'provides the correct attributes' do - expect(helper.common_invite_group_modal_data(group, GroupMember, 'false')).to include({ groups_filter: 'descendant_groups', parent_id: group.id }) + expect(helper.common_invite_group_modal_data(group, GroupMember, 'false')) + .to include({ groups_filter: 'descendant_groups', parent_id: group.id }) end end @@ -46,7 +47,8 @@ RSpec.describe InviteMembersHelper do end it 'does not return filter attributes' do - expect(helper.common_invite_group_modal_data(project.group, ProjectMember, 'true').keys).not_to include(:groups_filter, :parent_id) + expect(helper.common_invite_group_modal_data(project.group, ProjectMember, 'true').keys) + .not_to include(:groups_filter, :parent_id) end end end @@ -64,7 +66,7 @@ RSpec.describe InviteMembersHelper do expect(helper.common_invite_modal_dataset(project)).to include(attributes) end - context 'tasks_to_be_done' do + context 'with tasks_to_be_done' do using RSpec::Parameterized::TableSyntax subject(:output) { helper.common_invite_modal_dataset(source) } @@ -79,9 +81,7 @@ RSpec.describe InviteMembersHelper do { value: :issues, text: 'Create/import issues (tickets) to collaborate on ideas and plan work' } ].to_json ) - expect(output[:projects]).to eq( - [{ id: project.id, title: project.title }].to_json - ) + expect(output[:projects]).to eq([{ id: project.id, title: project.title }].to_json) expect(output[:new_project_path]).to eq( source.is_a?(Project) ? '' : new_project_path(namespace_id: group.id) ) @@ -93,8 +93,8 @@ RSpec.describe InviteMembersHelper do end end - context 'inviting members for tasks' do - where(:open_modal_param_present?, :logged_in?, :expected?) do + context 'when inviting members for tasks' do + where(:open_modal_param?, :logged_in?, :expected?) do true | true | true true | false | false false | true | false @@ -104,7 +104,7 @@ RSpec.describe InviteMembersHelper do with_them do before do allow(helper).to receive(:current_user).and_return(developer) if logged_in? - allow(helper).to receive(:params).and_return({ open_modal: 'invite_members_for_task' }) if open_modal_param_present? + allow(helper).to receive(:params).and_return({ open_modal: 'invite_members_for_task' }) if open_modal_param? end context 'when the source is a project' do @@ -120,36 +120,6 @@ RSpec.describe InviteMembersHelper do end end end - - context 'the invite_for_help_continuous_onboarding experiment' do - where(:invite_for_help_continuous_onboarding?, :logged_in?, :expected?) do - true | true | true - true | false | false - false | true | false - false | false | false - end - - with_them do - before do - allow(helper).to receive(:current_user).and_return(developer) if logged_in? - stub_experiments(invite_for_help_continuous_onboarding: :candidate) if invite_for_help_continuous_onboarding? - end - - context 'when the source is a project' do - let_it_be(:source) { project } - - it_behaves_like 'including the tasks to be done attributes' - end - - context 'when the source is a group' do - let_it_be(:source) { group } - - let(:expected?) { false } - - it_behaves_like 'including the tasks to be done attributes' - end - end - end end end @@ -172,11 +142,9 @@ RSpec.describe InviteMembersHelper do end context 'when the user can not manage project members' do - before do + it 'returns false' do expect(helper).to receive(:can?).with(owner, :admin_project_member, project).and_return(false) - end - it 'returns false' do expect(helper.can_invite_members_for_project?(project)).to eq false end end diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index f2e3e401766..1ae834c0769 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe IssuablesHelper do +RSpec.describe IssuablesHelper, feature_category: :team_planning do let(:label) { build_stubbed(:label) } let(:label2) { build_stubbed(:label) } @@ -98,7 +98,7 @@ RSpec.describe IssuablesHelper do end end - describe '#assigned_issuables_count', feature_category: :project_management do + describe '#assigned_issuables_count', feature_category: :team_planning do context 'when issuable is issues' do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project).tap { |p| p.add_developer(user) } } @@ -117,7 +117,7 @@ RSpec.describe IssuablesHelper do end end - describe '#assigned_open_issues_count_text', feature_category: :project_management do + describe '#assigned_open_issues_count_text', feature_category: :team_planning do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project).tap { |p| p.add_developer(user) } } @@ -200,6 +200,41 @@ RSpec.describe IssuablesHelper do expect(content).not_to match('gl-emoji') end end + + describe 'service desk reply to email address' do + let(:email) { 'user@example.com' } + let(:obfuscated_email) { 'us*****@e*****.c**' } + let(:service_desk_issue) { build_stubbed(:issue, project: project, author: User.support_bot, service_desk_reply_to: email) } + + subject { helper.issuable_meta(service_desk_issue, project) } + + context 'with anonymous user' do + before do + allow(helper).to receive(:current_user).and_return(nil) + end + + it { is_expected.to have_content(obfuscated_email) } + end + + context 'with signed in user' do + context 'when user has no role in project' do + before do + allow(helper).to receive(:current_user).and_return(user) + end + + it { is_expected.to have_content(obfuscated_email) } + end + + context 'when user has reporter role in project' do + before do + project.add_reporter(user) + allow(helper).to receive(:current_user).and_return(user) + end + + it { is_expected.to have_content(email) } + end + end + end end describe '#issuables_state_counter_text' do @@ -228,7 +263,7 @@ RSpec.describe IssuablesHelper do allow(helper).to receive(:issuables_count_for_state).and_return(-1) end - it 'returns avigation without badges' do + it 'returns navigation without badges' do expect(helper.issuables_state_counter_text(:issues, :opened, true)) .to eq('<span>Open</span>') expect(helper.issuables_state_counter_text(:issues, :closed, true)) @@ -387,6 +422,32 @@ RSpec.describe IssuablesHelper do expect(helper.issuable_initial_data(issue)).to match(hash_including(expected_data)) end + context 'for incident tab' do + let(:incident) { create(:incident) } + let(:params) do + ActionController::Parameters.new({ + controller: "projects/incidents", + action: "show", + namespace_id: "foo", + project_id: "bar", + id: incident.iid + }).permit! + end + + it 'includes incident attributes' do + @project = incident.project + allow(helper).to receive(:safe_params).and_return(params) + + expected_data = { + issueType: 'incident', + hasLinkedAlerts: false, + canUpdateTimelineEvent: true + } + + expect(helper.issuable_initial_data(incident)).to match(hash_including(expected_data)) + end + end + describe '#sentryIssueIdentifier' do let(:issue) { create(:issue, author: user) } diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 0024d6b7b4e..994a1ff4f75 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -300,7 +300,6 @@ RSpec.describe IssuesHelper do import_csv_issues_path: '#', initial_email: project.new_issuable_address(current_user, 'issue'), initial_sort: current_user&.user_preference&.issues_sort, - is_anonymous_search_disabled: 'true', is_issue_repositioning_disabled: 'true', is_project: 'true', is_public_visibility_restricted: Gitlab::CurrentSettings.restricted_visibility_levels ? 'false' : '', @@ -323,10 +322,6 @@ RSpec.describe IssuesHelper do end describe '#project_issues_list_data' do - before do - stub_feature_flags(disable_anonymous_search: true) - end - context 'when user is signed in' do it_behaves_like 'issues list data' do let(:current_user) { double.as_null_object } @@ -483,20 +478,8 @@ RSpec.describe IssuesHelper do let_it_be(:banned_user) { build(:user, :banned) } let_it_be(:hidden_issue) { build(:issue, author: banned_user) } - context 'when `ban_user_feature_flag` feature flag is enabled' do - it 'returns `true`' do - expect(helper.issue_hidden?(hidden_issue)).to eq(true) - end - end - - context 'when `ban_user_feature_flag` feature flag is disabled' do - before do - stub_feature_flags(ban_user_feature_flag: false) - end - - it 'returns `false`' do - expect(helper.issue_hidden?(hidden_issue)).to eq(false) - end + it 'returns `true`' do + expect(helper.issue_hidden?(hidden_issue)).to eq(true) end end diff --git a/spec/helpers/jira_connect_helper_spec.rb b/spec/helpers/jira_connect_helper_spec.rb index 97e37023c2d..31aeff85c70 100644 --- a/spec/helpers/jira_connect_helper_spec.rb +++ b/spec/helpers/jira_connect_helper_spec.rb @@ -2,13 +2,15 @@ require 'spec_helper' -RSpec.describe JiraConnectHelper do +RSpec.describe JiraConnectHelper, feature_category: :integrations 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) } let(:client_id) { '123' } + let(:enable_public_keys_storage_config) { false } + let(:enable_public_keys_storage_setting) { false } before do stub_application_setting(jira_connect_application_key: client_id) @@ -19,7 +21,10 @@ RSpec.describe JiraConnectHelper do 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' } + allow(Gitlab.config.gitlab).to receive(:url).and_return('http://test.host') + allow(Gitlab.config.jira_connect).to receive(:enable_public_keys_storage) + .and_return(enable_public_keys_storage_config) + stub_application_setting(jira_connect_public_key_storage_enabled: enable_public_keys_storage_setting) end it 'includes Jira Connect app attributes' do @@ -86,19 +91,6 @@ RSpec.describe JiraConnectHelper do 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 @@ -111,6 +103,26 @@ RSpec.describe JiraConnectHelper do it 'assigns gitlab_user_path to nil' do expect(subject[:gitlab_user_path]).to be_nil end + + it 'assignes public_key_storage_enabled to false' do + expect(subject[:public_key_storage_enabled]).to eq(false) + end + + context 'when public_key_storage is enabled via config' do + let(:enable_public_keys_storage_config) { true } + + it 'assignes public_key_storage_enabled to true' do + expect(subject[:public_key_storage_enabled]).to eq(true) + end + end + + context 'when public_key_storage is enabled via setting' do + let(:enable_public_keys_storage_setting) { true } + + it 'assignes public_key_storage_enabled to true' do + expect(subject[:public_key_storage_enabled]).to eq(true) + end + end end context 'user is logged in' do diff --git a/spec/helpers/learn_gitlab_helper_spec.rb b/spec/helpers/learn_gitlab_helper_spec.rb deleted file mode 100644 index 0d4f1965d92..00000000000 --- a/spec/helpers/learn_gitlab_helper_spec.rb +++ /dev/null @@ -1,162 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe LearnGitlabHelper do - include AfterNextHelpers - include Devise::Test::ControllerHelpers - - let_it_be(:user) { create(:user) } - 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(Onboarding::LearnGitlab) do |learn_gitlab| - allow(learn_gitlab).to receive(:project).and_return(project) - end - - Onboarding::Progress.onboard(namespace) - Onboarding::Progress.register(namespace, :git_write) - end - - describe '#learn_gitlab_enabled?' do - using RSpec::Parameterized::TableSyntax - - let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project, namespace: user.namespace) } - - let(:params) { { namespace_id: project.namespace.to_param, project_id: project } } - - subject { helper.learn_gitlab_enabled?(project) } - - where(:onboarding, :learn_gitlab_available, :result) do - true | true | true - true | false | false - false | true | false - end - - with_them do - before do - 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 - before do - sign_in(user) - end - - it { is_expected.to eq(result) } - end - end - - context 'when not signed in' do - it { is_expected.to eq(false) } - end - end - - describe '#learn_gitlab_data' do - subject(:learn_gitlab_data) { helper.learn_gitlab_data(project) } - - let(:onboarding_actions_data) { Gitlab::Json.parse(learn_gitlab_data[:actions]).deep_symbolize_keys } - let(:onboarding_sections_data) { Gitlab::Json.parse(learn_gitlab_data[:sections]).deep_symbolize_keys } - let(:onboarding_project_data) { Gitlab::Json.parse(learn_gitlab_data[:project]).deep_symbolize_keys } - - shared_examples 'has all data' do - it 'has all actions' do - expected_keys = [ - :issue_created, - :git_write, - :pipeline_created, - :merge_request_created, - :user_added, - :trial_started, - :required_mr_approvals_enabled, - :code_owners_enabled, - :security_scan_enabled - ] - - expect(onboarding_actions_data.keys).to contain_exactly(*expected_keys) - end - - 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(&:keys)).to match_array([[:svg]] * 3) - end - - it 'has all project data', :aggregate_failures do - expect(onboarding_project_data.keys).to contain_exactly(:name) - expect(onboarding_project_data.values).to match_array([project.name]) - end - end - - it_behaves_like 'has all data' - - it 'sets correct completion statuses' do - expect(onboarding_actions_data).to match({ - issue_created: a_hash_including(completed: false), - git_write: a_hash_including(completed: true), - pipeline_created: a_hash_including(completed: false), - merge_request_created: a_hash_including(completed: false), - user_added: a_hash_including(completed: false), - trial_started: a_hash_including(completed: false), - required_mr_approvals_enabled: a_hash_including(completed: false), - code_owners_enabled: a_hash_including(completed: false), - security_scan_enabled: a_hash_including(completed: false) - }) - end - - describe 'security_actions_continuous_onboarding experiment' do - let(:base_paths) do - { - trial_started: a_hash_including(url: %r{/learn_gitlab/-/issues/2\z}), - pipeline_created: a_hash_including(url: %r{/learn_gitlab/-/issues/7\z}), - code_owners_enabled: a_hash_including(url: %r{/learn_gitlab/-/issues/10\z}), - required_mr_approvals_enabled: a_hash_including(url: %r{/learn_gitlab/-/issues/11\z}), - issue_created: a_hash_including(url: %r{/learn_gitlab/-/issues\z}), - git_write: a_hash_including(url: %r{/learn_gitlab\z}), - user_added: a_hash_including(url: %r{/learn_gitlab/-/project_members\z}), - merge_request_created: a_hash_including(url: %r{/learn_gitlab/-/merge_requests\z}) - } - end - - context 'when control' do - before do - stub_experiments(security_actions_continuous_onboarding: :control) - end - - it 'sets correct paths' do - expect(onboarding_actions_data).to match( - base_paths.merge( - security_scan_enabled: a_hash_including( - url: %r{/learn_gitlab/-/security/configuration\z} - ) - ) - ) - end - end - - context 'when candidate' do - before do - stub_experiments(security_actions_continuous_onboarding: :candidate) - end - - it 'sets correct paths' do - expect(onboarding_actions_data).to match( - base_paths.merge( - license_scanning_run: a_hash_including( - url: described_class::LICENSE_SCANNING_RUN_URL - ), - secure_dependency_scanning_run: a_hash_including( - url: project_security_configuration_path(project, anchor: 'dependency-scanning') - ), - secure_dast_run: a_hash_including( - url: project_security_configuration_path(project, anchor: 'dast') - ) - ) - ) - end - end - end - end -end diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb index fb23b5c1dc8..6b43e97a0b4 100644 --- a/spec/helpers/merge_requests_helper_spec.rb +++ b/spec/helpers/merge_requests_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe MergeRequestsHelper do +RSpec.describe MergeRequestsHelper, feature_category: :code_review_workflow do include ProjectForksHelper describe '#format_mr_branch_names' do diff --git a/spec/helpers/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb index f7500709d0e..3e6780d6831 100644 --- a/spec/helpers/namespaces_helper_spec.rb +++ b/spec/helpers/namespaces_helper_spec.rb @@ -45,118 +45,6 @@ RSpec.describe NamespacesHelper do user_group.add_owner(user) end - describe '#namespaces_options' do - context 'when admin mode is enabled', :enable_admin_mode do - it 'returns groups without being a member for admin' do - allow(helper).to receive(:current_user).and_return(admin) - - options = helper.namespaces_options(user_group.id, display_path: true, extra_group: user_group.id) - - expect(options).to include(admin_group.name) - expect(options).to include(user_group.name) - end - end - - context 'when admin mode is disabled' do - it 'returns only allowed namespaces for admin' do - allow(helper).to receive(:current_user).and_return(admin) - - options = helper.namespaces_options(user_group.id, display_path: true, extra_group: user_group.id) - - expect(options).to include(admin_group.name) - expect(options).not_to include(user_group.name) - end - end - - it 'returns only allowed namespaces for user' do - allow(helper).to receive(:current_user).and_return(user) - - options = helper.namespaces_options - - expect(options).not_to include(admin_group.name) - expect(options).to include(user_group.name) - expect(options).to include(user.name) - end - - it 'avoids duplicate groups when extra_group is used' do - allow(helper).to receive(:current_user).and_return(admin) - - options = helper.namespaces_options(user_group.id, display_path: true, extra_group: build(:group, name: admin_group.name)) - - expect(options.scan("data-name=\"#{admin_group.name}\"").count).to eq(1) - expect(options).to include(admin_group.name) - end - - context 'when admin mode is disabled' do - it 'selects existing group' do - allow(helper).to receive(:current_user).and_return(admin) - user_group.add_owner(admin) - - options = helper.namespaces_options(:extra_group, display_path: true, extra_group: user_group) - - expect(options).to include("selected=\"selected\" value=\"#{user_group.id}\"") - expect(options).to include(admin_group.name) - end - end - - it 'selects the new group by default' do - # Ensure we don't select a group with the same name - create(:group, name: 'new-group', path: 'another-path') - - allow(helper).to receive(:current_user).and_return(user) - - options = helper.namespaces_options(:extra_group, display_path: true, extra_group: build(:group, name: 'new-group', path: 'new-group')) - - expect(options).to include(user_group.name) - expect(options).not_to include(admin_group.name) - expect(options).to include("selected=\"selected\" value=\"-1\"") - end - - it 'falls back to current user selection' do - allow(helper).to receive(:current_user).and_return(user) - - options = helper.namespaces_options(:extra_group, display_path: true, extra_group: build(:group, name: admin_group.name)) - - expect(options).to include(user_group.name) - expect(options).not_to include(admin_group.name) - expect(options).to include("selected=\"selected\" value=\"#{user.namespace.id}\"") - end - - it 'returns only groups if groups_only option is true' do - allow(helper).to receive(:current_user).and_return(user) - - options = helper.namespaces_options(nil, groups_only: true) - - expect(options).not_to include(user.name) - expect(options).to include(user_group.name) - end - - context 'when nested groups are available' do - it 'includes groups nested in groups the user can administer' do - allow(helper).to receive(:current_user).and_return(user) - child_group = create(:group, :private, parent: user_group) - - options = helper.namespaces_options - - expect(options).to include(child_group.name) - end - - it 'orders the groups correctly' do - allow(helper).to receive(:current_user).and_return(user) - child_group = create(:group, :private, parent: user_group) - other_child = create(:group, :private, parent: user_group) - sub_child = create(:group, :private, parent: child_group) - - expect(helper).to receive(:options_for_group) - .with([user_group, child_group, sub_child, other_child], anything) - .and_call_original - allow(helper).to receive(:options_for_group).and_call_original - - helper.namespaces_options - end - end - end - describe '#cascading_namespace_settings_popover_data' do attribute = :delayed_project_removal diff --git a/spec/helpers/nav/new_dropdown_helper_spec.rb b/spec/helpers/nav/new_dropdown_helper_spec.rb index 3a65131aab0..3a66fe474ab 100644 --- a/spec/helpers/nav/new_dropdown_helper_spec.rb +++ b/spec/helpers/nav/new_dropdown_helper_spec.rb @@ -2,41 +2,29 @@ require 'spec_helper' -RSpec.describe Nav::NewDropdownHelper do +RSpec.describe Nav::NewDropdownHelper, feature_category: :navigation do describe '#new_dropdown_view_model' do - let_it_be(:user) { build_stubbed(:user) } - + let(:user) { build_stubbed(:user) } let(:current_user) { user } let(:current_project) { nil } let(:current_group) { nil } - let(:with_can_create_project) { false } let(:with_can_create_group) { false } let(:with_can_create_snippet) { false } - let(:subject) { helper.new_dropdown_view_model(project: current_project, group: current_group) } - - def expected_menu_section(title:, menu_item:) - [ - { - title: title, - menu_items: [menu_item] - } - ] - end + subject(:view_model) { helper.new_dropdown_view_model(project: current_project, group: current_group) } before do allow(helper).to receive(:current_user) { current_user } - allow(helper).to receive(:can?) { false } - + allow(helper).to receive(:can?).and_return(false) allow(user).to receive(:can_create_project?) { with_can_create_project } allow(user).to receive(:can_create_group?) { with_can_create_group } allow(user).to receive(:can?).with(:create_snippet) { with_can_create_snippet } end - shared_examples 'invite member link shared example' do + shared_examples 'invite member item' do it 'shows invite member link with emoji' do - expect(subject[:menu_sections]).to eq( + expect(view_model[:menu_sections]).to eq( expected_menu_section( title: expected_title, menu_item: ::Gitlab::Nav::TopNavMenuItem.build( @@ -46,7 +34,8 @@ RSpec.describe Nav::NewDropdownHelper do href: expected_href, data: { track_action: 'click_link_invite_members', - track_label: 'plus_menu_dropdown' + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top' } ) ) @@ -55,34 +44,37 @@ RSpec.describe Nav::NewDropdownHelper do end it 'has title' do - expect(subject[:title]).to eq('Create new...') + expect(view_model[:title]).to eq('Create new...') end context 'when current_user is nil (anonymous)' do let(:current_user) { nil } - it 'is nil' do - expect(subject).to be_nil - end + it { is_expected.to be_nil } end context 'when group and project are nil' do it 'has no menu sections' do - expect(subject[:menu_sections]).to eq([]) + expect(view_model[:menu_sections]).to eq([]) end context 'when can create project' do let(:with_can_create_project) { true } it 'has project menu item' do - expect(subject[:menu_sections]).to eq( + expect(view_model[:menu_sections]).to eq( expected_menu_section( - title: _('GitLab'), + title: _('In GitLab'), menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'general_new_project', title: 'New project/repository', href: '/projects/new', - data: { track_action: 'click_link_new_project', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_project_link' } + data: { + track_action: 'click_link_new_project', + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top', + qa_selector: 'global_new_project_link' + } ) ) ) @@ -93,14 +85,19 @@ RSpec.describe Nav::NewDropdownHelper do let(:with_can_create_group) { true } it 'has group menu item' do - expect(subject[:menu_sections]).to eq( + expect(view_model[:menu_sections]).to eq( expected_menu_section( - title: _('GitLab'), + title: _('In GitLab'), menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'general_new_group', title: 'New group', href: '/groups/new', - data: { qa_selector: 'global_new_group_link', track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown' } + data: { + track_action: 'click_link_new_group', + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top', + qa_selector: 'global_new_group_link' + } ) ) ) @@ -111,14 +108,19 @@ RSpec.describe Nav::NewDropdownHelper do let(:with_can_create_snippet) { true } it 'has new snippet menu item' do - expect(subject[:menu_sections]).to eq( + expect(view_model[:menu_sections]).to eq( expected_menu_section( - title: _('GitLab'), + title: _('In GitLab'), menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'general_new_snippet', title: 'New snippet', href: '/-/snippets/new', - data: { track_action: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_snippet_link' } + data: { + track_action: 'click_link_new_snippet_parent', + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top', + qa_selector: 'global_new_snippet_link' + } ) ) ) @@ -127,36 +129,42 @@ RSpec.describe Nav::NewDropdownHelper do end context 'with persisted group' do - let_it_be(:group) { build_stubbed(:group) } - + let(:group) { build_stubbed(:group) } let(:current_group) { group } let(:with_can_create_projects_in_group) { false } let(:with_can_create_subgroup_in_group) { false } let(:with_can_admin_in_group) { false } before do - allow(group).to receive(:persisted?) { true } - allow(helper).to receive(:can?).with(current_user, :create_projects, group) { with_can_create_projects_in_group } - allow(helper).to receive(:can?).with(current_user, :create_subgroup, group) { with_can_create_subgroup_in_group } - allow(helper).to receive(:can?).with(current_user, :admin_group_member, group) { with_can_admin_in_group } + allow(group).to receive(:persisted?).and_return(true) + allow(helper) + .to receive(:can?).with(current_user, :create_projects, group) { with_can_create_projects_in_group } + allow(helper) + .to receive(:can?).with(current_user, :create_subgroup, group) { with_can_create_subgroup_in_group } + allow(helper) + .to receive(:can?).with(current_user, :admin_group_member, group) { with_can_admin_in_group } end it 'has no menu sections' do - expect(subject[:menu_sections]).to eq([]) + expect(view_model[:menu_sections]).to eq([]) end context 'when can create projects in group' do let(:with_can_create_projects_in_group) { true } it 'has new project menu item' do - expect(subject[:menu_sections]).to eq( + expect(view_model[:menu_sections]).to eq( expected_menu_section( - title: 'This group', + title: 'In this group', menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'new_project', title: 'New project/repository', href: "/projects/new?namespace_id=#{group.id}", - data: { track_action: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' } + data: { + track_action: 'click_link_new_project_group', + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top' + } ) ) ) @@ -167,14 +175,18 @@ RSpec.describe Nav::NewDropdownHelper do let(:with_can_create_subgroup_in_group) { true } it 'has new subgroup menu item' do - expect(subject[:menu_sections]).to eq( + expect(view_model[:menu_sections]).to eq( expected_menu_section( - title: 'This group', + title: 'In this group', menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'new_subgroup', title: 'New subgroup', href: "/groups/new?parent_id=#{group.id}#create-group-pane", - data: { track_action: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' } + data: { + track_action: 'click_link_new_subgroup', + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top' + } ) ) ) @@ -184,17 +196,16 @@ RSpec.describe Nav::NewDropdownHelper do context 'when can invite members' do let(:with_can_admin_in_group) { true } let(:with_invite_members_experiment) { true } - let(:expected_title) { 'This group' } + let(:expected_title) { 'In this group' } let(:expected_href) { "/groups/#{group.full_path}/-/group_members" } - it_behaves_like 'invite member link shared example' + it_behaves_like 'invite member item' end end context 'with persisted project' do - let_it_be(:project) { build_stubbed(:project) } - let_it_be(:merge_project) { build_stubbed(:project) } - + let(:project) { build_stubbed(:project) } + let(:merge_project) { build_stubbed(:project) } let(:current_project) { project } let(:with_show_new_issue_link) { false } let(:with_merge_project) { nil } @@ -209,21 +220,26 @@ RSpec.describe Nav::NewDropdownHelper do end it 'has no menu sections' do - expect(subject[:menu_sections]).to eq([]) + expect(view_model[:menu_sections]).to eq([]) end context 'with show_new_issue_link?' do let(:with_show_new_issue_link) { true } it 'shows new issue menu item' do - expect(subject[:menu_sections]).to eq( + expect(view_model[:menu_sections]).to eq( expected_menu_section( - title: 'This project', + title: 'In this project', menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'new_issue', title: 'New issue', href: "/#{project.path_with_namespace}/-/issues/new", - data: { track_action: 'click_link_new_issue', track_label: 'plus_menu_dropdown', qa_selector: 'new_issue_link' } + data: { + track_action: 'click_link_new_issue', + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top', + qa_selector: 'new_issue_link' + } ) ) ) @@ -234,14 +250,18 @@ RSpec.describe Nav::NewDropdownHelper do let(:with_merge_project) { merge_project } it 'shows merge project' do - expect(subject[:menu_sections]).to eq( + expect(view_model[:menu_sections]).to eq( expected_menu_section( - title: 'This project', + title: 'In this project', menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'new_mr', title: 'New merge request', href: "/#{merge_project.path_with_namespace}/-/merge_requests/new", - data: { track_action: 'click_link_new_mr', track_label: 'plus_menu_dropdown' } + data: { + track_action: 'click_link_new_mr', + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top' + } ) ) ) @@ -252,14 +272,18 @@ RSpec.describe Nav::NewDropdownHelper do let(:with_can_create_snippet_in_project) { true } it 'shows new snippet' do - expect(subject[:menu_sections]).to eq( + expect(view_model[:menu_sections]).to eq( expected_menu_section( - title: 'This project', + title: 'In this project', menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'new_snippet', title: 'New snippet', href: "/#{project.path_with_namespace}/-/snippets/new", - data: { track_action: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' } + data: { + track_action: 'click_link_new_snippet_project', + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top' + } ) ) ) @@ -269,11 +293,50 @@ RSpec.describe Nav::NewDropdownHelper do context 'when invite members experiment' do let(:with_invite_members_experiment) { true } let(:with_can_admin_project_member) { true } - let(:expected_title) { 'This project' } + let(:expected_title) { 'In this project' } let(:expected_href) { "/#{project.path_with_namespace}/-/project_members" } - it_behaves_like 'invite member link shared example' + it_behaves_like 'invite member item' + end + end + + context 'with persisted group and project' do + let(:project) { build_stubbed(:project) } + let(:group) { build_stubbed(:group) } + let(:current_project) { project } + let(:current_group) { group } + + before do + allow(helper).to receive(:show_new_issue_link?).with(project).and_return(true) + allow(helper).to receive(:can?).with(current_user, :create_projects, group).and_return(true) + end + + it 'gives precedence to group over project' do + group_section = expected_menu_section( + title: 'In this group', + menu_item: ::Gitlab::Nav::TopNavMenuItem.build( + id: 'new_project', + title: 'New project/repository', + href: "/projects/new?namespace_id=#{group.id}", + data: { + track_action: 'click_link_new_project_group', + track_label: 'plus_menu_dropdown', + track_property: 'navigation_top' + } + ) + ) + + expect(view_model[:menu_sections]).to eq(group_section) end end + + def expected_menu_section(title:, menu_item:) + [ + { + title: title, + menu_items: [menu_item] + } + ] + end end end diff --git a/spec/helpers/nav/top_nav_helper_spec.rb b/spec/helpers/nav/top_nav_helper_spec.rb index c4a8536032e..ce5ac2e5404 100644 --- a/spec/helpers/nav/top_nav_helper_spec.rb +++ b/spec/helpers/nav/top_nav_helper_spec.rb @@ -125,6 +125,7 @@ RSpec.describe Nav::TopNavHelper do data: { track_action: 'click_dropdown', track_label: 'projects_dropdown', + track_property: 'navigation_top', qa_selector: 'projects_dropdown' }, icon: 'project', @@ -222,6 +223,7 @@ RSpec.describe Nav::TopNavHelper do data: { track_action: 'click_dropdown', track_label: 'groups_dropdown', + track_property: 'navigation_top', qa_selector: 'groups_dropdown' }, icon: 'group', @@ -517,7 +519,7 @@ RSpec.describe Nav::TopNavHelper do { track_label: "menu_#{label}", track_action: 'click_dropdown', - track_property: 'navigation' + track_property: 'navigation_top' } end end diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb index 34d7cadf048..eb42ce18da0 100644 --- a/spec/helpers/page_layout_helper_spec.rb +++ b/spec/helpers/page_layout_helper_spec.rb @@ -257,12 +257,17 @@ RSpec.describe PageLayoutHelper do let(:time) { 3.hours.ago } before do - user.status = UserStatus.new(message: 'Some message', emoji: 'basketball', availability: 'busy', clear_status_at: time) + user.status = UserStatus.new( + message: 'Some message', + emoji: 'basketball', + availability: 'busy', + clear_status_at: time + ) end it 'merges the status properties with the defaults' do is_expected.to eq({ - current_clear_status_after: time.to_s, + current_clear_status_after: time.to_s(:iso8601), current_availability: 'busy', current_emoji: 'basketball', current_message: 'Some message', diff --git a/spec/helpers/preferences_helper_spec.rb b/spec/helpers/preferences_helper_spec.rb index 898999e328e..9d1564dfef1 100644 --- a/spec/helpers/preferences_helper_spec.rb +++ b/spec/helpers/preferences_helper_spec.rb @@ -27,6 +27,7 @@ RSpec.describe PreferencesHelper do expect(helper.dashboard_choices).to match_array [ { text: "Your Projects (default)", value: 'projects' }, { text: "Starred Projects", value: 'stars' }, + { text: "Your Activity", value: 'your_activity' }, { text: "Your Projects' Activity", value: 'project_activity' }, { text: "Starred Projects' Activity", value: 'starred_project_activity' }, { text: "Followed Users' Activity", value: 'followed_user_activity' }, diff --git a/spec/helpers/projects/ml/experiments_helper_spec.rb b/spec/helpers/projects/ml/experiments_helper_spec.rb index 2b70201456a..8ef81c49fa7 100644 --- a/spec/helpers/projects/ml/experiments_helper_spec.rb +++ b/spec/helpers/projects/ml/experiments_helper_spec.rb @@ -77,10 +77,10 @@ RSpec.describe Projects::Ml::ExperimentsHelper, feature_category: :mlops do end end - describe '#candidate_as_data' do + describe '#show_candidate_view_model' do let(:candidate) { candidate0 } - subject { Gitlab::Json.parse(helper.candidate_as_data(candidate)) } + subject { Gitlab::Json.parse(helper.show_candidate_view_model(candidate))['candidate'] } it 'generates the correct params' do expect(subject['params']).to include( @@ -109,4 +109,68 @@ RSpec.describe Projects::Ml::ExperimentsHelper, feature_category: :mlops do expect(subject['info']).to include(expected_info) end end + + describe '#experiments_as_data' do + let(:experiments) { [experiment] } + + subject { Gitlab::Json.parse(helper.experiments_as_data(project, experiments)) } + + before do + allow(experiment).to receive(:candidate_count).and_return(2) + end + + it 'generates the correct info' do + expected_info = { + "name" => experiment.name, + "path" => "/#{project.full_path}/-/ml/experiments/#{experiment.iid}", + "candidate_count" => 2 + } + + expect(subject[0]).to eq(expected_info) + end + end + + describe '#page_info' do + def paginator(cursor = nil) + experiment.candidates.keyset_paginate(cursor: cursor, per_page: 1) + end + + let_it_be(:first_page) { paginator } + let_it_be(:second_page) { paginator(first_page.cursor_for_next_page) } + + let(:page) { nil } + + subject { helper.page_info(page) } + + context 'when is first page' do + let(:page) { first_page } + + it 'generates the correct page_info' do + is_expected.to include({ + has_next_page: true, + has_previous_page: false, + start_cursor: nil + }) + end + end + + context 'when is last page' do + let(:page) { second_page } + + it 'generates the correct page_info' do + is_expected.to include({ + has_next_page: false, + has_previous_page: true, + start_cursor: second_page.cursor_for_previous_page, + end_cursor: nil + }) + end + end + end + + describe '#formatted_page_info' do + it 'formats to json' do + expect(helper.formatted_page_info({ a: 1, b: 'c' })).to eq("{\"a\":1,\"b\":\"c\"}") + end + end end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 91dd4c46a74..477b5cd7753 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe ProjectsHelper do +RSpec.describe ProjectsHelper, feature_category: :source_code_management do include ProjectForksHelper include AfterNextHelpers @@ -582,46 +582,24 @@ RSpec.describe ProjectsHelper do end end - describe '#show_merge_request_count' do + describe '#show_count?' do context 'enabled flag' do it 'returns true if compact mode is disabled' do - expect(helper.show_merge_request_count?).to be_truthy + expect(helper.show_count?).to be_truthy end it 'returns false if compact mode is enabled' do - expect(helper.show_merge_request_count?(compact_mode: true)).to be_falsey + expect(helper.show_count?(compact_mode: true)).to be_falsey end end context 'disabled flag' do it 'returns false if disabled flag is true' do - expect(helper.show_merge_request_count?(disabled: true)).to be_falsey + expect(helper.show_count?(disabled: true)).to be_falsey end it 'returns true if disabled flag is false' do - expect(helper.show_merge_request_count?).to be_truthy - end - end - end - - describe '#show_issue_count?' do - context 'enabled flag' do - it 'returns true if compact mode is disabled' do - expect(helper.show_issue_count?).to be_truthy - end - - it 'returns false if compact mode is enabled' do - expect(helper.show_issue_count?(compact_mode: true)).to be_falsey - end - end - - context 'disabled flag' do - it 'returns false if disabled flag is true' do - expect(helper.show_issue_count?(disabled: true)).to be_falsey - end - - it 'returns true if disabled flag is false' do - expect(helper.show_issue_count?).to be_truthy + expect(helper).to be_show_count end end end @@ -1050,6 +1028,28 @@ RSpec.describe ProjectsHelper do end end end + + describe '#able_to_see_forks_count?' do + subject { helper.able_to_see_forks_count?(project, user) } + + where(:can_read_code, :forking_enabled, :expected) do + false | false | false + true | false | false + false | true | false + true | true | true + end + + with_them do + before do + allow(project).to receive(:forking_enabled?).and_return(forking_enabled) + allow(helper).to receive(:can?).with(user, :read_code, project).and_return(can_read_code) + end + + it 'returns the correct response' do + expect(subject).to eq(expected) + end + end + end end describe '#fork_button_disabled_tooltip' do @@ -1352,4 +1352,30 @@ RSpec.describe ProjectsHelper do end end end + + describe '#vue_fork_divergence_data' do + it 'returns empty hash when fork source is not available' do + expect(helper.vue_fork_divergence_data(project, 'ref')).to eq({}) + end + + context 'when fork source is available' do + it 'returns the data related to fork divergence' do + source_project = project_with_repo + + allow(helper).to receive(:visible_fork_source).with(project).and_return(source_project) + + ahead_path = + "/#{project.full_path}/-/compare/#{source_project.default_branch}...ref?from_project_id=#{source_project.id}" + behind_path = + "/#{source_project.full_path}/-/compare/ref...#{source_project.default_branch}?from_project_id=#{project.id}" + + expect(helper.vue_fork_divergence_data(project, 'ref')).to eq({ + source_name: source_project.full_name, + source_path: project_path(source_project), + ahead_compare_path: ahead_path, + behind_compare_path: behind_path + }) + end + end + end end diff --git a/spec/helpers/registrations_helper_spec.rb b/spec/helpers/registrations_helper_spec.rb index b2f9a794cb3..eec87bc8712 100644 --- a/spec/helpers/registrations_helper_spec.rb +++ b/spec/helpers/registrations_helper_spec.rb @@ -8,4 +8,20 @@ RSpec.describe RegistrationsHelper do expect(helper.signup_username_data_attributes.keys).to include(:min_length, :min_length_message, :max_length, :max_length_message, :qa_selector) end end + + describe '#arkose_labs_challenge_enabled?' do + before do + stub_application_setting( + arkose_labs_private_api_key: nil, + arkose_labs_public_api_key: nil, + arkose_labs_namespace: nil + ) + stub_env('ARKOSE_LABS_PRIVATE_KEY', nil) + stub_env('ARKOSE_LABS_PUBLIC_KEY', nil) + end + + it 'is false' do + expect(helper.arkose_labs_challenge_enabled?).to eq false + end + end end diff --git a/spec/helpers/sidebars_helper_spec.rb b/spec/helpers/sidebars_helper_spec.rb index 299e4cb0133..672c2ef7589 100644 --- a/spec/helpers/sidebars_helper_spec.rb +++ b/spec/helpers/sidebars_helper_spec.rb @@ -2,11 +2,11 @@ require 'spec_helper' -RSpec.describe SidebarsHelper do +RSpec.describe SidebarsHelper, feature_category: :navigation do include Devise::Test::ControllerHelpers describe '#sidebar_tracking_attributes_by_object' do - subject { helper.sidebar_tracking_attributes_by_object(object) } + subject(:tracking_attrs) { helper.sidebar_tracking_attributes_by_object(object) } before do stub_application_setting(snowplow_enabled: true) @@ -16,7 +16,13 @@ RSpec.describe SidebarsHelper do let(:object) { build(:project) } it 'returns tracking attrs for project' do - expect(subject[:data]).to eq({ track_label: 'projects_side_navigation', track_property: 'projects_side_navigation', track_action: 'render' }) + attrs = { + track_label: 'projects_side_navigation', + track_property: 'projects_side_navigation', + track_action: 'render' + } + + expect(tracking_attrs[:data]).to eq(attrs) end end @@ -24,7 +30,13 @@ RSpec.describe SidebarsHelper do let(:object) { build(:group) } it 'returns tracking attrs for group' do - expect(subject[:data]).to eq({ track_label: 'groups_side_navigation', track_property: 'groups_side_navigation', track_action: 'render' }) + attrs = { + track_label: 'groups_side_navigation', + track_property: 'groups_side_navigation', + track_action: 'render' + } + + expect(tracking_attrs[:data]).to eq(attrs) end end @@ -32,38 +44,112 @@ RSpec.describe SidebarsHelper do let(:object) { build(:user) } it 'returns tracking attrs for user' do - expect(subject[:data]).to eq({ track_label: 'user_side_navigation', track_property: 'user_side_navigation', track_action: 'render' }) + attrs = { + track_label: 'user_side_navigation', + track_property: 'user_side_navigation', + track_action: 'render' + } + + expect(tracking_attrs[:data]).to eq(attrs) end end context 'when object is something else' do let(:object) { build(:ci_pipeline) } - it 'returns no attributes' do - expect(subject).to eq({}) - end + it { is_expected.to eq({}) } end end describe '#super_sidebar_context' do let(:user) { build(:user) } + let(:group) { build(:group) } - subject { helper.super_sidebar_context(user) } + subject { helper.super_sidebar_context(user, group: group, project: nil) } - it 'returns sidebar values from user', :use_clean_rails_memory_store_caching do + before do + allow(helper).to receive(:current_user) { user } Rails.cache.write(['users', user.id, 'assigned_open_issues_count'], 1) - Rails.cache.write(['users', user.id, 'assigned_open_merge_requests_count'], 2) + Rails.cache.write(['users', user.id, 'assigned_open_merge_requests_count'], 4) + Rails.cache.write(['users', user.id, 'review_requested_open_merge_requests_count'], 0) Rails.cache.write(['users', user.id, 'todos_pending_count'], 3) + Rails.cache.write(['users', user.id, 'total_merge_requests_count'], 4) + end - expect(subject).to eq({ + it 'returns sidebar values from user', :use_clean_rails_memory_store_caching do + expect(subject).to include({ name: user.name, username: user.username, avatar_url: user.avatar_url, assigned_open_issues_count: 1, - assigned_open_merge_requests_count: 2, todos_pending_count: 3, - issues_dashboard_path: issues_dashboard_path(assignee_username: user.username) + issues_dashboard_path: issues_dashboard_path(assignee_username: user.username), + total_merge_requests_count: 4, + support_path: helper.support_url, + display_whats_new: helper.display_whats_new?, + whats_new_most_recent_release_items_count: helper.whats_new_most_recent_release_items_count, + whats_new_version_digest: helper.whats_new_version_digest, + show_version_check: helper.show_version_check?, + gitlab_version: Gitlab.version_info, + gitlab_version_check: helper.gitlab_version_check }) end + + it 'returns "Merge requests" menu', :use_clean_rails_memory_store_caching do + expect(subject[:merge_request_menu]).to eq([ + { + name: _('Merge requests'), + items: [ + { + text: _('Assigned'), + href: merge_requests_dashboard_path(assignee_username: user.username), + count: 4 + }, + { + text: _('Review requests'), + href: merge_requests_dashboard_path(reviewer_username: user.username), + count: 0 + } + ] + } + ]) + end + + it 'returns "Create new" menu groups without headers', :use_clean_rails_memory_store_caching do + expect(subject[:create_new_menu_groups]).to eq([ + { + name: "", + items: [ + { href: "/projects/new", text: "New project/repository" }, + { href: "/groups/new", text: "New group" }, + { href: "/-/snippets/new", text: "New snippet" } + ] + } + ]) + end + + it 'returns "Create new" menu groups with headers', :use_clean_rails_memory_store_caching do + allow(group).to receive(:persisted?).and_return(true) + allow(helper).to receive(:can?).and_return(true) + + expect(subject[:create_new_menu_groups]).to contain_exactly( + a_hash_including( + name: "In this group", + items: array_including( + { href: "/projects/new", text: "New project/repository" }, + { href: "/groups/new#create-group-pane", text: "New subgroup" }, + { href: "/groups/#{group.full_path}/-/group_members", text: "Invite members" } + ) + ), + a_hash_including( + name: "In GitLab", + items: array_including( + { href: "/projects/new", text: "New project/repository" }, + { href: "/groups/new", text: "New group" }, + { href: "/-/snippets/new", text: "New snippet" } + ) + ) + ) + end end end diff --git a/spec/helpers/snippets_helper_spec.rb b/spec/helpers/snippets_helper_spec.rb index 48f67a291c4..43e663464c8 100644 --- a/spec/helpers/snippets_helper_spec.rb +++ b/spec/helpers/snippets_helper_spec.rb @@ -80,10 +80,25 @@ RSpec.describe SnippetsHelper do context 'for Project Snippets' do let(:snippet) { public_project_snippet } + let(:project) { snippet.project } it 'returns copy button of embedded snippets' do expect(subject).to eq(copy_button(blob.id.to_s)) end + + describe 'path helpers' do + specify '#toggle_award_emoji_project_project_snippet_path' do + expect(toggle_award_emoji_project_project_snippet_path(project, snippet, a: 1)).to eq( + "/#{project.full_path}/-/snippets/#{snippet.id}/toggle_award_emoji?a=1" + ) + end + + specify '#toggle_award_emoji_project_project_snippet_url' do + expect(toggle_award_emoji_project_project_snippet_url(project, snippet, a: 1)).to eq( + "http://test.host/#{project.full_path}/-/snippets/#{snippet.id}/toggle_award_emoji?a=1" + ) + end + end end def copy_button(blob_id) diff --git a/spec/helpers/timeboxes_routing_helper_spec.rb b/spec/helpers/timeboxes_routing_helper_spec.rb deleted file mode 100644 index 952194b6704..00000000000 --- a/spec/helpers/timeboxes_routing_helper_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe TimeboxesRoutingHelper do - let(:project) { build_stubbed(:project) } - let(:group) { build_stubbed(:group) } - - describe '#milestone_path' do - context 'for a group milestone' do - let(:milestone) { build_stubbed(:milestone, group: group, iid: 1) } - - it 'links to the group milestone page' do - expect(milestone_path(milestone)) - .to eq(group_milestone_path(group, milestone)) - end - end - - context 'for a project milestone' do - let(:milestone) { build_stubbed(:milestone, project: project, iid: 1) } - - it 'links to the project milestone page' do - expect(milestone_path(milestone)) - .to eq(project_milestone_path(project, milestone)) - end - end - end - - describe '#milestone_url' do - context 'for a group milestone' do - let(:milestone) { build_stubbed(:milestone, group: group, iid: 1) } - - it 'links to the group milestone page' do - expect(milestone_url(milestone)) - .to eq(group_milestone_url(group, milestone)) - end - end - - context 'for a project milestone' do - let(:milestone) { build_stubbed(:milestone, project: project, iid: 1) } - - it 'links to the project milestone page' do - expect(milestone_url(milestone)) - .to eq(project_milestone_url(project, milestone)) - end - end - end -end diff --git a/spec/helpers/users/callouts_helper_spec.rb b/spec/helpers/users/callouts_helper_spec.rb index a43a73edd53..4cb179e4f60 100644 --- a/spec/helpers/users/callouts_helper_spec.rb +++ b/spec/helpers/users/callouts_helper_spec.rb @@ -61,15 +61,6 @@ RSpec.describe Users::CalloutsHelper do end end - describe '.render_flash_user_callout' do - it 'renders the flash_user_callout partial' do - expect(helper).to receive(:render) - .with(/flash_user_callout/, flash_type: :warning, message: 'foo', feature_name: 'bar') - - helper.render_flash_user_callout(:warning, 'foo', 'bar') - end - end - describe '.show_feature_flags_new_version?' do subject { helper.show_feature_flags_new_version? } diff --git a/spec/helpers/web_hooks/web_hooks_helper_spec.rb b/spec/helpers/web_hooks/web_hooks_helper_spec.rb index bcd9d2df1dc..fdd0be8095b 100644 --- a/spec/helpers/web_hooks/web_hooks_helper_spec.rb +++ b/spec/helpers/web_hooks/web_hooks_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe WebHooks::WebHooksHelper do +RSpec.describe WebHooks::WebHooksHelper, :clean_gitlab_redis_shared_state, feature_category: :integrations do let_it_be_with_reload(:project) { create(:project) } let(:current_user) { nil } @@ -43,20 +43,12 @@ RSpec.describe WebHooks::WebHooksHelper do expect(helper).to be_show_project_hook_failed_callout(project: project) end - it 'caches the DB calls until the TTL', :use_clean_rails_memory_store_caching, :request_store do - helper.show_project_hook_failed_callout?(project: project) - - travel_to((described_class::EXPIRY_TTL - 1.second).from_now) do - expect do - helper.show_project_hook_failed_callout?(project: project) - end.not_to exceed_query_limit(0) + it 'stores a value' do + Gitlab::Redis::SharedState.with do |redis| + expect(redis).to receive(:set).with(anything, 'true', ex: 1.hour) end - travel_to((described_class::EXPIRY_TTL + 1.second).from_now) do - expect do - helper.show_project_hook_failed_callout?(project: project) - end.to exceed_query_limit(0) - end + helper.show_project_hook_failed_callout?(project: project) end end |