From 48aff82709769b098321c738f3444b9bdaa694c6 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 21 Oct 2020 07:08:36 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-5-stable-ee --- .../helpers/analytics/unique_visits_helper_spec.rb | 9 -- spec/helpers/application_helper_spec.rb | 26 +++++ spec/helpers/application_settings_helper_spec.rb | 20 ++++ spec/helpers/blob_helper_spec.rb | 48 ++++++--- spec/helpers/boards_helper_spec.rb | 59 +++++++--- spec/helpers/ci/runners_helper_spec.rb | 21 ++++ spec/helpers/clusters_helper_spec.rb | 44 ++++---- .../container_expiration_policies_helper_spec.rb | 25 +++++ spec/helpers/emails_helper_spec.rb | 112 +++++++++++++++++++ spec/helpers/external_link_helper_spec.rb | 11 +- spec/helpers/feature_flags_helper_spec.rb | 21 ++++ spec/helpers/gitlab_routing_helper_spec.rb | 4 +- spec/helpers/groups/group_members_helper_spec.rb | 58 ++++++++-- spec/helpers/icons_helper_spec.rb | 120 ++++++++++----------- spec/helpers/invite_members_helper_spec.rb | 77 +++++++++++++ spec/helpers/issuables_helper_spec.rb | 80 +++++++++++--- spec/helpers/issues_helper_spec.rb | 21 ++++ spec/helpers/labels_helper_spec.rb | 50 +++++---- spec/helpers/notes_helper_spec.rb | 59 +++++----- spec/helpers/operations_helper_spec.rb | 4 +- spec/helpers/packages_helper_spec.rb | 35 ++---- .../projects/alert_management_helper_spec.rb | 4 +- spec/helpers/projects/incidents_helper_spec.rb | 16 ++- spec/helpers/projects_helper_spec.rb | 114 +++++--------------- spec/helpers/releases_helper_spec.rb | 12 +++ spec/helpers/search_helper_spec.rb | 116 ++++++++++++++++---- spec/helpers/snippets_helper_spec.rb | 50 --------- spec/helpers/startupjs_helper_spec.rb | 20 ++++ spec/helpers/tree_helper_spec.rb | 110 +++++++++++++++++-- spec/helpers/user_callouts_helper_spec.rb | 22 ++++ spec/helpers/users_helper_spec.rb | 24 +++++ spec/helpers/visibility_level_helper_spec.rb | 24 ----- spec/helpers/whats_new_helper_spec.rb | 47 ++++++-- spec/helpers/wiki_helper_spec.rb | 13 ++- 34 files changed, 1030 insertions(+), 446 deletions(-) create mode 100644 spec/helpers/feature_flags_helper_spec.rb create mode 100644 spec/helpers/invite_members_helper_spec.rb create mode 100644 spec/helpers/startupjs_helper_spec.rb (limited to 'spec/helpers') diff --git a/spec/helpers/analytics/unique_visits_helper_spec.rb b/spec/helpers/analytics/unique_visits_helper_spec.rb index ff9769078c4..ff363e81ac7 100644 --- a/spec/helpers/analytics/unique_visits_helper_spec.rb +++ b/spec/helpers/analytics/unique_visits_helper_spec.rb @@ -22,15 +22,6 @@ RSpec.describe Analytics::UniqueVisitsHelper do helper.track_visit(target_id) end - it 'does not track visits if usage ping is disabled' do - sign_in(current_user) - expect(Gitlab::CurrentSettings).to receive(:usage_ping_enabled?).and_return(false) - - expect_any_instance_of(Gitlab::Analytics::UniqueVisits).not_to receive(:track_visit) - - helper.track_visit(target_id) - end - it 'does not track visit if user is not logged in' do expect_any_instance_of(Gitlab::Analytics::UniqueVisits).not_to receive(:track_visit) diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index ce4e73bdc55..a557e9e04da 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -222,6 +222,32 @@ RSpec.describe ApplicationHelper do end end + describe '#instance_review_permitted?' do + let_it_be(:non_admin_user) { create :user } + let_it_be(:admin_user) { create :user, :admin } + + before do + allow(::Gitlab::CurrentSettings).to receive(:instance_review_permitted?).and_return(app_setting) + allow(helper).to receive(:current_user).and_return(current_user) + end + + subject { helper.instance_review_permitted? } + + where(app_setting: [true, false], is_admin: [true, false, nil]) + + with_them do + let(:current_user) do + if is_admin.nil? + nil + else + is_admin ? admin_user : non_admin_user + end + end + + it { is_expected.to be(app_setting && is_admin) } + end + end + describe '#locale_path' do it 'returns the locale path with an `_`' do Gitlab::I18n.with_locale('pt-BR') do diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb index c5fd88ada8f..7f25721801f 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -146,4 +146,24 @@ RSpec.describe ApplicationSettingsHelper do ]) end end + + describe '.show_documentation_base_url_field?' do + subject { helper.show_documentation_base_url_field? } + + before do + stub_feature_flags(help_page_documentation_redirect: feature_flag) + end + + context 'when feature flag is enabled' do + let(:feature_flag) { true } + + it { is_expected.to eq(true) } + end + + context 'when feature flag is disabled' do + let(:feature_flag) { false } + + it { is_expected.to eq(false) } + end + end end diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb index 06f86e7716a..baa97781efa 100644 --- a/spec/helpers/blob_helper_spec.rb +++ b/spec/helpers/blob_helper_spec.rb @@ -5,16 +5,6 @@ require 'spec_helper' RSpec.describe BlobHelper do include TreeHelper - describe '#highlight' do - it 'wraps highlighted content' do - expect(helper.highlight('test.rb', '52')).to eq(%q[
52
]) - end - - it 'handles plain version' do - expect(helper.highlight('test.rb', '52', plain: true)).to eq(%q[
52
]) - end - end - describe "#sanitize_svg_data" do let(:input_svg_path) { File.join(Rails.root, 'spec', 'fixtures', 'unsanitized.svg') } let(:data) { File.read(input_svg_path) } @@ -455,13 +445,14 @@ RSpec.describe BlobHelper do end describe '#ide_fork_and_edit_path' do - let(:project) { create(:project) } - let(:current_user) { create(:user) } - let(:can_push_code) { true } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + + let(:current_user) { user } before do allow(helper).to receive(:current_user).and_return(current_user) - allow(helper).to receive(:can?).and_return(can_push_code) + allow(helper).to receive(:can?).and_return(true) end it 'returns path to fork the repo with a redirect param to the full IDE path' do @@ -482,6 +473,35 @@ RSpec.describe BlobHelper do end end + describe '#fork_and_edit_path' do + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + + let(:current_user) { user } + + before do + allow(helper).to receive(:current_user).and_return(current_user) + allow(helper).to receive(:can?).and_return(true) + end + + it 'returns path to fork the repo with a redirect param to the full edit path' do + uri = URI(helper.fork_and_edit_path(project, "master", "")) + params = CGI.unescape(uri.query) + + expect(uri.path).to eq("/#{project.namespace.path}/#{project.path}/-/forks") + expect(params).to include("continue[to]=/#{project.namespace.path}/#{project.path}/-/edit/master/") + expect(params).to include("namespace_key=#{current_user.namespace.id}") + end + + context 'when user is not logged in' do + let(:current_user) { nil } + + it 'returns nil' do + expect(helper.ide_fork_and_edit_path(project, "master", "")).to be_nil + end + end + end + describe '#editing_ci_config?' do let(:project) { build(:project) } diff --git a/spec/helpers/boards_helper_spec.rb b/spec/helpers/boards_helper_spec.rb index a805b96a8cc..b85ebec5545 100644 --- a/spec/helpers/boards_helper_spec.rb +++ b/spec/helpers/boards_helper_spec.rb @@ -34,23 +34,58 @@ RSpec.describe BoardsHelper do end describe '#board_data' do - let(:user) { create(:user) } - let(:board) { create(:board, project: project) } + let_it_be(:user) { create(:user) } + let_it_be(:board) { create(:board, project: project) } - before do - assign(:board, board) - assign(:project, project) + context 'project_board' do + before do + assign(:project, project) + assign(:board, board) - allow(helper).to receive(:current_user) { user } - allow(helper).to receive(:can?).with(user, :create_non_backlog_issues, board).and_return(true) - end + allow(helper).to receive(:current_user) { user } + allow(helper).to receive(:can?).with(user, :create_non_backlog_issues, board).and_return(true) + allow(helper).to receive(:can?).with(user, :admin_issue, board).and_return(true) + end + + it 'returns a board_lists_path as lists_endpoint' do + expect(helper.board_data[:lists_endpoint]).to eq(board_lists_path(board)) + end - it 'returns a board_lists_path as lists_endpoint' do - expect(helper.board_data[:lists_endpoint]).to eq(board_lists_path(board)) + it 'returns board type as parent' do + expect(helper.board_data[:parent]).to eq('project') + end + + it 'returns can_update for user permissions on the board' do + expect(helper.board_data[:can_update]).to eq('true') + end + + it 'returns required label endpoints' do + expect(helper.board_data[:labels_fetch_path]).to eq("/#{project.full_path}/-/labels.json?include_ancestor_groups=true") + expect(helper.board_data[:labels_manage_path]).to eq("/#{project.full_path}/-/labels") + end end - it 'returns board type as parent' do - expect(helper.board_data[:parent]).to eq('project') + context 'group board' do + let_it_be(:group) { create(:group, path: 'base') } + let_it_be(:board) { create(:board, group: group) } + + before do + assign(:group, group) + assign(:board, board) + + allow(helper).to receive(:current_user) { user } + allow(helper).to receive(:can?).with(user, :create_non_backlog_issues, board).and_return(true) + allow(helper).to receive(:can?).with(user, :admin_issue, board).and_return(true) + end + + it 'returns correct path for base group' do + expect(helper.build_issue_link_base).to eq('/base/:project_path/issues') + end + + it 'returns required label endpoints' do + expect(helper.board_data[:labels_fetch_path]).to eq("/groups/base/-/labels.json?include_ancestor_groups=true&only_group_labels=true") + expect(helper.board_data[:labels_manage_path]).to eq("/groups/base/-/labels") + end end end diff --git a/spec/helpers/ci/runners_helper_spec.rb b/spec/helpers/ci/runners_helper_spec.rb index a006933a2a5..38caae91ef2 100644 --- a/spec/helpers/ci/runners_helper_spec.rb +++ b/spec/helpers/ci/runners_helper_spec.rb @@ -53,4 +53,25 @@ RSpec.describe Ci::RunnersHelper do end end end + + describe '#group_shared_runners_settings_data' do + let(:group) { create(:group, parent: parent, shared_runners_enabled: false) } + let(:parent) { create(:group) } + + it 'returns group data for top level group' do + data = group_shared_runners_settings_data(parent) + + expect(data[:update_path]).to eq("/api/v4/groups/#{parent.id}") + expect(data[:shared_runners_availability]).to eq('enabled') + expect(data[:parent_shared_runners_availability]).to eq(nil) + end + + it 'returns group data for child group' do + data = group_shared_runners_settings_data(group) + + expect(data[:update_path]).to eq("/api/v4/groups/#{group.id}") + expect(data[:shared_runners_availability]).to eq('disabled_and_unoverridable') + expect(data[:parent_shared_runners_availability]).to eq('enabled') + end + end end diff --git a/spec/helpers/clusters_helper_spec.rb b/spec/helpers/clusters_helper_spec.rb index 6164f3b5e8d..6b08b6515cf 100644 --- a/spec/helpers/clusters_helper_spec.rb +++ b/spec/helpers/clusters_helper_spec.rb @@ -59,6 +59,24 @@ RSpec.describe ClustersHelper do end end + describe '#js_cluster_agents_list_data' do + let_it_be(:project) { build(:project, :repository) } + + subject { helper.js_cluster_agents_list_data(project) } + + it 'displays project default branch' do + expect(subject[:default_branch_name]).to eq(project.default_branch) + end + + it 'displays image path' do + expect(subject[:empty_state_image]).to match(%r(/illustrations/logos/clusters_empty|svg)) + end + + it 'displays project path' do + expect(subject[:project_path]).to eq(project.full_path) + end + end + describe '#js_clusters_list_data' do subject { helper.js_clusters_list_data('/path') } @@ -89,32 +107,6 @@ RSpec.describe ClustersHelper do end end - describe '#provider_icon' do - it 'will return GCP logo with gcp argument' do - logo = helper.provider_icon('gcp') - - expect(logo).to match(%r(img alt="Google GKE" data-src="|/illustrations/logos/google_gke|svg)) - end - - it 'will return AWS logo with aws argument' do - logo = helper.provider_icon('aws') - - expect(logo).to match(%r(img alt="Amazon EKS" data-src="|/illustrations/logos/amazon_eks|svg)) - end - - it 'will return default logo with unknown provider' do - logo = helper.provider_icon('unknown') - - expect(logo).to match(%r(img alt="Kubernetes Cluster" data-src="|/illustrations/logos/kubernetes|svg)) - end - - it 'will return default logo when provider is empty' do - logo = helper.provider_icon - - expect(logo).to match(%r(img alt="Kubernetes Cluster" data-src="|/illustrations/logos/kubernetes|svg)) - end - end - describe '#cluster_type_label' do subject { helper.cluster_type_label(cluster_type) } diff --git a/spec/helpers/container_expiration_policies_helper_spec.rb b/spec/helpers/container_expiration_policies_helper_spec.rb index b2a03f8d90f..7ad3804e3a9 100644 --- a/spec/helpers/container_expiration_policies_helper_spec.rb +++ b/spec/helpers/container_expiration_policies_helper_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe ContainerExpirationPoliciesHelper do + using RSpec::Parameterized::TableSyntax + describe '#keep_n_options' do it 'returns keep_n options formatted for dropdown usage' do expected_result = [ @@ -44,4 +46,27 @@ RSpec.describe ContainerExpirationPoliciesHelper do expect(helper.older_than_options).to eq(expected_result) end end + + describe '#container_expiration_policies_historic_entry_enabled?' do + let_it_be(:project) { build_stubbed(:project) } + + subject { helper.container_expiration_policies_historic_entry_enabled?(project) } + + where(:application_setting, :feature_flag, :expected_result) do + true | true | true + true | false | true + false | true | true + false | false | false + end + + with_them do + before do + stub_feature_flags(container_expiration_policies_historic_entry: false) + stub_application_setting(container_expiration_policies_enable_historic_entries: application_setting) + stub_feature_flags(container_expiration_policies_historic_entry: project) if feature_flag + end + + it { is_expected.to eq(expected_result) } + end + end end diff --git a/spec/helpers/emails_helper_spec.rb b/spec/helpers/emails_helper_spec.rb index 96ac4015c77..ef8b342a3f6 100644 --- a/spec/helpers/emails_helper_spec.rb +++ b/spec/helpers/emails_helper_spec.rb @@ -361,4 +361,116 @@ RSpec.describe EmailsHelper do end end end + + describe '#change_reviewer_notification_text' do + let(:mary) { build(:user, name: 'Mary') } + let(:john) { build(:user, name: 'John') } + let(:ted) { build(:user, name: 'Ted') } + + context 'to new reviewers only' do + let(:previous_reviewers) { [] } + let(:new_reviewers) { [john] } + + context 'with no html tag' do + let(:expected_output) do + 'Reviewer changed to John' + end + + it 'returns the expected output' do + expect(change_reviewer_notification_text(new_reviewers, previous_reviewers)).to eq(expected_output) + end + end + + context 'with tag' do + let(:expected_output) do + 'Reviewer changed to John' + end + + it 'returns the expected output' do + expect(change_reviewer_notification_text(new_reviewers, previous_reviewers, :strong)).to eq(expected_output) + end + end + end + + context 'from previous reviewers to new reviewers' do + let(:previous_reviewers) { [john, mary] } + let(:new_reviewers) { [ted] } + + context 'with no html tag' do + let(:expected_output) do + 'Reviewer changed from John and Mary to Ted' + end + + it 'returns the expected output' do + expect(change_reviewer_notification_text(new_reviewers, previous_reviewers)).to eq(expected_output) + end + end + + context 'with tag' do + let(:expected_output) do + 'Reviewer changed from John and Mary to Ted' + end + + it 'returns the expected output' do + expect(change_reviewer_notification_text(new_reviewers, previous_reviewers, :strong)).to eq(expected_output) + end + end + end + + context 'from previous reviewers to no reviewers' do + let(:previous_reviewers) { [john, mary] } + let(:new_reviewers) { [] } + + context 'with no html tag' do + let(:expected_output) do + 'Reviewer changed from John and Mary to Unassigned' + end + + it 'returns the expected output' do + expect(change_reviewer_notification_text(new_reviewers, previous_reviewers)).to eq(expected_output) + end + end + + context 'with tag' do + let(:expected_output) do + 'Reviewer changed from John and Mary to Unassigned' + end + + it 'returns the expected output' do + expect(change_reviewer_notification_text(new_reviewers, previous_reviewers, :strong)).to eq(expected_output) + end + end + end + + context "with a ") } + + let(:expected_output) do + 'Reviewer changed to <script>alert('hi')</script>' + end + + it 'escapes the html tag' do + expect(change_reviewer_notification_text(new_reviewers, previous_reviewers, :strong)).to eq(expected_output) + end + end + + context "with url in user's name" do + subject(:email_helper) { Object.new.extend(described_class) } + + let(:previous_reviewers) { [] } + let(:new_reviewers) { [fishy_user] } + let(:fishy_user) { build(:user, name: "example.com") } + + let(:expected_output) do + 'Reviewer changed to example_com' + end + + it "sanitizes user's name" do + expect(email_helper).to receive(:sanitize_name).and_call_original + expect(email_helper.change_reviewer_notification_text(new_reviewers, previous_reviewers)).to eq(expected_output) + end + end + end end diff --git a/spec/helpers/external_link_helper_spec.rb b/spec/helpers/external_link_helper_spec.rb index b1a1884d887..f5bb0568824 100644 --- a/spec/helpers/external_link_helper_spec.rb +++ b/spec/helpers/external_link_helper_spec.rb @@ -6,12 +6,15 @@ RSpec.describe ExternalLinkHelper do include IconsHelper it 'returns external link with icon' do - expect(external_link('https://gitlab.com', 'https://gitlab.com').to_s) - .to eq('https://gitlab.com ') + link = external_link('https://gitlab.com', 'https://gitlab.com').to_s + expect(link).to start_with('https://gitlab.com') + expect(link).to include('data-testid="external-link-icon"') end it 'allows options when creating external link with icon' do - expect(external_link('https://gitlab.com', 'https://gitlab.com', { "data-foo": "bar", class: "externalLink" }).to_s) - .to eq('https://gitlab.com ') + link = external_link('https://gitlab.com', 'https://gitlab.com', { "data-foo": "bar", class: "externalLink" }).to_s + + expect(link).to start_with('https://gitlab.com') + expect(link).to include('data-testid="external-link-icon"') end end diff --git a/spec/helpers/feature_flags_helper_spec.rb b/spec/helpers/feature_flags_helper_spec.rb new file mode 100644 index 00000000000..9a080736595 --- /dev/null +++ b/spec/helpers/feature_flags_helper_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe FeatureFlagsHelper do + let_it_be(:project) { create(:project) } + let_it_be(:feature_flag) { create(:operations_feature_flag, project: project) } + let_it_be(:user) { create(:user) } + + describe '#unleash_api_url' do + subject { helper.unleash_api_url(project) } + + it { is_expected.to end_with("/api/v4/feature_flags/unleash/#{project.id}") } + end + + describe '#unleash_api_instance_id' do + subject { helper.unleash_api_instance_id(project) } + + it { is_expected.not_to be_empty } + end +end diff --git a/spec/helpers/gitlab_routing_helper_spec.rb b/spec/helpers/gitlab_routing_helper_spec.rb index 1ad7c7bb9ff..0088f739879 100644 --- a/spec/helpers/gitlab_routing_helper_spec.rb +++ b/spec/helpers/gitlab_routing_helper_spec.rb @@ -187,7 +187,7 @@ RSpec.describe GitlabRoutingHelper do let(:ref) { 'test-ref' } let(:args) { {} } - subject { gitlab_raw_snippet_blob_path(snippet, blob.path, ref, args) } + subject { gitlab_raw_snippet_blob_path(snippet, blob.path, ref, **args) } it_behaves_like 'snippet blob raw path' @@ -222,7 +222,7 @@ RSpec.describe GitlabRoutingHelper do let(:ref) { 'snippet-test-ref' } let(:args) { {} } - subject { gitlab_raw_snippet_blob_url(snippet, blob.path, ref, args) } + subject { gitlab_raw_snippet_blob_url(snippet, blob.path, ref, **args) } it_behaves_like 'snippet blob raw url' diff --git a/spec/helpers/groups/group_members_helper_spec.rb b/spec/helpers/groups/group_members_helper_spec.rb index a25bf1c4157..bb92445cb19 100644 --- a/spec/helpers/groups/group_members_helper_spec.rb +++ b/spec/helpers/groups/group_members_helper_spec.rb @@ -5,9 +5,15 @@ require "spec_helper" RSpec.describe Groups::GroupMembersHelper do include MembersPresentation - describe '.group_member_select_options' do - let(:group) { create(:group) } + let_it_be(:current_user) { create(:user) } + let_it_be(:group) { create(:group) } + + before do + allow(helper).to receive(:can?).with(current_user, :owner_access, group).and_return(true) + allow(helper).to receive(:current_user).and_return(current_user) + end + describe '.group_member_select_options' do before do helper.instance_variable_set(:@group, group) end @@ -28,14 +34,6 @@ RSpec.describe Groups::GroupMembersHelper do end describe '#members_data_json' do - let(:current_user) { create(:user) } - let(:group) { create(:group) } - - before do - allow(helper).to receive(:can?).with(current_user, :owner_access, group).and_return(true) - allow(helper).to receive(:current_user).and_return(current_user) - end - shared_examples 'group_members.json' do it 'matches json schema' do json = helper.members_data_json(group, present_members([group_member])) @@ -48,6 +46,14 @@ RSpec.describe Groups::GroupMembersHelper do let(:group_member) { create(:group_member, group: group, created_by: current_user) } it_behaves_like 'group_members.json' + + context 'with user status set' do + let(:user) { create(:user) } + let!(:status) { create(:user_status, user: user) } + let(:group_member) { create(:group_member, group: group, user: user, created_by: current_user) } + + it_behaves_like 'group_members.json' + end end context 'for an invited group member' do @@ -62,4 +68,36 @@ RSpec.describe Groups::GroupMembersHelper do it_behaves_like 'group_members.json' end end + + describe '#group_members_list_data_attributes' do + let(:group_member) { create(:group_member, group: group, created_by: current_user) } + + before do + allow(helper).to receive(:group_group_member_path).with(group, ':id').and_return('/groups/foo-bar/-/group_members/:id') + end + + it 'returns expected hash' do + expect(helper.group_members_list_data_attributes(group, present_members([group_member]))).to include({ + members: helper.members_data_json(group, present_members([group_member])), + member_path: '/groups/foo-bar/-/group_members/:id', + group_id: group.id + }) + end + end + + describe '#linked_groups_list_data_attributes' do + include_context 'group_group_link' + + before do + allow(helper).to receive(:group_group_link_path).with(shared_group, ':id').and_return('/groups/foo-bar/-/group_links/:id') + end + + it 'returns expected hash' do + expect(helper.linked_groups_list_data_attributes(shared_group)).to include({ + members: helper.linked_groups_data_json(shared_group.shared_with_group_links), + member_path: '/groups/foo-bar/-/group_links/:id', + group_id: shared_group.id + }) + end + end end diff --git a/spec/helpers/icons_helper_spec.rb b/spec/helpers/icons_helper_spec.rb index 872aa821560..94012de3877 100644 --- a/spec/helpers/icons_helper_spec.rb +++ b/spec/helpers/icons_helper_spec.rb @@ -114,128 +114,128 @@ RSpec.describe IconsHelper do end describe 'file_type_icon_class' do - it 'returns folder class' do - expect(file_type_icon_class('folder', 0, 'folder_name')).to eq 'folder' + it 'returns folder-o class' do + expect(file_type_icon_class('folder', 0, 'folder_name')).to eq 'folder-o' end it 'returns share class' do expect(file_type_icon_class('file', '120000', 'link')).to eq 'share' end - it 'returns file-pdf-o class with .pdf' do - expect(file_type_icon_class('file', 0, 'filename.pdf')).to eq 'file-pdf-o' + it 'returns document class with .pdf' do + expect(file_type_icon_class('file', 0, 'filename.pdf')).to eq 'document' end - it 'returns file-image-o class with .jpg' do - expect(file_type_icon_class('file', 0, 'filename.jpg')).to eq 'file-image-o' + it 'returns doc-image class with .jpg' do + expect(file_type_icon_class('file', 0, 'filename.jpg')).to eq 'doc-image' end - it 'returns file-image-o class with .JPG' do - expect(file_type_icon_class('file', 0, 'filename.JPG')).to eq 'file-image-o' + it 'returns doc-image class with .JPG' do + expect(file_type_icon_class('file', 0, 'filename.JPG')).to eq 'doc-image' end - it 'returns file-image-o class with .png' do - expect(file_type_icon_class('file', 0, 'filename.png')).to eq 'file-image-o' + it 'returns doc-image class with .png' do + expect(file_type_icon_class('file', 0, 'filename.png')).to eq 'doc-image' end - it 'returns file-image-o class with .apng' do - expect(file_type_icon_class('file', 0, 'filename.apng')).to eq 'file-image-o' + it 'returns doc-image class with .apng' do + expect(file_type_icon_class('file', 0, 'filename.apng')).to eq 'doc-image' end - it 'returns file-image-o class with .webp' do - expect(file_type_icon_class('file', 0, 'filename.webp')).to eq 'file-image-o' + it 'returns doc-image class with .webp' do + expect(file_type_icon_class('file', 0, 'filename.webp')).to eq 'doc-image' end - it 'returns file-archive-o class with .tar' do - expect(file_type_icon_class('file', 0, 'filename.tar')).to eq 'file-archive-o' + it 'returns doc-compressed class with .tar' do + expect(file_type_icon_class('file', 0, 'filename.tar')).to eq 'doc-compressed' end - it 'returns file-archive-o class with .TAR' do - expect(file_type_icon_class('file', 0, 'filename.TAR')).to eq 'file-archive-o' + it 'returns doc-compressed class with .TAR' do + expect(file_type_icon_class('file', 0, 'filename.TAR')).to eq 'doc-compressed' end - it 'returns file-archive-o class with .tar.gz' do - expect(file_type_icon_class('file', 0, 'filename.tar.gz')).to eq 'file-archive-o' + it 'returns doc-compressed class with .tar.gz' do + expect(file_type_icon_class('file', 0, 'filename.tar.gz')).to eq 'doc-compressed' end - it 'returns file-audio-o class with .mp3' do - expect(file_type_icon_class('file', 0, 'filename.mp3')).to eq 'file-audio-o' + it 'returns volume-up class with .mp3' do + expect(file_type_icon_class('file', 0, 'filename.mp3')).to eq 'volume-up' end - it 'returns file-audio-o class with .MP3' do - expect(file_type_icon_class('file', 0, 'filename.MP3')).to eq 'file-audio-o' + it 'returns volume-up class with .MP3' do + expect(file_type_icon_class('file', 0, 'filename.MP3')).to eq 'volume-up' end - it 'returns file-audio-o class with .m4a' do - expect(file_type_icon_class('file', 0, 'filename.m4a')).to eq 'file-audio-o' + it 'returns volume-up class with .m4a' do + expect(file_type_icon_class('file', 0, 'filename.m4a')).to eq 'volume-up' end - it 'returns file-audio-o class with .wav' do - expect(file_type_icon_class('file', 0, 'filename.wav')).to eq 'file-audio-o' + it 'returns volume-up class with .wav' do + expect(file_type_icon_class('file', 0, 'filename.wav')).to eq 'volume-up' end - it 'returns file-video-o class with .avi' do - expect(file_type_icon_class('file', 0, 'filename.avi')).to eq 'file-video-o' + it 'returns live-preview class with .avi' do + expect(file_type_icon_class('file', 0, 'filename.avi')).to eq 'live-preview' end - it 'returns file-video-o class with .AVI' do - expect(file_type_icon_class('file', 0, 'filename.AVI')).to eq 'file-video-o' + it 'returns live-preview class with .AVI' do + expect(file_type_icon_class('file', 0, 'filename.AVI')).to eq 'live-preview' end - it 'returns file-video-o class with .mp4' do - expect(file_type_icon_class('file', 0, 'filename.mp4')).to eq 'file-video-o' + it 'returns live-preview class with .mp4' do + expect(file_type_icon_class('file', 0, 'filename.mp4')).to eq 'live-preview' end - it 'returns file-word-o class with .odt' do - expect(file_type_icon_class('file', 0, 'filename.odt')).to eq 'file-word-o' + it 'returns doc-text class with .odt' do + expect(file_type_icon_class('file', 0, 'filename.odt')).to eq 'doc-text' end - it 'returns file-word-o class with .doc' do - expect(file_type_icon_class('file', 0, 'filename.doc')).to eq 'file-word-o' + it 'returns doc-text class with .doc' do + expect(file_type_icon_class('file', 0, 'filename.doc')).to eq 'doc-text' end - it 'returns file-word-o class with .DOC' do - expect(file_type_icon_class('file', 0, 'filename.DOC')).to eq 'file-word-o' + it 'returns doc-text class with .DOC' do + expect(file_type_icon_class('file', 0, 'filename.DOC')).to eq 'doc-text' end - it 'returns file-word-o class with .docx' do - expect(file_type_icon_class('file', 0, 'filename.docx')).to eq 'file-word-o' + it 'returns doc-text class with .docx' do + expect(file_type_icon_class('file', 0, 'filename.docx')).to eq 'doc-text' end - it 'returns file-excel-o class with .xls' do - expect(file_type_icon_class('file', 0, 'filename.xls')).to eq 'file-excel-o' + it 'returns document class with .xls' do + expect(file_type_icon_class('file', 0, 'filename.xls')).to eq 'document' end - it 'returns file-excel-o class with .XLS' do - expect(file_type_icon_class('file', 0, 'filename.XLS')).to eq 'file-excel-o' + it 'returns document class with .XLS' do + expect(file_type_icon_class('file', 0, 'filename.XLS')).to eq 'document' end - it 'returns file-excel-o class with .xlsx' do - expect(file_type_icon_class('file', 0, 'filename.xlsx')).to eq 'file-excel-o' + it 'returns document class with .xlsx' do + expect(file_type_icon_class('file', 0, 'filename.xlsx')).to eq 'document' end - it 'returns file-excel-o class with .odp' do - expect(file_type_icon_class('file', 0, 'filename.odp')).to eq 'file-powerpoint-o' + it 'returns doc-chart class with .odp' do + expect(file_type_icon_class('file', 0, 'filename.odp')).to eq 'doc-chart' end - it 'returns file-excel-o class with .ppt' do - expect(file_type_icon_class('file', 0, 'filename.ppt')).to eq 'file-powerpoint-o' + it 'returns doc-chart class with .ppt' do + expect(file_type_icon_class('file', 0, 'filename.ppt')).to eq 'doc-chart' end - it 'returns file-excel-o class with .PPT' do - expect(file_type_icon_class('file', 0, 'filename.PPT')).to eq 'file-powerpoint-o' + it 'returns doc-chart class with .PPT' do + expect(file_type_icon_class('file', 0, 'filename.PPT')).to eq 'doc-chart' end - it 'returns file-excel-o class with .pptx' do - expect(file_type_icon_class('file', 0, 'filename.pptx')).to eq 'file-powerpoint-o' + it 'returns doc-chart class with .pptx' do + expect(file_type_icon_class('file', 0, 'filename.pptx')).to eq 'doc-chart' end - it 'returns file-text-o class with .unknow' do - expect(file_type_icon_class('file', 0, 'filename.unknow')).to eq 'file-text-o' + it 'returns doc-text class with .unknow' do + expect(file_type_icon_class('file', 0, 'filename.unknow')).to eq 'doc-text' end - it 'returns file-text-o class with no extension' do - expect(file_type_icon_class('file', 0, 'CHANGELOG')).to eq 'file-text-o' + it 'returns doc-text class with no extension' do + expect(file_type_icon_class('file', 0, 'CHANGELOG')).to eq 'doc-text' end end diff --git a/spec/helpers/invite_members_helper_spec.rb b/spec/helpers/invite_members_helper_spec.rb new file mode 100644 index 00000000000..b4e05d67553 --- /dev/null +++ b/spec/helpers/invite_members_helper_spec.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe InviteMembersHelper do + let_it_be(:project) { create(:project) } + let_it_be(:developer) { create(:user, developer_projects: [project]) } + let(:owner) { project.owner } + + 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 + + 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 + + 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 + + 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 false + 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 + + 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 + + context 'when a 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_b) { true } + + expect(helper.indirectly_invite_members?).to eq false + end + end + end +end diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 89a2a92ea57..e8e5adaa274 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -44,23 +44,6 @@ RSpec.describe IssuablesHelper do end end - describe '#issuable_labels_tooltip' do - let(:label_entity) { LabelEntity.represent(label).as_json } - let(:label2_entity) { LabelEntity.represent(label2).as_json } - - it 'returns label text with no labels' do - expect(issuable_labels_tooltip([])).to eq(_('Labels')) - end - - it 'returns label text with labels within max limit' do - expect(issuable_labels_tooltip([label_entity])).to eq(label[:title]) - end - - it 'returns label text with labels exceeding max limit' do - expect(issuable_labels_tooltip([label_entity, label2_entity], limit: 1)).to eq("#{label[:title]}, and 1 more") - end - end - describe '#issuables_state_counter_text' do let(:user) { create(:user) } @@ -306,6 +289,38 @@ RSpec.describe IssuablesHelper do end end + describe '#reviewer_sidebar_data' do + let(:user) { create(:user) } + + subject { helper.reviewer_sidebar_data(user, merge_request: merge_request) } + + context 'without merge_request' do + let(:merge_request) { nil } + + it 'returns hash of reviewer data' do + is_expected.to eql({ + avatar_url: user.avatar_url, + name: user.name, + username: user.username + }) + end + end + + context 'with merge_request' do + let(:merge_request) { build(:merge_request) } + + where(can_merge: [true, false]) + + with_them do + before do + allow(merge_request).to receive(:can_be_merged_by?).and_return(can_merge) + end + + it { is_expected.to include({ can_merge: can_merge })} + end + end + end + describe '#issuable_squash_option?' do using RSpec::Parameterized::TableSyntax @@ -337,4 +352,35 @@ RSpec.describe IssuablesHelper do expect(helper.sidebar_milestone_tooltip_label(milestone)).to eq('<img onerror=alert(1)>
Milestone') 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 + + helper.serialize_issuable(merge_request, serializer: 'widget') + end + + it 'suggest_pipeline experiment disabled' do + allow(helper).to receive(:experiment_enabled?).with(:suggest_pipeline) { false } + + expect_next_instance_of(MergeRequestSerializer) do |serializer| + expect(serializer).to receive(:represent).with(merge_request, { serializer: 'widget' }) + end + + helper.serialize_issuable(merge_request, serializer: 'widget') + end + end + end end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 3f84eeb12c2..1ed61bd3144 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -233,4 +233,25 @@ RSpec.describe IssuesHelper do expect(helper.show_moved_service_desk_issue_warning?(new_issue)).to be(false) end end + + describe '#use_startup_call' do + it "returns false when a query param is present" do + allow(controller.request).to receive(:query_parameters).and_return({ foo: 'bar' }) + + expect(helper.use_startup_call?).to eq(false) + end + + it "returns false when user has stored sort preference" do + controller.instance_variable_set(:@sort, 'updated_asc') + + expect(helper.use_startup_call?).to eq(false) + end + + it 'returns true when request.query_parameters is empty with default sorting preference' do + controller.instance_variable_set(:@sort, 'created_date') + allow(controller.request).to receive(:query_parameters).and_return({}) + + expect(helper.use_startup_call?).to eq(true) + end + end end diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb index 77e1d10354c..b93dc03e434 100644 --- a/spec/helpers/labels_helper_spec.rb +++ b/spec/helpers/labels_helper_spec.rb @@ -244,26 +244,6 @@ RSpec.describe LabelsHelper do end end - describe 'label_from_hash' do - it 'builds a group label with whitelisted attributes' do - label = label_from_hash({ title: 'foo', color: 'bar', id: 1, group_id: 1 }) - - expect(label).to be_a(GroupLabel) - expect(label.id).to be_nil - expect(label.title).to eq('foo') - expect(label.color).to eq('bar') - end - - it 'builds a project label with whitelisted attributes' do - label = label_from_hash({ title: 'foo', color: 'bar', id: 1, project_id: 1 }) - - expect(label).to be_a(ProjectLabel) - expect(label.id).to be_nil - expect(label.title).to eq('foo') - expect(label.color).to eq('bar') - end - end - describe '#label_status_tooltip' do let(:status) { 'unsubscribed'.inquiry } @@ -291,4 +271,34 @@ RSpec.describe LabelsHelper do expect(tooltip).to eq('This is an image') end end + + describe '#show_labels_full_path?' do + let_it_be(:group) { create(:group) } + let_it_be(:subgroup) { create(:group, parent: group) } + let_it_be(:project) { create(:project, group: group) } + + context 'within a project' do + it 'returns truthy' do + expect(show_labels_full_path?(project, nil)).to be_truthy + end + end + + context 'within a subgroup' do + it 'returns truthy' do + expect(show_labels_full_path?(nil, subgroup)).to be_truthy + end + end + + context 'within a group' do + it 'returns falsey' do + expect(show_labels_full_path?(nil, group)).to be_falsey + end + end + + context 'within the admin area' do + it 'returns falsey' do + expect(show_labels_full_path?(nil, nil)).to be_falsey + end + end + end end diff --git a/spec/helpers/notes_helper_spec.rb b/spec/helpers/notes_helper_spec.rb index 41511b65cc4..f9b3b535334 100644 --- a/spec/helpers/notes_helper_spec.rb +++ b/spec/helpers/notes_helper_spec.rb @@ -5,19 +5,19 @@ require "spec_helper" RSpec.describe NotesHelper do include RepoHelpers - let(:owner) { create(:owner) } - let(:group) { create(:group) } - let(:project) { create(:project, namespace: group) } - let(:maintainer) { create(:user) } - let(:reporter) { create(:user) } - let(:guest) { create(:user) } - - let(:owner_note) { create(:note, author: owner, project: project) } - let(:maintainer_note) { create(:note, author: maintainer, project: project) } - let(:reporter_note) { create(:note, author: reporter, project: project) } + let_it_be(:owner) { create(:owner) } + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, namespace: group) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:reporter) { create(:user) } + let_it_be(:guest) { create(:user) } + + let_it_be(:owner_note) { create(:note, author: owner, project: project) } + let_it_be(:maintainer_note) { create(:note, author: maintainer, project: project) } + let_it_be(:reporter_note) { create(:note, author: reporter, project: project) } let!(:notes) { [owner_note, maintainer_note, reporter_note] } - before do + before_all do group.add_owner(owner) project.add_maintainer(maintainer) project.add_reporter(reporter) @@ -72,14 +72,14 @@ RSpec.describe NotesHelper do end describe '#discussion_path' do - let(:project) { create(:project, :repository) } + let_it_be(:project) { create(:project, :repository) } let(:anchor) { discussion.line_code } context 'for a merge request discusion' do - let(:merge_request) { create(:merge_request, source_project: project, target_project: project, importing: true) } - let!(:merge_request_diff1) { merge_request.merge_request_diffs.create!(head_commit_sha: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') } - let!(:merge_request_diff2) { merge_request.merge_request_diffs.create!(head_commit_sha: nil) } - let!(:merge_request_diff3) { merge_request.merge_request_diffs.create!(head_commit_sha: '5937ac0a7beb003549fc5fd26fc247adbce4a52e') } + let_it_be(:merge_request) { create(:merge_request, source_project: project, target_project: project, importing: true) } + let_it_be(:merge_request_diff1) { merge_request.merge_request_diffs.create!(head_commit_sha: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') } + let_it_be(:merge_request_diff2) { merge_request.merge_request_diffs.create!(head_commit_sha: nil) } + let_it_be(:merge_request_diff3) { merge_request.merge_request_diffs.create!(head_commit_sha: '5937ac0a7beb003549fc5fd26fc247adbce4a52e') } context 'for a diff discussion' do context 'when the discussion is active' do @@ -229,20 +229,18 @@ RSpec.describe NotesHelper do end it 'return project notes path for project snippet' do - namespace = create(:namespace, path: 'nm') - @project = create(:project, path: 'test', namespace: namespace) + @project = project @snippet = create(:project_snippet, project: @project) @noteable = @snippet - expect(helper.notes_url).to eq("/nm/test/noteable/project_snippet/#{@noteable.id}/notes") + expect(helper.notes_url).to eq("/#{project.full_path}/noteable/project_snippet/#{@noteable.id}/notes") end it 'return project notes path for other noteables' do - namespace = create(:namespace, path: 'nm') - @project = create(:project, path: 'test', namespace: namespace) + @project = project @noteable = create(:issue, project: @project) - expect(helper.notes_url).to eq("/nm/test/noteable/issue/#{@noteable.id}/notes") + expect(helper.notes_url).to eq("/#{@project.full_path}/noteable/issue/#{@noteable.id}/notes") end end @@ -254,19 +252,17 @@ RSpec.describe NotesHelper do end it 'return project notes path for project snippet' do - namespace = create(:namespace, path: 'nm') - @project = create(:project, path: 'test', namespace: namespace) + @project = project note = create(:note_on_project_snippet, project: @project) - expect(helper.note_url(note)).to eq("/nm/test/notes/#{note.id}") + expect(helper.note_url(note)).to eq("/#{project.full_path}/notes/#{note.id}") end it 'return project notes path for other noteables' do - namespace = create(:namespace, path: 'nm') - @project = create(:project, path: 'test', namespace: namespace) + @project = project note = create(:note_on_issue, project: @project) - expect(helper.note_url(note)).to eq("/nm/test/notes/#{note.id}") + expect(helper.note_url(note)).to eq("/#{project.full_path}/notes/#{note.id}") end end @@ -279,8 +275,7 @@ RSpec.describe NotesHelper do end it 'returns namespace, project and note for project snippet' do - namespace = create(:namespace, path: 'nm') - @project = create(:project, path: 'test', namespace: namespace) + @project = project @snippet = create(:project_snippet, project: @project) @note = create(:note_on_personal_snippet) @@ -288,8 +283,7 @@ RSpec.describe NotesHelper do end it 'returns namespace, project and note path for other noteables' do - namespace = create(:namespace, path: 'nm') - @project = create(:project, path: 'test', namespace: namespace) + @project = project @note = create(:note_on_issue, project: @project) expect(helper.form_resources).to eq([@project, @note]) @@ -297,7 +291,6 @@ RSpec.describe NotesHelper do end describe '#noteable_note_url' do - let(:project) { create(:project) } let(:issue) { create(:issue, project: project) } let(:note) { create(:note_on_issue, noteable: issue, project: project) } diff --git a/spec/helpers/operations_helper_spec.rb b/spec/helpers/operations_helper_spec.rb index 3dac2cf54dc..8d2fc643caa 100644 --- a/spec/helpers/operations_helper_spec.rb +++ b/spec/helpers/operations_helper_spec.rb @@ -35,7 +35,7 @@ RSpec.describe OperationsHelper do 'url' => alerts_service.url, 'authorization_key' => nil, 'form_path' => project_service_path(project, alerts_service), - 'alerts_setup_url' => help_page_path('user/project/integrations/generic_alerts.md', anchor: 'setting-up-generic-alerts'), + 'alerts_setup_url' => help_page_path('operations/incident_management/alert_integrations.md', anchor: 'generic-http-endpoint'), 'alerts_usage_url' => project_alert_management_index_path(project), 'prometheus_form_path' => project_service_path(project, prometheus_service), 'prometheus_reset_key_path' => reset_alerting_token_project_settings_operations_path(project), @@ -145,7 +145,7 @@ RSpec.describe OperationsHelper do subject { helper.operations_settings_data } it 'returns the correct set of data' do - is_expected.to eq( + is_expected.to include( operations_settings_endpoint: project_settings_operations_path(project), templates: '[]', create_issue: 'false', diff --git a/spec/helpers/packages_helper_spec.rb b/spec/helpers/packages_helper_spec.rb index 1917c851547..dacd386d01c 100644 --- a/spec/helpers/packages_helper_spec.rb +++ b/spec/helpers/packages_helper_spec.rb @@ -52,37 +52,14 @@ RSpec.describe PackagesHelper do end end - describe 'packages_coming_soon_enabled?' do - it 'returns false when the feature flag is disabled' do - stub_feature_flags(packages_coming_soon: false) + describe 'composer_config_repository_name' do + let(:host) { Gitlab.config.gitlab.host } + let(:group_id) { 1 } - expect(helper.packages_coming_soon_enabled?(project)).to eq(false) - end - - it 'returns false when not on dev or gitlab.com' do - expect(helper.packages_coming_soon_enabled?(project)).to eq(false) - end - end - - describe 'packages_coming_soon_data' do - let_it_be(:group) { create(:group) } - - before do - allow(Gitlab).to receive(:dev_env_or_com?) { true } - end - - it 'returns the gitlab project on gitlab.com' do - allow(Gitlab).to receive(:com?) { true } - - expect(helper.packages_coming_soon_data(project)).to include({ project_path: 'gitlab-org/gitlab' }) - end - - it 'returns the test project when not on gitlab.com' do - expect(helper.packages_coming_soon_data(project)).to include({ project_path: 'gitlab-org/gitlab-test' }) - end + it 'return global unique composer registry id' do + id = helper.composer_config_repository_name(group_id) - it 'works correctly with a group' do - expect(helper.packages_coming_soon_data(group)).to include({ project_path: 'gitlab-org/gitlab-test' }) + expect(id).to eq("#{host}/#{group_id}") end end end diff --git a/spec/helpers/projects/alert_management_helper_spec.rb b/spec/helpers/projects/alert_management_helper_spec.rb index 183f0438c35..83b89abde58 100644 --- a/spec/helpers/projects/alert_management_helper_spec.rb +++ b/spec/helpers/projects/alert_management_helper_spec.rb @@ -32,7 +32,9 @@ RSpec.describe Projects::AlertManagementHelper do 'populating-alerts-help-url' => 'http://test.host/help/operations/incident_management/index.md#enable-alert-management', 'empty-alert-svg-path' => match_asset_path('/assets/illustrations/alert-management-empty-state.svg'), 'user-can-enable-alert-management' => 'true', - 'alert-management-enabled' => 'false' + 'alert-management-enabled' => 'false', + 'text-query': nil, + 'assignee-username-query': nil ) end end diff --git a/spec/helpers/projects/incidents_helper_spec.rb b/spec/helpers/projects/incidents_helper_spec.rb index 0affa67a902..7a8a6d5222f 100644 --- a/spec/helpers/projects/incidents_helper_spec.rb +++ b/spec/helpers/projects/incidents_helper_spec.rb @@ -9,18 +9,28 @@ RSpec.describe Projects::IncidentsHelper do let(:project_path) { project.full_path } let(:new_issue_path) { new_project_issue_path(project) } let(:issue_path) { project_issues_path(project) } + let(:params) do + { + search: 'search text', + author_username: 'root', + assignee_username: 'max.power' + } + end describe '#incidents_data' do - subject(:data) { helper.incidents_data(project) } + subject(:data) { helper.incidents_data(project, params) } it 'returns frontend configuration' do - expect(data).to match( + expect(data).to include( 'project-path' => project_path, 'new-issue-path' => new_issue_path, 'incident-template-name' => 'incident', 'incident-type' => 'incident', 'issue-path' => issue_path, - 'empty-list-svg-path' => match_asset_path('/assets/illustrations/incident-empty-state.svg') + 'empty-list-svg-path' => match_asset_path('/assets/illustrations/incident-empty-state.svg'), + 'text-query': 'search text', + 'author-username-query': 'root', + 'assignee-username-query': 'max.power' ) end end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 2b345ff3ae6..f081cf225b1 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -5,16 +5,15 @@ require 'spec_helper' RSpec.describe ProjectsHelper do include ProjectForksHelper - let_it_be(:project) { create(:project) } + let_it_be_with_reload(:project) { create(:project) } + let_it_be_with_refind(:project_with_repo) { create(:project, :repository) } let_it_be(:user) { create(:user) } - describe '#project_incident_management_setting' do - let(:project) { create(:project) } - - before do - helper.instance_variable_set(:@project, project) - end + before do + helper.instance_variable_set(:@project, project) + end + describe '#project_incident_management_setting' do context 'when incident_management_setting exists' do let(:project_incident_management_setting) do create(:project_incident_management_setting, project: project) @@ -40,20 +39,14 @@ RSpec.describe ProjectsHelper do end describe '#error_tracking_setting_project_json' do - let(:project) { create(:project) } - context 'error tracking setting does not exist' do - before do - helper.instance_variable_set(:@project, project) - end - it 'returns nil' do expect(helper.error_tracking_setting_project_json).to be_nil end end context 'error tracking setting exists' do - let!(:error_tracking_setting) { create(:project_error_tracking_setting, project: project) } + let_it_be(:error_tracking_setting) { create(:project_error_tracking_setting, project: project) } context 'api_url present' do let(:json) do @@ -65,24 +58,16 @@ RSpec.describe ProjectsHelper do }.to_json end - before do - helper.instance_variable_set(:@project, project) - end - it 'returns error tracking json' do expect(helper.error_tracking_setting_project_json).to eq(json) end end context 'api_url not present' do - before do + it 'returns nil' do project.error_tracking_setting.api_url = nil project.error_tracking_setting.enabled = false - helper.instance_variable_set(:@project, project) - end - - it 'returns nil' do expect(helper.error_tracking_setting_project_json).to be_nil end end @@ -98,8 +83,7 @@ RSpec.describe ProjectsHelper do end describe "can_change_visibility_level?" do - let(:project) { create(:project) } - let(:user) { create(:project_member, :reporter, user: create(:user), project: project).user } + let_it_be(:user) { create(:project_member, :reporter, user: create(:user), project: project).user } let(:forked_project) { fork_project(project, user) } it "returns false if there are no appropriate permissions" do @@ -142,8 +126,7 @@ RSpec.describe ProjectsHelper do end describe '#can_disable_emails?' do - let(:project) { create(:project) } - let(:user) { create(:project_member, :maintainer, user: create(:user), project: project).user } + let_it_be(:user) { create(:project_member, :maintainer, user: create(:user), project: project).user } it 'returns true for the project owner' do allow(helper).to receive(:can?).with(project.owner, :set_emails_disabled, project) { true } @@ -166,11 +149,7 @@ RSpec.describe ProjectsHelper do end describe "readme_cache_key" do - let(:project) { create(:project, :repository) } - - before do - helper.instance_variable_set(:@project, project) - end + let(:project) { project_with_repo } it "returns a valid cach key" do expect(helper.send(:readme_cache_key)).to eq("#{project.full_path}-#{project.commit.id}-readme") @@ -184,8 +163,7 @@ RSpec.describe ProjectsHelper do end describe "#project_list_cache_key", :clean_gitlab_redis_shared_state do - let(:project) { create(:project, :repository) } - let(:user) { create(:user) } + let(:project) { project_with_repo } before do allow(helper).to receive(:current_user).and_return(user) @@ -249,8 +227,6 @@ RSpec.describe ProjectsHelper do describe '#load_pipeline_status' do it 'loads the pipeline status in batch' do - project = build(:project) - helper.load_pipeline_status([project]) # Skip lazy loading of the `pipeline_status` attribute pipeline_status = project.instance_variable_get('@pipeline_status') @@ -260,8 +236,6 @@ RSpec.describe ProjectsHelper do end describe '#show_no_ssh_key_message?' do - let(:user) { create(:user) } - before do allow(helper).to receive(:current_user).and_return(user) end @@ -282,8 +256,6 @@ RSpec.describe ProjectsHelper do end describe '#show_no_password_message?' do - let(:user) { create(:user) } - before do allow(helper).to receive(:current_user).and_return(user) end @@ -424,7 +396,6 @@ RSpec.describe ProjectsHelper do before do allow(helper).to receive(:current_user).and_return(user) - helper.instance_variable_set(:@project, project) end context 'when there is no current_user' do @@ -444,9 +415,6 @@ RSpec.describe ProjectsHelper do end describe '#get_project_nav_tabs' do - let_it_be(:user) { create(:user) } - let(:project) { create(:project) } - before do allow(helper).to receive(:can?) { true } end @@ -524,7 +492,14 @@ RSpec.describe ProjectsHelper do subject { helper.send(:can_view_operations_tab?, user, project) } - [:read_environment, :read_cluster, :metrics_dashboard].each do |ability| + [ + :metrics_dashboard, + :read_alert_management_alert, + :read_environment, + :read_issue, + :read_sentry_issue, + :read_cluster + ].each do |ability| it 'includes operations tab' do allow(helper).to receive(:can?).and_return(false) allow(helper).to receive(:can?).with(user, ability, project).and_return(true) @@ -536,7 +511,6 @@ RSpec.describe ProjectsHelper do describe '#show_projects' do let(:projects) do - create(:project) Project.all end @@ -561,8 +535,8 @@ RSpec.describe ProjectsHelper do end end - describe('#push_to_create_project_command') do - let(:user) { create(:user, username: 'john') } + describe '#push_to_create_project_command' do + let(:user) { build_stubbed(:user, username: 'john') } it 'returns the command to push to create project over HTTP' do allow(Gitlab::CurrentSettings.current_application_settings).to receive(:enabled_git_access_protocol) { 'http' } @@ -578,8 +552,6 @@ RSpec.describe ProjectsHelper do end describe '#any_projects?' do - let!(:project) { create(:project) } - it 'returns true when projects will be returned' do expect(helper.any_projects?(Project.all)).to eq(true) end @@ -609,7 +581,7 @@ RSpec.describe ProjectsHelper do end describe '#git_user_name' do - let(:user) { double(:user, name: 'John "A" Doe53') } + let(:user) { build_stubbed(:user, name: 'John "A" Doe53') } before do allow(helper).to receive(:current_user).and_return(user) @@ -632,8 +604,6 @@ RSpec.describe ProjectsHelper do end context 'user logged in' do - let(:user) { create(:user) } - before do allow(helper).to receive(:current_user).and_return(user) end @@ -658,7 +628,6 @@ RSpec.describe ProjectsHelper do end describe 'show_xcode_link' do - let!(:project) { create(:project) } let(:mac_ua) { 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36' } let(:ios_ua) { 'Mozilla/5.0 (iPad; CPU OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3' } @@ -799,7 +768,7 @@ RSpec.describe ProjectsHelper do describe '#show_auto_devops_implicitly_enabled_banner?' do using RSpec::Parameterized::TableSyntax - let(:user) { create(:user) } + let_it_be_with_reload(:project_with_auto_devops) { create(:project, :repository, :auto_devops) } let(:feature_visibilities) do { @@ -873,9 +842,9 @@ RSpec.describe ProjectsHelper do with_them do let(:project) do if project_setting.nil? - create(:project, :repository) + project_with_repo else - create(:project, :repository, :auto_devops) + project_with_auto_devops end end @@ -896,14 +865,8 @@ RSpec.describe ProjectsHelper do end describe '#can_import_members?' do - let(:project) { create(:project) } - let(:user) { create(:user) } let(:owner) { project.owner } - before do - helper.instance_variable_set(:@project, project) - end - it 'returns false if user cannot admin_project_member' do allow(helper).to receive(:current_user) { user } expect(helper.can_import_members?).to eq false @@ -916,12 +879,6 @@ RSpec.describe ProjectsHelper do end describe '#metrics_external_dashboard_url' do - let(:project) { create(:project) } - - before do - helper.instance_variable_set(:@project, project) - end - context 'metrics_setting exists' do it 'returns external_dashboard_url' do metrics_setting = create(:project_metrics_setting, project: project) @@ -938,12 +895,6 @@ RSpec.describe ProjectsHelper do end describe '#grafana_integration_url' do - let(:project) { create(:project) } - - before do - helper.instance_variable_set(:@project, project) - end - subject { helper.grafana_integration_url } it { is_expected.to eq(nil) } @@ -956,12 +907,6 @@ RSpec.describe ProjectsHelper do end describe '#grafana_integration_token' do - let(:project) { create(:project) } - - before do - helper.instance_variable_set(:@project, project) - end - subject { helper.grafana_integration_masked_token } it { is_expected.to eq(nil) } @@ -974,12 +919,6 @@ RSpec.describe ProjectsHelper do end describe '#grafana_integration_enabled?' do - let(:project) { create(:project) } - - before do - helper.instance_variable_set(:@project, project) - end - subject { helper.grafana_integration_enabled? } it { is_expected.to eq(nil) } @@ -992,7 +931,6 @@ RSpec.describe ProjectsHelper do end describe '#project_license_name(project)', :request_store do - let_it_be(:project) { create(:project) } let_it_be(:repository) { project.repository } subject { project_license_name(project) } diff --git a/spec/helpers/releases_helper_spec.rb b/spec/helpers/releases_helper_spec.rb index f10a2ed8e60..704e8dc40cb 100644 --- a/spec/helpers/releases_helper_spec.rb +++ b/spec/helpers/releases_helper_spec.rb @@ -64,6 +64,7 @@ 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 + project_path tag_name markdown_preview_path markdown_docs_path @@ -80,6 +81,7 @@ 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 + project_path releases_page_path markdown_preview_path markdown_docs_path @@ -92,5 +94,15 @@ RSpec.describe ReleasesHelper do expect(helper.data_for_new_release_page.keys).to match_array(keys) end end + + describe '#data_for_show_page' do + it 'has the needed data to display the individual "release" page' do + keys = %i(project_id + project_path + tag_name) + + expect(helper.data_for_show_page.keys).to match_array(keys) + end + end end end diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index 594c5c11994..6fe071521cd 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -29,7 +29,7 @@ RSpec.describe SearchHelper do end it "includes Help sections" do - expect(search_autocomplete_opts("hel").size).to eq(9) + expect(search_autocomplete_opts("hel").size).to eq(8) end it "includes default sections" do @@ -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 first 5 of the users recent issues' do + it 'includes the users recently viewed issues' 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) @@ -81,13 +81,11 @@ RSpec.describe SearchHelper do issue1 = create(:issue, title: 'issue 1', project: project1) issue2 = create(:issue, title: 'issue 2', project: project2) - other_issues = create_list(:issue, 5) - - expect(recent_issues).to receive(:search).with('the search term').and_return(Issue.id_in_ordered([issue1.id, issue2.id, *other_issues.map(&:id)])) + expect(recent_issues).to receive(:search).with('the search term').and_return(Issue.id_in_ordered([issue1.id, issue2.id])) results = search_autocomplete_opts("the search term") - expect(results.count).to eq(5) + expect(results.count).to eq(2) expect(results[0]).to include({ category: 'Recent issues', @@ -106,7 +104,7 @@ RSpec.describe SearchHelper do }) end - it 'includes the first 5 of the users recent merge requests' do + it 'includes the users recently viewed merge requests' 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) @@ -114,13 +112,11 @@ RSpec.describe SearchHelper do merge_request1 = create(:merge_request, :unique_branches, title: 'Merge request 1', target_project: project1, source_project: project1) merge_request2 = create(:merge_request, :unique_branches, title: 'Merge request 2', target_project: project2, source_project: project2) - other_merge_requests = create_list(:merge_request, 5) - - expect(recent_merge_requests).to receive(:search).with('the search term').and_return(MergeRequest.id_in_ordered([merge_request1.id, merge_request2.id, *other_merge_requests.map(&:id)])) + expect(recent_merge_requests).to receive(:search).with('the search term').and_return(MergeRequest.id_in_ordered([merge_request1.id, merge_request2.id])) results = search_autocomplete_opts("the search term") - expect(results.count).to eq(5) + expect(results.count).to eq(2) expect(results[0]).to include({ category: 'Recent merge requests', @@ -357,14 +353,6 @@ RSpec.describe SearchHelper do describe '#show_user_search_tab?' do subject { show_user_search_tab? } - context 'when users_search feature is disabled' do - before do - stub_feature_flags(users_search: false) - end - - it { is_expected.to eq(false) } - end - context 'when project search' do before do @project = :some_project @@ -399,4 +387,94 @@ RSpec.describe SearchHelper do end end end + + describe '#repository_ref' do + let_it_be(:project) { create(:project, :repository) } + let(:params) { { repository_ref: 'the-repository-ref-param' } } + + subject { repository_ref(project) } + + it { is_expected.to eq('the-repository-ref-param') } + + context 'when the param :repository_ref is not set' do + let(:params) { { repository_ref: nil } } + + it { is_expected.to eq(project.default_branch) } + end + + context 'when the repository_ref param is a number' do + let(:params) { { repository_ref: 111111 } } + + it { is_expected.to eq('111111') } + end + end + + describe '#highlight_and_truncate_issue' do + let(:description) { 'hello world' } + let(:issue) { create(:issue, description: description) } + let(:user) { create(:user) } + + before do + allow(self).to receive(:current_user).and_return(user) + end + + subject { highlight_and_truncate_issue(issue, 'test', {}) } + + context 'when description is not present' do + let(:description) { nil } + + it 'does nothing' do + expect(self).not_to receive(:simple_search_highlight_and_truncate) + + subject + end + end + + context 'when description present' do + using RSpec::Parameterized::TableSyntax + + where(:description, :expected) do + 'test' | 'test' + 'this test should not be blue' | 'this test should not be blue' + '
Click Me test' | 'Click Me test' + ' test' | ' test' + 'Lorem test ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec.' | 'Lorem test ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Don...' + end + + with_them do + it 'sanitizes, truncates, and highlights the search term' do + expect(subject).to eq(expected) + end + end + end + end + + describe '#search_service' do + using RSpec::Parameterized::TableSyntax + + subject { search_service } + + before do + allow(self).to receive(:current_user).and_return(:the_current_user) + end + + where(:confidential, :expected) do + '0' | false + '1' | true + 'yes' | true + 'no' | false + true | true + false | false + end + + let(:params) {{ confidential: confidential }} + + with_them do + it 'transforms confidentiality param' do + expect(::SearchService).to receive(:new).with(:the_current_user, { confidential: expected }) + + subject + end + end + end end diff --git a/spec/helpers/snippets_helper_spec.rb b/spec/helpers/snippets_helper_spec.rb index a3244bec56f..5a3c8e37e8c 100644 --- a/spec/helpers/snippets_helper_spec.rb +++ b/spec/helpers/snippets_helper_spec.rb @@ -63,32 +63,6 @@ RSpec.describe SnippetsHelper do end end - describe '#snippet_embed_tag' do - subject { snippet_embed_tag(snippet) } - - context 'personal snippets' do - let(:snippet) { public_personal_snippet } - - context 'public' do - it 'returns a script tag with the snippet full url' do - expect(subject).to eq(script_embed("http://test.host/-/snippets/#{snippet.id}")) - end - end - end - - context 'project snippets' do - let(:snippet) { public_project_snippet } - - it 'returns a script tag with the snippet full url' do - expect(subject).to eq(script_embed("http://test.host/#{snippet.project.path_with_namespace}/-/snippets/#{snippet.id}")) - end - end - - def script_embed(url) - "" - end - end - describe '#download_raw_snippet_button' do subject { download_raw_snippet_button(snippet) } @@ -142,28 +116,4 @@ RSpec.describe SnippetsHelper do end end end - - describe '#snippet_embed_input' do - subject { snippet_embed_input(snippet) } - - context 'with PersonalSnippet' do - let(:snippet) { public_personal_snippet } - - it 'returns the input component' do - expect(subject).to eq embed_input(snippet_url(snippet)) - end - end - - context 'with ProjectSnippet' do - let(:snippet) { public_project_snippet } - - it 'returns the input component' do - expect(subject).to eq embed_input(project_snippet_url(snippet.project, snippet)) - end - end - - def embed_input(url) - "\" autocomplete=\"off\">" - end - end end diff --git a/spec/helpers/startupjs_helper_spec.rb b/spec/helpers/startupjs_helper_spec.rb new file mode 100644 index 00000000000..6d61c38d4a5 --- /dev/null +++ b/spec/helpers/startupjs_helper_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe StartupjsHelper do + describe '#page_startup_graphql_calls' do + let(:query_location) { 'repository/path_last_commit' } + let(:query_content) do + File.read(File.join(Rails.root, 'app/graphql/queries', "#{query_location}.query.graphql")) + end + + it 'returns an array containing GraphQL Page Startup Calls' do + helper.add_page_startup_graphql_call(query_location, { ref: 'foo' }) + + startup_graphql_calls = helper.page_startup_graphql_calls + + expect(startup_graphql_calls).to include({ query: query_content, variables: { ref: 'foo' } }) + end + end +end diff --git a/spec/helpers/tree_helper_spec.rb b/spec/helpers/tree_helper_spec.rb index 97b6802dde9..b5d356b985c 100644 --- a/spec/helpers/tree_helper_spec.rb +++ b/spec/helpers/tree_helper_spec.rb @@ -167,31 +167,60 @@ RSpec.describe TreeHelper do end end - describe '#vue_ide_link_data' do + describe '#web_ide_button_data' do + let(:blob) { project.repository.blob_at('refs/heads/master', @path) } + before do + @path = '' + @project = project + @ref = sha + allow(helper).to receive(:current_user).and_return(nil) allow(helper).to receive(:can_collaborate_with_project?).and_return(true) allow(helper).to receive(:can?).and_return(true) end - subject { helper.vue_ide_link_data(project, sha) } + subject { helper.web_ide_button_data(blob: blob) } it 'returns a list of attributes related to the project' do expect(subject).to include( - ide_base_path: project.full_path, + project_path: project.full_path, + ref: sha, + + is_fork: false, needs_to_fork: false, + gitpod_enabled: false, + is_blob: false, + + show_edit_button: false, show_web_ide_button: true, show_gitpod_button: false, - gitpod_url: "", - gitpod_enabled: nil + + edit_url: '', + web_ide_url: "/-/ide/project/#{project.full_path}/edit/#{sha}", + gitpod_url: '' ) end + context 'a blob is passed' do + before do + @path = 'README.md' + end + + it 'returns edit url and webide url for the blob' do + expect(subject).to include( + show_edit_button: true, + edit_url: "/#{project.full_path}/-/edit/#{sha}/#{@path}", + web_ide_url: "/-/ide/project/#{project.full_path}/edit/#{sha}/-/#{@path}" + ) + end + end + 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) } + let(:forked_project) { create(:project, :repository, namespace: user.namespace) } before do project.add_guest(user) @@ -200,9 +229,49 @@ RSpec.describe TreeHelper do allow(helper).to receive(:current_user).and_return(user) end - it 'includes ide_base_path: forked_project.full_path' do + it 'includes forked project path as project_path' do + expect(subject).to include( + project_path: forked_project.full_path, + is_fork: true, + needs_to_fork: false, + show_edit_button: false, + web_ide_url: "/-/ide/project/#{forked_project.full_path}/edit/#{sha}" + ) + end + + context 'a blob is passed' do + before do + @path = 'README.md' + end + + it 'returns edit url and web ide for the blob in the fork' do + expect(subject).to include( + is_blob: true, + show_edit_button: true, + # edit urls are automatically redirected to the fork + edit_url: "/#{project.full_path}/-/edit/#{sha}/#{@path}", + web_ide_url: "/-/ide/project/#{forked_project.full_path}/edit/#{sha}/-/#{@path}" + ) + end + end + end + + context 'for archived project' do + before do + allow(helper).to receive(:can_collaborate_with_project?).and_return(false) + allow(helper).to receive(:can?).and_return(false) + + project.update!(archived: true) + + @path = 'README.md' + end + + it 'does not show any buttons' do expect(subject).to include( - ide_base_path: forked_project.full_path + is_blob: true, + show_edit_button: false, + show_web_ide_button: false, + show_gitpod_button: false ) end end @@ -216,11 +285,32 @@ RSpec.describe TreeHelper do allow(helper).to receive(:current_user).and_return(user) end - it 'includes ide_base_path: project.full_path' do + it 'includes original project path as project_path' do expect(subject).to include( - ide_base_path: project.full_path + project_path: project.full_path, + + is_fork: false, + needs_to_fork: false, + + show_edit_button: false, + web_ide_url: "/-/ide/project/#{project.full_path}/edit/#{sha}" ) end + + context 'a blob is passed' do + before do + @path = 'README.md' + end + + it 'returns edit url and web ide for the blob in the fork' do + expect(subject).to include( + is_blob: true, + show_edit_button: true, + edit_url: "/#{project.full_path}/-/edit/#{sha}/#{@path}", + web_ide_url: "/-/ide/project/#{project.full_path}/edit/#{sha}/-/#{@path}" + ) + end + end end context 'gitpod feature is enabled' do diff --git a/spec/helpers/user_callouts_helper_spec.rb b/spec/helpers/user_callouts_helper_spec.rb index a42be3c87fb..bcb0b5c51e7 100644 --- a/spec/helpers/user_callouts_helper_spec.rb +++ b/spec/helpers/user_callouts_helper_spec.rb @@ -139,4 +139,26 @@ RSpec.describe UserCalloutsHelper do helper.render_flash_user_callout(:warning, 'foo', 'bar') end end + + describe '.show_feature_flags_new_version?' do + subject { helper.show_feature_flags_new_version? } + + let(:user) { create(:user) } + + before do + allow(helper).to receive(:current_user).and_return(user) + end + + context 'when the feature flags new version info has not been dismissed' do + it { is_expected.to be_truthy } + end + + context 'when the feature flags new version has been dismissed' do + before do + create(:user_callout, user: user, feature_name: described_class::FEATURE_FLAGS_NEW_VERSION) + end + + it { is_expected.to be_falsy } + end + end end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 8dfdb23c64b..c9dc3fcff3f 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -126,6 +126,16 @@ RSpec.describe UsersHelper do end end + context 'with a pending approval user' do + it 'returns the pending approval badge' do + blocked_pending_approval_user = create(:user, :blocked_pending_approval) + + badges = helper.user_badges_in_admin_section(blocked_pending_approval_user) + + expect(filter_ee_badges(badges)).to eq([text: 'Pending approval', variant: 'info']) + end + end + context 'with an admin user' do it "returns the admin badge" do admin_user = create(:admin) @@ -179,6 +189,20 @@ RSpec.describe UsersHelper do end end + describe '#can_force_email_confirmation?' do + subject { helper.can_force_email_confirmation?(user) } + + context 'for a user that is already confirmed' do + it { is_expected.to eq(false) } + end + + context 'for a user that is not confirmed' do + let(:user) { create(:user, :unconfirmed) } + + it { is_expected.to eq(true) } + end + end + describe '#work_information' do subject { helper.work_information(user) } diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb index 7ef911131ba..cd1fc70bbc1 100644 --- a/spec/helpers/visibility_level_helper_spec.rb +++ b/spec/helpers/visibility_level_helper_spec.rb @@ -47,13 +47,6 @@ RSpec.describe VisibilityLevelHelper do .to match /group/i end end - - context 'called with a Snippet' do - it 'delegates snippets to #snippet_visibility_level_description' do - expect(visibility_level_description(Gitlab::VisibilityLevel::INTERNAL, project_snippet)) - .to match /snippet/i - end - end end describe "#project_visibility_level_description" do @@ -68,23 +61,6 @@ RSpec.describe VisibilityLevelHelper do end end - describe "#snippet_visibility_level_description" do - it 'describes visibility only for me' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, personal_snippet)) - .to eq _('The snippet is visible only to me.') - end - - it 'describes visibility for project members' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, project_snippet)) - .to eq _('The snippet is visible only to project members.') - end - - it 'defaults to personal snippet' do - expect(snippet_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE)) - .to eq _('The snippet is visible only to me.') - end - end - describe "disallowed_visibility_level?" do describe "forks" do let(:project) { create(:project, :internal) } diff --git a/spec/helpers/whats_new_helper_spec.rb b/spec/helpers/whats_new_helper_spec.rb index db880163454..80d4ca8ddea 100644 --- a/spec/helpers/whats_new_helper_spec.rb +++ b/spec/helpers/whats_new_helper_spec.rb @@ -3,20 +3,49 @@ require 'spec_helper' RSpec.describe WhatsNewHelper do - describe '#whats_new_most_recent_release_items' 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 } - it 'returns json from the most recent file' do - allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob) + before do + allow(helper).to receive(:whats_new_most_recent_version).and_return(version) + end + + context 'when version exist' do + let(:version) { '84.0' } + + it { is_expected.to eq('display-whats-new-notification-84.0') } + end + + context 'when recent release items do NOT exist' do + let(:version) { nil } + + it { is_expected.to be_nil } + end + end + + describe '#whats_new_most_recent_release_items_count' do + subject { helper.whats_new_most_recent_release_items_count } - expect(helper.whats_new_most_recent_release_items).to include({ title: "bright and sunshinin' day" }.to_json) + 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) + + expect(subject).to eq(1) + end end - it 'fails gracefully and logs an error' do - allow(YAML).to receive(:load_file).and_raise + context 'when recent release items do NOT exist' do + before do + allow(YAML).to receive(:safe_load).and_raise + + expect(Gitlab::ErrorTracking).to receive(:track_exception) + end - expect(Gitlab::ErrorTracking).to receive(:track_exception) - expect(helper.whats_new_most_recent_release_items).to eq(''.to_json) + it 'fails gracefully and logs an error' do + expect(subject).to be_nil + end end end end diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb index 65a52412f8c..45e1859893f 100644 --- a/spec/helpers/wiki_helper_spec.rb +++ b/spec/helpers/wiki_helper_spec.rb @@ -54,14 +54,18 @@ RSpec.describe WikiHelper do end describe '#wiki_attachment_upload_url' do - it 'returns the upload endpoint for project wikis' do - @wiki = build_stubbed(:project_wiki) + let_it_be(:wiki) { build_stubbed(:project_wiki) } + + before do + @wiki = wiki + end + it 'returns the upload endpoint for project wikis' do expect(helper.wiki_attachment_upload_url).to end_with("/api/v4/projects/#{@wiki.project.id}/wikis/attachments") end it 'raises an exception for unsupported wiki containers' do - @wiki = Wiki.new(User.new) + allow(wiki).to receive(:container).and_return(User.new) expect do helper.wiki_attachment_upload_url @@ -131,7 +135,8 @@ RSpec.describe WikiHelper do 'wiki-format' => :markdown, 'wiki-title-size' => 9, 'wiki-content-size' => 4, - 'wiki-directory-nest-level' => 2 + 'wiki-directory-nest-level' => 2, + 'wiki-container-type' => 'Project' ) end -- cgit v1.2.3