diff options
Diffstat (limited to 'spec/helpers')
32 files changed, 732 insertions, 445 deletions
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 261d8c8c302..3384f9fea05 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe ApplicationHelper do + include Devise::Test::ControllerHelpers + describe 'current_controller?' do before do stub_controller_name('foo') @@ -419,7 +421,7 @@ RSpec.describe ApplicationHelper do end it 'includes all possible body data elements and associates the project elements with project' do - expect(helper).to receive(:can?).with(nil, :download_code, project) + expect(helper).to receive(:can?).with(nil, :read_code, project) expect(helper.body_data).to eq( { page: 'application', @@ -437,7 +439,7 @@ RSpec.describe ApplicationHelper do let_it_be(:project) { create(:project, :repository, group: create(:group)) } it 'includes all possible body data elements and associates the project elements with project' do - expect(helper).to receive(:can?).with(nil, :download_code, project) + expect(helper).to receive(:can?).with(nil, :read_code, project) expect(helper.body_data).to eq( { page: 'application', @@ -463,7 +465,7 @@ RSpec.describe ApplicationHelper do stub_controller_method(:action_name, 'show') stub_controller_method(:params, { id: issue.id }) - expect(helper).to receive(:can?).with(nil, :download_code, project).and_return(false) + expect(helper).to receive(:can?).with(nil, :read_code, project).and_return(false) expect(helper.body_data).to eq( { page: 'projects:issues:show', @@ -479,12 +481,34 @@ RSpec.describe ApplicationHelper do end end - context 'when current_user has download_code permission' do - it 'returns find_file with the default branch' do + describe 'find_file attribute' do + subject { helper.body_data[:find_file] } + + before do allow(helper).to receive(:current_user).and_return(user) + end + + context 'when the project has no repository' do + before do + allow(project).to receive(:empty_repo?).and_return(true) + end + + it { is_expected.to be_nil } + end - expect(helper).to receive(:can?).with(user, :download_code, project).and_return(true) - expect(helper.body_data[:find_file]).to end_with(project.default_branch) + context 'when user cannot read_code for the project' do + before do + allow(helper).to receive(:can?).with(user, :read_code, project).and_return(false) + end + + it { is_expected.to be_nil } + end + + context 'when current_user has read_code permission' do + it 'returns find_file with the default branch' do + expect(helper).to receive(:can?).with(user, :read_code, project).and_return(true) + expect(subject).to end_with(project.default_branch) + end end end end @@ -651,4 +675,40 @@ RSpec.describe ApplicationHelper do end end end + + describe 'stylesheet_link_tag_defer' do + it 'uses print stylesheet by default' do + expect(helper.stylesheet_link_tag_defer('test')).to eq( '<link rel="stylesheet" media="print" href="/stylesheets/test.css" />') + end + + it 'uses regular stylesheet when no_startup_css param present' do + allow(helper.controller).to receive(:params).and_return({ no_startup_css: '' }) + + 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 eafdbfa8d0a..914c866c464 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -273,15 +273,9 @@ RSpec.describe ApplicationSettingsHelper do end end - describe '.registration_features_can_be_prompted?' do + describe '.registration_features_can_be_prompted?', :without_license do subject { helper.registration_features_can_be_prompted? } - before do - if Gitlab.ee? - allow(License).to receive(:current).and_return(nil) - end - end - context 'when service ping is enabled' do before do stub_application_setting(usage_ping_enabled: true) diff --git a/spec/helpers/avatars_helper_spec.rb b/spec/helpers/avatars_helper_spec.rb index 9c0f8b77d45..cef72d24c43 100644 --- a/spec/helpers/avatars_helper_spec.rb +++ b/spec/helpers/avatars_helper_spec.rb @@ -297,28 +297,22 @@ RSpec.describe AvatarsHelper do subject { helper.user_avatar_without_link(options) } it 'displays user avatar' do - is_expected.to eq tag( - :img, - alt: "#{user.name}'s avatar", - src: avatar_icon_for_user(user, 16), - data: { container: 'body' }, - class: 'avatar s16 has-tooltip', - title: user.name - ) + is_expected.to eq tag.img(alt: "#{user.name}'s avatar", + src: avatar_icon_for_user(user, 16), + data: { container: 'body' }, + class: 'avatar s16 has-tooltip', + title: user.name) end context 'with css_class parameter' do let(:options) { { user: user, css_class: '.cat-pics' } } it 'uses provided css_class' do - is_expected.to eq tag( - :img, - alt: "#{user.name}'s avatar", - src: avatar_icon_for_user(user, 16), - data: { container: 'body' }, - class: "avatar s16 #{options[:css_class]} has-tooltip", - title: user.name - ) + is_expected.to eq tag.img(alt: "#{user.name}'s avatar", + src: avatar_icon_for_user(user, 16), + data: { container: 'body' }, + class: "avatar s16 #{options[:css_class]} has-tooltip", + title: user.name) end end @@ -326,14 +320,11 @@ RSpec.describe AvatarsHelper do let(:options) { { user: user, size: 99 } } it 'uses provided size' do - is_expected.to eq tag( - :img, - alt: "#{user.name}'s avatar", - src: avatar_icon_for_user(user, options[:size]), - data: { container: 'body' }, - class: "avatar s#{options[:size]} has-tooltip", - title: user.name - ) + is_expected.to eq tag.img(alt: "#{user.name}'s avatar", + src: avatar_icon_for_user(user, options[:size]), + data: { container: 'body' }, + class: "avatar s#{options[:size]} has-tooltip", + title: user.name) end end @@ -341,14 +332,11 @@ RSpec.describe AvatarsHelper do let(:options) { { user: user, url: '/over/the/rainbow.png' } } it 'uses provided url' do - is_expected.to eq tag( - :img, - alt: "#{user.name}'s avatar", - src: options[:url], - data: { container: 'body' }, - class: "avatar s16 has-tooltip", - title: user.name - ) + is_expected.to eq tag.img(alt: "#{user.name}'s avatar", + src: options[:url], + data: { container: 'body' }, + class: "avatar s16 has-tooltip", + title: user.name) end end @@ -356,14 +344,11 @@ RSpec.describe AvatarsHelper do let(:options) { { user: user, lazy: true } } it 'adds `lazy` class to class list, sets `data-src` with avatar URL and `src` with placeholder image' do - is_expected.to eq tag( - :img, - alt: "#{user.name}'s avatar", - src: LazyImageTagHelper.placeholder_image, - data: { container: 'body', src: avatar_icon_for_user(user, 16) }, - class: "avatar s16 has-tooltip lazy", - title: user.name - ) + is_expected.to eq tag.img(alt: "#{user.name}'s avatar", + src: LazyImageTagHelper.placeholder_image, + data: { container: 'body', src: avatar_icon_for_user(user, 16) }, + class: "avatar s16 has-tooltip lazy", + title: user.name) end end @@ -372,14 +357,11 @@ RSpec.describe AvatarsHelper do let(:options) { { user: user, has_tooltip: true } } it 'adds has-tooltip' do - is_expected.to eq tag( - :img, - alt: "#{user.name}'s avatar", - src: avatar_icon_for_user(user, 16), - data: { container: 'body' }, - class: "avatar s16 has-tooltip", - title: user.name - ) + is_expected.to eq tag.img(alt: "#{user.name}'s avatar", + src: avatar_icon_for_user(user, 16), + data: { container: 'body' }, + class: "avatar s16 has-tooltip", + title: user.name) end end @@ -387,13 +369,10 @@ RSpec.describe AvatarsHelper do let(:options) { { user: user, has_tooltip: false } } it 'does not add has-tooltip or data container' do - is_expected.to eq tag( - :img, - alt: "#{user.name}'s avatar", - src: avatar_icon_for_user(user, 16), - class: "avatar s16", - title: user.name - ) + is_expected.to eq tag.img(alt: "#{user.name}'s avatar", + src: avatar_icon_for_user(user, 16), + class: "avatar s16", + title: user.name) end end end @@ -405,26 +384,20 @@ RSpec.describe AvatarsHelper do let(:options) { { user: user, user_name: 'Tinky Winky' } } it 'prefers user parameter' do - is_expected.to eq tag( - :img, - alt: "#{user.name}'s avatar", - src: avatar_icon_for_user(user, 16), - data: { container: 'body' }, - class: "avatar s16 has-tooltip", - title: user.name - ) + is_expected.to eq tag.img(alt: "#{user.name}'s avatar", + src: avatar_icon_for_user(user, 16), + data: { container: 'body' }, + class: "avatar s16 has-tooltip", + title: user.name) end end it 'uses user_name and user_email parameter if user is not present' do - is_expected.to eq tag( - :img, - alt: "#{options[:user_name]}'s avatar", - src: helper.avatar_icon_for_email(options[:user_email], 16), - data: { container: 'body' }, - class: "avatar s16 has-tooltip", - title: options[:user_name] - ) + is_expected.to eq tag.img(alt: "#{options[:user_name]}'s avatar", + src: helper.avatar_icon_for_email(options[:user_email], 16), + data: { container: 'body' }, + class: "avatar s16 has-tooltip", + title: options[:user_name]) end end @@ -435,14 +408,11 @@ RSpec.describe AvatarsHelper do let(:options) { { user: user_with_avatar, only_path: false } } it 'will return avatar with a full path' do - is_expected.to eq tag( - :img, - alt: "#{user_with_avatar.name}'s avatar", - src: avatar_icon_for_user(user_with_avatar, 16, only_path: false), - data: { container: 'body' }, - class: "avatar s16 has-tooltip", - title: user_with_avatar.name - ) + is_expected.to eq tag.img(alt: "#{user_with_avatar.name}'s avatar", + src: avatar_icon_for_user(user_with_avatar, 16, only_path: false), + data: { container: 'body' }, + class: "avatar s16 has-tooltip", + title: user_with_avatar.name) end end @@ -450,14 +420,11 @@ RSpec.describe AvatarsHelper do let(:options) { { user_email: user_with_avatar.email, user_name: user_with_avatar.username, only_path: false } } it 'will return avatar with a full path' do - is_expected.to eq tag( - :img, - alt: "#{user_with_avatar.username}'s avatar", - src: helper.avatar_icon_for_email(user_with_avatar.email, 16, only_path: false), - data: { container: 'body' }, - class: "avatar s16 has-tooltip", - title: user_with_avatar.username - ) + is_expected.to eq tag.img(alt: "#{user_with_avatar.username}'s avatar", + src: helper.avatar_icon_for_email(user_with_avatar.email, 16, only_path: false), + data: { container: 'body' }, + class: "avatar s16 has-tooltip", + title: user_with_avatar.username) end end end @@ -480,14 +447,11 @@ RSpec.describe AvatarsHelper do let(:resource) { user.namespace } it 'displays user avatar' do - is_expected.to eq tag( - :img, - alt: "#{user.name}'s avatar", - src: avatar_icon_for_user(user, 32), - data: { container: 'body' }, - class: 'avatar s32 has-tooltip', - title: user.name - ) + is_expected.to eq tag.img(alt: "#{user.name}'s avatar", + src: avatar_icon_for_user(user, 32), + data: { container: 'body' }, + class: 'avatar s32 has-tooltip', + title: user.name) end end diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index fe652e905cc..dac0d3fe182 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -80,6 +80,7 @@ RSpec.describe BlobHelper do end end end + context 'viewer related' do include FakeBlobHelpers diff --git a/spec/helpers/ci/secure_files_helper_spec.rb b/spec/helpers/ci/secure_files_helper_spec.rb index 02da44f56b2..54307e670e1 100644 --- a/spec/helpers/ci/secure_files_helper_spec.rb +++ b/spec/helpers/ci/secure_files_helper_spec.rb @@ -19,58 +19,40 @@ RSpec.describe Ci::SecureFilesHelper do subject { helper.show_secure_files_setting(project, user) } describe '#show_secure_files_setting' do - context 'when the :ci_secure_files feature flag is enabled' do - before do - stub_feature_flags(ci_secure_files: true) - end + context 'authenticated user with admin permissions' do + let(:user) { maintainer } - context 'authenticated user with admin permissions' do - let(:user) { maintainer } - - it { is_expected.to be true } - end - - context 'authenticated user with read permissions' do - let(:user) { developer } - - it { is_expected.to be true } - end + it { is_expected.to be true } + end - context 'authenticated user with guest permissions' do - let(:user) { guest } + context 'authenticated user with read permissions' do + let(:user) { developer } - it { is_expected.to be false } - end + it { is_expected.to be true } + end - context 'authenticated user with no permissions' do - let(:user) { anonymous } + context 'authenticated user with guest permissions' do + let(:user) { guest } - it { is_expected.to be false } - end + it { is_expected.to be false } + end - context 'unconfirmed user' do - let(:user) { unconfirmed } + context 'authenticated user with no permissions' do + let(:user) { anonymous } - it { is_expected.to be false } - end + it { is_expected.to be false } + end - context 'unauthenticated user' do - let(:user) { nil } + context 'unconfirmed user' do + let(:user) { unconfirmed } - it { is_expected.to be false } - end + it { is_expected.to be false } end - context 'when the :ci_secure_files feature flag is disabled' do - before do - stub_feature_flags(ci_secure_files: false) - end - - context 'authenticated user with admin permissions' do - let(:user) { maintainer } + context 'unauthenticated user' do + let(:user) { nil } - it { is_expected.to be false } - end + it { is_expected.to be false } end end end diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb index 78c0d0a2b11..a46f8c13f00 100644 --- a/spec/helpers/diff_helper_spec.rb +++ b/spec/helpers/diff_helper_spec.rb @@ -483,7 +483,18 @@ RSpec.describe DiffHelper do end describe '#conflicts' do - let(:merge_request) { instance_double(MergeRequest, cannot_be_merged?: true) } + let(:merge_request) do + instance_double( + MergeRequest, + cannot_be_merged?: cannot_be_merged?, + source_branch_exists?: source_branch_exists?, + target_branch_exists?: target_branch_exists? + ) + end + + let(:cannot_be_merged?) { true } + let(:source_branch_exists?) { true } + let(:target_branch_exists?) { true } let(:can_be_resolved_in_ui?) { true } let(:allow_tree_conflicts) { false } let(:files) { [instance_double(Gitlab::Conflict::File, path: 'a')] } @@ -508,7 +519,23 @@ RSpec.describe DiffHelper do end context 'when merge request can be merged' do - let(:merge_request) { instance_double(MergeRequest, cannot_be_merged?: false) } + let(:cannot_be_merged?) { false } + + it 'returns nil' do + expect(helper.conflicts).to be_nil + end + end + + context 'when source branch does not exist' do + let(:source_branch_exists?) { false } + + it 'returns nil' do + expect(helper.conflicts).to be_nil + end + end + + context 'when target branch does not exist' do + let(:target_branch_exists?) { false } it 'returns nil' do expect(helper.conflicts).to be_nil diff --git a/spec/helpers/environment_helper_spec.rb b/spec/helpers/environment_helper_spec.rb index 1fcbcd8c4f9..c8d67d6dac2 100644 --- a/spec/helpers/environment_helper_spec.rb +++ b/spec/helpers/environment_helper_spec.rb @@ -50,6 +50,7 @@ RSpec.describe EnvironmentHelper do expect(subject).to eq({ name: environment.name, id: environment.id, + project_full_path: project.full_path, external_url: environment.external_url, can_update_environment: true, can_destroy_environment: true, diff --git a/spec/helpers/git_helper_spec.rb b/spec/helpers/git_helper_spec.rb index 0dd9eecb7f0..543b9ce7a82 100644 --- a/spec/helpers/git_helper_spec.rb +++ b/spec/helpers/git_helper_spec.rb @@ -15,11 +15,13 @@ RSpec.describe GitHelper do it { expect(strip_signature).to eq("Version 1.69.0\n\n") } end + context 'strips PGP MESSAGE' do let(:strip_signature) { helper.strip_signature( pgp_message_tag ) } it { expect(strip_signature).to eq("Version 1.69.0\n\n") } end + context 'strips SIGNED MESSAGE' do let(:strip_signature) { helper.strip_signature( x509_message_tag ) } diff --git a/spec/helpers/groups/observability_helper_spec.rb b/spec/helpers/groups/observability_helper_spec.rb index 4393f4e9bec..6d0a8631f78 100644 --- a/spec/helpers/groups/observability_helper_spec.rb +++ b/spec/helpers/groups/observability_helper_spec.rb @@ -10,17 +10,17 @@ RSpec.describe Groups::ObservabilityHelper do context 'if observability_path is missing from params' do it 'returns the iframe src for action: dashboards' do allow(helper).to receive(:params).and_return({ action: 'dashboards' }) - expect(helper.observability_iframe_src(group)).to eq("#{observability_url}/#{group.id}/") + expect(helper.observability_iframe_src(group)).to eq("#{observability_url}/-/#{group.id}/") end it 'returns the iframe src for action: manage' do allow(helper).to receive(:params).and_return({ action: 'manage' }) - expect(helper.observability_iframe_src(group)).to eq("#{observability_url}/#{group.id}/dashboards") + expect(helper.observability_iframe_src(group)).to eq("#{observability_url}/-/#{group.id}/dashboards") end it 'returns the iframe src for action: explore' do allow(helper).to receive(:params).and_return({ action: 'explore' }) - expect(helper.observability_iframe_src(group)).to eq("#{observability_url}/#{group.id}/explore") + expect(helper.observability_iframe_src(group)).to eq("#{observability_url}/-/#{group.id}/explore") end end @@ -28,7 +28,7 @@ RSpec.describe Groups::ObservabilityHelper do context 'if observability_path is valid' do it 'returns the iframe src by injecting the observability path' do allow(helper).to receive(:params).and_return({ action: '/explore', observability_path: '/foo?bar=foobar' }) - expect(helper.observability_iframe_src(group)).to eq("#{observability_url}/#{group.id}/foo?bar=foobar") + expect(helper.observability_iframe_src(group)).to eq("#{observability_url}/-/#{group.id}/foo?bar=foobar") end end @@ -40,7 +40,7 @@ RSpec.describe Groups::ObservabilityHelper do "/test?groupId=<script>alert('attack!')</script>" }) expect(helper.observability_iframe_src(group)).to eq( - "#{observability_url}/#{group.id}/test?groupId=alert('attack!')" + "#{observability_url}/-/#{group.id}/test?groupId=alert('attack!')" ) end end diff --git a/spec/helpers/groups/settings_helper_spec.rb b/spec/helpers/groups/settings_helper_spec.rb index f8c0bfc19a1..ed948f5456c 100644 --- a/spec/helpers/groups/settings_helper_spec.rb +++ b/spec/helpers/groups/settings_helper_spec.rb @@ -11,8 +11,7 @@ RSpec.describe Groups::SettingsHelper do using RSpec::Parameterized::TableSyntax fake_form_id = "fake_form_id" - - where(:is_paid, :is_button_disabled, :form_value_id) do + where(:prevent_delete_response, :is_button_disabled, :form_value_id) do true | "true" | nil true | "true" | fake_form_id false | "false" | nil @@ -21,7 +20,7 @@ RSpec.describe Groups::SettingsHelper do with_them do it "returns expected parameters" do - allow(group).to receive(:paid?).and_return(is_paid) + allow(group).to receive(:prevent_delete?).and_return(prevent_delete_response) expected = helper.group_settings_confirm_modal_data(group, form_value_id) expect(expected).to eq({ diff --git a/spec/helpers/ide_helper_spec.rb b/spec/helpers/ide_helper_spec.rb index 447967fd345..29b2784412e 100644 --- a/spec/helpers/ide_helper_spec.rb +++ b/spec/helpers/ide_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe IdeHelper do +RSpec.describe IdeHelper, feature_category: :web_ide do describe '#ide_data' do let_it_be(:project) { create(:project) } let_it_be(:user) { project.creator } @@ -18,6 +18,8 @@ RSpec.describe IdeHelper do 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 @@ -30,7 +32,11 @@ RSpec.describe IdeHelper do help_page_path('user/project/web_ide/index.md', anchor: 'vscode-reimplementation'), 'branch-name' => 'master', 'project-path' => project.path_with_namespace, - 'csp-nonce' => 'test-csp-nonce' + 'csp-nonce' => 'test-csp-nonce', + 'ide-remote-path' => ide_remote_path(remote_host: ':remote_host', remote_path: ':remote_path'), + 'file-path' => 'foo/README.md', + 'merge-request' => '7', + 'fork-info' => nil ) end diff --git a/spec/helpers/invite_members_helper_spec.rb b/spec/helpers/invite_members_helper_spec.rb index c753d553371..48e94ec7e98 100644 --- a/spec/helpers/invite_members_helper_spec.rb +++ b/spec/helpers/invite_members_helper_spec.rb @@ -21,7 +21,8 @@ RSpec.describe InviteMembersHelper do invalid_groups: project.related_group_ids, help_link: help_page_url('user/permissions'), is_project: 'true', - access_levels: ProjectMember.access_level_roles.to_json + access_levels: ProjectMember.access_level_roles.to_json, + full_path: project.full_path } expect(helper.common_invite_group_modal_data(project, ProjectMember, 'true')).to include(attributes) @@ -56,7 +57,8 @@ RSpec.describe InviteMembersHelper do id: project.id, root_id: project.root_ancestor.id, name: project.name, - default_access_level: Gitlab::Access::GUEST + default_access_level: Gitlab::Access::GUEST, + full_path: project.full_path } expect(helper.common_invite_modal_dataset(project)).to include(attributes) diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 18a21b59409..15b57a4c9eb 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -98,6 +98,66 @@ RSpec.describe IssuablesHelper do end end + describe '#assigned_issuables_count', feature_category: :project_management 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) } } + + subject { helper.assigned_issuables_count(:issues) } + + before do + allow(helper).to receive(:current_user).and_return(user) + end + + context 'when assigned issues count is over 100' do + let_it_be(:issues) { create_list(:issue, 101, project: project, assignees: [user]) } + + before do + stub_feature_flags(limit_assigned_issues_count: false) + end + + it { is_expected.to eq 101 } + + context 'when FF limit_assigned_issues_count is enabled' do + before do + stub_feature_flags(limit_assigned_issues_count: true) + end + + it { is_expected.to eq 100 } + end + end + end + end + + describe '#assigned_open_issues_count_text', feature_category: :project_management do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project).tap { |p| p.add_developer(user) } } + + subject { helper.assigned_open_issues_count_text } + + before do + allow(helper).to receive(:current_user).and_return(user) + end + + context 'when assigned issues count is over 99' do + let_it_be(:issues) { create_list(:issue, 100, project: project, assignees: [user]) } + + before do + stub_feature_flags(limit_assigned_issues_count: false) + end + + it { is_expected.to eq '100' } + + context 'when FF limit_assigned_issues_count is enabled' do + before do + stub_feature_flags(limit_assigned_issues_count: true) + end + + it { is_expected.to eq '99+' } + end + end + end + describe '#issuable_meta', time_travel_to: '2022-08-05 00:00:00 +0000' do let(:user) { create(:user) } diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index e5bd8e6532f..ed363268cdf 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -3,9 +3,8 @@ require 'spec_helper' RSpec.describe IssuesHelper do - let(:project) { create(:project) } - let(:issue) { create(:issue, project: project) } - let(:ext_project) { create(:project, :with_redmine_integration) } + let_it_be(:project) { create(:project) } + let_it_be_with_reload(:issue) { create(:issue, project: project) } describe '#work_item_type_icon' do it 'returns icon of all standard base types' do @@ -381,6 +380,27 @@ RSpec.describe IssuesHelper do end end + describe '#dashboard_issues_list_data' do + let(:current_user) { double.as_null_object } + + it 'returns expected result' do + allow(helper).to receive(:current_user).and_return(current_user) + allow(helper).to receive(:image_path).and_return('#') + allow(helper).to receive(:url_for).and_return('#') + + expected = { + calendar_path: '#', + empty_state_svg_path: '#', + initial_sort: current_user&.user_preference&.issues_sort, + is_public_visibility_restricted: Gitlab::CurrentSettings.restricted_visibility_levels ? 'false' : '', + is_signed_in: current_user.present?.to_s, + rss_path: '#' + } + + expect(helper.dashboard_issues_list_data(current_user)).to include(expected) + end + end + describe '#issues_form_data' do it 'returns expected result' do expected = { diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb index 85420d4afda..e8e981251e3 100644 --- a/spec/helpers/labels_helper_spec.rb +++ b/spec/helpers/labels_helper_spec.rb @@ -321,4 +321,27 @@ RSpec.describe LabelsHelper do expect(wrap_label_html('xss', label: xss_label, small: false)).not_to include('color:') end end + + describe '#label_subscription_toggle_button_text' do + let(:label) { instance_double(Label) } + let(:current_user) { instance_double(User) } + + subject { label_subscription_toggle_button_text(label) } + + context 'when the label is subscribed' do + before do + allow(label).to receive(:subscribed?).and_return(true) + end + + it { is_expected.to eq(_('Unsubscribe')) } + end + + context 'when the label is not subscribed' do + before do + allow(label).to receive(:subscribed?).and_return(false) + end + + it { is_expected.to eq(_('Subscribe')) } + end + end end diff --git a/spec/helpers/listbox_helper_spec.rb b/spec/helpers/listbox_helper_spec.rb index cba00b43ae5..bae9c40aa02 100644 --- a/spec/helpers/listbox_helper_spec.rb +++ b/spec/helpers/listbox_helper_spec.rb @@ -30,7 +30,7 @@ RSpec.describe ListboxHelper do *%w[ dropdown b-dropdown - gl-new-dropdown + gl-dropdown btn-group js-redirect-listbox ]) diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb index 0b3d400041c..d1c86abf6e9 100644 --- a/spec/helpers/markup_helper_spec.rb +++ b/spec/helpers/markup_helper_spec.rb @@ -445,11 +445,25 @@ RSpec.describe MarkupHelper do shared_examples_for 'common markdown examples' do let(:project_base) { build(:project, :repository) } + it 'displays inline code' do + object = create_object('Text with `inline code`') + expected = 'Text with <code>inline code</code>' + + expect(first_line_in_markdown(object, attribute, 100, is_todo: true, project: project)).to match(expected) + end + + it 'truncates the text with multiple paragraphs' do + object = create_object("Paragraph 1\n\nParagraph 2") + expected = 'Paragraph 1...' + + expect(first_line_in_markdown(object, attribute, 100, is_todo: true, project: project)).to match(expected) + end + it 'displays the first line of a code block' do object = create_object("```\nCode block\nwith two lines\n```") expected = %r{<pre.+><code><span class="line">Code block\.\.\.</span>\n</code></pre>} - expect(first_line_in_markdown(object, attribute, 100, project: project)).to match(expected) + expect(first_line_in_markdown(object, attribute, 100, is_todo: true, project: project)).to match(expected) end it 'truncates a single long line of text' do @@ -457,7 +471,7 @@ RSpec.describe MarkupHelper do object = create_object(text * 4) expected = (text * 2).sub(/.{3}/, '...') - expect(first_line_in_markdown(object, attribute, 150, project: project)).to match(expected) + expect(first_line_in_markdown(object, attribute, 150, is_todo: true, project: project)).to match(expected) end it 'preserves code color scheme' do @@ -466,28 +480,15 @@ RSpec.describe MarkupHelper do "<code><span class=\"line\"><span class=\"k\">def</span> <span class=\"nf\">test</span>...</span>\n" \ "</code></pre>\n" - expect(first_line_in_markdown(object, attribute, 150, project: project)).to eq(expected) + expect(first_line_in_markdown(object, attribute, 150, is_todo: true, project: project)).to eq(expected) end - context 'when images are allowed' do - it 'preserves data-src for lazy images' do - object = create_object("![ImageTest](/uploads/test.png)") - image_url = "data-src=\".*/uploads/test.png\"" - text = first_line_in_markdown(object, attribute, 150, project: project, allow_images: true) + it 'removes any images' do + object = create_object("![ImageTest](/uploads/test.png)") + text = first_line_in_markdown(object, attribute, 150, is_todo: true, project: project) - expect(text).to match(image_url) - expect(text).to match('<a') - end - end - - context 'when images are not allowed' do - it 'removes any images' do - object = create_object("![ImageTest](/uploads/test.png)") - text = first_line_in_markdown(object, attribute, 150, project: project) - - expect(text).not_to match('<img') - expect(text).not_to match('<a') - end + expect(text).not_to match('<img') + expect(text).not_to match('<a') end context 'labels formatting' do @@ -497,7 +498,7 @@ RSpec.describe MarkupHelper do create(:label, title: 'label_1', project: project) object = create_object(label_title, project: project) - first_line_in_markdown(object, attribute, 150, project: project) + first_line_in_markdown(object, attribute, 150, is_todo: true, project: project) end it 'preserves style attribute for a label that can be accessed by current_user' do @@ -518,10 +519,10 @@ RSpec.describe MarkupHelper do end it 'keeps whitelisted tags' do - html = '<a><i></i></a> <strong>strong</strong><em>em</em><b>b</b>' + html = '<i></i> <strong>strong</strong><em>em</em><b>b</b>' object = create_object(html) - result = first_line_in_markdown(object, attribute, 100, project: project) + result = first_line_in_markdown(object, attribute, 100, is_todo: true, project: project) expect(result).to include(html) end @@ -530,7 +531,7 @@ RSpec.describe MarkupHelper do object = create_object("hello \n\n [Test](README.md)") expect do - first_line_in_markdown(object, attribute, nil, project: project) + first_line_in_markdown(object, attribute, 100, is_todo: true, project: project) end.not_to change { Gitlab::GitalyClient.get_request_count } end end diff --git a/spec/helpers/nav/top_nav_helper_spec.rb b/spec/helpers/nav/top_nav_helper_spec.rb index 0d43cfaae90..c4a8536032e 100644 --- a/spec/helpers/nav/top_nav_helper_spec.rb +++ b/spec/helpers/nav/top_nav_helper_spec.rb @@ -122,10 +122,10 @@ RSpec.describe Nav::TopNavHelper do title: 'Switch to' ) expected_primary = ::Gitlab::Nav::TopNavMenuItem.build( - css_class: 'qa-projects-dropdown', data: { track_action: 'click_dropdown', - track_label: 'projects_dropdown' + track_label: 'projects_dropdown', + qa_selector: 'projects_dropdown' }, icon: 'project', id: 'project', @@ -219,10 +219,10 @@ RSpec.describe Nav::TopNavHelper do title: 'Switch to' ) expected_primary = ::Gitlab::Nav::TopNavMenuItem.build( - css_class: 'qa-groups-dropdown', data: { track_action: 'click_dropdown', - track_label: 'groups_dropdown' + track_label: 'groups_dropdown', + qa_selector: 'groups_dropdown' }, icon: 'group', id: 'groups', @@ -323,10 +323,7 @@ RSpec.describe Nav::TopNavHelper do title: 'Explore' ) expected_primary = ::Gitlab::Nav::TopNavMenuItem.build( - data: { - qa_selector: 'milestones_link', - **menu_data_tracking_attrs('milestones') - }, + data: { **menu_data_tracking_attrs('milestones') }, href: '/dashboard/milestones', icon: 'clock', id: 'milestones', @@ -385,10 +382,7 @@ RSpec.describe Nav::TopNavHelper do title: 'Explore' ) expected_primary = ::Gitlab::Nav::TopNavMenuItem.build( - data: { - qa_selector: 'activity_link', - **menu_data_tracking_attrs('activity') - }, + data: { **menu_data_tracking_attrs('activity') }, href: '/dashboard/activity', icon: 'history', id: 'activity', @@ -417,15 +411,13 @@ RSpec.describe Nav::TopNavHelper do it 'has admin as first :secondary item' do expected_admin_item = ::Gitlab::Nav::TopNavMenuItem.build( data: { - qa_selector: 'menu_item_link', - qa_title: 'Admin', + qa_selector: 'admin_area_link', **menu_data_tracking_attrs('admin') }, id: 'admin', title: 'Admin', icon: 'admin', - href: '/admin', - css_class: 'qa-admin-area-link' + href: '/admin' ) expect(subject[:secondary].first).to eq(expected_admin_item) diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb index 1e16d969744..34d7cadf048 100644 --- a/spec/helpers/page_layout_helper_spec.rb +++ b/spec/helpers/page_layout_helper_spec.rb @@ -108,8 +108,8 @@ RSpec.describe PageLayoutHelper do tags = helper.page_card_meta_tags aggregate_failures do - expect(tags).to include %q(<meta property="twitter:label1" content="foo" />) - expect(tags).to include %q(<meta property="twitter:data1" content="bar" />) + expect(tags).to include %q(<meta property="twitter:label1" content="foo">) + expect(tags).to include %q(<meta property="twitter:data1" content="bar">) end end diff --git a/spec/helpers/preferred_language_switcher_helper_spec.rb b/spec/helpers/preferred_language_switcher_helper_spec.rb new file mode 100644 index 00000000000..aab65ecc210 --- /dev/null +++ b/spec/helpers/preferred_language_switcher_helper_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe PreferredLanguageSwitcherHelper do + include StubLanguagesTranslationPercentage + + describe '#ordered_selectable_locales' do + before do + stub_languages_translation_percentage(es: 65, en: 100, zh_CN: described_class::SWITCHER_MINIMUM_TRANSLATION_LEVEL) + end + + it 'returns filtered and ordered by translation level selectable locales' do + expect(helper.ordered_selectable_locales).to eq( + [ + { value: 'en', text: 'English', percentage: 100 }, + { value: 'zh_CN', text: "简体ä¸æ–‡", percentage: described_class::SWITCHER_MINIMUM_TRANSLATION_LEVEL } + ] + ) + end + end +end diff --git a/spec/helpers/programming_languages_helper_spec.rb b/spec/helpers/programming_languages_helper_spec.rb new file mode 100644 index 00000000000..bbea48be64d --- /dev/null +++ b/spec/helpers/programming_languages_helper_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ProgrammingLanguagesHelper do + describe '.search_language_placeholder' do + let(:programming_language) { build(:programming_language, id: 1, name: 'Ruby') } + + before do + allow(helper).to receive(:programming_languages).and_return([programming_language]) + end + + context 'with no `language` param' do + it 'returns a placeholder' do + expect(helper.search_language_placeholder).to eq(_('Language')) + end + end + + context 'with a `language` param' do + before do + allow(helper).to receive(:params).and_return({ language: '2' }) + end + + context 'when invalid' do + it 'returns a placeholder' do + expect(helper.search_language_placeholder).to eq(_('Language')) + end + end + + context 'when valid' do + let(:programming_language) { build(:programming_language, id: 2, name: 'Ruby') } + + it 'returns the chosen language' do + expect(helper.search_language_placeholder).to eq('Ruby') + end + end + end + end + + describe '.programming_languages' do + it 'callings ProgrammingLanguage.most_popular' do + expect(ProgrammingLanguage).to receive(:most_popular) + + helper.programming_languages + end + end + + describe '.language_state_class' do + let(:language) { build(:programming_language, id: language_id) } + + before do + allow(helper).to receive(:params).and_return({ language: '1' }) + end + + context 'when language param matches' do + let(:language_id) { 1 } + + it 'returns `is-active`' do + expect(helper.language_state_class(language)).to be('is-active') + end + end + + context 'when language param does not match' do + let(:language_id) { 2 } + + it 'returns ``' do + expect(helper.language_state_class(language)).to be('') + end + end + end +end diff --git a/spec/helpers/projects/ml/experiments_helper_spec.rb b/spec/helpers/projects/ml/experiments_helper_spec.rb index e4421ff7606..e6959a03c4a 100644 --- a/spec/helpers/projects/ml/experiments_helper_spec.rb +++ b/spec/helpers/projects/ml/experiments_helper_spec.rb @@ -5,28 +5,36 @@ require 'rspec' require 'spec_helper' require 'mime/types' -RSpec.describe Projects::Ml::ExperimentsHelper do - let_it_be(:project) { build(:project, :private) } - let_it_be(:experiment) { build(:ml_experiments, user_id: project.creator, project: project) } - let_it_be(:candidates) do - create_list(:ml_candidates, 2, experiment: experiment, user: project.creator).tap do |c| - c[0].params.create!([{ name: 'param1', value: 'p1' }, { name: 'param2', value: 'p2' }]) - c[0].metrics.create!( +RSpec.describe Projects::Ml::ExperimentsHelper, feature_category: :mlops do + let_it_be(:project) { create(:project, :private) } + let_it_be(:experiment) { create(:ml_experiments, user_id: project.creator, project: project) } + let_it_be(:candidate0) do + create(:ml_candidates, experiment: experiment, user: project.creator).tap do |c| + c.params.build([{ name: 'param1', value: 'p1' }, { name: 'param2', value: 'p2' }]) + c.metrics.create!( [{ name: 'metric1', value: 0.1 }, { name: 'metric2', value: 0.2 }, { name: 'metric3', value: 0.3 }] ) + end + end - c[1].params.create!([{ name: 'param2', value: 'p3' }, { name: 'param3', value: 'p4' }]) - c[1].metrics.create!(name: 'metric3', value: 0.4) + let_it_be(:candidate1) do + create(:ml_candidates, experiment: experiment, user: project.creator).tap do |c| + c.params.build([{ name: 'param2', value: 'p3' }, { name: 'param3', value: 'p4' }]) + c.metrics.create!(name: 'metric3', value: 0.4) end end + let_it_be(:candidates) { [candidate0, candidate1] } + describe '#candidates_table_items' do subject { helper.candidates_table_items(candidates) } it 'creates the correct model for the table' do expected_value = [ - { 'param1' => 'p1', 'param2' => 'p2', 'metric1' => '0.1000', 'metric2' => '0.2000', 'metric3' => '0.3000' }, - { 'param2' => 'p3', 'param3' => 'p4', 'metric3' => '0.4000' } + { 'param1' => 'p1', 'param2' => 'p2', 'metric1' => '0.1000', 'metric2' => '0.2000', 'metric3' => '0.3000', + 'artifact' => nil, 'details' => "/#{project.full_path}/-/ml/candidates/#{candidate0.iid}" }, + { 'param2' => 'p3', 'param3' => 'p4', 'metric3' => '0.4000', + 'artifact' => nil, 'details' => "/#{project.full_path}/-/ml/candidates/#{candidate1.iid}" } ] expect(Gitlab::Json.parse(subject)).to match_array(expected_value) @@ -46,4 +54,40 @@ RSpec.describe Projects::Ml::ExperimentsHelper do it { is_expected.to match_array(%w[metric1 metric2 metric3]) } end end + + describe '#candidate_as_data' do + let(:candidate) { candidate0 } + let(:package) do + create(:generic_package, name: candidate.package_name, version: candidate.package_version, project: project) + end + + subject { Gitlab::Json.parse(helper.candidate_as_data(candidate)) } + + it 'generates the correct params' do + expect(subject['params']).to include( + hash_including('name' => 'param1', 'value' => 'p1'), + hash_including('name' => 'param2', 'value' => 'p2') + ) + end + + it 'generates the correct metrics' do + expect(subject['metrics']).to include( + hash_including('name' => 'metric1', 'value' => 0.1), + hash_including('name' => 'metric2', 'value' => 0.2), + hash_including('name' => 'metric3', 'value' => 0.3) + ) + end + + it 'generates the correct info' do + expected_info = { + 'iid' => candidate.iid, + 'path_to_artifact' => "/#{project.full_path}/-/packages/#{package.id}", + 'experiment_name' => candidate.experiment.name, + 'path_to_experiment' => "/#{project.full_path}/-/ml/experiments/#{experiment.iid}", + 'status' => 'running' + } + + expect(subject['info']).to include(expected_info) + end + end end diff --git a/spec/helpers/projects/pipeline_helper_spec.rb b/spec/helpers/projects/pipeline_helper_spec.rb index 0d3466d6ed2..35045aaef2a 100644 --- a/spec/helpers/projects/pipeline_helper_spec.rb +++ b/spec/helpers/projects/pipeline_helper_spec.rb @@ -25,6 +25,7 @@ RSpec.describe Projects::PipelineHelper do graphql_resource_etag: graphql_etag_pipeline_path(pipeline), metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: project.namespace, project_id: project, format: :json), pipeline_iid: pipeline.iid, + pipeline_path: pipeline_path(pipeline), pipeline_project_path: project.full_path, total_job_count: pipeline.total_size, summary_endpoint: summary_project_pipeline_tests_path(project, pipeline, format: :json), diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 39b8b552672..db50c74ec4e 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -404,10 +404,6 @@ RSpec.describe ProjectsHelper do Project.all end - before do - stub_feature_flags(project_list_filter_bar: false) - end - it 'returns true when there are projects' do expect(helper.show_projects?(projects, {})).to eq(true) end @@ -963,7 +959,6 @@ RSpec.describe ProjectsHelper do lfsEnabled: !!project.lfs_enabled, emailsDisabled: project.emails_disabled?, metricsDashboardAccessLevel: project.project_feature.metrics_dashboard_access_level, - operationsAccessLevel: project.project_feature.operations_access_level, showDefaultAwardEmojis: project.show_default_award_emojis?, securityAndComplianceAccessLevel: project.security_and_compliance_access_level, containerRegistryAccessLevel: project.project_feature.container_registry_access_level, @@ -1338,6 +1333,27 @@ RSpec.describe ProjectsHelper do end end + describe '#fork_divergence_message' do + using RSpec::Parameterized::TableSyntax + + where(:behind, :ahead, :message) do + 0 | 0 | 'Up to date with upstream repository' + 1 | 0 | '1 commit behind upstream repository' + 2 | 0 | '2 commits behind upstream repository' + 0 | 1 | '1 commit ahead of upstream repository' + 0 | 2 | '2 commits ahead of upstream repository' + 5 | 7 | '5 commits behind, 7 commits ahead of upstream repository' + nil | 7 | 'Fork has diverged from upstream repository' + 7 | nil | 'Fork has diverged from upstream repository' + end + + with_them do + it 'returns message based on behind/ahead values' do + expect(helper.fork_divergence_message({ behind: behind, ahead: ahead })).to eq(message) + end + end + end + describe '#localized_project_human_access' do using RSpec::Parameterized::TableSyntax diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index 192dfaa9caf..45864320115 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe SearchHelper do +RSpec.describe SearchHelper, feature_category: :global_search do include MarkupHelper include BadgesHelper @@ -60,6 +60,44 @@ RSpec.describe SearchHelper do expect(search_autocomplete_opts(project.name).size).to eq(1) end + context 'for users' do + let_it_be(:another_user) { create(:user, name: 'Jane Doe') } + let(:term) { 'jane' } + + it 'makes a call to SearchService' do + params = { search: term, per_page: 5, scope: 'users' } + expect(SearchService).to receive(:new).with(current_user, params).and_call_original + + search_autocomplete_opts(term) + end + + it 'returns users matching the term' do + result = search_autocomplete_opts(term) + expect(result.size).to eq(1) + expect(result.first[:id]).to eq(another_user.id) + end + + context 'when current_user cannot read_users_list' do + before do + allow(Ability).to receive(:allowed?).and_return(true) + allow(Ability).to receive(:allowed?).with(current_user, :read_users_list).and_return(false) + end + + it 'returns an empty array' do + expect(search_autocomplete_opts(term)).to eq([]) + end + end + + context 'with limiting' do + let!(:users) { create_list(:user, 6, name: 'Jane Doe') } + + it 'only returns the first 5 users' do + result = search_autocomplete_opts(term) + expect(result.size).to eq(5) + end + end + end + it "includes the required project attrs" do project = create(:project, namespace: create(:namespace, owner: user)) result = search_autocomplete_opts(project.name).first @@ -858,17 +896,18 @@ RSpec.describe SearchHelper do end context 'code' do - where(:feature_flag_tab_enabled, :show_elasticsearch_tabs, :project_search_tabs, :condition) do - false | false | false | false - true | true | true | true - true | false | false | false - false | true | false | false - false | false | true | true - true | false | true | true + where(:feature_flag_tab_enabled, :show_elasticsearch_tabs, :global_project, :project_search_tabs, :condition) do + false | false | nil | false | false + true | true | nil | true | true + true | false | nil | false | false + false | true | nil | false | false + false | false | ref(:project) | true | true + true | false | ref(:project) | false | false end with_them do it 'data item condition is set correctly' do + @project = global_project allow(search_service).to receive(:show_elasticsearch_tabs?).and_return(show_elasticsearch_tabs) allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_code_tab).and_return(feature_flag_tab_enabled) allow(self).to receive(:project_search_tabs?).with(:blobs).and_return(project_search_tabs) @@ -879,16 +918,16 @@ RSpec.describe SearchHelper do end context 'issues' do - where(:feature_flag_tab_enabled, :project_search_tabs, :condition) do - false | false | false - true | true | true - true | false | true - false | true | true + where(:project_search_tabs, :global_search_issues_tab, :condition) do + false | false | false + false | true | true + true | false | true + true | true | true end with_them do it 'data item condition is set correctly' do - allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_issues_tab).and_return(feature_flag_tab_enabled) + allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_issues_tab).and_return(global_search_issues_tab) allow(self).to receive(:project_search_tabs?).with(:issues).and_return(project_search_tabs) expect(search_navigation[:issues][:condition]).to eq(condition) @@ -897,11 +936,11 @@ RSpec.describe SearchHelper do end context 'merge requests' do - where(:feature_flag_tab_enabled, :project_search_tabs, :condition) do - false | false | false - true | true | true - true | false | true - false | true | true + where(:project_search_tabs, :feature_flag_tab_enabled, :condition) do + false | false | false + true | false | true + false | true | true + true | true | true end with_them do @@ -915,16 +954,19 @@ RSpec.describe SearchHelper do end context 'wiki' do - where(:project_search_tabs, :show_elasticsearch_tabs, :condition) do - false | false | false - true | true | true - true | false | true - false | true | true + where(:global_search_wiki_tab, :show_elasticsearch_tabs, :global_project, :project_search_tabs, :condition) do + false | false | nil | true | true + false | false | nil | false | false + false | true | nil | false | false + true | false | nil | false | false + true | true | ref(:project) | false | false end with_them do it 'data item condition is set correctly' do + @project = global_project allow(search_service).to receive(:show_elasticsearch_tabs?).and_return(show_elasticsearch_tabs) + allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_wiki_tab).and_return(global_search_wiki_tab) allow(self).to receive(:project_search_tabs?).with(:wiki).and_return(project_search_tabs) expect(search_navigation[:wiki_blobs][:condition]).to eq(condition) @@ -933,17 +975,20 @@ RSpec.describe SearchHelper do end context 'commits' do - where(:feature_flag_tab_enabled, :show_elasticsearch_tabs, :project_search_tabs, :condition) do - false | false | false | false - true | true | true | true - true | false | false | false - false | true | true | true + where(:global_search_commits_tab, :show_elasticsearch_tabs, :global_project, :project_search_tabs, :condition) do + false | false | nil | true | true + false | false | nil | false | false + false | true | nil | false | false + true | false | nil | false | false + true | true | ref(:project) | false | false + true | true | nil | false | true end with_them do it 'data item condition is set correctly' do + @project = global_project allow(search_service).to receive(:show_elasticsearch_tabs?).and_return(show_elasticsearch_tabs) - allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_commits_tab).and_return(feature_flag_tab_enabled) + allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_commits_tab).and_return(global_search_commits_tab) allow(self).to receive(:project_search_tabs?).with(:commits).and_return(project_search_tabs) expect(search_navigation[:commits][:condition]).to eq(condition) @@ -952,11 +997,11 @@ RSpec.describe SearchHelper do end context 'comments' do - where(:show_elasticsearch_tabs, :project_search_tabs, :condition) do - true | true | true - false | false | false - true | false | true - false | true | true + where(:project_search_tabs, :show_elasticsearch_tabs, :condition) do + true | true | true + false | false | false + false | true | true + true | false | true end with_them do @@ -1012,7 +1057,7 @@ RSpec.describe SearchHelper do with_them do it 'data item condition is set correctly' do - @show_snippets = global_show_snippets + allow(search_service).to receive(:show_snippets?).and_return(global_show_snippets) @project = global_project expect(search_navigation[:snippet_titles][:condition]).to eq(condition) @@ -1063,9 +1108,9 @@ RSpec.describe SearchHelper do allow(self).to receive(:can?).and_return(true) allow(self).to receive(:project_search_tabs?).and_return(true) allow(self).to receive(:feature_flag_tab_enabled?).and_return(true) - allow(search_service).to receive(:show_elasticsearch_tabs?).and_return(true) allow(self).to receive(:feature_flag_tab_enabled?).and_return(true) - @show_snippets = true + allow(search_service).to receive(:show_elasticsearch_tabs?).and_return(true) + allow(search_service).to receive(:show_snippets?).and_return(true) @project = nil end diff --git a/spec/helpers/sorting_helper_spec.rb b/spec/helpers/sorting_helper_spec.rb index 3e555301325..d561b08efac 100644 --- a/spec/helpers/sorting_helper_spec.rb +++ b/spec/helpers/sorting_helper_spec.rb @@ -109,103 +109,14 @@ RSpec.describe SortingHelper do describe '#projects_sort_options_hash' do it 'returns a hash of available sorting options' do - expect(projects_sort_options_hash).to include(project_common_options) - end - end - - describe '#projects_reverse_sort_options_hash' do - context 'returns a reversed hash of available sorting options' do - using RSpec::Parameterized::TableSyntax - - where(:sort_key, :reverse_sort_title) do - sort_value_latest_activity | sort_value_oldest_activity - sort_value_recently_created | sort_value_oldest_created - sort_value_name | sort_value_name_desc - sort_value_stars_desc | sort_value_stars_asc - sort_value_oldest_activity | sort_value_latest_activity - sort_value_oldest_created | sort_value_recently_created - sort_value_name_desc | sort_value_name - sort_value_stars_asc | sort_value_stars_desc - end - - with_them do - it do - reverse_hash = projects_reverse_sort_options_hash - - expect(reverse_hash).to include(sort_key) - expect(reverse_hash[sort_key]).to eq(reverse_sort_title) - end - end - end - end - - describe '#project_sort_direction_button' do - context 'returns the correct icon for each sort option' do - using RSpec::Parameterized::TableSyntax - - sort_lowest_icon = 'sort-lowest' - sort_highest_icon = 'sort-highest' - - where(:selected_sort, :icon) do - sort_value_latest_activity | sort_highest_icon - sort_value_recently_created | sort_highest_icon - sort_value_name_desc | sort_highest_icon - sort_value_stars_desc | sort_highest_icon - sort_value_oldest_activity | sort_lowest_icon - sort_value_oldest_created | sort_lowest_icon - sort_value_name | sort_lowest_icon - sort_value_stars_asc | sort_lowest_icon - end - - with_them do - it do - set_sorting_url selected_sort - - expect(project_sort_direction_button(selected_sort)).to include(icon) - end - end - end - - it 'returns the correct link to reverse the current sort option' do - sort_options_links = projects_reverse_sort_options_hash - - sort_options_links.each do |selected_sort, reverse_sort| - set_sorting_url selected_sort - - expect(project_sort_direction_button(selected_sort)).to include(reverse_sort) - end - end - end - - 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_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 }) - expect(projects_sort_option_titles).to eq(options) - end - end - - describe 'with project_list_filter_bar off' do - before do - stub_feature_flags(project_list_filter_bar: false) - end - - 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_recently_created => sort_title_recently_created, - sort_value_stars_desc => sort_title_most_stars - }) - - expect(projects_sort_options_hash).to eq(options) - end + expect(projects_sort_options_hash).to eq(options) end end end diff --git a/spec/helpers/tab_helper_spec.rb b/spec/helpers/tab_helper_spec.rb index 80a1224abbb..5b74eda34cd 100644 --- a/spec/helpers/tab_helper_spec.rb +++ b/spec/helpers/tab_helper_spec.rb @@ -7,7 +7,7 @@ RSpec.describe TabHelper do describe 'gl_tabs_nav' do it 'creates a tabs navigation' do - expect(helper.gl_tabs_nav).to match(%r{<ul class="nav gl-tabs-nav"><\/ul>}) + expect(helper.gl_tabs_nav).to match(%r{<ul class="nav gl-tabs-nav"></ul>}) end it 'captures block output' do diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb index 7c91dd0570f..ca334a04fe9 100644 --- a/spec/helpers/todos_helper_spec.rb +++ b/spec/helpers/todos_helper_spec.rb @@ -14,6 +14,8 @@ RSpec.describe TodosHelper do note: 'I am note, hear me roar') end + let_it_be(:group) { create(:group, :public, name: 'Group 1') } + let_it_be(:design_todo) do create(:todo, :mentioned, user: user, @@ -37,6 +39,10 @@ RSpec.describe TodosHelper do create(:todo, target: issue) end + let_it_be(:group_todo) do + create(:todo, target: group) + end + describe '#todos_count_format' do it 'shows fuzzy count for 100 or more items' do expect(helper.todos_count_format(100)).to eq '99+' @@ -50,16 +56,14 @@ RSpec.describe TodosHelper do end end - describe '#todo_target_link' do + describe '#todo_target_name' do context 'when given a design' do let(:todo) { design_todo } - it 'produces a good link' do - path = helper.todo_target_path(todo) - link = helper.todo_target_link(todo) - expected = "<a href=\"#{path}\">design #{design.to_reference}</a>" + it 'references the filename of the design' do + name = helper.todo_target_name(todo) - expect(link).to eq(expected) + expect(name).to eq(design.to_reference.to_s) end end end @@ -94,7 +98,7 @@ RSpec.describe TodosHelper do it 'returns the title' do title = helper.todo_target_title(todo) - expect(title).to eq("\"Issue 1\"") + expect(title).to eq("Issue 1") end end end @@ -155,33 +159,51 @@ RSpec.describe TodosHelper do expect(path).to eq("/#{issue.project.full_path}/-/issues/#{issue.iid}##{dom_id(note)}") end end + + context 'when a user requests access to group' do + let_it_be(:group_access_request_todo) do + create(:todo, + target_id: group.id, + target_type: group.class.polymorphic_name, + group: group, + action: Todo::MEMBER_ACCESS_REQUESTED) + end + + it 'responds with access requests tab' do + path = helper.todo_target_path(group_access_request_todo) + + access_request_path = Gitlab::Routing.url_helpers.group_group_members_url(group, tab: 'access_requests') + + expect(path).to eq(access_request_path) + end + end end - describe '#todo_target_type_name' do - subject { helper.todo_target_type_name(todo) } + describe '#todo_target_aria_label' do + subject { helper.todo_target_aria_label(todo) } context 'when given a design todo' do let(:todo) { design_todo } - it { is_expected.to eq('design') } + it { is_expected.to eq("Design ##{todo.target.iid}[#{todo.target.title}]") } end context 'when given an alert todo' do let(:todo) { alert_todo } - it { is_expected.to eq('alert') } + it { is_expected.to eq("Alert ^alert##{todo.target.iid}") } end context 'when given a task todo' do let(:todo) { task_todo } - it { is_expected.to eq('task') } + it { is_expected.to eq("Task ##{todo.target.iid}") } end context 'when given an issue todo' do let(:todo) { issue_todo } - it { is_expected.to eq('issue') } + it { is_expected.to eq("Issue ##{todo.target.iid}") } end context 'when given a merge request todo' do @@ -190,7 +212,7 @@ RSpec.describe TodosHelper do create(:todo, target: merge_request) end - it { is_expected.to eq('merge request') } + it { is_expected.to eq("Merge Request !#{todo.target.iid}") } end end @@ -229,7 +251,7 @@ RSpec.describe TodosHelper do todo.target.update!(state: 'closed') end - it_behaves_like 'a rendered state pill', css: '.gl-bg-red-500', state: 'closed' + it_behaves_like 'a rendered state pill', css: '.badge-danger', state: 'closed' end context 'merged MR' do @@ -237,7 +259,7 @@ RSpec.describe TodosHelper do todo.target.update!(state: 'merged') end - it_behaves_like 'a rendered state pill', css: '.gl-bg-blue-500', state: 'merged' + it_behaves_like 'a rendered state pill', css: '.badge-info', state: 'merged' end end @@ -251,7 +273,7 @@ RSpec.describe TodosHelper do todo.target.update!(state: 'closed') end - it_behaves_like 'a rendered state pill', css: '.gl-bg-blue-500', state: 'closed' + it_behaves_like 'a rendered state pill', css: '.badge-info', state: 'closed' end end @@ -265,7 +287,7 @@ RSpec.describe TodosHelper do todo.target.resolve! end - it_behaves_like 'a rendered state pill', css: '.gl-bg-blue-500', state: 'resolved' + it_behaves_like 'a rendered state pill', css: '.badge-info', state: 'resolved' end end end @@ -329,17 +351,17 @@ RSpec.describe TodosHelper do where(:action, :self_added?, :expected_action_name) do Todo::ASSIGNED | false | s_('Todos|assigned you') Todo::ASSIGNED | true | s_('Todos|assigned') - Todo::REVIEW_REQUESTED | true | s_('Todos|requested a review of') - Todo::MENTIONED | true | format(s_("Todos|mentioned %{who} on"), who: s_('Todos|yourself')) - Todo::MENTIONED | false | format(s_("Todos|mentioned %{who} on"), who: _('you')) - Todo::DIRECTLY_ADDRESSED | true | format(s_("Todos|mentioned %{who} on"), who: s_('Todos|yourself')) - Todo::DIRECTLY_ADDRESSED | false | format(s_("Todos|mentioned %{who} on"), who: _('you')) - Todo::BUILD_FAILED | true | s_('Todos|The pipeline failed in') - Todo::MARKED | true | s_('Todos|added a todo for') - Todo::APPROVAL_REQUIRED | true | format(s_("Todos|set %{who} as an approver for"), who: s_('Todos|yourself')) - Todo::APPROVAL_REQUIRED | false | format(s_("Todos|set %{who} as an approver for"), who: _('you')) + Todo::REVIEW_REQUESTED | true | s_('Todos|requested a review') + Todo::MENTIONED | true | format(s_("Todos|mentioned %{who}"), who: s_('Todos|yourself')) + Todo::MENTIONED | false | format(s_("Todos|mentioned %{who}"), who: _('you')) + Todo::DIRECTLY_ADDRESSED | true | format(s_("Todos|mentioned %{who}"), who: s_('Todos|yourself')) + Todo::DIRECTLY_ADDRESSED | false | format(s_("Todos|mentioned %{who}"), who: _('you')) + Todo::BUILD_FAILED | true | s_('Todos|The pipeline failed') + Todo::MARKED | true | s_('Todos|added a to-do item') + Todo::APPROVAL_REQUIRED | true | format(s_("Todos|set %{who} as an approver"), who: s_('Todos|yourself')) + Todo::APPROVAL_REQUIRED | false | format(s_("Todos|set %{who} as an approver"), who: _('you')) Todo::UNMERGEABLE | true | s_('Todos|Could not merge') - Todo::MERGE_TRAIN_REMOVED | true | s_("Todos|Removed from Merge Train:") + Todo::MERGE_TRAIN_REMOVED | true | s_("Todos|Removed from Merge Train") end with_them do @@ -350,5 +372,45 @@ RSpec.describe TodosHelper do it { expect(helper.todo_action_name(alert_todo)).to eq(expected_action_name) } end + + context 'member access requested' do + context 'when source is group' do + it 'returns group access message' do + group_todo.action = Todo::MEMBER_ACCESS_REQUESTED + + expect(helper.todo_action_name(group_todo)).to eq( + format(s_("Todos|has requested access to group %{which}"), which: _(group.name)) + ) + end + end + end + end + + describe '#todo_due_date' do + subject(:result) { helper.todo_due_date(todo) } + + context 'due date is today' do + let_it_be(:issue_with_today_due_date) do + create(:issue, title: 'Issue 1', project: project, due_date: Date.current) + end + + let(:todo) do + create(:todo, project: issue_with_today_due_date.project, target: issue_with_today_due_date, note: note) + end + + it { expect(result).to match('Due today') } + end + + context 'due date is not today' do + let_it_be(:issue_with_tomorrow_due_date) do + create(:issue, title: 'Issue 1', project: project, due_date: Date.tomorrow) + end + + let(:todo) do + create(:todo, project: issue_with_tomorrow_due_date.project, target: issue_with_tomorrow_due_date, note: note) + end + + it { expect(result).to match("Due #{l(Date.tomorrow, format: Date::DATE_FORMATS[:medium])}") } + end end end diff --git a/spec/helpers/version_check_helper_spec.rb b/spec/helpers/version_check_helper_spec.rb index 959c4a94a78..2bb85e7b6b8 100644 --- a/spec/helpers/version_check_helper_spec.rb +++ b/spec/helpers/version_check_helper_spec.rb @@ -34,4 +34,42 @@ RSpec.describe VersionCheckHelper do end end end + + describe '#gitlab_version_check' do + before do + allow_next_instance_of(VersionCheck) do |instance| + allow(instance).to receive(:response).and_return({ "severity" => "success" }) + end + end + + it 'returns an instance of the VersionCheck class' do + expect(helper.gitlab_version_check).to eq({ "severity" => "success" }) + end + end + + describe '#show_security_patch_upgrade_alert?' do + describe 'return conditions' do + where(:show_version_check, :gitlab_version_check, :result) do + [ + [false, nil, false], + [false, { "severity" => "success" }, false], + [false, { "severity" => "danger" }, false], + [true, nil, false], + [true, { "severity" => "success" }, false], + [true, { "severity" => "danger" }, true] + ] + end + + with_them do + before do + allow(helper).to receive(:show_version_check?).and_return(show_version_check) + allow(helper).to receive(:gitlab_version_check).and_return(gitlab_version_check) + end + + it 'returns correct results' do + expect(helper.show_security_patch_upgrade_alert?).to eq result + end + end + end + end end diff --git a/spec/helpers/web_hooks/web_hooks_helper_spec.rb b/spec/helpers/web_hooks/web_hooks_helper_spec.rb index 473f33a982f..bcd9d2df1dc 100644 --- a/spec/helpers/web_hooks/web_hooks_helper_spec.rb +++ b/spec/helpers/web_hooks/web_hooks_helper_spec.rb @@ -7,39 +7,16 @@ RSpec.describe WebHooks::WebHooksHelper do let(:current_user) { nil } let(:callout_dismissed) { false } - let(:web_hooks_disable_failed) { false } - let(:webhooks_failed_callout) { false } before do allow(helper).to receive(:current_user).and_return(current_user) allow(helper).to receive(:web_hook_disabled_dismissed?).with(project).and_return(callout_dismissed) - - stub_feature_flags( - webhooks_failed_callout: webhooks_failed_callout, - web_hooks_disable_failed: web_hooks_disable_failed - ) end shared_context 'user is logged in' do let(:current_user) { create(:user) } end - shared_context 'webhooks_failed_callout is enabled' do - let(:webhooks_failed_callout) { true } - end - - shared_context 'webhooks_failed_callout is enabled for this project' do - let(:webhooks_failed_callout) { project } - end - - shared_context 'web_hooks_disable_failed is enabled' do - let(:web_hooks_disable_failed) { true } - end - - shared_context 'web_hooks_disable_failed is enabled for this project' do - let(:web_hooks_disable_failed) { project } - end - shared_context 'the user has permission' do before do project.add_maintainer(current_user) @@ -59,8 +36,6 @@ RSpec.describe WebHooks::WebHooksHelper do describe '#show_project_hook_failed_callout?' do context 'all conditions are met' do include_context 'user is logged in' - include_context 'webhooks_failed_callout is enabled' - include_context 'web_hooks_disable_failed is enabled' include_context 'the user has permission' include_context 'a hook has failed' @@ -85,23 +60,9 @@ RSpec.describe WebHooks::WebHooksHelper do end end - context 'all conditions are met, project scoped flags' do - include_context 'user is logged in' - include_context 'webhooks_failed_callout is enabled for this project' - include_context 'web_hooks_disable_failed is enabled for this project' - include_context 'the user has permission' - include_context 'a hook has failed' - - it 'is true' do - expect(helper).to be_show_project_hook_failed_callout(project: project) - end - end - context 'one condition is not met' do contexts = [ 'user is logged in', - 'webhooks_failed_callout is enabled', - 'web_hooks_disable_failed is enabled', 'the user has permission', 'a hook has failed' ] diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb index 59624dc0682..497cd5d1e7f 100644 --- a/spec/helpers/wiki_helper_spec.rb +++ b/spec/helpers/wiki_helper_spec.rb @@ -76,7 +76,7 @@ RSpec.describe WikiHelper do describe '#wiki_sort_controls' do let(:wiki) { create(:project_wiki) } let(:wiki_link) { helper.wiki_sort_controls(wiki, direction) } - let(:classes) { "gl-button btn btn-default btn-icon has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort" } + let(:classes) { "gl-button btn btn-default btn-icon has-tooltip reverse-sort-btn rspec-reverse-sort" } def expected_link(direction, icon_class) path = "/#{wiki.project.full_path}/-/wikis/pages?direction=#{direction}" diff --git a/spec/helpers/x509_helper_spec.rb b/spec/helpers/x509_helper_spec.rb index 4e3e8c8d3f6..dfe9259bd0f 100644 --- a/spec/helpers/x509_helper_spec.rb +++ b/spec/helpers/x509_helper_spec.rb @@ -57,22 +57,4 @@ RSpec.describe X509Helper do end end end - - describe '#x509_signature?' do - let(:x509_signature) { create(:x509_commit_signature) } - let(:gpg_signature) { create(:gpg_signature) } - - it 'detects a x509 signed commit' do - signature = Gitlab::X509::Signature.new( - X509Helpers::User1.signed_commit_signature, - X509Helpers::User1.signed_commit_base_data, - X509Helpers::User1.certificate_email, - X509Helpers::User1.signed_commit_time - ) - - expect(x509_signature?(x509_signature)).to be_truthy - expect(x509_signature?(signature)).to be_truthy - expect(x509_signature?(gpg_signature)).to be_falsey - end - end end |