diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
commit | b76ae638462ab0f673e5915986070518dd3f9ad3 (patch) | |
tree | bdab0533383b52873be0ec0eb4d3c66598ff8b91 /spec/helpers | |
parent | 434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff) |
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'spec/helpers')
22 files changed, 370 insertions, 398 deletions
diff --git a/spec/helpers/admin/user_actions_helper_spec.rb b/spec/helpers/admin/user_actions_helper_spec.rb index d945b13cad6..3bc380fbc99 100644 --- a/spec/helpers/admin/user_actions_helper_spec.rb +++ b/spec/helpers/admin/user_actions_helper_spec.rb @@ -106,7 +106,7 @@ RSpec.describe Admin::UserActionsHelper do group.add_owner(user) end - it { is_expected.to contain_exactly("edit", "block", "ban", "deactivate") } + it { is_expected.to contain_exactly("edit", "block", "ban", "deactivate", "delete_with_contributions") } end context 'the user is a bot' do diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index bf533ca7034..7e3f665a99c 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -472,4 +472,23 @@ RSpec.describe ApplicationHelper do allow(helper.controller).to receive(method_name).and_return(value) end end + + describe '#gitlab_ui_form_for' do + let_it_be(:user) { build(:user) } + + before do + allow(helper).to receive(:users_path).and_return('/root') + allow(helper).to receive(:form_for).and_call_original + end + + it 'adds custom form builder to options and calls `form_for`' do + options = { html: { class: 'foo-bar' } } + expected_options = options.merge({ builder: ::Gitlab::FormBuilders::GitlabUiFormBuilder, url: '/root' }) + + expect do |b| + helper.gitlab_ui_form_for(user, options, &b) + end.to yield_with_args(::Gitlab::FormBuilders::GitlabUiFormBuilder) + expect(helper).to have_received(:form_for).with(user, expected_options) + end + end end diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb index 90bfb2e72e6..6d51d85fd64 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -238,7 +238,7 @@ RSpec.describe ApplicationSettingsHelper do expect(helper.kroki_available_formats).to eq([ { name: 'kroki_formats_blockdiag', - label: 'BlockDiag (includes BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag and RackDiag)', + label: 'BlockDiag (includes BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag, and RackDiag)', value: true }, { @@ -254,4 +254,34 @@ RSpec.describe ApplicationSettingsHelper do ]) end end + + describe '.pending_user_count' do + let(:user_cap) { 200 } + + before do + stub_application_setting(new_user_signups_cap: user_cap) + end + + subject(:pending_user_count) { helper.pending_user_count } + + context 'when new_user_signups_cap is present' do + it 'returns the number of blocked pending users' do + create(:user, state: :blocked_pending_approval) + + expect(pending_user_count).to eq 1 + end + end + + context 'when the new_user_signups_cap is not present' do + let(:user_cap) { nil } + + it { is_expected.to eq 0 } + + it 'does not query users unnecessarily' do + expect(User).not_to receive(:blocked_pending_approval) + + pending_user_count + end + end + end end diff --git a/spec/helpers/button_helper_spec.rb b/spec/helpers/button_helper_spec.rb index 09495bbde35..5601ab2df2a 100644 --- a/spec/helpers/button_helper_spec.rb +++ b/spec/helpers/button_helper_spec.rb @@ -174,7 +174,7 @@ RSpec.describe ButtonHelper do expect(element.attr('itemprop')).to eq(nil) expect(element.inner_text).to eq("") - expect(element.to_html).to include sprite_icon('copy-to-clipboard') + expect(element.to_html).to include sprite_icon('copy-to-clipboard', css_class: 'gl-icon') end end @@ -195,6 +195,10 @@ RSpec.describe ButtonHelper do it 'shows copy to clipboard button with provided `button_text` as button label' do expect(element(button_text: 'Copy text').inner_text).to eq('Copy text') end + + it 'adds `gl-button-icon` class to icon' do + expect(element(button_text: 'Copy text')).to have_css('svg.gl-button-icon') + end end context 'with `hide_tooltip` attribute provided' do diff --git a/spec/helpers/ci/pipeline_editor_helper_spec.rb b/spec/helpers/ci/pipeline_editor_helper_spec.rb index 3ce4657282e..3183a0a2394 100644 --- a/spec/helpers/ci/pipeline_editor_helper_spec.rb +++ b/spec/helpers/ci/pipeline_editor_helper_spec.rb @@ -47,7 +47,7 @@ RSpec.describe Ci::PipelineEditorHelper do "empty-state-illustration-path" => 'foo', "initial-branch-name" => nil, "lint-help-page-path" => help_page_path('ci/lint', anchor: 'validate-basic-logic-and-syntax'), - "needs-help-page-path" => help_page_path('ci/yaml/README', anchor: 'needs'), + "needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'), "new-merge-request-path" => '/mock/project/-/merge_requests/new', "pipeline_etag" => graphql_etag_pipeline_sha_path(project.commit.sha), "pipeline-page-path" => project_pipelines_path(project), @@ -56,7 +56,7 @@ RSpec.describe Ci::PipelineEditorHelper do "project-namespace" => project.namespace.full_path, "runner-help-page-path" => help_page_path('ci/runners/index'), "total-branches" => project.repository.branches.length, - "yml-help-page-path" => help_page_path('ci/yaml/README') + "yml-help-page-path" => help_page_path('ci/yaml/index') }) end end @@ -74,7 +74,7 @@ RSpec.describe Ci::PipelineEditorHelper do "empty-state-illustration-path" => 'foo', "initial-branch-name" => nil, "lint-help-page-path" => help_page_path('ci/lint', anchor: 'validate-basic-logic-and-syntax'), - "needs-help-page-path" => help_page_path('ci/yaml/README', anchor: 'needs'), + "needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'), "new-merge-request-path" => '/mock/project/-/merge_requests/new', "pipeline_etag" => '', "pipeline-page-path" => project_pipelines_path(project), @@ -83,7 +83,7 @@ RSpec.describe Ci::PipelineEditorHelper do "project-namespace" => project.namespace.full_path, "runner-help-page-path" => help_page_path('ci/runners/index'), "total-branches" => 0, - "yml-help-page-path" => help_page_path('ci/yaml/README') + "yml-help-page-path" => help_page_path('ci/yaml/index') }) end end diff --git a/spec/helpers/clusters_helper_spec.rb b/spec/helpers/clusters_helper_spec.rb index f64afa1ed71..f1e19f17c72 100644 --- a/spec/helpers/clusters_helper_spec.rb +++ b/spec/helpers/clusters_helper_spec.rb @@ -82,6 +82,10 @@ RSpec.describe ClustersHelper do expect(subject[:get_started_docs_url]).to eq(help_page_path('user/clusters/agent/index', anchor: 'define-a-configuration-repository')) expect(subject[:integration_docs_url]).to eq(help_page_path('user/clusters/agent/index', anchor: 'get-started-with-gitops-and-the-gitlab-agent')) end + + it 'displays kas address' do + expect(subject[:kas_address]).to eq(Gitlab::Kas.external_url) + end end describe '#js_clusters_list_data' do diff --git a/spec/helpers/environment_helper_spec.rb b/spec/helpers/environment_helper_spec.rb index 8c542ca01f4..0eecae32cc1 100644 --- a/spec/helpers/environment_helper_spec.rb +++ b/spec/helpers/environment_helper_spec.rb @@ -22,4 +22,41 @@ RSpec.describe EnvironmentHelper do end end end + + describe '#environments_detail_data_json' do + subject { helper.environments_detail_data_json(user, project, environment) } + + let_it_be(:auto_stop_at) { Time.now.utc } + let_it_be(:user) { create(:user) } + let_it_be(:project, reload: true) { create(:project, :repository) } + let_it_be(:environment) { create(:environment, project: project, auto_stop_at: auto_stop_at) } + + before do + allow(helper).to receive(:current_user).and_return(user) + allow(helper).to receive(:can?).and_return(true) + end + + it 'returns the correct data' do + expect(subject).to eq({ + name: environment.name, + id: environment.id, + external_url: environment.external_url, + can_update_environment: true, + can_destroy_environment: true, + can_read_environment: true, + can_stop_environment: true, + can_admin_environment: true, + environment_metrics_path: environment_metrics_path(environment), + environments_fetch_path: project_environments_path(project, format: :json), + environment_edit_path: edit_project_environment_path(project, environment), + environment_stop_path: stop_project_environment_path(project, environment), + environment_delete_path: environment_delete_path(environment), + environment_cancel_auto_stop_path: cancel_auto_stop_project_environment_path(project, environment), + environment_terminal_path: terminal_project_environment_path(project, environment), + has_terminals: false, + is_environment_available: true, + auto_stop_at: auto_stop_at + }.to_json) + end + end end diff --git a/spec/helpers/environments_helper_spec.rb b/spec/helpers/environments_helper_spec.rb index 22867a5b652..60bed247d85 100644 --- a/spec/helpers/environments_helper_spec.rb +++ b/spec/helpers/environments_helper_spec.rb @@ -199,4 +199,13 @@ RSpec.describe EnvironmentsHelper do expect(helper.environment_logs_data(project, environment)).to eq(expected_data) end end + + describe '#environment_data' do + it 'returns the environment as JSON' do + expected_data = { id: environment.id, + name: environment.name, + external_url: environment.external_url }.to_json + expect(helper.environment_data(environment)).to eq(expected_data) + end + end end diff --git a/spec/helpers/groups/group_members_helper_spec.rb b/spec/helpers/groups/group_members_helper_spec.rb index b409bebaac3..f5bc587bce3 100644 --- a/spec/helpers/groups/group_members_helper_spec.rb +++ b/spec/helpers/groups/group_members_helper_spec.rb @@ -9,6 +9,7 @@ RSpec.describe Groups::GroupMembersHelper do let_it_be(:group) { create(:group) } before do + allow(helper).to receive(:can?).with(current_user, :export_group_memberships, group).and_return(false) 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 @@ -23,7 +24,7 @@ RSpec.describe Groups::GroupMembersHelper do end end - describe '#group_members_app_data_json' do + describe '#group_members_app_data' do include_context 'group_group_link' let(:members) { create_list(:group_member, 2, group: shared_group, created_by: current_user) } @@ -33,27 +34,26 @@ RSpec.describe Groups::GroupMembersHelper do let(:members_collection) { members } subject do - Gitlab::Json.parse( - helper.group_members_app_data_json( - shared_group, - members: present_members(members_collection), - invited: present_members(invited), - access_requests: present_members(access_requests) - ) + helper.group_members_app_data( + shared_group, + members: present_members(members_collection), + invited: present_members(invited), + access_requests: present_members(access_requests) ) end shared_examples 'members.json' do |member_type| it 'returns `members` property that matches json schema' do - expect(subject[member_type]['members'].to_json).to match_schema('members') + expect(subject[member_type.to_sym][:members].to_json).to match_schema('members') end it 'sets `member_path` property' do - expect(subject[member_type]['member_path']).to eq('/groups/foo-bar/-/group_members/:id') + expect(subject[member_type.to_sym][:member_path]).to eq('/groups/foo-bar/-/group_members/:id') end end before do + allow(helper).to receive(:can?).with(current_user, :export_group_memberships, shared_group).and_return(true) allow(helper).to receive(:group_group_member_path).with(shared_group, ':id').and_return('/groups/foo-bar/-/group_members/:id') allow(helper).to receive(:group_group_link_path).with(shared_group, ':id').and_return('/groups/foo-bar/-/group_links/:id') allow(helper).to receive(:can?).with(current_user, :admin_group_member, shared_group).and_return(true) @@ -63,7 +63,7 @@ RSpec.describe Groups::GroupMembersHelper do expected = { source_id: shared_group.id, can_manage_members: true - }.as_json + } expect(subject).to include(expected) end @@ -90,11 +90,11 @@ RSpec.describe Groups::GroupMembersHelper do context 'group links' do it 'sets `group.members` property that matches json schema' do - expect(subject['group']['members'].to_json).to match_schema('group_link/group_group_links') + expect(subject[:group][:members].to_json).to match_schema('group_link/group_group_links') end it 'sets `member_path` property' do - expect(subject['group']['member_path']).to eq('/groups/foo-bar/-/group_links/:id') + expect(subject[:group][:member_path]).to eq('/groups/foo-bar/-/group_links/:id') end end @@ -108,7 +108,7 @@ RSpec.describe Groups::GroupMembersHelper do params: {} }.as_json - expect(subject['access_request']['pagination']).to include(expected) + expect(subject[:access_request][:pagination].as_json).to include(expected) end end @@ -124,7 +124,7 @@ RSpec.describe Groups::GroupMembersHelper do params: { invited_members_page: nil, search_invited: nil } }.as_json - expect(subject['user']['pagination']).to include(expected) + expect(subject[:user][:pagination].as_json).to include(expected) end end end diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index ad6852f63df..42da1cb71f1 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -19,11 +19,15 @@ RSpec.describe GroupsHelper do end end - describe '#group_dependency_proxy_url' do + describe '#group_dependency_proxy_image_prefix' do + let_it_be(:group) { build_stubbed(:group, path: 'GroupWithUPPERcaseLetters') } + it 'converts uppercase letters to lowercase' do - group = build_stubbed(:group, path: 'GroupWithUPPERcaseLetters') + expect(group_dependency_proxy_image_prefix(group)).to end_with("/groupwithuppercaseletters#{DependencyProxy::URL_SUFFIX}") + end - expect(group_dependency_proxy_url(group)).to end_with("/groupwithuppercaseletters#{DependencyProxy::URL_SUFFIX}") + it 'removes the protocol' do + expect(group_dependency_proxy_image_prefix(group)).not_to include('http') end end @@ -263,42 +267,6 @@ RSpec.describe GroupsHelper do end end - describe '#group_container_registry_nav' do - let_it_be(:group) { create(:group, :public) } - let_it_be(:user) { create(:user) } - - before do - stub_container_registry_config(enabled: true) - allow(helper).to receive(:current_user) { user } - allow(helper).to receive(:can?).with(user, :read_container_image, group) { true } - helper.instance_variable_set(:@group, group) - end - - subject { helper.group_container_registry_nav? } - - context 'when container registry is enabled' do - it { is_expected.to be_truthy } - - it 'is disabled for guest' do - allow(helper).to receive(:can?).with(user, :read_container_image, group) { false } - expect(subject).to be false - end - end - - context 'when container registry is not enabled' do - before do - stub_container_registry_config(enabled: false) - end - - it { is_expected.to be_falsy } - - it 'is disabled for guests' do - allow(helper).to receive(:can?).with(user, :read_container_image, group) { false } - expect(subject).to be false - end - end - end - describe '#group_sidebar_links' do let_it_be(:group) { create(:group, :public) } let_it_be(:user) { create(:user) } @@ -313,15 +281,30 @@ RSpec.describe GroupsHelper do it 'returns all the expected links' do links = [ :overview, :activity, :issues, :labels, :milestones, :merge_requests, - :group_members, :settings + :runners, :group_members, :settings ] expect(helper.group_sidebar_links).to include(*links) end - it 'includes settings when the user can admin the group' do + it 'excludes runners when the user cannot admin the group' do + expect(helper).to receive(:current_user) { user } + # TODO Proper policies, such as `read_group_runners, should be implemented per + # See https://gitlab.com/gitlab-org/gitlab/-/issues/334802 + expect(helper).to receive(:can?).twice.with(user, :admin_group, group) { false } + + expect(helper.group_sidebar_links).not_to include(:runners) + end + + it 'excludes runners when the feature "runner_list_group_view_vue_ui" is disabled' do + stub_feature_flags(runner_list_group_view_vue_ui: false) + + expect(helper.group_sidebar_links).not_to include(:runners) + end + + it 'excludes settings when the user can admin the group' do expect(helper).to receive(:current_user) { user } - expect(helper).to receive(:can?).with(user, :admin_group, group) { false } + expect(helper).to receive(:can?).twice.with(user, :admin_group, group) { false } expect(helper.group_sidebar_links).not_to include(:settings) end @@ -540,22 +523,22 @@ RSpec.describe GroupsHelper do end end - describe '#cached_issuables_count' do - let_it_be(:current_user) { create(:user) } - let_it_be(:group) { create(:group, name: 'group') } - - context 'with issues type' do - let(:type) { :issues } - let(:count_service) { Groups::OpenIssuesCountService } + describe '#can_admin_group_member?' do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } - it_behaves_like 'cached issuables count' + before do + allow(helper).to receive(:current_user) { user } end - context 'with merge requests type' do - let(:type) { :merge_requests } - let(:count_service) { Groups::MergeRequestsCountService } + it 'returns true when current_user can admin members' do + group.add_owner(user) + + expect(helper.can_admin_group_member?(group)).to be(true) + end - it_behaves_like 'cached issuables count' + it 'returns false when current_user can not admin members' do + expect(helper.can_admin_group_member?(group)).to be(false) end end end diff --git a/spec/helpers/invite_members_helper_spec.rb b/spec/helpers/invite_members_helper_spec.rb index 3d2adaa5b5d..e0e05140d6c 100644 --- a/spec/helpers/invite_members_helper_spec.rb +++ b/spec/helpers/invite_members_helper_spec.rb @@ -14,102 +14,92 @@ RSpec.describe InviteMembersHelper do helper.extend(Gitlab::Experimentation::ControllerConcern) end - context 'with project' do - before do - allow(helper).to receive(:current_user) { owner } - assign(:project, project) - end - - describe "#can_invite_members_for_project?" do - context 'when the user can_manage_project_members' do + describe '#common_invite_modal_dataset' do + context 'when member_areas_of_focus is enabled', :experiment do + context 'with control experience' do before do - allow(helper).to receive(:can_manage_project_members?).and_return(true) + stub_experiments(member_areas_of_focus: :control) end - it 'returns true' do - expect(helper.can_invite_members_for_project?(project)).to eq true - expect(helper).to have_received(:can_manage_project_members?) - end + it 'has expected attributes' do + attributes = { + areas_of_focus_options: [], + no_selection_areas_of_focus: [] + } - context 'when feature flag is disabled' do - before do - stub_feature_flags(invite_members_group_modal: false) - end - - it 'returns false' do - expect(helper.can_invite_members_for_project?(project)).to eq false - expect(helper).not_to have_received(:can_manage_project_members?) - end + expect(helper.common_invite_modal_dataset(project)).to include(attributes) end end - context 'when the user can not manage project members' do + context 'with candidate experience' do before do - expect(helper).to receive(:can_manage_project_members?).and_return(false) + stub_experiments(member_areas_of_focus: :candidate) end - it 'returns false' do - expect(helper.can_invite_members_for_project?(project)).to eq false + it 'has expected attributes', :aggregate_failures do + output = helper.common_invite_modal_dataset(project) + + expect(output[:no_selection_areas_of_focus]).to eq ['no_selection'] + expect(Gitlab::Json.parse(output[:areas_of_focus_options]).first['value']).to eq 'Contribute to the codebase' end end 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 true' do - expect(helper.directly_invite_members?).to eq true - end + context 'when member_areas_of_focus is disabled' do + before do + stub_feature_flags(member_areas_of_focus: false) end - context 'when the user is a developer' do - before do - allow(helper).to receive(:current_user) { developer } - end + it 'has expected attributes' do + attributes = { + id: project.id, + name: project.name, + default_access_level: Gitlab::Access::GUEST, + areas_of_focus_options: [], + no_selection_areas_of_focus: [] + } - it 'returns false' do - expect(helper.directly_invite_members?).to eq false - end + expect(helper.common_invite_modal_dataset(project)).to match(attributes) end end end - context 'with group' do - let_it_be(:group) { create(:group) } + context 'with project' do + before do + allow(helper).to receive(:current_user) { owner } + assign(:project, project) + end - describe "#invite_group_members?" do - context 'when the user is an owner' do + describe "#can_invite_members_for_project?" do + context 'when the user can_admin_project_member' do before do - group.add_owner(owner) - allow(helper).to receive(:current_user) { owner } + allow(helper).to receive(:can?).with(owner, :admin_project_member, project).and_return(true) end - it 'returns false' do - allow(helper).to receive(:experiment_enabled?).with(:invite_members_empty_group_version_a) { false } - - expect(helper.invite_group_members?(group)).to eq false + it 'returns true', :aggregate_failures do + expect(helper.can_invite_members_for_project?(project)).to eq true + expect(helper).to have_received(:can?).with(owner, :admin_project_member, project) end - it 'returns true' do - allow(helper).to receive(:experiment_enabled?).with(:invite_members_empty_group_version_a) { true } + context 'when feature flag is disabled' do + before do + stub_feature_flags(invite_members_group_modal: false) + end - expect(helper.invite_group_members?(group)).to eq true + it 'returns false', :aggregate_failures do + expect(helper.can_invite_members_for_project?(project)).to eq false + expect(helper).not_to have_received(:can?).with(owner, :admin_project_member, project) + end end end - context 'when the user is a developer' do + context 'when the user can not manage project members' do before do - group.add_developer(developer) - allow(helper).to receive(:current_user) { developer } + expect(helper).to receive(:can?).with(owner, :admin_project_member, project).and_return(false) end it 'returns false' do - allow(helper).to receive(:experiment_enabled?).with(:invite_members_empty_group_version_a) { true } - - expect(helper.invite_group_members?(group)).to eq false + expect(helper.can_invite_members_for_project?(project)).to eq false end end end diff --git a/spec/helpers/issuables_description_templates_helper_spec.rb b/spec/helpers/issuables_description_templates_helper_spec.rb index 95460174266..638dd201fc8 100644 --- a/spec/helpers/issuables_description_templates_helper_spec.rb +++ b/spec/helpers/issuables_description_templates_helper_spec.rb @@ -41,19 +41,6 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do context 'when project parent group does not have a file template project' do it_behaves_like 'project issuable templates' end - - context 'when project parent group has a file template project' do - let_it_be(:file_template_project) { create(:project, :custom_repo, group: parent_group, files: issuable_template_files) } - let_it_be(:group, reload: true) { create(:group, parent: parent_group) } - let_it_be(:project, reload: true) { create(:project, :custom_repo, group: group, files: issuable_template_files) } - - before do - project.update!(group: group) - parent_group.update_columns(file_template_project_id: file_template_project.id) - end - - it_behaves_like 'project issuable templates' - end end end @@ -65,16 +52,12 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do allow(helper).to receive(:issuable_templates).and_return(templates) end - context 'with matching project templates' do + context 'with project templates' do let(:templates) do { "" => [ - { name: "another_issue_template", id: "another_issue_template", project_id: project.id }, - { name: "custom_issue_template", id: "custom_issue_template", project_id: project.id } - ], - "Instance" => [ - { name: "first_issue_issue_template", id: "first_issue_issue_template", project_id: non_existing_record_id }, - { name: "second_instance_issue_template", id: "second_instance_issue_template", project_id: non_existing_record_id } + { name: "another_issue_template", id: "another_issue_template" }, + { name: "custom_issue_template", id: "custom_issue_template" } ] } end @@ -90,10 +73,6 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do "Project Templates" => [ { name: "another_issue_template", id: "another_issue_template", project_id: non_existing_record_id }, { name: "custom_issue_template", id: "custom_issue_template", project_id: non_existing_record_id } - ], - "Instance" => [ - { name: "first_issue_issue_template", id: "first_issue_issue_template", project_id: non_existing_record_id }, - { name: "second_instance_issue_template", id: "second_instance_issue_template", project_id: non_existing_record_id } ] } end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 96aba312ba3..9cf3808ab72 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -1,14 +1,26 @@ # frozen_string_literal: true -require "spec_helper" +require 'spec_helper' RSpec.describe IssuesHelper do let(:project) { create(:project) } let(:issue) { create :issue, project: project } let(:ext_project) { create :redmine_project } + describe '#work_item_type_icon' do + it 'returns icon of all standard base types' do + WorkItem::Type.base_types.each do |type| + expect(work_item_type_icon(type[0])).to eq "issue-type-#{type[0].to_s.dasherize}" + end + end + + it 'defaults to issue icon if type is unknown' do + expect(work_item_type_icon('invalid')).to eq 'issue-type-issue' + end + end + describe '#award_user_list' do - it "returns a comma-separated list of the first X users" do + it 'returns a comma-separated list of the first X users' do user = build_stubbed(:user, name: 'Joe') awards = Array.new(3, build_stubbed(:award_emoji, user: user)) @@ -24,7 +36,7 @@ RSpec.describe IssuesHelper do expect(award_user_list([award], nil)).to eq 'Joe' end - it "truncates lists" do + it 'truncates lists' do user = build_stubbed(:user, name: 'Jane') awards = Array.new(5, build_stubbed(:award_emoji, user: user)) @@ -32,14 +44,14 @@ RSpec.describe IssuesHelper do .to eq('Jane, Jane, Jane, and 2 more.') end - it "displays the current user in front of other users" do + it 'displays the current user in front of other users' do current_user = build_stubbed(:user) my_award = build_stubbed(:award_emoji, user: current_user) award = build_stubbed(:award_emoji, user: build_stubbed(:user, name: 'Jane')) awards = Array.new(5, award).push(my_award) expect(award_user_list(awards, current_user, limit: 2)) - .to eq("You, Jane, and 4 more.") + .to eq('You, Jane, and 4 more.') end end @@ -54,19 +66,19 @@ RSpec.describe IssuesHelper do end end - it "returns disabled string for unauthenticated user" do - expect(helper.award_state_class(awardable, AwardEmoji.all, nil)).to eq("disabled") + it 'returns disabled string for unauthenticated user' do + expect(helper.award_state_class(awardable, AwardEmoji.all, nil)).to eq('disabled') end - it "returns disabled for a user that does not have access to the awardable" do - expect(helper.award_state_class(awardable, AwardEmoji.all, build(:user))).to eq("disabled") + it 'returns disabled for a user that does not have access to the awardable' do + expect(helper.award_state_class(awardable, AwardEmoji.all, build(:user))).to eq('disabled') end - it "returns active string for author" do - expect(helper.award_state_class(awardable, AwardEmoji.all, upvote.user)).to eq("active") + it 'returns active string for author' do + expect(helper.award_state_class(awardable, AwardEmoji.all, upvote.user)).to eq('active') end - it "is blank for a user that has access to the awardable" do + it 'is blank for a user that has access to the awardable' do user = build(:user) expect(helper).to receive(:can?).with(user, :award_emoji, awardable).and_return(true) @@ -74,40 +86,40 @@ RSpec.describe IssuesHelper do end end - describe "awards_sort" do - it "sorts a hash so thumbsup and thumbsdown are always on top" do - data = { "thumbsdown" => "some value", "lifter" => "some value", "thumbsup" => "some value" } + describe 'awards_sort' do + it 'sorts a hash so thumbsup and thumbsdown are always on top' do + data = { 'thumbsdown' => 'some value', 'lifter' => 'some value', 'thumbsup' => 'some value' } expect(awards_sort(data).keys).to eq(%w(thumbsup thumbsdown lifter)) end end - describe "#link_to_discussions_to_resolve" do - describe "passing only a merge request" do + describe '#link_to_discussions_to_resolve' do + describe 'passing only a merge request' do let(:merge_request) { create(:merge_request) } - it "links just the merge request" do + it 'links just the merge request' do expected_path = project_merge_request_path(merge_request.project, merge_request) expect(link_to_discussions_to_resolve(merge_request, nil)).to include(expected_path) end - it "contains the reference to the merge request" do + it 'contains the reference to the merge request' do expect(link_to_discussions_to_resolve(merge_request, nil)).to include(merge_request.to_reference) end end - describe "when passing a discussion" do + describe 'when passing a discussion' do let(:diff_note) { create(:diff_note_on_merge_request) } let(:merge_request) { diff_note.noteable } let(:discussion) { diff_note.to_discussion } - it "links to the merge request with first note if a single discussion was passed" do + it 'links to the merge request with first note if a single discussion was passed' do expected_path = Gitlab::UrlBuilder.build(diff_note) expect(link_to_discussions_to_resolve(merge_request, discussion)).to include(expected_path) end - it "contains both the reference to the merge request and a mention of the discussion" do + it 'contains both the reference to the merge request and a mention of the discussion' do expect(link_to_discussions_to_resolve(merge_request, discussion)).to include("#{merge_request.to_reference} (discussion #{diff_note.id})") end end @@ -235,13 +247,13 @@ RSpec.describe IssuesHelper do end describe '#use_startup_call' do - it "returns false when a query param is present" 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 + 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) @@ -265,13 +277,13 @@ RSpec.describe IssuesHelper do it 'returns expected result' do expected = { - can_create_issue: "true", - can_reopen_issue: "true", - can_report_spam: "false", - can_update_issue: "true", + can_create_issue: 'true', + can_reopen_issue: 'true', + can_report_spam: 'false', + can_update_issue: 'true', iid: issue.iid, - is_issue_author: "false", - issue_type: "issue", + is_issue_author: 'false', + issue_type: 'issue', new_issue_path: new_project_issue_path(project), project_path: project.full_path, report_abuse_path: new_abuse_report_path(user_id: issue.author.id, ref_url: issue_url(issue)), @@ -307,7 +319,7 @@ RSpec.describe IssuesHelper do initial_email: project.new_issuable_address(current_user, 'issue'), is_signed_in: current_user.present?.to_s, issues_path: project_issues_path(project), - jira_integration_path: help_page_url('integration/jira/', anchor: 'view-jira-issues'), + jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'), markdown_help_path: help_page_path('user/markdown'), max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes), new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.id }), @@ -345,7 +357,7 @@ RSpec.describe IssuesHelper do end it 'returns manual ordering class' do - expect(helper.issue_manual_ordering_class).to eq("manual-ordering") + expect(helper.issue_manual_ordering_class).to eq('manual-ordering') end context 'when manual sorting disabled' do diff --git a/spec/helpers/nav/new_dropdown_helper_spec.rb b/spec/helpers/nav/new_dropdown_helper_spec.rb index e3d9bc5b174..03b9c538225 100644 --- a/spec/helpers/nav/new_dropdown_helper_spec.rb +++ b/spec/helpers/nav/new_dropdown_helper_spec.rb @@ -221,13 +221,13 @@ RSpec.describe Nav::NewDropdownHelper do let(:with_show_new_issue_link) { false } let(:with_merge_project) { nil } let(:with_can_create_snippet_in_project) { false } - let(:with_can_import_members) { false } + let(:with_can_admin_project_member) { false } before do allow(helper).to receive(:show_new_issue_link?).with(project) { with_show_new_issue_link } allow(helper).to receive(:merge_request_source_project_for_project).with(project) { with_merge_project } allow(helper).to receive(:can?).with(user, :create_snippet, project) { with_can_create_snippet_in_project } - allow(helper).to receive(:can_import_members?) { with_can_import_members } + allow(helper).to receive(:can_admin_project_member?) { with_can_admin_project_member } end it 'has no menu sections' do @@ -290,7 +290,7 @@ RSpec.describe Nav::NewDropdownHelper do context 'when invite members experiment' do let(:with_invite_members_experiment) { true } - let(:with_can_import_members) { true } + let(:with_can_admin_project_member) { true } let(:expected_title) { 'This project' } let(:expected_href) { "/#{project.path_with_namespace}/-/project_members" } diff --git a/spec/helpers/nav_helper_spec.rb b/spec/helpers/nav_helper_spec.rb index 4c5f440b8a3..f0ad2038347 100644 --- a/spec/helpers/nav_helper_spec.rb +++ b/spec/helpers/nav_helper_spec.rb @@ -112,16 +112,6 @@ RSpec.describe NavHelper do it { is_expected.to all(be_a(String)) } end - describe '.group_issues_sub_menu_items' do - subject { helper.group_issues_sub_menu_items } - - before do - allow(helper).to receive(:current_user).and_return(nil) - end - - it { is_expected.to all(be_a(String)) } - end - describe '#page_has_markdown?' do using RSpec::Parameterized::TableSyntax diff --git a/spec/helpers/packages_helper_spec.rb b/spec/helpers/packages_helper_spec.rb index 8b3c8411fbd..bc60c582ff8 100644 --- a/spec/helpers/packages_helper_spec.rb +++ b/spec/helpers/packages_helper_spec.rb @@ -219,4 +219,25 @@ RSpec.describe PackagesHelper do it { is_expected.to eq(expected_result) } end end + + describe '#package_details_data' do + let_it_be(:package) { create(:package) } + + before do + allow(helper).to receive(:current_user) { project.owner } + allow(helper).to receive(:can?) { true } + end + + it 'when use_presenter is true populate the package key' do + result = helper.package_details_data(project, package, true) + + expect(result[:package]).not_to be_nil + end + + it 'when use_presenter is false the package key is nil' do + result = helper.package_details_data(project, package, false) + + expect(result[:package]).to be_nil + end + end end diff --git a/spec/helpers/projects/project_members_helper_spec.rb b/spec/helpers/projects/project_members_helper_spec.rb index b180b5ec06f..4e3a0147509 100644 --- a/spec/helpers/projects/project_members_helper_spec.rb +++ b/spec/helpers/projects/project_members_helper_spec.rb @@ -8,142 +8,8 @@ RSpec.describe Projects::ProjectMembersHelper do let_it_be(:current_user) { create(:user) } let_it_be(:project) { create(:project) } - let(:allow_admin_project) { nil } - before do allow(helper).to receive(:current_user).and_return(current_user) - allow(helper).to receive(:can?).with(current_user, :admin_project_member, project).and_return(allow_admin_project) - end - - shared_examples 'when `current_user` does not have `admin_project_member` permissions' do - let(:allow_admin_project) { false } - - it { is_expected.to be(false) } - end - - describe '#can_manage_project_members?' do - subject { helper.can_manage_project_members?(project) } - - context 'when `current_user` has `admin_project_member` permissions' do - let(:allow_admin_project) { true } - - it { is_expected.to be(true) } - end - - include_examples 'when `current_user` does not have `admin_project_member` permissions' - end - - describe '#show_groups?' do - subject { helper.show_groups?(project.project_group_links) } - - context 'when group links exist' do - let!(:project_group_link) { create(:project_group_link, project: project) } - - it { is_expected.to be(true) } - end - - context 'when `search_groups` param is set' do - before do - allow(helper).to receive(:params).and_return({ search_groups: 'foo' }) - end - - it { is_expected.to be(true) } - end - - context 'when `search_groups` param is not set and group links do not exist' do - it { is_expected.to be(false) } - end - end - - describe '#show_invited_members?' do - subject { helper.show_invited_members?(project, project.project_members.invite) } - - context 'when `current_user` has `admin_project_member` permissions' do - let(:allow_admin_project) { true } - - context 'when invited members exist' do - let!(:invite) { create(:project_member, :invited, project: project) } - - it { is_expected.to be(true) } - end - - context 'when invited members do not exist' do - it { is_expected.to be(false) } - end - end - - include_examples 'when `current_user` does not have `admin_project_member` permissions' - end - - describe '#show_access_requests?' do - subject { helper.show_access_requests?(project, project.requesters) } - - context 'when `current_user` has `admin_project_member` permissions' do - let(:allow_admin_project) { true } - - context 'when access requests exist' do - let!(:access_request) { create(:project_member, :access_request, project: project) } - - it { is_expected.to be(true) } - end - - context 'when access requests do not exist' do - it { is_expected.to be(false) } - end - end - - include_examples 'when `current_user` does not have `admin_project_member` permissions' - end - - describe '#groups_tab_active?' do - subject { helper.groups_tab_active? } - - context 'when `search_groups` param is set' do - before do - allow(helper).to receive(:params).and_return({ search_groups: 'foo' }) - end - - it { is_expected.to be(true) } - end - - context 'when `search_groups` param is not set' do - it { is_expected.to be(false) } - end - end - - describe '#current_user_is_group_owner?' do - let(:group) { create(:group) } - - subject { helper.current_user_is_group_owner?(project2) } - - describe "when current user is the owner of the project's parent group" do - let(:project2) { create(:project, namespace: group) } - - before do - group.add_owner(current_user) - end - - it { is_expected.to be(true) } - end - - describe "when current user is not the owner of the project's parent group" do - let_it_be(:user) { create(:user) } - - let(:project2) { create(:project, namespace: group) } - - before do - group.add_owner(user) - end - - it { is_expected.to be(false) } - end - - describe "when project does not have a parent group" do - let(:user) { create(:user) } - let(:project2) { create(:project, namespace: user.namespace) } - - it { is_expected.to be(false) } - end end describe 'project members' do @@ -155,8 +21,6 @@ RSpec.describe Projects::ProjectMembersHelper do let(:members_collection) { members } describe '#project_members_app_data_json' do - let(:allow_admin_project) { true } - subject do Gitlab::Json.parse( helper.project_members_app_data_json( @@ -171,6 +35,7 @@ RSpec.describe Projects::ProjectMembersHelper do before do allow(helper).to receive(:project_project_member_path).with(project, ':id').and_return('/foo-bar/-/project_members/:id') + project.add_maintainer(current_user) end it 'returns expected json' do diff --git a/spec/helpers/projects/terraform_helper_spec.rb b/spec/helpers/projects/terraform_helper_spec.rb index 8833e23c47d..9c2f009be26 100644 --- a/spec/helpers/projects/terraform_helper_spec.rb +++ b/spec/helpers/projects/terraform_helper_spec.rb @@ -22,6 +22,18 @@ RSpec.describe Projects::TerraformHelper do expect(subject[:project_path]).to eq(project.full_path) end + it 'includes access token path' do + expect(subject[:access_tokens_path]).to eq(profile_personal_access_tokens_path) + end + + it 'includes username' do + expect(subject[:username]).to eq(current_user.username) + end + + it 'includes terraform state api url' do + expect(subject[:terraform_api_url]).to eq("#{Settings.gitlab.url}/api/v4/projects/#{project.id}/terraform/state") + end + it 'indicates the user is a terraform admin' do expect(subject[:terraform_admin]).to eq(true) end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 75e80f5edbc..4dac4403f70 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -720,21 +720,21 @@ RSpec.describe ProjectsHelper do end end - describe '#can_import_members?' do + describe '#can_admin_project_member?' do context 'when user is project owner' do before do allow(helper).to receive(:current_user) { project.owner } end it 'returns true for owner of project' do - expect(helper.can_import_members?).to eq true + expect(helper.can_admin_project_member?(project)).to eq true end end context 'when user is not a project owner' do using RSpec::Parameterized::TableSyntax - where(:user_project_role, :can_import) do + where(:user_project_role, :can_admin) do :maintainer | true :developer | false :reporter | false @@ -748,7 +748,7 @@ RSpec.describe ProjectsHelper do end it 'resolves if the user can import members' do - expect(helper.can_import_members?).to eq can_import + expect(helper.can_admin_project_member?(project)).to eq can_admin end end end @@ -918,33 +918,39 @@ RSpec.describe ProjectsHelper do end end - describe '#project_permissions_settings' do - context 'with no project_setting associated' do - it 'includes a value for edit commit messages' do - settings = project_permissions_settings(project) + describe '#project_permissions_panel_data' do + subject { helper.project_permissions_panel_data(project) } - expect(settings[:allowEditingCommitMessages]).to be_falsy - end - end - - context 'when commits are allowed to be edited' do - it 'includes the edit commit message value' do - project.create_project_setting(allow_editing_commit_messages: true) - - settings = project_permissions_settings(project) - - expect(settings[:allowEditingCommitMessages]).to be_truthy - end + before do + allow(helper).to receive(:can?) { true } + allow(helper).to receive(:current_user).and_return(user) end - context 'when commits are not allowed to be edited' do - it 'returns false to the edit commit message value' do - project.create_project_setting(allow_editing_commit_messages: false) - - settings = project_permissions_settings(project) - - expect(settings[:allowEditingCommitMessages]).to be_falsy - end + it 'includes project_permissions_settings' do + settings = subject.dig(:currentSettings) + + expect(settings).to include( + packagesEnabled: !!project.packages_enabled, + visibilityLevel: project.visibility_level, + requestAccessEnabled: !!project.request_access_enabled, + issuesAccessLevel: project.project_feature.issues_access_level, + repositoryAccessLevel: project.project_feature.repository_access_level, + forkingAccessLevel: project.project_feature.forking_access_level, + mergeRequestsAccessLevel: project.project_feature.merge_requests_access_level, + buildsAccessLevel: project.project_feature.builds_access_level, + wikiAccessLevel: project.project_feature.wiki_access_level, + snippetsAccessLevel: project.project_feature.snippets_access_level, + pagesAccessLevel: project.project_feature.pages_access_level, + analyticsAccessLevel: project.project_feature.analytics_access_level, + containerRegistryEnabled: !!project.container_registry_enabled, + lfsEnabled: !!project.lfs_enabled, + emailsDisabled: project.emails_disabled?, + metricsDashboardAccessLevel: project.project_feature.metrics_dashboard_access_level, + operationsAccessLevel: project.project_feature.operations_access_level, + showDefaultAwardEmojis: project.show_default_award_emojis?, + securityAndComplianceAccessLevel: project.security_and_compliance_access_level, + containerRegistryAccessLevel: project.project_feature.container_registry_access_level + ) end end end diff --git a/spec/helpers/snippets_helper_spec.rb b/spec/helpers/snippets_helper_spec.rb index 35882c9337b..12d791d8710 100644 --- a/spec/helpers/snippets_helper_spec.rb +++ b/spec/helpers/snippets_helper_spec.rb @@ -92,4 +92,23 @@ RSpec.describe SnippetsHelper do end end end + + describe '#snippet_report_abuse_path' do + let(:snippet) { public_personal_snippet } + let(:current_user) { create(:user) } + + subject { snippet_report_abuse_path(snippet) } + + it 'returns false if the user cannot submit the snippet as spam' do + allow(snippet).to receive(:submittable_as_spam_by?).and_return(false) + + expect(subject).to be_falsey + end + + it 'returns true if the user can submit the snippet as spam' do + allow(snippet).to receive(:submittable_as_spam_by?).and_return(true) + + expect(subject).to be_truthy + end + end end diff --git a/spec/helpers/time_zone_helper_spec.rb b/spec/helpers/time_zone_helper_spec.rb index 391e9bd38ed..e6cb20b5800 100644 --- a/spec/helpers/time_zone_helper_spec.rb +++ b/spec/helpers/time_zone_helper_spec.rb @@ -68,4 +68,24 @@ RSpec.describe TimeZoneHelper, :aggregate_failures do end end end + + describe '#local_time' do + let_it_be(:timezone) { 'America/Los_Angeles' } + + before do + travel_to Time.find_zone(timezone).local(2021, 7, 20, 15, 30, 45) + end + + context 'when a valid timezone is passed' do + it 'returns local time' do + expect(helper.local_time(timezone)).to eq('3:30 PM') + end + end + + context 'when an invalid timezone is passed' do + it 'returns local time using the configured default timezone (UTC in this case)' do + expect(helper.local_time('Foo/Bar')).to eq('10:30 PM') + end + end + end end diff --git a/spec/helpers/user_callouts_helper_spec.rb b/spec/helpers/user_callouts_helper_spec.rb index 90333cb0ad5..5ef1e9d4daf 100644 --- a/spec/helpers/user_callouts_helper_spec.rb +++ b/spec/helpers/user_callouts_helper_spec.rb @@ -61,34 +61,6 @@ RSpec.describe UserCalloutsHelper do end end - describe '.show_service_templates_deprecated_callout?' do - using RSpec::Parameterized::TableSyntax - - let_it_be(:admin) { create(:user, :admin) } - let_it_be(:non_admin) { create(:user) } - - subject { helper.show_service_templates_deprecated_callout? } - - where(:self_managed, :is_admin_user, :has_active_service_template, :callout_dismissed, :should_show_callout) do - true | true | true | false | true - true | true | true | true | false - true | false | true | false | false - false | true | true | false | false - true | true | false | false | false - end - - with_them do - before do - allow(::Gitlab).to receive(:com?).and_return(!self_managed) - allow(helper).to receive(:current_user).and_return(is_admin_user ? admin : non_admin) - allow(helper).to receive(:user_dismissed?).with(described_class::SERVICE_TEMPLATES_DEPRECATED_CALLOUT) { callout_dismissed } - create(:service, :template, type: 'MattermostService', active: has_active_service_template) - end - - it { is_expected.to be should_show_callout } - end - end - describe '.show_customize_homepage_banner?' do subject { helper.show_customize_homepage_banner? } |