diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-19 08:27:35 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-19 08:27:35 +0000 |
commit | 7e9c479f7de77702622631cff2628a9c8dcbc627 (patch) | |
tree | c8f718a08e110ad7e1894510980d2155a6549197 /spec/helpers | |
parent | e852b0ae16db4052c1c567d9efa4facc81146e88 (diff) | |
download | gitlab-ce-7e9c479f7de77702622631cff2628a9c8dcbc627.tar.gz |
Add latest changes from gitlab-org/gitlab@13-6-stable-eev13.6.0-rc42
Diffstat (limited to 'spec/helpers')
31 files changed, 1072 insertions, 173 deletions
diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb index 7f25721801f..479e2d7ef9d 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -166,4 +166,32 @@ RSpec.describe ApplicationSettingsHelper do it { is_expected.to eq(false) } end end + + describe '.signup_enabled?' do + subject { helper.signup_enabled? } + + context 'when signup is enabled' do + before do + stub_application_setting(signup_enabled: true) + end + + it { is_expected.to be true } + end + + context 'when signup is disabled' do + before do + stub_application_setting(signup_enabled: false) + end + + it { is_expected.to be false } + end + + context 'when `signup_enabled` is nil' do + before do + stub_application_setting(signup_enabled: nil) + end + + it { is_expected.to be false } + end + end end diff --git a/spec/helpers/auth_helper_spec.rb b/spec/helpers/auth_helper_spec.rb index e0d316baa17..b4cea7fb695 100644 --- a/spec/helpers/auth_helper_spec.rb +++ b/spec/helpers/auth_helper_spec.rb @@ -260,4 +260,41 @@ RSpec.describe AuthHelper do end end end + + describe '#google_tag_manager_enabled?' do + let(:is_gitlab_com) { true } + let(:user) { nil } + + before do + allow(Gitlab).to receive(:com?).and_return(is_gitlab_com) + stub_config(extra: { google_tag_manager_id: 'key' }) + allow(helper).to receive(:current_user).and_return(user) + end + + subject(:google_tag_manager_enabled?) { helper.google_tag_manager_enabled? } + + context 'on gitlab.com and a key set without a current user' do + it { is_expected.to be_truthy } + end + + context 'when not on gitlab.com' do + let(:is_gitlab_com) { false } + + it { is_expected.to be_falsey } + end + + context 'when current user is set' do + let(:user) { instance_double('User') } + + it { is_expected.to be_falsey } + end + + context 'when no key is set' do + before do + stub_config(extra: {}) + end + + it { is_expected.to be_falsey } + end + end end diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index baa97781efa..cafe4c4275e 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -236,11 +236,7 @@ RSpec.describe BlobHelper do let(:data) { File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) } let(:blob) { fake_blob(path: Gitlab::FileDetector::PATTERNS[:gitlab_ci], data: data) } - context 'experiment enabled' do - before do - allow(helper).to receive(:experiment_enabled?).and_return(true) - end - + context 'feature enabled' do it 'is true' do expect(helper.show_suggest_pipeline_creation_celebration?).to be_truthy end @@ -284,9 +280,9 @@ RSpec.describe BlobHelper do end end - context 'experiment disabled' do + context 'feature disabled' do before do - allow(helper).to receive(:experiment_enabled?).and_return(false) + stub_feature_flags(suggest_pipeline: false) end it 'is false' do @@ -298,11 +294,7 @@ RSpec.describe BlobHelper do context 'when file is not a pipeline config file' do let(:blob) { fake_blob(path: 'LICENSE') } - context 'experiment enabled' do - before do - allow(helper).to receive(:experiment_enabled?).and_return(true) - end - + context 'feature enabled' do it 'is false' do expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey end @@ -444,6 +436,55 @@ RSpec.describe BlobHelper do end end + describe '#ide_merge_request_path' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:merge_request) { create(:merge_request, source_project: project)} + + it 'returns IDE path for the given MR if MR is not merged' do + expect(helper.ide_merge_request_path(merge_request)).to eq("/-/ide/project/#{project.full_path}/merge_requests/#{merge_request.iid}") + end + + context 'when the MR comes from a fork' do + include ProjectForksHelper + + let(:forked_project) { fork_project(project, nil, repository: true) } + let(:merge_request) { create(:merge_request, source_project: forked_project, target_project: project) } + + it 'returns IDE path for MR in the forked repo with target project included as param' do + expect(helper.ide_merge_request_path(merge_request)).to eq("/-/ide/project/#{forked_project.full_path}/merge_requests/#{merge_request.iid}?target_project=#{CGI.escape(project.full_path)}") + end + end + + context 'when the MR is merged' do + let(:current_user) { build(:user) } + + let_it_be(:merge_request) { create(:merge_request, :merged, source_project: project, source_branch: 'testing-1', target_branch: 'feature-1') } + + before do + allow(helper).to receive(:current_user).and_return(current_user) + allow(helper).to receive(:can?).and_return(true) + end + + it 'returns default IDE url with master branch' do + expect(helper.ide_merge_request_path(merge_request)).to eq("/-/ide/project/#{project.full_path}/edit/master") + end + + it 'includes file path passed' do + expect(helper.ide_merge_request_path(merge_request, 'README.md')).to eq("/-/ide/project/#{project.full_path}/edit/master/-/README.md") + end + + context 'when target branch exists' do + before do + allow(merge_request).to receive(:target_branch_exists?).and_return(true) + end + + it 'returns IDE edit url with the target branch' do + expect(helper.ide_merge_request_path(merge_request)).to eq("/-/ide/project/#{project.full_path}/edit/feature-1") + end + end + end + end + describe '#ide_fork_and_edit_path' do let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } diff --git a/spec/helpers/branches_helper_spec.rb b/spec/helpers/branches_helper_spec.rb index 1f7bf25afcd..2ad15adff59 100644 --- a/spec/helpers/branches_helper_spec.rb +++ b/spec/helpers/branches_helper_spec.rb @@ -28,5 +28,23 @@ RSpec.describe BranchesHelper do expect(subject).to eq(expected_array) end end + + context 'when an access level tied to a deploy key is provided' do + let!(:protected_branch) { create(:protected_branch, :no_one_can_push) } + let!(:deploy_key) { create(:deploy_key, deploy_keys_projects: [create(:deploy_keys_project, :write_access, project: protected_branch.project)]) } + + let(:push_level) { protected_branch.push_access_levels.first } + let(:deploy_key_push_level) { create(:protected_branch_push_access_level, protected_branch: protected_branch, deploy_key: deploy_key) } + let(:access_levels) { [push_level, deploy_key_push_level] } + + it 'returns the correct array' do + expected_array = [ + { id: push_level.id, type: :role, access_level: Gitlab::Access::NO_ACCESS }, + { id: deploy_key_push_level.id, type: :deploy_key, deploy_key_id: deploy_key.id } + ] + + expect(subject).to eq(expected_array) + end + end end end diff --git a/spec/helpers/breadcrumbs_helper_spec.rb b/spec/helpers/breadcrumbs_helper_spec.rb new file mode 100644 index 00000000000..8e2a684656b --- /dev/null +++ b/spec/helpers/breadcrumbs_helper_spec.rb @@ -0,0 +1,145 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BreadcrumbsHelper do + describe '#push_to_schema_breadcrumb' do + let(:element_name) { 'BreadCrumbElement' } + let(:link) { 'http://test.host/foo' } + let(:breadcrumb_list) { helper.instance_variable_get(:@schema_breadcrumb_list) } + + subject { helper.push_to_schema_breadcrumb(element_name, link) } + + it 'enqueue element name, link and position' do + subject + + aggregate_failures do + expect(breadcrumb_list[0]['name']).to eq element_name + expect(breadcrumb_list[0]['item']).to eq link + expect(breadcrumb_list[0]['position']).to eq(1) + end + end + + context 'when link is relative' do + let(:link) { '/foo' } + + it 'converts the url into absolute' do + subject + + expect(breadcrumb_list[0]['item']).to eq "http://test.host#{link}" + end + end + + describe 'when link is invalid' do + let(:link) { 'invalid://foo[]' } + + it 'returns the current url' do + subject + + expect(breadcrumb_list[0]['item']).to eq 'http://test.host' + end + end + + describe 'when link is nil' do + let(:link) { nil } + + it 'returns the current url' do + subject + + expect(breadcrumb_list[0]['item']).to eq 'http://test.host' + end + end + end + + describe '#schema_breadcrumb_json' do + let(:elements) do + [ + %w(element1 http://test.host/link1), + %w(element2 http://test.host/link2) + ] + end + + subject { helper.schema_breadcrumb_json } + + it 'returns the breadcrumb schema in json format' do + enqueue_breadcrumb_elements + + expected_result = { + '@context' => 'https://schema.org', + '@type' => 'BreadcrumbList', + 'itemListElement' => [ + { + '@type' => 'ListItem', + 'position' => 1, + 'name' => elements[0][0], + 'item' => elements[0][1] + }, + { + '@type' => 'ListItem', + 'position' => 2, + 'name' => elements[1][0], + 'item' => elements[1][1] + } + ] + }.to_json + + expect(subject).to eq expected_result + end + + context 'when extra breadcrumb element is added' do + let(:extra_elements) do + [ + %w(extra_element1 http://test.host/extra_link1), + %w(extra_element2 http://test.host/extra_link2) + ] + end + + it 'include the extra elements before the last element' do + enqueue_breadcrumb_elements + + extra_elements.each do |el| + add_to_breadcrumbs(el[0], el[1]) + end + + expected_result = { + '@context' => 'https://schema.org', + '@type' => 'BreadcrumbList', + 'itemListElement' => [ + { + '@type' => 'ListItem', + 'position' => 1, + 'name' => elements[0][0], + 'item' => elements[0][1] + }, + { + '@type' => 'ListItem', + 'position' => 2, + 'name' => extra_elements[0][0], + 'item' => extra_elements[0][1] + }, + { + '@type' => 'ListItem', + 'position' => 3, + 'name' => extra_elements[1][0], + 'item' => extra_elements[1][1] + }, + { + '@type' => 'ListItem', + 'position' => 4, + 'name' => elements[1][0], + 'item' => elements[1][1] + } + ] + }.to_json + + expect(subject).to eq expected_result + end + end + + def enqueue_breadcrumb_elements + elements.each do |el| + helper.push_to_schema_breadcrumb(el[0], el[1]) + end + end + end +end diff --git a/spec/helpers/ci/pipeline_editor_helper_spec.rb b/spec/helpers/ci/pipeline_editor_helper_spec.rb new file mode 100644 index 00000000000..8f38d3b1439 --- /dev/null +++ b/spec/helpers/ci/pipeline_editor_helper_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::PipelineEditorHelper do + let_it_be(:project) { create(:project) } + + describe 'can_view_pipeline_editor?' do + subject { helper.can_view_pipeline_editor?(project) } + + it 'user can view editor if they can collaborate' do + allow(helper).to receive(:can_collaborate_with_project?).and_return(true) + + expect(subject).to be true + end + + it 'user can not view editor if they cannot collaborate' do + allow(helper).to receive(:can_collaborate_with_project?).and_return(false) + + expect(subject).to be false + end + + it 'user can not view editor if feature is disabled' do + allow(helper).to receive(:can_collaborate_with_project?).and_return(true) + stub_feature_flags(ci_pipeline_editor_page: false) + + expect(subject).to be false + end + end +end diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb index ef1f0940074..c085c3bdbd9 100644 --- a/spec/helpers/diff_helper_spec.rb +++ b/spec/helpers/diff_helper_spec.rb @@ -130,6 +130,38 @@ RSpec.describe DiffHelper do end end + describe "#diff_link_number" do + using RSpec::Parameterized::TableSyntax + + let(:line) do + double(:line, type: line_type) + end + + # This helper is used to generate the line numbers on the + # diff lines. It essentially just returns a blank string + # on the old/new lines. The following table tests all the + # possible permutations for clarity. + + where(:line_type, :match, :line_number, :expected_return_value) do + "new" | "new" | 1 | " " + "new" | "old" | 2 | 2 + "old" | "new" | 3 | 3 + "old" | "old" | 4 | " " + "new-nonewline" | "new" | 5 | 5 + "new-nonewline" | "old" | 6 | 6 + "old-nonewline" | "new" | 7 | 7 + "old-nonewline" | "old" | 8 | 8 + "match" | "new" | 9 | 9 + "match" | "old" | 10 | 10 + end + + with_them do + it "returns the expected value" do + expect(helper.diff_link_number(line.type, match, line_number)).to eq(expected_return_value) + end + end + end + describe "#mark_inline_diffs" do let(:old_line) { %{abc 'def'} } let(:new_line) { %{abc "def"} } @@ -326,4 +358,30 @@ RSpec.describe DiffHelper do expect(diff_file_path_text(diff_file, max: 10)).to eq("...open.rb") end end + + describe 'unified_diff_lines_view_type' do + before do + controller.params[:view] = 'parallel' + end + + describe 'unified diffs enabled' do + before do + stub_feature_flags(unified_diff_lines: true) + end + + it 'returns inline view' do + expect(helper.unified_diff_lines_view_type(project)).to eq 'inline' + end + end + + describe 'unified diffs disabled' do + before do + stub_feature_flags(unified_diff_lines: false) + end + + it 'returns parallel view' do + expect(helper.unified_diff_lines_view_type(project)).to eq :parallel + end + end + end end diff --git a/spec/helpers/dropdowns_helper_spec.rb b/spec/helpers/dropdowns_helper_spec.rb index fd1125d0024..c30cb159803 100644 --- a/spec/helpers/dropdowns_helper_spec.rb +++ b/spec/helpers/dropdowns_helper_spec.rb @@ -246,8 +246,8 @@ RSpec.describe DropdownsHelper do expect(content).to include('dropdown-loading') end - it 'returns an icon in the content' do - expect(content.scan('icon').count).to eq(1) + it 'returns a gl-spinner in the content' do + expect(content).to include('gl-spinner') end end end diff --git a/spec/helpers/gitlab_routing_helper_spec.rb b/spec/helpers/gitlab_routing_helper_spec.rb index 0088f739879..f23ffcee35d 100644 --- a/spec/helpers/gitlab_routing_helper_spec.rb +++ b/spec/helpers/gitlab_routing_helper_spec.rb @@ -322,4 +322,14 @@ RSpec.describe GitlabRoutingHelper do end end end + + context 'releases' do + let(:release) { create(:release) } + + describe '#release_url' do + it 'returns the url for the release page' do + expect(release_url(release)).to eq("http://test.host/#{release.project.full_path}/-/releases/#{release.tag}") + end + end + end end diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index 08b25d64b43..8eb1b7b3b3d 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -87,15 +87,26 @@ RSpec.describe GroupsHelper do end describe 'group_title' do - let(:group) { create(:group) } - let(:nested_group) { create(:group, parent: group) } - let(:deep_nested_group) { create(:group, parent: nested_group) } - let!(:very_deep_nested_group) { create(:group, parent: deep_nested_group) } + let_it_be(:group) { create(:group) } + let_it_be(:nested_group) { create(:group, parent: group) } + let_it_be(:deep_nested_group) { create(:group, parent: nested_group) } + let_it_be(:very_deep_nested_group) { create(:group, parent: deep_nested_group) } + + subject { helper.group_title(very_deep_nested_group) } it 'outputs the groups in the correct order' do - expect(helper.group_title(very_deep_nested_group)) + expect(subject) .to match(%r{<li style="text-indent: 16px;"><a.*>#{deep_nested_group.name}.*</li>.*<a.*>#{very_deep_nested_group.name}</a>}m) end + + it 'enqueues the elements in the breadcrumb schema list' do + expect(helper).to receive(:push_to_schema_breadcrumb).with(group.name, group_path(group)) + expect(helper).to receive(:push_to_schema_breadcrumb).with(nested_group.name, group_path(nested_group)) + expect(helper).to receive(:push_to_schema_breadcrumb).with(deep_nested_group.name, group_path(deep_nested_group)) + expect(helper).to receive(:push_to_schema_breadcrumb).with(very_deep_nested_group.name, group_path(very_deep_nested_group)) + + subject + end end # rubocop:disable Layout/SpaceBeforeComma @@ -370,6 +381,26 @@ RSpec.describe GroupsHelper do end end + describe '#show_thanks_for_purchase_banner?' do + subject { helper.show_thanks_for_purchase_banner? } + + it 'returns true with purchased_quantity present in params' do + allow(controller).to receive(:params) { { purchased_quantity: '1' } } + + is_expected.to be_truthy + end + + it 'returns false with purchased_quantity not present in params' do + is_expected.to be_falsey + end + + it 'returns false with purchased_quantity is empty in params' do + allow(controller).to receive(:params) { { purchased_quantity: '' } } + + is_expected.to be_falsey + end + end + describe '#show_invite_banner?' do let_it_be(:current_user) { create(:user) } let_it_be_with_refind(:group) { create(:group) } diff --git a/spec/helpers/icons_helper_spec.rb b/spec/helpers/icons_helper_spec.rb index 94012de3877..c05b2b206cc 100644 --- a/spec/helpers/icons_helper_spec.rb +++ b/spec/helpers/icons_helper_spec.rb @@ -97,19 +97,19 @@ RSpec.describe IconsHelper do it 'returns right icon name for standard auth' do icon_name = 'standard' expect(audit_icon(icon_name).to_s) - .to eq '<i class="fa fa-key"></i>' + .to eq sprite_icon('key') end it 'returns right icon name for two-factor auth' do icon_name = 'two-factor' expect(audit_icon(icon_name).to_s) - .to eq '<i class="fa fa-key"></i>' + .to eq sprite_icon('key') end it 'returns right icon name for google_oauth2 auth' do icon_name = 'google_oauth2' expect(audit_icon(icon_name).to_s) - .to eq '<i class="fa fa-google"></i>' + .to eq sprite_icon('google') end end diff --git a/spec/helpers/invite_members_helper_spec.rb b/spec/helpers/invite_members_helper_spec.rb index b4e05d67553..d75b3c9f2e3 100644 --- a/spec/helpers/invite_members_helper_spec.rb +++ b/spec/helpers/invite_members_helper_spec.rb @@ -7,70 +7,110 @@ RSpec.describe InviteMembersHelper do let_it_be(:developer) { create(:user, developer_projects: [project]) } let(:owner) { project.owner } - before do - assign(:project, project) - end + context 'with project' do + before do + assign(:project, project) + end - describe "#directly_invite_members?" do - context 'when the user is an owner' do - before do - allow(helper).to receive(:current_user) { owner } - end + describe "#directly_invite_members?" do + context 'when the user is an owner' do + before do + allow(helper).to receive(:current_user) { owner } + end + + it 'returns false' do + allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_a) { false } - it 'returns false' do - allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_a) { false } + expect(helper.directly_invite_members?).to eq false + end - expect(helper.directly_invite_members?).to eq false + it 'returns true' do + allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_a) { true } + + expect(helper.directly_invite_members?).to eq true + end end - it 'returns true' do - allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_a) { true } + context 'when the user is a developer' do + before do + allow(helper).to receive(:current_user) { developer } + end + + it 'returns false' do + allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_a) { true } - expect(helper.directly_invite_members?).to eq true + expect(helper.directly_invite_members?).to eq false + end end end - context 'when the user is a developer' do - before do - allow(helper).to receive(:current_user) { developer } + describe "#indirectly_invite_members?" do + context 'when a user is a developer' do + before do + allow(helper).to receive(:current_user) { developer } + end + + it 'returns false' do + allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_b) { false } + + expect(helper.indirectly_invite_members?).to eq false + end + + it 'returns true' do + allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_b) { true } + + expect(helper.indirectly_invite_members?).to eq true + end end - it 'returns false' do - allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_a) { true } + context 'when a user is an owner' do + before do + allow(helper).to receive(:current_user) { owner } + end - expect(helper.directly_invite_members?).to eq false + it 'returns false' do + allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_b) { true } + + expect(helper.indirectly_invite_members?).to eq false + end end end end - describe "#indirectly_invite_members?" do - context 'when a user is a developer' do - before do - allow(helper).to receive(:current_user) { developer } - end + context 'with group' do + let_it_be(:group) { create(:group) } - it 'returns false' do - allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_b) { false } + describe "#invite_group_members?" do + context 'when the user is an owner' do + before do + group.add_owner(owner) + allow(helper).to receive(:current_user) { owner } + end - expect(helper.indirectly_invite_members?).to eq false - end + it 'returns false' do + allow(helper).to receive(:experiment_enabled?).with(:invite_members_empty_group_version_a) { false } - it 'returns true' do - allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_b) { true } + expect(helper.invite_group_members?(group)).to eq false + end - expect(helper.indirectly_invite_members?).to eq true - end - end + it 'returns true' do + allow(helper).to receive(:experiment_enabled?).with(:invite_members_empty_group_version_a) { true } - context 'when a user is an owner' do - before do - allow(helper).to receive(:current_user) { owner } + expect(helper.invite_group_members?(group)).to eq true + end end - it 'returns false' do - allow(helper).to receive(:experiment_enabled?).with(:invite_members_version_b) { true } + context 'when the user is a developer' do + before do + group.add_developer(developer) + allow(helper).to receive(:current_user) { developer } + end + + it 'returns false' do + allow(helper).to receive(:experiment_enabled?).with(:invite_members_empty_group_version_a) { true } - expect(helper.indirectly_invite_members?).to eq false + expect(helper.invite_group_members?(group)).to eq false + end end end end diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index e8e5adaa274..0e3752f220e 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -345,42 +345,29 @@ RSpec.describe IssuablesHelper do end end - describe '#sidebar_milestone_tooltip_label' do - it 'escapes HTML in the milestone title' do - milestone = build(:milestone, title: '<img onerror=alert(1)>') + describe '#issuable_display_type' do + using RSpec::Parameterized::TableSyntax - expect(helper.sidebar_milestone_tooltip_label(milestone)).to eq('<img onerror=alert(1)><br/>Milestone') + where(:issuable_type, :issuable_display_type) do + :issue | 'issue' + :incident | 'incident' + :merge_request | 'merge request' end - end - - describe '#serialize_issuable' do - context 'when it is a merge request' do - let(:merge_request) { build(:merge_request) } - let(:user) { build(:user) } - - before do - allow(helper).to receive(:current_user) { user } - end - - it 'has suggest_pipeline experiment enabled' do - allow(helper).to receive(:experiment_enabled?).with(:suggest_pipeline) { true } - expect_next_instance_of(MergeRequestSerializer) do |serializer| - expect(serializer).to receive(:represent).with(merge_request, { serializer: 'widget', experiment_enabled: :suggest_pipeline }) - end + with_them do + let(:issuable) { build_stubbed(issuable_type) } - helper.serialize_issuable(merge_request, serializer: 'widget') - end + subject { helper.issuable_display_type(issuable) } - it 'suggest_pipeline experiment disabled' do - allow(helper).to receive(:experiment_enabled?).with(:suggest_pipeline) { false } + it { is_expected.to eq(issuable_display_type) } + end + end - expect_next_instance_of(MergeRequestSerializer) do |serializer| - expect(serializer).to receive(:represent).with(merge_request, { serializer: 'widget' }) - end + describe '#sidebar_milestone_tooltip_label' do + it 'escapes HTML in the milestone title' do + milestone = build(:milestone, title: '<img onerror=alert(1)>') - helper.serialize_issuable(merge_request, serializer: 'widget') - end + expect(helper.sidebar_milestone_tooltip_label(milestone)).to eq('<img onerror=alert(1)><br/>Milestone') end end end diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb index 302ab0cc137..6c5855eeb91 100644 --- a/spec/helpers/markup_helper_spec.rb +++ b/spec/helpers/markup_helper_spec.rb @@ -9,6 +9,7 @@ RSpec.describe MarkupHelper do project.add_maintainer(user) user end + let_it_be(:issue) { create(:issue, project: project) } let_it_be(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let_it_be(:snippet) { create(:project_snippet, project: project) } diff --git a/spec/helpers/operations_helper_spec.rb b/spec/helpers/operations_helper_spec.rb index 8d2fc643caa..09f9bba8f9e 100644 --- a/spec/helpers/operations_helper_spec.rb +++ b/spec/helpers/operations_helper_spec.rb @@ -43,7 +43,9 @@ RSpec.describe OperationsHelper do 'prometheus_api_url' => nil, 'prometheus_activated' => 'false', 'prometheus_url' => notify_project_prometheus_alerts_url(project, format: :json), - 'disabled' => 'false' + 'disabled' => 'false', + 'project_path' => project.full_path, + 'multi_integrations' => 'false' ) end end diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb index e8a5c4613fe..99cdee6dbb2 100644 --- a/spec/helpers/page_layout_helper_spec.rb +++ b/spec/helpers/page_layout_helper_spec.rb @@ -56,19 +56,24 @@ RSpec.describe PageLayoutHelper do end %w(project user group).each do |type| + let(:object) { build(type, trait) } + let(:trait) { :with_avatar } + context "with @#{type} assigned" do - it "uses #{type.titlecase} avatar if available" do - object = double(avatar_url: 'http://example.com/uploads/-/system/avatar.png') + before do assign(type, object) + end - expect(helper.page_image).to eq object.avatar_url + it "uses #{type.titlecase} avatar full url" do + expect(helper.page_image).to eq object.avatar_url(only_path: false) end - it 'falls back to the default when avatar_url is nil' do - object = double(avatar_url: nil) - assign(type, object) + context 'when avatar_url is nil' do + let(:trait) { nil } - expect(helper.page_image).to match_asset_path 'assets/gitlab_logo.png' + it 'falls back to the default when avatar_url is nil' do + expect(helper.page_image).to match_asset_path 'assets/gitlab_logo.png' + end end end @@ -132,4 +137,126 @@ RSpec.describe PageLayoutHelper do end end end + + describe '#page_canonical_link' do + let(:user) { build(:user) } + + subject { helper.page_canonical_link(link) } + + before do + allow(helper).to receive(:current_user).and_return(user) + end + + context 'when link is passed' do + let(:link) { 'https://gitlab.com' } + + it 'stores and returns the link value' do + expect(subject).to eq link + expect(helper.page_canonical_link(nil)).to eq link + end + end + + context 'when no link is provided' do + let(:link) { nil } + let(:request) { ActionDispatch::Request.new(env) } + let(:env) do + { + 'ORIGINAL_FULLPATH' => '/foo/', + 'PATH_INFO' => '/foo', + 'HTTP_HOST' => 'test.host', + 'REQUEST_METHOD' => method, + 'rack.url_scheme' => 'http' + } + end + + before do + allow(helper).to receive(:request).and_return(request) + end + + shared_examples 'generates the canonical url using the params in the context' do + specify { expect(subject).to eq 'http://test.host/foo' } + end + + shared_examples 'does not return a canonical url' do + specify { expect(subject).to be_nil } + end + + it_behaves_like 'generates the canonical url using the params in the context' do + let(:method) { 'GET' } + end + + it_behaves_like 'generates the canonical url using the params in the context' do + let(:method) { 'HEAD' } + end + + it_behaves_like 'does not return a canonical url' do + let(:method) { 'POST' } + end + + it_behaves_like 'does not return a canonical url' do + let(:method) { 'PUT' } + end + end + end + + describe '#page_itemtype' do + subject { helper.page_itemtype(itemtype) } + + context 'when itemtype is passed' do + let(:itemtype) { 'http://schema.org/Person' } + + it 'stores and returns the itemtype value' do + attrs = { itemscope: true, itemtype: itemtype } + + expect(subject).to eq attrs + expect(helper.page_itemtype(nil)).to eq attrs + end + end + + context 'when no itemtype is provided' do + let(:itemtype) { nil } + + it 'returns an empty hash' do + expect(subject).to eq({}) + end + end + end + + describe '#user_status_properties' do + using RSpec::Parameterized::TableSyntax + + let(:user) { build(:user) } + + availability_types = Types::AvailabilityEnum.enum + + where(:message, :emoji, :availability) do + "Some message" | UserStatus::DEFAULT_EMOJI | availability_types[:busy] + "Some message" | UserStatus::DEFAULT_EMOJI | availability_types[:not_set] + "Some message" | "basketball" | availability_types[:busy] + "Some message" | "basketball" | availability_types[:not_set] + "Some message" | "" | availability_types[:busy] + "Some message" | "" | availability_types[:not_set] + "" | UserStatus::DEFAULT_EMOJI | availability_types[:busy] + "" | UserStatus::DEFAULT_EMOJI | availability_types[:not_set] + "" | "basketball" | availability_types[:busy] + "" | "basketball" | availability_types[:not_set] + "" | "" | availability_types[:busy] + "" | "" | availability_types[:not_set] + end + + with_them do + it "sets the default user status fields" do + user.status = UserStatus.new(message: message, emoji: emoji, availability: availability) + result = { + can_set_user_availability: true, + current_availability: availability, + current_emoji: emoji, + current_message: message, + default_emoji: UserStatus::DEFAULT_EMOJI + } + + expect(helper.user_status_properties(user)).to eq(result) + end + end + end end diff --git a/spec/helpers/profiles_helper_spec.rb b/spec/helpers/profiles_helper_spec.rb index 61b7ff94edb..9687d038162 100644 --- a/spec/helpers/profiles_helper_spec.rb +++ b/spec/helpers/profiles_helper_spec.rb @@ -80,6 +80,38 @@ RSpec.describe ProfilesHelper do end end + describe "#user_status_set_to_busy?" do + using RSpec::Parameterized::TableSyntax + + where(:availability, :result) do + "busy" | true + "not_set" | false + "" | false + nil | false + end + + with_them do + it { expect(helper.user_status_set_to_busy?(OpenStruct.new(availability: availability))).to eq(result) } + end + end + + describe "#show_status_emoji?" do + using RSpec::Parameterized::TableSyntax + + where(:message, :emoji, :result) do + "Some message" | UserStatus::DEFAULT_EMOJI | true + "Some message" | "" | true + "" | "basketball" | true + "" | "basketball" | true + "" | UserStatus::DEFAULT_EMOJI | false + "" | UserStatus::DEFAULT_EMOJI | false + end + + with_them do + it { expect(helper.show_status_emoji?(OpenStruct.new(message: message, emoji: emoji))).to eq(result) } + end + end + def stub_cas_omniauth_provider provider = OpenStruct.new( 'name' => 'cas3', diff --git a/spec/helpers/projects/terraform_helper_spec.rb b/spec/helpers/projects/terraform_helper_spec.rb new file mode 100644 index 00000000000..de363c42d21 --- /dev/null +++ b/spec/helpers/projects/terraform_helper_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::TerraformHelper do + describe '#js_terraform_list_data' do + let_it_be(:project) { create(:project) } + + subject { helper.js_terraform_list_data(project) } + + it 'displays image path' do + image_path = ActionController::Base.helpers.image_path( + 'illustrations/empty-state/empty-serverless-lg.svg' + ) + + expect(subject[:empty_state_image]).to eq(image_path) + end + + it 'displays project path' do + expect(subject[:project_path]).to eq(project.full_path) + end + end +end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index f081cf225b1..9635a6f9c82 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -999,4 +999,15 @@ RSpec.describe ProjectsHelper do end end end + + describe '#project_title' do + subject { helper.project_title(project) } + + it 'enqueues the elements in the breadcrumb schema list' do + expect(helper).to receive(:push_to_schema_breadcrumb).with(project.namespace.name, user_path(project.owner)) + expect(helper).to receive(:push_to_schema_breadcrumb).with(project.name, project_path(project)) + + subject + end + end end diff --git a/spec/helpers/recaptcha_experiment_helper_spec.rb b/spec/helpers/recaptcha_helper_spec.rb index e677164c950..e7f9ba5b73a 100644 --- a/spec/helpers/recaptcha_experiment_helper_spec.rb +++ b/spec/helpers/recaptcha_helper_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe RecaptchaExperimentHelper, type: :helper do +RSpec.describe RecaptchaHelper, type: :helper do let(:session) { {} } before do diff --git a/spec/helpers/releases_helper_spec.rb b/spec/helpers/releases_helper_spec.rb index 704e8dc40cb..e6bf91ceef6 100644 --- a/spec/helpers/releases_helper_spec.rb +++ b/spec/helpers/releases_helper_spec.rb @@ -64,12 +64,13 @@ RSpec.describe ReleasesHelper do describe '#data_for_edit_release_page' do it 'has the needed data to display the "edit release" page' do keys = %i(project_id + group_id + group_milestones_available project_path tag_name markdown_preview_path markdown_docs_path releases_page_path - update_release_api_docs_path release_assets_docs_path manage_milestones_path new_milestone_path) @@ -81,11 +82,12 @@ RSpec.describe ReleasesHelper do describe '#data_for_new_release_page' do it 'has the needed data to display the "new release" page' do keys = %i(project_id + group_id + group_milestones_available project_path releases_page_path markdown_preview_path markdown_docs_path - update_release_api_docs_path release_assets_docs_path manage_milestones_path new_milestone_path diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index 6fe071521cd..34af3ce7e5e 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -73,7 +73,7 @@ RSpec.describe SearchHelper do expect(result.keys).to match_array(%i[category id label url avatar_url]) end - it 'includes the users recently viewed issues' do + it 'includes the users recently viewed issues', :aggregate_failures do recent_issues = instance_double(::Gitlab::Search::RecentIssues) expect(::Gitlab::Search::RecentIssues).to receive(:new).with(user: user).and_return(recent_issues) project1 = create(:project, :with_avatar, namespace: user.namespace) @@ -104,7 +104,7 @@ RSpec.describe SearchHelper do }) end - it 'includes the users recently viewed merge requests' do + it 'includes the users recently viewed merge requests', :aggregate_failures do recent_merge_requests = instance_double(::Gitlab::Search::RecentMergeRequests) expect(::Gitlab::Search::RecentMergeRequests).to receive(:new).with(user: user).and_return(recent_merge_requests) project1 = create(:project, :with_avatar, namespace: user.namespace) @@ -143,12 +143,44 @@ RSpec.describe SearchHelper do context "with a current project" do before do @project = create(:project, :repository) + allow(self).to receive(:can?).with(user, :read_feature_flag, @project).and_return(false) end - it "includes project-specific sections" do + it "includes project-specific sections", :aggregate_failures do expect(search_autocomplete_opts("Files").size).to eq(1) expect(search_autocomplete_opts("Commits").size).to eq(1) end + + context 'when user does not have access to project' do + it 'does not include issues by iid' do + issue = create(:issue, project: @project) + results = search_autocomplete_opts("\##{issue.iid}") + + expect(results.count).to eq(0) + end + end + + context 'when user has project access' do + before do + @project = create(:project, :repository, namespace: user.namespace) + allow(self).to receive(:can?).with(user, :read_feature_flag, @project).and_return(true) + end + + it 'includes issues by iid', :aggregate_failures do + issue = create(:issue, project: @project, title: 'test title') + results = search_autocomplete_opts("\##{issue.iid}") + + expect(results.count).to eq(1) + + expect(results.first).to include({ + category: 'In this project', + id: issue.id, + label: 'test title (#1)', + url: ::Gitlab::Routing.url_helpers.project_issue_path(issue.project, issue), + avatar_url: '' # project has no avatar + }) + end + end end end @@ -204,11 +236,34 @@ RSpec.describe SearchHelper do end describe 'search_entries_empty_message' do - it 'returns the formatted entry message' do - message = search_entries_empty_message('projects', '<h1>foo</h1>') + let!(:group) { build(:group) } + let!(:project) { build(:project, group: group) } + + context 'global search' do + let(:message) { search_entries_empty_message('projects', '<h1>foo</h1>', nil, nil) } + + it 'returns the formatted entry message' do + expect(message).to eq("We couldn't find any projects matching <code><h1>foo</h1></code>") + expect(message).to be_html_safe + end + end + + context 'group search' do + let(:message) { search_entries_empty_message('projects', '<h1>foo</h1>', group, nil) } - expect(message).to eq("We couldn't find any projects matching <code><h1>foo</h1></code>") - expect(message).to be_html_safe + it 'returns the formatted entry message' do + expect(message).to start_with('We couldn't find any projects matching <code><h1>foo</h1></code> in group <a') + expect(message).to be_html_safe + end + end + + context 'project search' do + let(:message) { search_entries_empty_message('projects', '<h1>foo</h1>', group, project) } + + it 'returns the formatted entry message' do + expect(message).to start_with('We couldn't find any projects matching <code><h1>foo</h1></code> in project <a') + expect(message).to be_html_safe + end end end @@ -343,6 +398,19 @@ RSpec.describe SearchHelper do expect(link).to have_link('Projects', href: search_path(scope: 'projects', search: 'hello', project_id: 23)) end + it 'restricts the params' do + expect(self).to receive(:params).and_return( + ActionController::Parameters.new( + search: 'hello', + unknown: 42 + ) + ) + + link = search_filter_link('projects', 'Projects') + + expect(link).to have_link('Projects', href: search_path(scope: 'projects', search: 'hello')) + end + it 'assigns given data attributes on the list container' do link = search_filter_link('projects', 'Projects', data: { foo: 'bar' }) @@ -409,7 +477,7 @@ RSpec.describe SearchHelper do end end - describe '#highlight_and_truncate_issue' do + describe '#highlight_and_truncate_issuable' do let(:description) { 'hello world' } let(:issue) { create(:issue, description: description) } let(:user) { create(:user) } @@ -418,7 +486,7 @@ RSpec.describe SearchHelper do allow(self).to receive(:current_user).and_return(user) end - subject { highlight_and_truncate_issue(issue, 'test', {}) } + subject { highlight_and_truncate_issuable(issue, 'test', {}) } context 'when description is not present' do let(:description) { nil } @@ -477,4 +545,38 @@ RSpec.describe SearchHelper do end end end + + describe '#issuable_state_to_badge_class' do + context 'with merge request' do + it 'returns correct badge based on status' do + expect(issuable_state_to_badge_class(build(:merge_request, :merged))).to eq(:primary) + expect(issuable_state_to_badge_class(build(:merge_request, :closed))).to eq(:danger) + expect(issuable_state_to_badge_class(build(:merge_request, :opened))).to eq(:success) + end + end + + context 'with an issue' do + it 'returns correct badge based on status' do + expect(issuable_state_to_badge_class(build(:issue, :closed))).to eq(:info) + expect(issuable_state_to_badge_class(build(:issue, :opened))).to eq(:success) + end + end + end + + describe '#issuable_state_text' do + context 'with merge request' do + it 'returns correct badge based on status' do + expect(issuable_state_text(build(:merge_request, :merged))).to eq(_('Merged')) + expect(issuable_state_text(build(:merge_request, :closed))).to eq(_('Closed')) + expect(issuable_state_text(build(:merge_request, :opened))).to eq(_('Open')) + end + end + + context 'with an issue' do + it 'returns correct badge based on status' do + expect(issuable_state_text(build(:issue, :closed))).to eq(_('Closed')) + expect(issuable_state_text(build(:issue, :opened))).to eq(_('Open')) + end + end + end end diff --git a/spec/helpers/sorting_helper_spec.rb b/spec/helpers/sorting_helper_spec.rb index 6c52016139b..1c300aea2df 100644 --- a/spec/helpers/sorting_helper_spec.rb +++ b/spec/helpers/sorting_helper_spec.rb @@ -50,6 +50,24 @@ RSpec.describe SortingHelper do end end + describe '#search_sort_direction_button' do + before do + set_sorting_url 'test_label' + end + + it 'keeps label filter param' do + expect(search_sort_direction_button('created_asc')).to include('label_name=test_label') + end + + it 'returns icon with sort-lowest when sort is asc' do + expect(search_sort_direction_button('created_asc')).to include('sort-lowest') + end + + it 'returns icon with sort-highest when sort is desc' do + expect(search_sort_direction_button('created_desc')).to include('sort-highest') + end + end + def stub_controller_path(value) allow(helper.controller).to receive(:controller_path).and_return(value) end diff --git a/spec/helpers/sourcegraph_helper_spec.rb b/spec/helpers/sourcegraph_helper_spec.rb index 6a95c8e4a43..d03893ea9ae 100644 --- a/spec/helpers/sourcegraph_helper_spec.rb +++ b/spec/helpers/sourcegraph_helper_spec.rb @@ -5,60 +5,43 @@ require 'spec_helper' RSpec.describe SourcegraphHelper do describe '#sourcegraph_url_message' do let(:sourcegraph_url) { 'http://sourcegraph.example.com' } + let(:feature_conditional) { false } + let(:public_only) { false } + let(:is_com) { true } before do allow(Gitlab::CurrentSettings).to receive(:sourcegraph_url).and_return(sourcegraph_url) allow(Gitlab::CurrentSettings).to receive(:sourcegraph_url_is_com?).and_return(is_com) + allow(Gitlab::CurrentSettings).to receive(:sourcegraph_public_only).and_return(public_only) + allow(Gitlab::Sourcegraph).to receive(:feature_conditional?).and_return(feature_conditional) end subject { helper.sourcegraph_url_message } context 'with .com sourcegraph url' do - let(:is_com) { true } - - it { is_expected.to have_text('Uses Sourcegraph.com') } - it { is_expected.to have_link('Sourcegraph.com', href: sourcegraph_url) } + it { is_expected.to have_text('Uses %{linkStart}Sourcegraph.com%{linkEnd}. This feature is experimental.') } end context 'with custom sourcegraph url' do let(:is_com) { false } - it { is_expected.to have_text('Uses a custom Sourcegraph instance') } - it { is_expected.to have_link('Sourcegraph instance', href: sourcegraph_url) } - - context 'with unsafe url' do - let(:sourcegraph_url) { '\" onload=\"alert(1);\"' } - - it { is_expected.to have_link('Sourcegraph instance', href: sourcegraph_url) } - end + it { is_expected.to have_text('Uses a custom %{linkStart}Sourcegraph instance%{linkEnd}. This feature is experimental.') } end - end - - describe '#sourcegraph_experimental_message' do - let(:feature_conditional) { false } - let(:public_only) { false } - - before do - allow(Gitlab::CurrentSettings).to receive(:sourcegraph_public_only).and_return(public_only) - allow(Gitlab::Sourcegraph).to receive(:feature_conditional?).and_return(feature_conditional) - end - - subject { helper.sourcegraph_experimental_message } context 'when not limited by feature or public only' do - it { is_expected.to eq "This feature is experimental." } + it { is_expected.to eq 'Uses %{linkStart}Sourcegraph.com%{linkEnd}. This feature is experimental.' } end context 'when limited by feature' do let(:feature_conditional) { true } - it { is_expected.to eq "This feature is experimental and currently limited to certain projects." } + it { is_expected.to eq 'Uses %{linkStart}Sourcegraph.com%{linkEnd}. This feature is experimental and currently limited to certain projects.' } end context 'when limited by public only' do let(:public_only) { true } - it { is_expected.to eq "This feature is experimental and limited to public projects." } + it { is_expected.to eq 'Uses %{linkStart}Sourcegraph.com%{linkEnd}. This feature is experimental and limited to public projects.' } end end end diff --git a/spec/helpers/stat_anchors_helper_spec.rb b/spec/helpers/stat_anchors_helper_spec.rb new file mode 100644 index 00000000000..c6556647bc8 --- /dev/null +++ b/spec/helpers/stat_anchors_helper_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe StatAnchorsHelper do + let(:anchor_klass) { ProjectPresenter::AnchorData } + + describe '#stat_anchor_attrs' do + subject { helper.stat_anchor_attrs(anchor) } + + context 'when anchor is a link' do + let(:anchor) { anchor_klass.new(true) } + + it 'returns the proper attributes' do + expect(subject[:class]).to include('stat-link') + end + end + + context 'when anchor is not a link' do + context 'when class_modifier is set' do + let(:anchor) { anchor_klass.new(false, nil, nil, 'default') } + + it 'returns the proper attributes' do + expect(subject[:class]).to include('btn btn-default') + end + end + + context 'when class_modifier is not set' do + let(:anchor) { anchor_klass.new(false) } + + it 'returns the proper attributes' do + expect(subject[:class]).to include('btn btn-missing') + end + end + end + + context 'when itemprop is not set' do + let(:anchor) { anchor_klass.new(false, nil, nil, nil, nil, false) } + + it 'returns the itemprop attributes' do + expect(subject[:itemprop]).to be_nil + end + end + + context 'when itemprop is set set' do + let(:anchor) { anchor_klass.new(false, nil, nil, nil, nil, true) } + + it 'returns the itemprop attributes' do + expect(subject[:itemprop]).to eq true + end + end + end +end diff --git a/spec/helpers/time_helper_spec.rb b/spec/helpers/time_helper_spec.rb index 6663a5c81c8..3e406f5e74e 100644 --- a/spec/helpers/time_helper_spec.rb +++ b/spec/helpers/time_helper_spec.rb @@ -37,4 +37,14 @@ RSpec.describe TimeHelper do it { expect(duration_in_numbers(duration)).to eq formatted_string } end end + + describe "#time_in_milliseconds" do + it "returns the time in milliseconds" do + freeze_time do + time = (Time.now.to_f * 1000).to_i + + expect(time_in_milliseconds).to eq time + end + end + end end diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb index 6b658a475b1..9481d756c16 100644 --- a/spec/helpers/todos_helper_spec.rb +++ b/spec/helpers/todos_helper_spec.rb @@ -12,6 +12,7 @@ RSpec.describe TodosHelper do project: issue.project, note: 'I am note, hear me roar') end + let_it_be(:design_todo) do create(:todo, :mentioned, user: user, @@ -20,6 +21,7 @@ RSpec.describe TodosHelper do author: author, note: note) end + let_it_be(:alert_todo) do alert = create(:alert_management_alert, iid: 1001) create(:todo, target: alert) diff --git a/spec/helpers/tree_helper_spec.rb b/spec/helpers/tree_helper_spec.rb index b5d356b985c..620bf248d7b 100644 --- a/spec/helpers/tree_helper_spec.rb +++ b/spec/helpers/tree_helper_spec.rb @@ -7,6 +7,8 @@ RSpec.describe TreeHelper do let(:repository) { project.repository } let(:sha) { 'c1c67abbaf91f624347bb3ae96eabe3a1b742478' } + let_it_be(:user) { create(:user) } + def create_file(filename) project.repository.create_file( project.creator, @@ -219,7 +221,6 @@ RSpec.describe TreeHelper do context 'user does not have write access but a personal fork exists' do include ProjectForksHelper - let_it_be(:user) { create(:user) } let(:forked_project) { create(:project, :repository, namespace: user.namespace) } before do @@ -277,8 +278,6 @@ RSpec.describe TreeHelper do end context 'user has write access' do - let_it_be(:user) { create(:user) } - before do project.add_developer(user) @@ -314,8 +313,6 @@ RSpec.describe TreeHelper do end context 'gitpod feature is enabled' do - let_it_be(:user) { create(:user) } - before do stub_feature_flags(gitpod: true) allow(Gitlab::CurrentSettings) @@ -358,4 +355,28 @@ RSpec.describe TreeHelper do end end end + + describe '.patch_branch_name' do + before do + allow(helper).to receive(:current_user).and_return(user) + end + + subject { helper.patch_branch_name('master') } + + it 'returns a patch branch name' do + freeze_time do + epoch = Time.now.strftime('%s%L').last(5) + + expect(subject).to eq "#{user.username}-master-patch-#{epoch}" + end + end + + context 'without a current_user' do + let(:user) { nil } + + it 'returns nil' do + expect(subject).to be nil + end + end + end end diff --git a/spec/helpers/user_callouts_helper_spec.rb b/spec/helpers/user_callouts_helper_spec.rb index bcb0b5c51e7..4ab3be877b4 100644 --- a/spec/helpers/user_callouts_helper_spec.rb +++ b/spec/helpers/user_callouts_helper_spec.rb @@ -161,4 +161,50 @@ RSpec.describe UserCalloutsHelper do it { is_expected.to be_falsy } end end + + describe '.show_registration_enabled_user_callout?' do + let_it_be(:admin) { create(:user, :admin) } + + subject { helper.show_registration_enabled_user_callout? } + + context 'when `current_user` is not an admin' do + before do + allow(helper).to receive(:current_user).and_return(user) + stub_application_setting(signup_enabled: true) + allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { false } + end + + it { is_expected.to be false } + end + + context 'when signup is disabled' do + before do + allow(helper).to receive(:current_user).and_return(admin) + stub_application_setting(signup_enabled: false) + allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { false } + end + + it { is_expected.to be false } + end + + context 'when user has dismissed callout' do + before do + allow(helper).to receive(:current_user).and_return(admin) + stub_application_setting(signup_enabled: true) + allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { true } + end + + it { is_expected.to be false } + end + + context 'when `current_user` is an admin, signup is enabled, and user has not dismissed callout' do + before do + allow(helper).to receive(:current_user).and_return(admin) + stub_application_setting(signup_enabled: true) + allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { false } + end + + it { is_expected.to be true } + end + end end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index c9dc3fcff3f..9ebbf975903 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -204,40 +204,72 @@ RSpec.describe UsersHelper do end describe '#work_information' do - subject { helper.work_information(user) } + let(:with_schema_markup) { false } - context 'when both job_title and organization are present' do - let(:user) { build(:user, organization: 'GitLab', job_title: 'Frontend Engineer') } + subject { helper.work_information(user, with_schema_markup: with_schema_markup) } - it 'returns job title concatenated with organization' do - is_expected.to eq('Frontend Engineer at GitLab') - end + context 'when neither organization nor job_title are present' do + it { is_expected.to be_nil } end - context 'when only organization is present' do - let(:user) { build(:user, organization: 'GitLab') } + context 'when user parameter is nil' do + let(:user) { nil } - it "returns organization" do - is_expected.to eq('GitLab') - end + it { is_expected.to be_nil } end - context 'when only job_title is present' do - let(:user) { build(:user, job_title: 'Frontend Engineer') } + context 'without schema markup' do + context 'when both job_title and organization are present' do + let(:user) { build(:user, organization: 'GitLab', job_title: 'Frontend Engineer') } - it 'returns job title' do - is_expected.to eq('Frontend Engineer') + it 'returns job title concatenated with organization' do + is_expected.to eq('Frontend Engineer at GitLab') + end end - end - context 'when neither organization nor job_title are present' do - it { is_expected.to be_nil } + context 'when only organization is present' do + let(:user) { build(:user, organization: 'GitLab') } + + it "returns organization" do + is_expected.to eq('GitLab') + end + end + + context 'when only job_title is present' do + let(:user) { build(:user, job_title: 'Frontend Engineer') } + + it 'returns job title' do + is_expected.to eq('Frontend Engineer') + end + end end - context 'when user parameter is nil' do - let(:user) { nil } + context 'with schema markup' do + let(:with_schema_markup) { true } - it { is_expected.to be_nil } + context 'when both job_title and organization are present' do + let(:user) { build(:user, organization: 'GitLab', job_title: 'Frontend Engineer') } + + it 'returns job title concatenated with organization' do + is_expected.to eq('<span itemprop="jobTitle">Frontend Engineer</span> at <span itemprop="worksFor">GitLab</span>') + end + end + + context 'when only organization is present' do + let(:user) { build(:user, organization: 'GitLab') } + + it "returns organization" do + is_expected.to eq('<span itemprop="worksFor">GitLab</span>') + end + end + + context 'when only job_title is present' do + let(:user) { build(:user, job_title: 'Frontend Engineer') } + + it 'returns job title' do + is_expected.to eq('<span itemprop="jobTitle">Frontend Engineer</span>') + end + end end end end diff --git a/spec/helpers/whats_new_helper_spec.rb b/spec/helpers/whats_new_helper_spec.rb index 80d4ca8ddea..1c8684de75c 100644 --- a/spec/helpers/whats_new_helper_spec.rb +++ b/spec/helpers/whats_new_helper_spec.rb @@ -3,21 +3,23 @@ require 'spec_helper' RSpec.describe WhatsNewHelper do + let(:fixture_dir_glob) { Dir.glob(File.join('spec', 'fixtures', 'whats_new', '*.yml')) } + describe '#whats_new_storage_key' do subject { helper.whats_new_storage_key } - before do - allow(helper).to receive(:whats_new_most_recent_version).and_return(version) - end - context 'when version exist' do - let(:version) { '84.0' } + before do + allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) + end - it { is_expected.to eq('display-whats-new-notification-84.0') } + it { is_expected.to eq('display-whats-new-notification-01.05') } end context 'when recent release items do NOT exist' do - let(:version) { nil } + before do + allow(helper).to receive(:whats_new_release_items).and_return(nil) + end it { is_expected.to be_nil } end @@ -27,8 +29,6 @@ RSpec.describe WhatsNewHelper do subject { helper.whats_new_most_recent_release_items_count } context 'when recent release items exist' do - let(:fixture_dir_glob) { Dir.glob(File.join('spec', 'fixtures', 'whats_new', '*.yml')) } - it 'returns the count from the most recent file' do expect(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) @@ -48,4 +48,13 @@ RSpec.describe WhatsNewHelper do end end end + + # Testing this important private method here because the request spec required multiple confusing mocks and felt wrong and overcomplicated + describe '#whats_new_items_cache_key' do + it 'returns a key containing the most recent file name and page parameter' do + allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) + + expect(helper.send(:whats_new_items_cache_key, 2)).to eq('whats_new:release_items:file-20201225_01_05:page-2') + end + end end |