diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-18 11:17:02 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-18 11:17:02 +0300 |
commit | b39512ed755239198a9c294b6a45e65c05900235 (patch) | |
tree | d234a3efade1de67c46b9e5a38ce813627726aa7 /spec/helpers | |
parent | d31474cf3b17ece37939d20082b07f6657cc79a9 (diff) |
Add latest changes from gitlab-org/gitlab@15-3-stable-eev15.3.0-rc42
Diffstat (limited to 'spec/helpers')
23 files changed, 533 insertions, 181 deletions
diff --git a/spec/helpers/admin/identities_helper_spec.rb b/spec/helpers/admin/identities_helper_spec.rb new file mode 100644 index 00000000000..9a7fdd3aa69 --- /dev/null +++ b/spec/helpers/admin/identities_helper_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Admin::IdentitiesHelper do + let_it_be(:user) { create(:user) } + let_it_be(:identity) { create(:identity, provider: 'ldapmain', extern_uid: 'ldap-uid') } + + describe '#label_for_identity_provider' do + it 'shows label for identity provider' do + expect(helper.label_for_identity_provider(identity)).to eq 'ldap (ldapmain)' + end + end + + describe '#provider_id_cell_testid' do + it 'shows blank provider id for data-testid' do + expect(helper.provider_id_cell_testid(identity)).to eq 'provider_id_blank' + end + end + + describe '#provider_id' do + it 'shows no provider id' do + expect(helper.provider_id(identity)).to eq '-' + end + end + + describe '#saml_group_cell_testid' do + it 'shows blank SAML group for data-testid' do + expect(helper.saml_group_cell_testid(identity)).to eq 'saml_group_blank' + end + end + + describe '#saml_group_link' do + it 'shows no link to SAML group' do + expect(helper.saml_group_link(identity)).to eq '-' + end + end + + describe '#identity_cells_to_render?' do + context 'without identities' do + it 'returns false' do + expect(helper.identity_cells_to_render?([], user)).to eq false + end + end + + context 'with identities' do + it 'returns true' do + expect(helper.identity_cells_to_render?(identity, user)).to eq true + end + end + end + + describe '#scim_identities_collection' do + it 'returns empty array' do + expect(helper.scim_identities_collection(user)).to eq [] + end + end +end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 47c31546629..264431b1bb5 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -192,6 +192,14 @@ RSpec.describe ApplicationHelper do end end + describe '#community_forum' do + subject { helper.community_forum } + + it 'returns the url' do + is_expected.to eq("https://forum.gitlab.com") + end + end + describe '#support_url' do context 'when alternate support url is specified' do let(:alternate_url) { 'http://company.example.com/getting-help' } diff --git a/spec/helpers/boards_helper_spec.rb b/spec/helpers/boards_helper_spec.rb index 8d5dc3fb4be..ccc150c397a 100644 --- a/spec/helpers/boards_helper_spec.rb +++ b/spec/helpers/boards_helper_spec.rb @@ -130,6 +130,7 @@ RSpec.describe BoardsHelper do it 'returns can_admin_list as false by default' do expect(helper.board_data[:can_admin_list]).to eq('false') end + it 'returns can_admin_list as true when user can admin the board lists' do allow(helper).to receive(:can?).with(user, :admin_issue_board_list, project).and_return(true) @@ -141,6 +142,7 @@ RSpec.describe BoardsHelper do it 'returns can_admin_board as false by default' do expect(helper.board_data[:can_admin_board]).to eq('false') end + it 'returns can_admin_board as true when user can admin the board' do allow(helper).to receive(:can?).with(user, :admin_issue_board, project).and_return(true) @@ -178,6 +180,7 @@ RSpec.describe BoardsHelper do it 'returns can_admin_list as false by default' do expect(helper.board_data[:can_admin_list]).to eq('false') end + it 'returns can_admin_list as true when user can admin the board lists' do allow(helper).to receive(:can?).with(user, :admin_issue_board_list, base_group).and_return(true) diff --git a/spec/helpers/ci/pipeline_editor_helper_spec.rb b/spec/helpers/ci/pipeline_editor_helper_spec.rb index bc9e47a4ca1..1950d685980 100644 --- a/spec/helpers/ci/pipeline_editor_helper_spec.rb +++ b/spec/helpers/ci/pipeline_editor_helper_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe Ci::PipelineEditorHelper do + include CycleAnalyticsHelpers + let_it_be(:project) { create(:project) } describe 'can_view_pipeline_editor?' do @@ -62,8 +64,7 @@ RSpec.describe Ci::PipelineEditorHelper do "project-path" => project.path, "project-full-path" => project.full_path, "project-namespace" => project.namespace.full_path, - "runner-help-page-path" => help_page_path('ci/runners/index'), - "simulate-pipeline-help-page-path" => help_page_path('ci/lint', anchor: 'simulate-a-pipeline'), + "simulate-pipeline-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'simulate-a-cicd-pipeline'), "total-branches" => project.repository.branches.length, "validate-tab-illustration-path" => 'illustrations/validate.svg', "yml-help-page-path" => help_page_path('ci/yaml/index') @@ -93,8 +94,7 @@ RSpec.describe Ci::PipelineEditorHelper do "project-path" => project.path, "project-full-path" => project.full_path, "project-namespace" => project.namespace.full_path, - "runner-help-page-path" => help_page_path('ci/runners/index'), - "simulate-pipeline-help-page-path" => help_page_path('ci/lint', anchor: 'simulate-a-pipeline'), + "simulate-pipeline-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'simulate-a-cicd-pipeline'), "total-branches" => 0, "validate-tab-illustration-path" => 'illustrations/validate.svg', "yml-help-page-path" => help_page_path('ci/yaml/index') diff --git a/spec/helpers/ci/runners_helper_spec.rb b/spec/helpers/ci/runners_helper_spec.rb index 4d1b1c7682c..3b18572ad64 100644 --- a/spec/helpers/ci/runners_helper_spec.rb +++ b/spec/helpers/ci/runners_helper_spec.rb @@ -109,7 +109,7 @@ RSpec.describe Ci::RunnersHelper do it 'returns group data for top level group' do result = { - update_path: "/api/v4/groups/#{parent.id}", + group_id: parent.id, shared_runners_setting: Namespace::SR_ENABLED, parent_shared_runners_setting: nil }.merge(runner_constants) @@ -119,7 +119,7 @@ RSpec.describe Ci::RunnersHelper do it 'returns group data for child group' do result = { - update_path: "/api/v4/groups/#{group.id}", + group_id: group.id, shared_runners_setting: Namespace::SR_DISABLED_AND_UNOVERRIDABLE, parent_shared_runners_setting: Namespace::SR_ENABLED }.merge(runner_constants) diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb index b5b572e9719..b27954de0d4 100644 --- a/spec/helpers/commits_helper_spec.rb +++ b/spec/helpers/commits_helper_spec.rb @@ -153,16 +153,24 @@ RSpec.describe CommitsHelper do end describe "#conditionally_paginate_diff_files" do - let(:diffs_collection) { instance_double(Gitlab::Diff::FileCollection::Commit, diff_files: diff_files) } - let(:diff_files) { Gitlab::Git::DiffCollection.new(files) } - let(:page) { nil } + let_it_be(:project) { create(:project, :repository) } + + let(:diffs_collection) { instance_double(Gitlab::Diff::FileCollection::Commit, diff_files: decorated_diff_files, project: project) } + let(:decorated_diff_files) do + diffs.map do |diff| + Gitlab::Diff::File.new(diff, repository: project.repository) + end + end + let(:diffs) { Gitlab::Git::DiffCollection.new(files) } let(:files) do Array.new(85).map do { too_large: false, diff: "" } end end + let(:page) { nil } + subject { helper.conditionally_paginate_diff_files(diffs_collection, paginate: paginate, page: page, per: Projects::CommitController::COMMIT_DIFFS_PER_PAGE) } before do @@ -203,8 +211,8 @@ RSpec.describe CommitsHelper do context "pagination is disabled" do let(:paginate) { false } - it "returns a standard DiffCollection" do - expect(subject).to be_a(Gitlab::Git::DiffCollection) + it "returns the unpaginated collection" do + expect(subject.size).to eq(85) end end end diff --git a/spec/helpers/form_helper_spec.rb b/spec/helpers/form_helper_spec.rb index c9c8c6b13b6..4b76c370810 100644 --- a/spec/helpers/form_helper_spec.rb +++ b/spec/helpers/form_helper_spec.rb @@ -3,6 +3,82 @@ require 'spec_helper' RSpec.describe FormHelper do + include Devise::Test::ControllerHelpers + + describe '#dropdown_max_select' do + context "with the :limit_reviewer_and_assignee_size feature flag on" do + it 'correctly returns the max amount of reviewers or assignees to allow' do + max = MergeRequest::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS + + expect(helper.dropdown_max_select({})) + .to eq(max) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => 5 })) + .to eq(5) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => max + 5 })) + .to eq(max) + end + end + + context "with the :limit_reviewer_and_assignee_size feature flag off" do + before do + stub_feature_flags(limit_reviewer_and_assignee_size: false) + end + + it 'correctly returns the max amount of reviewers or assignees to allow' do + expect(helper.dropdown_max_select({})) + .to eq(nil) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => 5 })) + .to eq(5) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => 120 })) + .to eq(120) + end + end + end + + describe '#reviewers_dropdown_options' do + let(:merge_request) { build(:merge_request) } + + context "with the :limit_reviewer_and_assignee_size feature flag on" do + context "with multiple reviewers" do + it 'correctly returns the max amount of reviewers or assignees to allow' do + allow(helper).to receive(:merge_request_supports_multiple_reviewers?).and_return(true) + + expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) + .to eq(MergeRequest::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS) + end + end + + context "with only 1 reviewer" do + it 'correctly returns the max amount of reviewers or assignees to allow' do + expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) + .to eq(1) + end + end + end + + context "with the :limit_reviewer_and_assignee_size feature flag off" do + before do + stub_feature_flags(limit_reviewer_and_assignee_size: false) + end + + context "with multiple reviewers" do + it 'correctly returns the max amount of reviewers or assignees to allow' do + allow(helper).to receive(:merge_request_supports_multiple_reviewers?).and_return(true) + + expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) + .to eq(nil) + end + end + + context "with only 1 reviewer" do + it 'correctly returns the max amount of reviewers or assignees to allow' do + expect(helper.reviewers_dropdown_options(merge_request)[:data][:'max-select']) + .to eq(1) + end + end + end + end + describe 'form_errors' do it 'returns nil when model has no errors' do model = double(errors: []) @@ -13,10 +89,7 @@ RSpec.describe FormHelper do it 'renders an appropriately styled alert div' do model = double(errors: errors_stub('Error 1')) - expect(helper.form_errors(model, pajamas_alert: false)) - .to include('<div class="alert alert-danger" id="error_explanation">') - - expect(helper.form_errors(model, pajamas_alert: true)) + expect(helper.form_errors(model)) .to include( '<div class="gl-alert gl-mb-5 gl-alert-danger gl-alert-not-dismissible" id="error_explanation" role="alert">' ) diff --git a/spec/helpers/gitlab_script_tag_helper_spec.rb b/spec/helpers/gitlab_script_tag_helper_spec.rb index 35f2c0795be..9d71e25286e 100644 --- a/spec/helpers/gitlab_script_tag_helper_spec.rb +++ b/spec/helpers/gitlab_script_tag_helper_spec.rb @@ -14,6 +14,16 @@ RSpec.describe GitlabScriptTagHelper do expect(helper.javascript_include_tag(script_url).to_s) .to eq "<script src=\"/javascripts/#{script_url}\" defer=\"defer\" nonce=\"noncevalue\"></script>" end + + it 'returns a script tag with defer=false and a nonce' do + expect(helper.javascript_include_tag(script_url, defer: nil).to_s) + .to eq "<script src=\"/javascripts/#{script_url}\" nonce=\"noncevalue\"></script>" + end + + it 'returns a script tag with a nonce even nonce is set to nil' do + expect(helper.javascript_include_tag(script_url, nonce: nil).to_s) + .to eq "<script src=\"/javascripts/#{script_url}\" defer=\"defer\" nonce=\"noncevalue\"></script>" + end end describe 'inline script tag' do diff --git a/spec/helpers/groups/group_members_helper_spec.rb b/spec/helpers/groups/group_members_helper_spec.rb index 89c26c21338..0d53225bbcf 100644 --- a/spec/helpers/groups/group_members_helper_spec.rb +++ b/spec/helpers/groups/group_members_helper_spec.rb @@ -173,7 +173,7 @@ RSpec.describe Groups::GroupMembersHelper do describe '#group_member_header_subtext' do it 'contains expected text with group name' do - expect(helper.group_member_header_subtext(group)).to match("You can invite a new member to .*#{group.name}") + expect(helper.group_member_header_subtext(group)).to match("You're viewing members of .*#{group.name}") end end end diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index d00cd8f1d6b..2c1061d2f1b 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe GroupsHelper do include ApplicationHelper + include AvatarsHelper describe '#group_icon_url' do it 'returns an url for the avatar' do @@ -135,6 +136,37 @@ RSpec.describe GroupsHelper do end end + describe '#group_title_link' do + let_it_be(:group) { create(:group, :with_avatar) } + + let(:raw_link) { group_title_link(group, show_avatar: true) } + let(:document) { Nokogiri::HTML.parse(raw_link) } + + describe 'link' do + subject(:link) { document.css('.group-path').first } + + it 'uses the group name as innerText' do + expect(link.inner_text).to eq(group.name) + end + + it 'links to the group path' do + expect(link.attr('href')).to eq(group_path(group)) + end + end + + describe 'icon' do + subject(:icon) { document.css('.avatar-tile').first } + + it 'specifies the group name as the alt text' do + expect(icon.attr('alt')).to eq(group.name) + end + + it 'uses the group\'s avatar_url' do + expect(icon.attr('src')).to eq(group.avatar_url) + end + end + end + describe '#share_with_group_lock_help_text' do context 'traversal queries' do let_it_be_with_reload(:root_group) { create(:group) } @@ -420,9 +452,31 @@ RSpec.describe GroupsHelper do end end - describe '#group_name_and_path_app_data' do - let_it_be(:group) { build(:group, name: 'My awesome group', path: 'my-awesome-group') } + describe '#subgroup_creation_data' do + let_it_be(:name) { 'parent group' } + let_it_be(:group) { build(:group, name: name) } let_it_be(:subgroup) { build(:group, parent: group) } + + context 'when group has a parent' do + it 'returns expected hash' do + expect(subgroup_creation_data(subgroup)).to eq({ + import_existing_group_path: '/groups/new#import-group-pane', + parent_group_name: name + }) + end + end + + context 'when group does not have a parent' do + it 'returns expected hash' do + expect(subgroup_creation_data(group)).to eq({ + import_existing_group_path: '/groups/new#import-group-pane', + parent_group_name: nil + }) + end + end + end + + describe '#group_name_and_path_app_data' do let_it_be(:root_url) { 'https://gitlab.com/' } before do @@ -432,17 +486,10 @@ RSpec.describe GroupsHelper do context 'when group has a parent' do it 'returns expected hash' do - expect(group_name_and_path_app_data(subgroup)).to match( - { base_path: 'https://gitlab.com/my-awesome-group', mattermost_enabled: 'true' } - ) - end - end - - context 'when group does not have a parent' do - it 'returns expected hash' do - expect(group_name_and_path_app_data(group)).to match( - { base_path: root_url, mattermost_enabled: 'true' } - ) + expect(group_name_and_path_app_data).to match({ + base_path: 'https://gitlab.com/', + mattermost_enabled: 'true' + }) end end end @@ -461,7 +508,7 @@ RSpec.describe GroupsHelper do it 'returns expected hash' do expect(helper.subgroups_and_projects_list_app_data(group)).to match({ show_schema_markup: 'true', - new_subgroup_path: including("groups/new?parent_id=#{group.id}"), + new_subgroup_path: including("groups/new?parent_id=#{group.id}#create-group-pane"), new_project_path: including("/projects/new?namespace_id=#{group.id}"), new_subgroup_illustration: including('illustrations/subgroup-create-new-sm'), new_project_illustration: including('illustrations/project-create-new-sm'), diff --git a/spec/helpers/issuables_description_templates_helper_spec.rb b/spec/helpers/issuables_description_templates_helper_spec.rb index 768ce5975c1..bd8af384d40 100644 --- a/spec/helpers/issuables_description_templates_helper_spec.rb +++ b/spec/helpers/issuables_description_templates_helper_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do - include_context 'project issuable templates context' - describe '#issuable_templates' do + include_context 'project issuable templates context' + let_it_be(:inherited_from) { nil } let_it_be(:user) { create(:user) } let_it_be(:parent_group, reload: true) { create(:group) } @@ -44,7 +44,7 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do end end - describe '#selected_template' do + describe '#available_service_desk_templates_for' do let_it_be(:project) { build(:project) } before do @@ -72,46 +72,103 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do ].to_json expect(helper.available_service_desk_templates_for(@project)).to eq(value) end + end - context 'when no issuable_template parameter or default template is present' do - it 'does not select a template' do - expect(helper.selected_template(project)).to be(nil) - end + context 'when there are no templates in the project' do + let(:templates) { {} } + + it 'returns empty array' do + value = [].to_json + expect(helper.available_service_desk_templates_for(@project)).to eq(value) end + end + end - context 'when an issuable_template parameter has been provided' do - before do - allow(helper).to receive(:params).and_return({ issuable_template: 'another_issue_template' }) - end + describe '#selected_template_name' do + let(:template_names) { %w(another_issue_template custom_issue_template) } - it 'selects the issuable template' do - expect(helper.selected_template(project)).to eq('another_issue_template') - end + context 'when no issuable_template parameter is provided' do + it 'does not select a template' do + expect(helper.selected_template_name(template_names)).to be_nil end + end - context 'when there is a default template' do - let(:templates) do - { - "" => [ - { name: "another_issue_template", id: "another_issue_template", project_id: project.id }, - { name: "default", id: "default", project_id: project.id } - ] - } + context 'when an issuable_template parameter has been provided' do + before do + allow(helper).to receive(:params).and_return({ issuable_template: template_param_value }) + end + + context 'when param matches existing templates' do + let(:template_param_value) { 'another_issue_template' } + + it 'returns the matching issuable template' do + expect(helper.selected_template_name(template_names)).to eq('another_issue_template') end + end - it 'selects the default template' do - expect(helper.selected_template(project)).to eq('default') + context 'when param does not match any templates' do + let(:template_param_value) { 'non_matching_issue_template' } + + it 'returns nil' do + expect(helper.selected_template_name(template_names)).to be_nil end end end + end - context 'when there are not templates in the project' do - let(:templates) { {} } + describe '#default_template_name' do + context 'when a default template is available' do + let(:template_names) { %w(another_issue_template deFault) } - it 'returns empty array' do - value = [].to_json - expect(helper.available_service_desk_templates_for(@project)).to eq(value) + it 'returns the default template' do + issue = build(:issue) + + expect(helper.default_template_name(template_names, issue)).to be('deFault') + end + + it 'returns nil when issuable has a description set' do + issue = build(:issue, description: 'from template in project settings') + + expect(helper.default_template_name(template_names, issue)).to be_nil + end + + it 'returns nil when issuable is persisted' do + issue = create(:issue) + + expect(helper.default_template_name(template_names, issue)).to be_nil + end + end + + context 'when there is no default template' do + let(:template_names) { %w(another_issue_template) } + + it 'returns nil' do + expect(helper.default_template_name(template_names, build(:issue))).to be_nil end end end + + describe '#template_names' do + let(:project) { build(:project) } + let(:templates) do + { + "Project templates" => [ + { name: "another_issue_template", id: "another_issue_template", project_id: project.id }, + { name: "custom_issue_template", id: "custom_issue_template", project_id: project.id } + ], + "Group templates" => [ + { name: "another_issue_template", id: "another_issue_template", project_id: project.id } + ] + } + end + + before do + allow(helper).to receive(:ref_project).and_return(project) + allow(helper).to receive(:issuable_templates).and_return(templates) + end + + it 'returns unique list of template names' do + expect(helper.template_names(build(:issue))).to contain_exactly('another_issue_template', 'custom_issue_template') + end + end end diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 73527bea14e..069465c2fec 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -98,11 +98,55 @@ RSpec.describe IssuablesHelper do end end - describe '#issuable_meta' do + describe '#issuable_meta', time_travel_to: '2022-08-05 00:00:00 +0000' do let(:user) { create(:user) } let_it_be(:project) { create(:project) } + describe 'Issuable created status text' do + subject { helper.issuable_meta(issuable, project) } + + context 'when issuable is a work item and flag is off' do + using RSpec::Parameterized::TableSyntax + + before do + stub_feature_flags(work_items: false) + end + + where(:issuable_type, :text) do + :issue | 'Issue created Aug 05, 2022 by' + :incident | 'Incident created Aug 05, 2022 by' + end + + let(:issuable) { build_stubbed(:work_item, issuable_type, created_at: Date.current) } + + with_them do + it { is_expected.to have_content(text) } + end + end + + context 'when issuable is a work item and flag is on' do + using RSpec::Parameterized::TableSyntax + + where(:issuable_type, :text) do + :issue | 'Issue created Aug 05, 2022 by' + :incident | 'Incident created Aug 05, 2022 by' + end + + let(:issuable) { build_stubbed(:work_item, issuable_type, created_at: Date.current) } + + with_them do + it { is_expected.to have_content(text) } + end + end + + context 'when issuable is not a work item' do + let(:issuable) { build_stubbed(:merge_request, created_at: Date.current) } + + it { is_expected.to have_content('Created Aug 05, 2022') } + end + end + describe 'author status' do let(:issuable) { build(:merge_request, source_project: project, author: user, created_at: '2020-01-30') } @@ -299,7 +343,7 @@ RSpec.describe IssuablesHelper do initialTitleText: issue.title, initialDescriptionHtml: '<p dir="auto">issue text</p>', initialDescriptionText: 'issue text', - initialTaskStatus: '0 of 0 tasks completed', + initialTaskStatus: '0 of 0 checklist items completed', issueType: 'issue', iid: issue.iid.to_s, isHidden: false diff --git a/spec/helpers/members_helper_spec.rb b/spec/helpers/members_helper_spec.rb index e94eb63fc2c..4a3a623ce77 100644 --- a/spec/helpers/members_helper_spec.rb +++ b/spec/helpers/members_helper_spec.rb @@ -74,4 +74,37 @@ RSpec.describe MembersHelper do expect(localized_tasks_to_be_done_choices).to include(*MemberTask::TASKS.keys) end end + + describe '#member_request_access_link' do + let(:project) { create(:project) } + let(:group) { create(:group) } + let(:project_member) { create(:project_member, :reporter, project: project) } + let(:group_member) { create(:group_member, :reporter, group: group) } + + it 'returns request link for project members' do + user = project_member.user + source = project_member.source + link = member_request_access_link(project_member) + + user_link = link_to user.name, user, class: :highlight + access_level = content_tag :span, project_member.human_access, class: :highlight + source_link = link_to source.human_name, polymorphic_url([project_member.source, :members]), class: :highlight + source_type = source.model_name.singular + + expect(link).to eq "#{user_link} requested #{access_level} access to the #{source_link} #{source_type}." + end + + it 'returns the request link for group members' do + user = group_member.user + source = group_member.source + link = member_request_access_link(group_member) + + user_link = link_to user.name, user, class: :highlight + access_level = content_tag :span, group_member.human_access, class: :highlight + source_link = link_to source.human_name, polymorphic_url([group_member.source, :members]), class: :highlight + source_type = source.model_name.singular + + expect(link).to eq "#{user_link} requested #{access_level} access to the #{source_link} #{source_type}." + end + end end diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb index 97ad55d9df9..fb23b5c1dc8 100644 --- a/spec/helpers/merge_requests_helper_spec.rb +++ b/spec/helpers/merge_requests_helper_spec.rb @@ -27,6 +27,38 @@ RSpec.describe MergeRequestsHelper do end end + describe '#merge_path_description' do + let(:project) { create(:project) } + let(:forked_project) { fork_project(project) } + let(:merge_request_forked) { create(:merge_request, source_project: forked_project, target_project: project) } + let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } + + where(:case_name, :mr, :with_arrow, :result) do + [ + ['forked with arrow', ref(:merge_request_forked), true, lazy do + "Project:Branches: #{ + mr.source_project_path}:#{mr.source_branch} → #{ + mr.target_project.full_path}:#{mr.target_branch}" + end], + ['forked default', ref(:merge_request_forked), false, lazy do + "Project:Branches: #{ + mr.source_project_path}:#{mr.source_branch} to #{ + mr.target_project.full_path}:#{mr.target_branch}" + end], + ['with arrow', ref(:merge_request), true, lazy { "Branches: #{mr.source_branch} → #{mr.target_branch}" }], + ['default', ref(:merge_request), false, lazy { "Branches: #{mr.source_branch} to #{mr.target_branch}" }] + ] + end + + with_them do + subject { merge_path_description(mr, with_arrow: with_arrow) } + + it { + is_expected.to eq(result) + } + end + end + describe '#tab_link_for' do let(:merge_request) { create(:merge_request, :simple) } let(:options) { {} } @@ -46,8 +78,7 @@ RSpec.describe MergeRequestsHelper do let(:user) do double( assigned_open_merge_requests_count: 1, - review_requested_open_merge_requests_count: 2, - attention_requested_open_merge_requests_count: 3 + review_requested_open_merge_requests_count: 2 ) end @@ -57,33 +88,12 @@ RSpec.describe MergeRequestsHelper do allow(helper).to receive(:current_user).and_return(user) end - describe 'mr_attention_requests disabled' do - before do - allow(user).to receive(:mr_attention_requests_enabled?).and_return(false) - end - - it "returns assigned, review requested and total merge request counts" do - expect(subject).to eq( - assigned: user.assigned_open_merge_requests_count, - review_requested: user.review_requested_open_merge_requests_count, - total: user.assigned_open_merge_requests_count + user.review_requested_open_merge_requests_count - ) - end - end - - describe 'mr_attention_requests enabled' do - before do - allow(user).to receive(:mr_attention_requests_enabled?).and_return(true) - end - - it "returns assigned, review requested, attention requests and total merge request counts" do - expect(subject).to eq( - assigned: user.assigned_open_merge_requests_count, - review_requested: user.review_requested_open_merge_requests_count, - attention_requested_count: user.attention_requested_open_merge_requests_count, - total: user.attention_requested_open_merge_requests_count - ) - end + it "returns assigned, review requested and total merge request counts" do + expect(subject).to eq( + assigned: user.assigned_open_merge_requests_count, + review_requested: user.review_requested_open_merge_requests_count, + total: user.assigned_open_merge_requests_count + user.review_requested_open_merge_requests_count + ) end end @@ -134,6 +144,7 @@ RSpec.describe MergeRequestsHelper do it 'returns reviewer label with no names' do expect(helper.reviewers_label(merge_request)).to eq("Reviewers: ") end + it 'returns reviewer label only with include_value: false' do expect(helper.reviewers_label(merge_request, include_value: false)).to eq("Reviewers") end diff --git a/spec/helpers/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb index 39f0e1c15f5..f7500709d0e 100644 --- a/spec/helpers/namespaces_helper_spec.rb +++ b/spec/helpers/namespaces_helper_spec.rb @@ -45,39 +45,6 @@ RSpec.describe NamespacesHelper do user_group.add_owner(user) end - describe '#namespaces_as_json' do - let(:result) { helper.namespaces_as_json(user) } - - before do - allow(helper).to receive(:current_user).and_return(user) - end - - it 'returns the user\'s groups' do - json_data = Gitlab::Json.parse(result) - - expect(result).to include('group') - expect(json_data['group']).to include( - "id" => user_group.id, - "name" => user_group.name, - "display_path" => user_group.full_path, - "human_name" => user_group.human_name - ) - end - - it 'returns the user\'s namespace' do - user_namespace = user.namespace - json_data = Gitlab::Json.parse(result) - - expect(result).to include('user') - expect(json_data['user']).to include( - "id" => user_namespace.id, - "name" => user_namespace.name, - "display_path" => user_namespace.full_path, - "human_name" => user_namespace.human_name - ) - end - end - describe '#namespaces_options' do context 'when admin mode is enabled', :enable_admin_mode do it 'returns groups without being a member for admin' do diff --git a/spec/helpers/nav/new_dropdown_helper_spec.rb b/spec/helpers/nav/new_dropdown_helper_spec.rb index 2fe237fb996..45664a7e0bd 100644 --- a/spec/helpers/nav/new_dropdown_helper_spec.rb +++ b/spec/helpers/nav/new_dropdown_helper_spec.rb @@ -173,7 +173,7 @@ RSpec.describe Nav::NewDropdownHelper do menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'new_subgroup', title: 'New subgroup', - href: "/groups/new?parent_id=#{group.id}", + href: "/groups/new?parent_id=#{group.id}#create-group-pane", data: { track_action: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' } ) ) diff --git a/spec/helpers/nav/top_nav_helper_spec.rb b/spec/helpers/nav/top_nav_helper_spec.rb index 9d43e057521..e4fa503b5ee 100644 --- a/spec/helpers/nav/top_nav_helper_spec.rb +++ b/spec/helpers/nav/top_nav_helper_spec.rb @@ -88,18 +88,6 @@ RSpec.describe Nav::TopNavHelper do expect(subject[:shortcuts]).to eq(expected_shortcuts) end - it 'has expected :secondary' do - expected_secondary = [ - ::Gitlab::Nav::TopNavMenuItem.build( - href: '/help', - id: 'help', - title: 'Help', - icon: 'question-o' - ) - ] - expect(subject[:secondary]).to eq(expected_secondary) - end - context 'with current nav as project' do before do helper.nav('project') diff --git a/spec/helpers/profiles_helper_spec.rb b/spec/helpers/profiles_helper_spec.rb index 399726263db..63641e65942 100644 --- a/spec/helpers/profiles_helper_spec.rb +++ b/spec/helpers/profiles_helper_spec.rb @@ -67,38 +67,6 @@ RSpec.describe ProfilesHelper do end end - describe "#user_status_set_to_busy?" do - using RSpec::Parameterized::TableSyntax - - where(:availability, :result) do - "busy" | true - "not_set" | false - "" | false - nil | false - end - - with_them do - it { expect(helper.user_status_set_to_busy?(OpenStruct.new(availability: availability))).to eq(result) } - end - end - - describe "#show_status_emoji?" do - using RSpec::Parameterized::TableSyntax - - where(:message, :emoji, :result) do - "Some message" | UserStatus::DEFAULT_EMOJI | true - "Some message" | "" | true - "" | "basketball" | true - "" | "basketball" | true - "" | UserStatus::DEFAULT_EMOJI | false - "" | UserStatus::DEFAULT_EMOJI | false - end - - with_them do - it { expect(helper.show_status_emoji?(OpenStruct.new(message: message, emoji: emoji))).to eq(result) } - end - end - describe "#ssh_key_expiration_tooltip" do using RSpec::Parameterized::TableSyntax diff --git a/spec/helpers/projects/pipeline_helper_spec.rb b/spec/helpers/projects/pipeline_helper_spec.rb index 2b2dad286c7..8ce4e9f5293 100644 --- a/spec/helpers/projects/pipeline_helper_spec.rb +++ b/spec/helpers/projects/pipeline_helper_spec.rb @@ -27,7 +27,13 @@ RSpec.describe Projects::PipelineHelper do metrics_path: namespace_project_ci_prometheus_metrics_histograms_path(namespace_id: project.namespace, project_id: project, format: :json), pipeline_iid: pipeline.iid, pipeline_project_path: project.full_path, - total_job_count: pipeline.total_size + total_job_count: pipeline.total_size, + summary_endpoint: summary_project_pipeline_tests_path(project, pipeline, format: :json), + suite_endpoint: project_pipeline_test_path(project, pipeline, suite_name: 'suite', format: :json), + blob_path: project_blob_path(project, pipeline.sha), + has_test_report: pipeline.has_reports?(Ci::JobArtifact.test_reports), + empty_state_image_path: match_asset_path('illustrations/empty-state/empty-test-cases-lg.svg'), + artifacts_expired_image_path: match_asset_path('illustrations/pipeline.svg') }) end end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index b7cc8c217a4..04c066986b7 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -966,7 +966,10 @@ RSpec.describe ProjectsHelper do 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 + containerRegistryAccessLevel: project.project_feature.container_registry_access_level, + environmentsAccessLevel: project.project_feature.environments_access_level, + featureFlagsAccessLevel: project.project_feature.feature_flags_access_level, + releasesAccessLevel: project.project_feature.releases_access_level ) end @@ -1313,4 +1316,38 @@ RSpec.describe ProjectsHelper do end end end + + describe '#project_coverage_chart_data_attributes' do + let(:ref) { 'ref' } + let(:daily_coverage_options) do + { + base_params: { + start_date: Date.current - 90.days, + end_date: Date.current, + ref_path: project.repository.expand_ref(ref), + param_type: 'coverage' + }, + download_path: namespace_project_ci_daily_build_group_report_results_path( + namespace_id: project.namespace, + project_id: project, + format: :csv + ), + graph_api_path: namespace_project_ci_daily_build_group_report_results_path( + namespace_id: project.namespace, + project_id: project, + format: :json + ) + } + end + + it 'returns project data to render coverage chart' do + expect(helper.project_coverage_chart_data_attributes(daily_coverage_options, ref)).to include( + graph_endpoint: start_with(daily_coverage_options.fetch(:graph_api_path)), + graph_start_date: daily_coverage_options.dig(:base_params, :start_date).strftime('%b %d'), + graph_end_date: daily_coverage_options.dig(:base_params, :end_date).strftime('%b %d'), + graph_ref: ref, + graph_csv_path: start_with(daily_coverage_options.fetch(:download_path)) + ) + end + end end diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index 1ead1fc9b8b..513e2865ee3 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -74,19 +74,21 @@ RSpec.describe SearchHelper do expect(result.keys).to match_array(%i[category id value label url avatar_url]) end - it 'includes the users recently viewed issues', :aggregate_failures do + it 'includes the users recently viewed issues and project with correct order', :aggregate_failures do recent_issues = instance_double(::Gitlab::Search::RecentIssues) expect(::Gitlab::Search::RecentIssues).to receive(:new).with(user: user).and_return(recent_issues) project1 = create(:project, :with_avatar, namespace: user.namespace) project2 = create(:project, namespace: user.namespace) issue1 = create(:issue, title: 'issue 1', project: project1) issue2 = create(:issue, title: 'issue 2', project: project2) + project = create(:project, title: 'the search term') + project.add_developer(user) 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(2) + expect(results.count).to eq(3) expect(results[0]).to include({ category: 'Recent issues', @@ -103,6 +105,13 @@ RSpec.describe SearchHelper do url: Gitlab::Routing.url_helpers.project_issue_path(issue2.project, issue2), avatar_url: '' # This project didn't have an avatar so set this to '' }) + + expect(results[2]).to include({ + category: 'Projects', + id: project.id, + label: project.full_name, + url: Gitlab::Routing.url_helpers.project_path(project) + }) end it 'includes the users recently viewed issues with the exact same name', :aggregate_failures do diff --git a/spec/helpers/storage_helper_spec.rb b/spec/helpers/storage_helper_spec.rb index 4b46bf169e0..6c3556c874b 100644 --- a/spec/helpers/storage_helper_spec.rb +++ b/spec/helpers/storage_helper_spec.rb @@ -57,8 +57,8 @@ RSpec.describe StorageHelper do let_it_be(:paid_group) { create(:group) } before do - allow(helper).to receive(:can?).with(current_user, :maintain_namespace, free_group).and_return(true) - allow(helper).to receive(:can?).with(current_user, :maintain_namespace, paid_group).and_return(true) + allow(helper).to receive(:can?).with(current_user, :maintainer_access, free_group).and_return(true) + allow(helper).to receive(:can?).with(current_user, :maintainer_access, paid_group).and_return(true) allow(helper).to receive(:current_user) { current_user } allow(paid_group).to receive(:paid?).and_return(true) @@ -84,7 +84,7 @@ RSpec.describe StorageHelper do end it 'returns nil when current_user do not have access usage quotas page' do - allow(helper).to receive(:can?).with(current_user, :maintain_namespace, free_group).and_return(false) + allow(helper).to receive(:can?).with(current_user, :maintainer_access, free_group).and_return(false) expect(helper.storage_enforcement_banner_info(free_group)).to be(nil) end @@ -97,12 +97,16 @@ RSpec.describe StorageHelper do context 'when current_user can access the usage quotas page' do it 'returns a hash' do + used_storage = helper.storage_counter(free_group.root_storage_statistics&.storage_size || 0) + expect(helper.storage_enforcement_banner_info(free_group)).to eql({ - text: "From #{storage_enforcement_date} storage limits will apply to this namespace. You are currently using 0 Bytes of namespace storage. View and manage your usage from <strong>Group settings > Usage quotas</strong>.", + text_paragraph_1: "Effective #{storage_enforcement_date}, namespace storage limits will apply to the <strong>#{free_group.name}</strong> namespace. View the <a href=\"/help/user/usage_quotas#namespace-storage-limit-enforcement-schedule\" >rollout schedule for this change</a>.", + text_paragraph_2: "The namespace is currently using <strong>#{used_storage}</strong> of namespace storage. Group owners can view namespace storage usage and purchase more from <strong>Group settings > Usage quotas</strong>. <a href=\"/help/user/usage_quotas#manage-your-storage-usage\" >Learn more.</a>", + text_paragraph_3: "See our <a href=\"https://about.gitlab.com/pricing/faq-efficient-free-tier/#storage-limits-on-gitlab-saas-free-tier\" >FAQ</a> for more information.", variant: 'warning', + namespace_id: free_group.id, callouts_feature_name: 'storage_enforcement_banner_second_enforcement_threshold', - callouts_path: '/-/users/group_callouts', - learn_more_link: '<a rel="noopener noreferrer" target="_blank" href="/help//">Learn more.</a>' + callouts_path: '/-/users/group_callouts' }) end @@ -112,7 +116,7 @@ RSpec.describe StorageHelper do end it 'returns a hash with the correct storage size text' do - expect(helper.storage_enforcement_banner_info(free_group)[:text]).to eql("From #{storage_enforcement_date} storage limits will apply to this namespace. You are currently using 100 KB of namespace storage. View and manage your usage from <strong>Group settings > Usage quotas</strong>.") + expect(helper.storage_enforcement_banner_info(free_group)[:text_paragraph_2]).to eql("The namespace is currently using <strong>100 KB</strong> of namespace storage. Group owners can view namespace storage usage and purchase more from <strong>Group settings > Usage quotas</strong>. <a href=\"/help/user/usage_quotas#manage-your-storage-usage\" >Learn more.</a>") end end @@ -120,11 +124,12 @@ RSpec.describe StorageHelper do let_it_be(:sub_group) { build(:group) } before do + allow(helper).to receive(:can?).with(current_user, :maintainer_access, sub_group).and_return(true) allow(sub_group).to receive(:root_ancestor).and_return(free_group) end it 'returns the banner hash' do - expect(helper.storage_enforcement_banner_info(sub_group).keys).to match_array(%i(text variant callouts_feature_name callouts_path learn_more_link)) + expect(helper.storage_enforcement_banner_info(sub_group).keys).to match_array(%i(text_paragraph_1 text_paragraph_2 text_paragraph_3 variant namespace_id callouts_feature_name callouts_path)) end end end @@ -136,7 +141,8 @@ RSpec.describe StorageHelper do end it 'returns the enforcement info' do - expect(helper.storage_enforcement_banner_info(free_group)[:text]).to include("From #{Date.current} storage limits will apply to this namespace.") + puts helper.storage_enforcement_banner_info(free_group)[:text_paragraph_1] + expect(helper.storage_enforcement_banner_info(free_group)[:text_paragraph_1]).to include("Effective #{Date.current}, namespace storage limits will apply") end end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 88030299574..78a15f52be5 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -421,6 +421,25 @@ RSpec.describe UsersHelper do end end + describe '#user_email_help_text' do + subject(:user_email_help_text) { helper.user_email_help_text(user) } + + context 'when `user.unconfirmed_email` is not set' do + it 'contains avatar detection text' do + expect(user_email_help_text).to include _('We also use email for avatar detection if no avatar is uploaded.') + end + end + + context 'when `user.unconfirmed_email` is set' do + let(:user) { create(:user, :unconfirmed, unconfirmed_email: 'foo@bar.com') } + + it 'contains resend confirmation e-mail text' do + expect(user_email_help_text).to include _('Resend confirmation e-mail') + expect(user_email_help_text).to include _('Please click the link in the confirmation email before continuing. It was sent to ') + end + end + end + describe '#admin_user_actions_data_attributes' do subject(:data) { helper.admin_user_actions_data_attributes(user) } |