diff options
Diffstat (limited to 'spec/helpers')
25 files changed, 805 insertions, 274 deletions
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 264431b1bb5..a4b2c963c74 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -486,6 +486,25 @@ RSpec.describe ApplicationHelper do end end + describe '#gitlab_ui_form_with' do + let_it_be(:user) { build(:user) } + + before do + allow(helper).to receive(:users_path).and_return('/root') + allow(helper).to receive(:form_with).and_call_original + end + + it 'adds custom form builder to options and calls `form_with`' do + options = { model: user, html: { class: 'foo-bar' } } + expected_options = options.merge({ builder: ::Gitlab::FormBuilders::GitlabUiFormBuilder }) + + expect do |b| + helper.gitlab_ui_form_with(**options, &b) + end.to yield_with_args(::Gitlab::FormBuilders::GitlabUiFormBuilder) + expect(helper).to have_received(:form_with).with(expected_options) + end + end + describe '#page_class' do context 'when logged_out_marketing_header experiment is enabled' do let_it_be(:expected_class) { 'logged-out-marketing-header-candidate' } diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb index 1703727db21..c75e9caa77a 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -51,12 +51,13 @@ RSpec.describe ApplicationSettingsHelper do end it 'contains rate limit parameters' do - expect(helper.visible_attributes).to include(*%i( - issues_create_limit notes_create_limit project_export_limit - project_download_export_limit project_export_limit project_import_limit - raw_blob_request_limit group_export_limit group_download_export_limit - group_import_limit users_get_by_id_limit search_rate_limit search_rate_limit_unauthenticated - )) + expect(helper.visible_attributes).to include( + *%i( + issues_create_limit notes_create_limit project_export_limit + project_download_export_limit project_export_limit project_import_limit + raw_blob_request_limit group_export_limit group_download_export_limit + group_import_limit users_get_by_id_limit search_rate_limit search_rate_limit_unauthenticated + )) end context 'when GitLab.com' do @@ -233,23 +234,24 @@ RSpec.describe ApplicationSettingsHelper do end it 'returns available formats correctly' do - expect(helper.kroki_available_formats).to eq([ - { - name: 'kroki_formats_blockdiag', - label: 'BlockDiag (includes BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag, and RackDiag)', - value: true - }, - { - name: 'kroki_formats_bpmn', - label: 'BPMN', - value: false - }, - { - name: 'kroki_formats_excalidraw', - label: 'Excalidraw', - value: false - } - ]) + expect(helper.kroki_available_formats).to eq( + [ + { + name: 'kroki_formats_blockdiag', + label: 'BlockDiag (includes BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag, and RackDiag)', + value: true + }, + { + name: 'kroki_formats_bpmn', + label: 'BPMN', + value: false + }, + { + name: 'kroki_formats_excalidraw', + label: 'Excalidraw', + value: false + } + ]) end end diff --git a/spec/helpers/boards_helper_spec.rb b/spec/helpers/boards_helper_spec.rb index ccc150c397a..27b7bac5a88 100644 --- a/spec/helpers/boards_helper_spec.rb +++ b/spec/helpers/boards_helper_spec.rb @@ -105,10 +105,6 @@ RSpec.describe BoardsHelper do allow(helper).to receive(:can?).with(user, :admin_issue_board, project).and_return(false) end - it 'returns a board_lists_path as lists_endpoint' do - expect(helper.board_data[:lists_endpoint]).to eq(board_lists_path(project_board)) - end - it 'returns board type as parent' do expect(helper.board_data[:parent]).to eq('project') end @@ -189,14 +185,4 @@ RSpec.describe BoardsHelper do end end end - - describe '#current_board_json' do - let(:board_json) { helper.current_board_json } - - it 'can serialise with a basic set of attributes' do - assign(:board, project_board) - - expect(board_json).to match_schema('current-board') - end - end end diff --git a/spec/helpers/ci/pipeline_editor_helper_spec.rb b/spec/helpers/ci/pipeline_editor_helper_spec.rb index 1950d685980..c9aac63a883 100644 --- a/spec/helpers/ci/pipeline_editor_helper_spec.rb +++ b/spec/helpers/ci/pipeline_editor_helper_spec.rb @@ -3,8 +3,6 @@ require 'spec_helper' RSpec.describe Ci::PipelineEditorHelper do - include CycleAnalyticsHelpers - let_it_be(:project) { create(:project) } describe 'can_view_pipeline_editor?' do @@ -25,6 +23,30 @@ RSpec.describe Ci::PipelineEditorHelper do describe '#js_pipeline_editor_data' do let(:project) { create(:project, :repository) } + let(:default_helper_data) do + { + "ci-config-path": project.ci_config_path_or_default, + "ci-examples-help-page-path" => help_page_path('ci/examples/index'), + "ci-help-page-path" => help_page_path('ci/index'), + "ci-lint-path" => project_ci_lint_path(project), + "default-branch" => project.default_branch_or_main, + "empty-state-illustration-path" => 'illustrations/empty.svg', + "initial-branch-name" => nil, + "includes-help-page-path" => help_page_path('ci/yaml/includes'), + "lint-help-page-path" => help_page_path('ci/lint', anchor: 'check-cicd-syntax'), + "lint-unavailable-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'configuration-validation-currently-not-available-message'), + "needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'), + "new-merge-request-path" => '/mock/project/-/merge_requests/new', + "pipeline-page-path" => project_pipelines_path(project), + "project-path" => project.path, + "project-full-path" => project.full_path, + "project-namespace" => project.namespace.full_path, + "simulate-pipeline-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'simulate-a-cicd-pipeline'), + "uses-external-config" => 'false', + "validate-tab-illustration-path" => 'illustrations/validate.svg', + "yml-help-page-path" => help_page_path('ci/yaml/index') + } + end before do allow(helper) @@ -46,29 +68,10 @@ RSpec.describe Ci::PipelineEditorHelper do context 'with a project with commits' do it 'returns pipeline editor data' do - expect(pipeline_editor_data).to eq({ - "ci-config-path": project.ci_config_path_or_default, - "ci-examples-help-page-path" => help_page_path('ci/examples/index'), - "ci-help-page-path" => help_page_path('ci/index'), - "ci-lint-path" => project_ci_lint_path(project), - "default-branch" => project.default_branch_or_main, - "empty-state-illustration-path" => 'illustrations/empty.svg', - "initial-branch-name" => nil, - "includes-help-page-path" => help_page_path('ci/yaml/includes'), - "lint-help-page-path" => help_page_path('ci/lint', anchor: 'check-cicd-syntax'), - "lint-unavailable-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'configuration-validation-currently-not-available-message'), - "needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'), - "new-merge-request-path" => '/mock/project/-/merge_requests/new', + expect(pipeline_editor_data).to eq(default_helper_data.merge({ "pipeline_etag" => graphql_etag_pipeline_sha_path(project.commit.sha), - "pipeline-page-path" => project_pipelines_path(project), - "project-path" => project.path, - "project-full-path" => project.full_path, - "project-namespace" => project.namespace.full_path, - "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') - }) + "total-branches" => project.repository.branches.length + })) end end @@ -76,29 +79,10 @@ RSpec.describe Ci::PipelineEditorHelper do let(:project) { create(:project, :empty_repo) } it 'returns pipeline editor data' do - expect(pipeline_editor_data).to eq({ - "ci-config-path": project.ci_config_path_or_default, - "ci-examples-help-page-path" => help_page_path('ci/examples/index'), - "ci-help-page-path" => help_page_path('ci/index'), - "ci-lint-path" => project_ci_lint_path(project), - "default-branch" => project.default_branch_or_main, - "empty-state-illustration-path" => 'illustrations/empty.svg', - "initial-branch-name" => nil, - "includes-help-page-path" => help_page_path('ci/yaml/includes'), - "lint-help-page-path" => help_page_path('ci/lint', anchor: 'check-cicd-syntax'), - "lint-unavailable-help-page-path" => help_page_path('ci/pipeline_editor/index', anchor: 'configuration-validation-currently-not-available-message'), - "needs-help-page-path" => help_page_path('ci/yaml/index', anchor: 'needs'), - "new-merge-request-path" => '/mock/project/-/merge_requests/new', + expect(pipeline_editor_data).to eq(default_helper_data.merge({ "pipeline_etag" => '', - "pipeline-page-path" => project_pipelines_path(project), - "project-path" => project.path, - "project-full-path" => project.full_path, - "project-namespace" => project.namespace.full_path, - "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') - }) + "total-branches" => 0 + })) end end @@ -113,11 +97,38 @@ RSpec.describe Ci::PipelineEditorHelper do end end + context 'with a remote CI config' do + before do + create(:commit, project: project) + project.ci_config_path = 'http://example.com/path/to/ci/config.yml' + end + + it 'returns true for uses-external-config in pipeline editor data' do + expect(pipeline_editor_data['uses-external-config']).to eq('true') + end + end + + context 'with a CI config from an external project' do + before do + create(:commit, project: project) + project.ci_config_path = '.gitlab-ci.yml@group/project' + end + + it 'returns true for uses-external-config in pipeline editor data' do + expect(pipeline_editor_data['uses-external-config']).to eq('true') + end + end + context 'with a non-default branch name' do let(:user) { create(:user) } before do - create_commit('Message', project, user, 'feature') + project.repository.commit_files( + user, + branch_name: 'feature', + message: 'Message', + actions: [{ action: :create, file_path: 'a/new.file', content: 'This is a new file' }] + ) controller.params[:branch_name] = 'feature' end diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb index 0cc53da98b2..27738f73ea5 100644 --- a/spec/helpers/commits_helper_spec.rb +++ b/spec/helpers/commits_helper_spec.rb @@ -227,10 +227,11 @@ RSpec.describe CommitsHelper do end it 'returns data for cherry picking into a project' do - expect(helper.cherry_pick_projects_data(forked_project)).to match_array([ - { id: project.id.to_s, name: project.full_path, refsUrl: refs_project_path(project) }, - { id: forked_project.id.to_s, name: forked_project.full_path, refsUrl: refs_project_path(forked_project) } - ]) + expect(helper.cherry_pick_projects_data(forked_project)).to match_array( + [ + { id: project.id.to_s, name: project.full_path, refsUrl: refs_project_path(project) }, + { id: forked_project.id.to_s, name: forked_project.full_path, refsUrl: refs_project_path(forked_project) } + ]) end end diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb index cc6804f0355..7005b3dc53e 100644 --- a/spec/helpers/events_helper_spec.rb +++ b/spec/helpers/events_helper_spec.rb @@ -24,6 +24,45 @@ RSpec.describe EventsHelper do end end + describe '#localized_action_name' do + it 'handles all valid design events' do + created, updated, destroyed = %i[created updated destroyed].map do |trait| + event = build(:design_event, trait) + helper.localized_action_name(event) + end + + expect(created).to eq(_('added')) + expect(updated).to eq(_('updated')) + expect(destroyed).to eq(_('removed')) + end + + context 'handles correct base actions' do + using RSpec::Parameterized::TableSyntax + + where(:trait, :localized_action_name) do + :created | s_('Event|created') + :updated | s_('Event|opened') + :closed | s_('Event|closed') + :reopened | s_('Event|opened') + :commented | s_('Event|commented on') + :merged | s_('Event|accepted') + :joined | s_('Event|joined') + :left | s_('Event|left') + :destroyed | s_('Event|destroyed') + :expired | s_('Event|removed due to membership expiration from') + :approved | s_('Event|approved') + end + + with_them do + it 'with correct name and method' do + event = build(:event, trait) + + expect(helper.localized_action_name(event)).to eq(localized_action_name) + end + end + end + end + describe '#event_commit_title' do let(:message) { 'foo & bar ' + 'A' * 70 + '\n' + 'B' * 80 } diff --git a/spec/helpers/form_helper_spec.rb b/spec/helpers/form_helper_spec.rb index 4b76c370810..14ff5d97057 100644 --- a/spec/helpers/form_helper_spec.rb +++ b/spec/helpers/form_helper_spec.rb @@ -6,35 +6,85 @@ RSpec.describe FormHelper do include Devise::Test::ControllerHelpers describe '#dropdown_max_select' do + let(:feature_flag) { :limit_reviewer_and_assignee_size } + context "with the :limit_reviewer_and_assignee_size feature flag on" do + before do + stub_feature_flags(feature_flag => true) + end + it 'correctly returns the max amount of reviewers or assignees to allow' do - max = MergeRequest::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS + max = Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS - expect(helper.dropdown_max_select({})) + expect(helper.dropdown_max_select({}, feature_flag)) .to eq(max) - expect(helper.dropdown_max_select({ 'max-select'.to_sym => 5 })) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => 5 }, feature_flag)) .to eq(5) - expect(helper.dropdown_max_select({ 'max-select'.to_sym => max + 5 })) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => max + 5 }, feature_flag)) .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) + stub_feature_flags(feature_flag => false) end it 'correctly returns the max amount of reviewers or assignees to allow' do - expect(helper.dropdown_max_select({})) + expect(helper.dropdown_max_select({}, feature_flag)) .to eq(nil) - expect(helper.dropdown_max_select({ 'max-select'.to_sym => 5 })) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => 5 }, feature_flag)) .to eq(5) - expect(helper.dropdown_max_select({ 'max-select'.to_sym => 120 })) + expect(helper.dropdown_max_select({ 'max-select'.to_sym => 120 }, feature_flag)) .to eq(120) end end end + describe '#assignees_dropdown_options' do + let(:merge_request) { build(:merge_request) } + + context "with the :limit_assignees_per_issuable feature flag on" do + context "with multiple assignees" do + it 'correctly returns the max amount of assignees to allow' do + allow(helper).to receive(:merge_request_supports_multiple_assignees?).and_return(true) + + expect(helper.assignees_dropdown_options(:merge_request)[:data][:'max-select']) + .to eq(Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS) + end + end + + context "with only 1 assignee" do + it 'correctly returns the max amount of assignees to allow' do + expect(helper.assignees_dropdown_options(:merge_request)[:data][:'max-select']) + .to eq(1) + end + end + end + + context "with the :limit_assignees_per_issuable feature flag off" do + before do + stub_feature_flags(limit_assignees_per_issuable: false) + end + + context "with multiple assignees" do + it 'correctly returns the max amount of assignees to allow' do + allow(helper).to receive(:merge_request_supports_multiple_assignees?).and_return(true) + + expect(helper.assignees_dropdown_options(:merge_request)[:data][:'max-select']) + .to eq(nil) + end + end + + context "with only 1 assignee" do + it 'correctly returns the max amount of assignees to allow' do + expect(helper.assignees_dropdown_options(:merge_request)[:data][:'max-select']) + .to eq(1) + end + end + end + end + describe '#reviewers_dropdown_options' do let(:merge_request) { build(:merge_request) } @@ -44,7 +94,7 @@ RSpec.describe FormHelper 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) + .to eq(Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS) end end diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index 00e620832b3..a38483a956d 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -388,22 +388,30 @@ RSpec.describe GroupsHelper do end describe '#show_thanks_for_purchase_alert?' do - subject { helper.show_thanks_for_purchase_alert? } + subject { helper.show_thanks_for_purchase_alert?(quantity) } - it 'returns true with purchased_quantity present in params' do - allow(controller).to receive(:params) { { purchased_quantity: '1' } } + context 'with quantity present' do + let(:quantity) { 1 } - is_expected.to be_truthy + it 'returns true' do + is_expected.to be_truthy + end end - it 'returns false with purchased_quantity not present in params' do - is_expected.to be_falsey + context 'with quantity not present' do + let(:quantity) { nil } + + it 'returns false' do + is_expected.to be_falsey + end end - it 'returns false with purchased_quantity is empty in params' do - allow(controller).to receive(:params) { { purchased_quantity: '' } } + context 'with quantity empty' do + let(:quantity) { '' } - is_expected.to be_falsey + it 'returns false' do + is_expected.to be_falsey + end end end @@ -523,12 +531,14 @@ RSpec.describe GroupsHelper do describe '#group_overview_tabs_app_data' do let_it_be(:group) { create(:group) } let_it_be(:user) { create(:user) } + let_it_be(:initial_sort) { 'created_asc' } before do allow(helper).to receive(:current_user).and_return(user) allow(helper).to receive(:can?).with(user, :create_subgroup, group) { true } allow(helper).to receive(:can?).with(user, :create_projects, group) { true } + allow(helper).to receive(:project_list_sort_by).and_return(initial_sort) end it 'returns expected hash' do @@ -537,7 +547,8 @@ RSpec.describe GroupsHelper do subgroups_and_projects_endpoint: including("/groups/#{group.path}/-/children.json"), shared_projects_endpoint: including("/groups/#{group.path}/-/shared_projects.json"), archived_projects_endpoint: including("/groups/#{group.path}/-/children.json?archived=only"), - current_group_visibility: group.visibility + current_group_visibility: group.visibility, + initial_sort: initial_sort }.merge(helper.group_overview_tabs_app_data(group)) ) end diff --git a/spec/helpers/hooks_helper_spec.rb b/spec/helpers/hooks_helper_spec.rb index bac73db5dd4..8f438a3ddc8 100644 --- a/spec/helpers/hooks_helper_spec.rb +++ b/spec/helpers/hooks_helper_spec.rb @@ -8,6 +8,13 @@ RSpec.describe HooksHelper do let(:service_hook) { create(:service_hook, integration: create(:drone_ci_integration)) } let(:system_hook) { create(:system_hook) } + describe '#webhook_form_data' do + subject { helper.webhook_form_data(project_hook) } + + it { expect(subject[:url]).to eq(project_hook.url) } + it { expect(subject[:url_variables]).to be_nil } + end + describe '#link_to_test_hook' do let(:trigger) { 'push_events' } diff --git a/spec/helpers/ide_helper_spec.rb b/spec/helpers/ide_helper_spec.rb index dc0a234f981..e750379f62d 100644 --- a/spec/helpers/ide_helper_spec.rb +++ b/spec/helpers/ide_helper_spec.rb @@ -5,75 +5,113 @@ require 'spec_helper' RSpec.describe IdeHelper do describe '#ide_data' do let_it_be(:project) { create(:project) } + let_it_be(:user) { project.creator } before do - allow(helper).to receive(:current_user).and_return(project.creator) + allow(helper).to receive(:current_user).and_return(user) + allow(helper).to receive(:content_security_policy_nonce).and_return('test-csp-nonce') end - context 'when instance vars are not set' do - it 'returns instance data in the hash as nil' do - expect(helper.ide_data) - .to include( - 'branch-name' => nil, - 'file-path' => nil, - 'merge-request' => nil, - 'fork-info' => nil, - 'project' => nil, - 'preview-markdown-path' => nil - ) - end - end - - context 'when instance vars are set' do - it 'returns instance data in the hash' do - fork_info = { ide_path: '/test/ide/path' } + context 'with vscode_web_ide=true and instance vars set' do + before do + stub_feature_flags(vscode_web_ide: true) self.instance_variable_set(:@branch, 'master') - self.instance_variable_set(:@path, 'foo/bar') - self.instance_variable_set(:@merge_request, '1') - self.instance_variable_set(:@fork_info, fork_info) self.instance_variable_set(:@project, project) + end - serialized_project = API::Entities::Project.represent(project, current_user: project.creator).to_json - + it 'returns hash' do expect(helper.ide_data) - .to include( + .to eq( + 'can-use-new-web-ide' => 'true', + 'use-new-web-ide' => 'true', + 'user-preferences-path' => profile_preferences_path, 'branch-name' => 'master', - 'file-path' => 'foo/bar', - 'merge-request' => '1', - 'fork-info' => fork_info.to_json, - 'project' => serialized_project, - 'preview-markdown-path' => Gitlab::Routing.url_helpers.preview_markdown_project_path(project) + 'project-path' => project.path_with_namespace, + 'csp-nonce' => 'test-csp-nonce' ) end + + it 'does not use new web ide if user.use_legacy_web_ide' do + allow(user).to receive(:use_legacy_web_ide).and_return(true) + + expect(helper.ide_data).to include('use-new-web-ide' => 'false') + end end - context 'environments guidance experiment', :experiment do + context 'with vscode_web_ide=false' do before do - stub_experiments(in_product_guidance_environments_webide: :candidate) - self.instance_variable_set(:@project, project) + stub_feature_flags(vscode_web_ide: false) end - context 'when project has no enviornments' do - it 'enables environment guidance' do - expect(helper.ide_data).to include('enable-environments-guidance' => 'true') + context 'when instance vars are not set' do + it 'returns instance data in the hash as nil' do + expect(helper.ide_data) + .to include( + 'can-use-new-web-ide' => 'false', + 'use-new-web-ide' => 'false', + 'user-preferences-path' => profile_preferences_path, + 'branch-name' => nil, + 'file-path' => nil, + 'merge-request' => nil, + 'fork-info' => nil, + 'project' => nil, + 'preview-markdown-path' => nil + ) end + end - context 'and the callout has been dismissed' do - it 'disables environment guidance' do - callout = create(:callout, feature_name: :web_ide_ci_environments_guidance, user: project.creator) - callout.update!(dismissed_at: Time.now - 1.week) - allow(helper).to receive(:current_user).and_return(User.find(project.creator.id)) - expect(helper.ide_data).to include('enable-environments-guidance' => 'false') - end + context 'when instance vars are set' do + it 'returns instance data in the hash' do + fork_info = { ide_path: '/test/ide/path' } + + self.instance_variable_set(:@branch, 'master') + self.instance_variable_set(:@path, 'foo/bar') + self.instance_variable_set(:@merge_request, '1') + self.instance_variable_set(:@fork_info, fork_info) + self.instance_variable_set(:@project, project) + + serialized_project = API::Entities::Project.represent(project, current_user: project.creator).to_json + + expect(helper.ide_data) + .to include( + 'branch-name' => 'master', + 'file-path' => 'foo/bar', + 'merge-request' => '1', + 'fork-info' => fork_info.to_json, + 'project' => serialized_project, + 'preview-markdown-path' => Gitlab::Routing.url_helpers.preview_markdown_project_path(project) + ) end end - context 'when the project has environments' do - it 'disables environment guidance' do - create(:environment, project: project) + context 'environments guidance experiment', :experiment do + before do + stub_experiments(in_product_guidance_environments_webide: :candidate) + self.instance_variable_set(:@project, project) + end + + context 'when project has no enviornments' do + it 'enables environment guidance' do + expect(helper.ide_data).to include('enable-environments-guidance' => 'true') + end + + context 'and the callout has been dismissed' do + it 'disables environment guidance' do + callout = create(:callout, feature_name: :web_ide_ci_environments_guidance, user: project.creator) + callout.update!(dismissed_at: Time.now - 1.week) + allow(helper).to receive(:current_user).and_return(User.find(project.creator.id)) + expect(helper.ide_data).to include('enable-environments-guidance' => 'false') + end + end + end - expect(helper.ide_data).to include('enable-environments-guidance' => 'false') + context 'when the project has environments' do + it 'disables environment guidance' do + create(:environment, project: project) + + expect(helper.ide_data).to include('enable-environments-guidance' => 'false') + end end end end diff --git a/spec/helpers/invite_members_helper_spec.rb b/spec/helpers/invite_members_helper_spec.rb index 4d47732e008..c753d553371 100644 --- a/spec/helpers/invite_members_helper_spec.rb +++ b/spec/helpers/invite_members_helper_spec.rb @@ -11,10 +11,6 @@ RSpec.describe InviteMembersHelper do let(:owner) { project.owner } - before do - helper.extend(Gitlab::Experimentation::ControllerConcern) - end - describe '#common_invite_group_modal_data' do it 'has expected common attributes' do attributes = { diff --git a/spec/helpers/issuables_description_templates_helper_spec.rb b/spec/helpers/issuables_description_templates_helper_spec.rb index bd8af384d40..b32a99fe989 100644 --- a/spec/helpers/issuables_description_templates_helper_spec.rb +++ b/spec/helpers/issuables_description_templates_helper_spec.rb @@ -64,12 +64,12 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do it 'returns project templates' do value = [ - "", - [ - { name: "another_issue_template", id: "another_issue_template", project_id: project.id }, - { name: "custom_issue_template", id: "custom_issue_template", project_id: project.id } - ] - ].to_json + "", + [ + { name: "another_issue_template", id: "another_issue_template", project_id: project.id }, + { name: "custom_issue_template", id: "custom_issue_template", project_id: project.id } + ] + ].to_json expect(helper.available_service_desk_templates_for(@project)).to eq(value) end end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index a58fe9a6cd9..e5bd8e6532f 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -4,8 +4,8 @@ require 'spec_helper' RSpec.describe IssuesHelper do let(:project) { create(:project) } - let(:issue) { create :issue, project: project } - let(:ext_project) { create :redmine_project } + let(:issue) { create(:issue, project: project) } + let(:ext_project) { create(:project, :with_redmine_integration) } describe '#work_item_type_icon' do it 'returns icon of all standard base types' do diff --git a/spec/helpers/listbox_helper_spec.rb b/spec/helpers/listbox_helper_spec.rb index 0a27aa04b37..cba00b43ae5 100644 --- a/spec/helpers/listbox_helper_spec.rb +++ b/spec/helpers/listbox_helper_spec.rb @@ -26,13 +26,14 @@ RSpec.describe ListboxHelper do describe '#gl_redirect_listbox_tag' do it 'creates root element with expected classes' do - expect(subject.classes).to include(*%w[ - dropdown - b-dropdown - gl-new-dropdown - btn-group - js-redirect-listbox - ]) + expect(subject.classes).to include( + *%w[ + dropdown + b-dropdown + gl-new-dropdown + btn-group + js-redirect-listbox + ]) end it 'sets data attributes for items and selected' do @@ -41,14 +42,15 @@ RSpec.describe ListboxHelper do end it 'adds styled button' do - expect(subject.at_css('button').classes).to include(*%w[ - btn - dropdown-toggle - btn-default - btn-md - gl-button - gl-dropdown-toggle - ]) + expect(subject.at_css('button').classes).to include( + *%w[ + btn + dropdown-toggle + btn-default + btn-md + gl-button + gl-dropdown-toggle + ]) end it 'sets button text to selected item' do diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb index 8a7a6d003f4..a2e34471324 100644 --- a/spec/helpers/markup_helper_spec.rb +++ b/spec/helpers/markup_helper_spec.rb @@ -425,21 +425,21 @@ FooBar end it 'delegates to #markdown_unsafe when file name corresponds to Markdown' do - expect(helper).to receive(:gitlab_markdown?).with('foo.md').and_return(true) + expect(Gitlab::MarkupHelper).to receive(:gitlab_markdown?).with('foo.md').and_return(true) expect(helper).to receive(:markdown_unsafe).and_return('NOEL') expect(helper.markup('foo.md', content)).to eq('NOEL') end it 'delegates to #asciidoc_unsafe when file name corresponds to AsciiDoc' do - expect(helper).to receive(:asciidoc?).with('foo.adoc').and_return(true) + expect(Gitlab::MarkupHelper).to receive(:asciidoc?).with('foo.adoc').and_return(true) expect(helper).to receive(:asciidoc_unsafe).and_return('NOEL') expect(helper.markup('foo.adoc', content)).to eq('NOEL') end it 'uses passed in rendered content' do - expect(helper).not_to receive(:gitlab_markdown?) + expect(Gitlab::MarkupHelper).not_to receive(:gitlab_markdown?) expect(helper).not_to receive(:markdown_unsafe) expect(helper.markup('foo.md', content, rendered: '<p>NOEL</p>')).to eq('<p>NOEL</p>') @@ -562,20 +562,6 @@ FooBar shared_examples_for 'common markdown examples' do let(:project_base) { build(:project, :repository) } - it 'displays inline code' do - object = create_object('Text with `inline code`') - expected = 'Text with <code>inline code</code>' - - expect(first_line_in_markdown(object, attribute, 100, project: project)).to match(expected) - end - - it 'truncates the text with multiple paragraphs' do - object = create_object("Paragraph 1\n\nParagraph 2") - expected = 'Paragraph 1...' - - expect(first_line_in_markdown(object, attribute, 100, project: project)).to match(expected) - end - it 'displays the first line of a code block' do object = create_object("```\nCode block\nwith two lines\n```") expected = %r{<pre.+><code><span class="line">Code block\.\.\.</span>\n</code></pre>} @@ -591,18 +577,6 @@ FooBar expect(first_line_in_markdown(object, attribute, 150, project: project)).to match(expected) end - it 'preserves a link href when link text is truncated' do - text = 'The quick brown fox jumped over the lazy dog' # 44 chars - link_url = 'http://example.com/foo/bar/baz' # 30 chars - input = "#{text}#{text}#{text} #{link_url}" # 163 chars - expected_link_text = 'http://example...</a>' - - object = create_object(input) - - expect(first_line_in_markdown(object, attribute, 150, project: project)).to match(link_url) - expect(first_line_in_markdown(object, attribute, 150, project: project)).to match(expected_link_text) - end - it 'preserves code color scheme' do object = create_object("```ruby\ndef test\n 'hello world'\nend\n```") expected = "\n<pre class=\"code highlight js-syntax-highlight language-ruby\">" \ @@ -669,40 +643,6 @@ FooBar expect(result).to include(html) end - it 'truncates Markdown properly' do - object = create_object("@#{user.username}, can you look at this?\nHello world\n") - actual = first_line_in_markdown(object, attribute, 100, project: project) - - doc = Nokogiri::HTML.parse(actual) - - # Make sure we didn't create invalid markup - expect(doc.errors).to be_empty - - # Leading user link - expect(doc.css('a').length).to eq(1) - expect(doc.css('a')[0].attr('href')).to eq user_path(user) - expect(doc.css('a')[0].text).to eq "@#{user.username}" - - expect(doc.content).to eq "@#{user.username}, can you look at this?..." - end - - it 'truncates Markdown with emoji properly' do - object = create_object("foo :wink:\nbar :grinning:") - actual = first_line_in_markdown(object, attribute, 100, project: project) - - doc = Nokogiri::HTML.parse(actual) - - # Make sure we didn't create invalid markup - # But also account for the 2 errors caused by the unknown `gl-emoji` elements - expect(doc.errors.length).to eq(2) - - expect(doc.css('gl-emoji').length).to eq(2) - expect(doc.css('gl-emoji')[0].attr('data-name')).to eq 'wink' - expect(doc.css('gl-emoji')[1].attr('data-name')).to eq 'grinning' - - expect(doc.content).to eq "foo 😉\nbar 😀" - end - it 'does not post-process truncated text', :request_store do object = create_object("hello \n\n [Test](README.md)") diff --git a/spec/helpers/milestones_helper_spec.rb b/spec/helpers/milestones_helper_spec.rb new file mode 100644 index 00000000000..f7f3b7d8227 --- /dev/null +++ b/spec/helpers/milestones_helper_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MilestonesHelper do + let_it_be(:issuable) { build(:merge_request) } + + describe '#milestone_header_class' do + using RSpec::Parameterized::TableSyntax + + color_primary = 'gl-bg-blue-500 gl-text-white' + border_empty = 'gl-border-bottom-0 gl-rounded-base' + + where(:primary, :issuables, :header_color, :header_border) do + true | [issuable] | color_primary | '' + true | [] | color_primary | border_empty + false | [] | '' | border_empty + false | [issuable] | '' | '' + end + + with_them do + subject { helper.milestone_header_class(primary, issuables) } + + it { is_expected.to eq("#{header_color} #{header_border} gl-display-flex") } + end + end + + describe '#milestone_counter_class' do + context 'when primary is set to true' do + subject { helper.milestone_counter_class(true) } + + it { is_expected.to eq('gl-text-white') } + end + + context 'when primary is set to false' do + subject { helper.milestone_counter_class(false) } + + it { is_expected.to eq('gl-text-gray-500') } + end + end +end diff --git a/spec/helpers/nav_helper_spec.rb b/spec/helpers/nav_helper_spec.rb index f0ad2038347..4a37e17fb08 100644 --- a/spec/helpers/nav_helper_spec.rb +++ b/spec/helpers/nav_helper_spec.rb @@ -116,7 +116,7 @@ RSpec.describe NavHelper do using RSpec::Parameterized::TableSyntax where path: %w( - merge_requests#show + projects/merge_requests#show projects/merge_requests/conflicts#show issues#show milestones#show diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index a9db2a1c008..07c2d50f70a 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -825,7 +825,7 @@ RSpec.describe ProjectsHelper do end context 'gitaly is working appropriately' do - let(:license) { Licensee::License.new('mit') } + let(:license) { ::Gitlab::Git::DeclaredLicense.new(key: 'mit', name: 'MIT License') } before do expect(repository).to receive(:license).and_return(license) @@ -1336,4 +1336,24 @@ RSpec.describe ProjectsHelper do ) end end + + describe '#localized_project_human_access' do + using RSpec::Parameterized::TableSyntax + + where(:key, :localized_project_human_access) do + Gitlab::Access::NO_ACCESS | _('No access') + Gitlab::Access::MINIMAL_ACCESS | _("Minimal Access") + Gitlab::Access::GUEST | _('Guest') + Gitlab::Access::REPORTER | _('Reporter') + Gitlab::Access::DEVELOPER | _('Developer') + Gitlab::Access::MAINTAINER | _('Maintainer') + Gitlab::Access::OWNER | _('Owner') + end + + with_them do + it 'with correct key' do + expect(helper.localized_project_human_access(key)).to eq(localized_project_human_access) + end + end + end end diff --git a/spec/helpers/recaptcha_helper_spec.rb b/spec/helpers/recaptcha_helper_spec.rb index 8ad91a0a217..2c327431437 100644 --- a/spec/helpers/recaptcha_helper_spec.rb +++ b/spec/helpers/recaptcha_helper_spec.rb @@ -9,21 +9,70 @@ RSpec.describe RecaptchaHelper, type: :helper do allow(helper).to receive(:session) { session } end - describe '.show_recaptcha_sign_up?' do - context 'when reCAPTCHA is disabled' do - it 'returns false' do - stub_application_setting(recaptcha_enabled: false) + shared_examples 'Gitlab QA bypass' do + context 'when GITLAB_QA_USER_AGENT env var is present' do + using RSpec::Parameterized::TableSyntax - expect(helper.show_recaptcha_sign_up?).to be_falsey + where(:dot_com, :user_agent, :qa_user_agent, :result) do + false | 'qa_user_agent' | 'qa_user_agent' | true + true | nil | 'qa_user_agent' | true + true | '' | 'qa_user_agent' | true + true | 'qa_user_agent' | '' | true + true | 'qa_user_agent' | nil | true + true | 'qa_user_agent' | 'qa_user_agent' | false end - end - context 'when reCAPTCHA is enabled' do - it 'returns true' do - stub_application_setting(recaptcha_enabled: true) + with_them do + before do + allow(Gitlab).to receive(:com?).and_return(dot_com) + stub_env('GITLAB_QA_USER_AGENT', qa_user_agent) + + request_double = instance_double(ActionController::TestRequest, user_agent: user_agent) + allow(helper).to receive(:request).and_return(request_double) + end - expect(helper.show_recaptcha_sign_up?).to be_truthy + it { is_expected.to eq result } end end end + + describe '.show_recaptcha_sign_up?' do + let(:setting_state) { true } + + before do + stub_application_setting(recaptcha_enabled: setting_state) + end + + subject { helper.show_recaptcha_sign_up? } + + it { is_expected.to eq true } + + context 'when setting is disabled' do + let(:setting_state) { false } + + it { is_expected.to eq false } + end + + include_examples 'Gitlab QA bypass' + end + + describe '.recaptcha_enabled_on_login?' do + let(:setting_state) { true } + + before do + stub_application_setting(login_recaptcha_protection_enabled: setting_state) + end + + subject { helper.recaptcha_enabled_on_login? } + + it { is_expected.to eq true } + + context 'when setting is disabled' do + let(:setting_state) { false } + + it { is_expected.to eq false } + end + + include_examples 'Gitlab QA bypass' + end end diff --git a/spec/helpers/releases_helper_spec.rb b/spec/helpers/releases_helper_spec.rb index 59a92c067f4..5a9deb5c63b 100644 --- a/spec/helpers/releases_helper_spec.rb +++ b/spec/helpers/releases_helper_spec.rb @@ -49,6 +49,12 @@ RSpec.describe ReleasesHelper do expect(helper.data_for_releases_page[:new_release_path]).to eq(new_project_release_path(project)) end end + + context 'new releases redirect new milestone creation' do + it 'redirects new_milestone_path back to the release page' do + expect(helper.data_for_new_release_page[:new_milestone_path]).to include('redirect_path') + end + end end describe '#data_for_edit_release_page' do diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index ad0705e4fbf..20718ad2f48 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -776,7 +776,7 @@ RSpec.describe SearchHelper do end context 'project data' do - let(:project) { create(:project) } + let_it_be(:project) { create(:project) } let(:project_metadata) { { project_path: project.path, issues_path: "/issues" } } let(:scope) { 'issues' } let(:code_search) { true } @@ -848,4 +848,295 @@ RSpec.describe SearchHelper do end end end + + describe '.search_navigation' do + using RSpec::Parameterized::TableSyntax + let(:user) { build(:user) } + let_it_be(:project) { build(:project) } + + before do + allow(self).to receive(:current_user).and_return(user) + allow(self).to receive(:can?).and_return(true) + allow(self).to receive(:project_search_tabs?).and_return(false) + allow(self).to receive(:feature_flag_tab_enabled?).and_return(false) + end + + context 'projects' do + where(:global_project, :condition) do + nil | true + ref(:project) | false + end + + with_them do + it 'data item condition is set correctly' do + @project = global_project + + expect(search_navigation[:projects][:condition]).to eq(condition) + end + end + end + + context 'code' do + where(:feature_flag_tab_enabled, :show_elasticsearch_tabs, :project_search_tabs, :condition) do + false | false | false | false + true | true | true | true + true | false | false | true + false | true | false | true + false | false | true | true + true | false | true | true + end + + with_them do + it 'data item condition is set correctly' do + allow(search_service).to receive(:show_elasticsearch_tabs?).and_return(show_elasticsearch_tabs) + allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_code_tab).and_return(feature_flag_tab_enabled) + allow(self).to receive(:project_search_tabs?).with(:blobs).and_return(project_search_tabs) + + expect(search_navigation[:blobs][:condition]).to eq(condition) + end + end + end + + context 'issues' do + where(:feature_flag_tab_enabled, :project_search_tabs, :condition) do + false | false | false + true | true | true + true | false | true + false | true | true + end + + with_them do + it 'data item condition is set correctly' do + allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_issues_tab).and_return(feature_flag_tab_enabled) + allow(self).to receive(:project_search_tabs?).with(:issues).and_return(project_search_tabs) + + expect(search_navigation[:issues][:condition]).to eq(condition) + end + end + end + + context 'merge requests' do + where(:feature_flag_tab_enabled, :project_search_tabs, :condition) do + false | false | false + true | true | true + true | false | true + false | true | true + end + + with_them do + it 'data item condition is set correctly' do + allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_merge_requests_tab).and_return(feature_flag_tab_enabled) + allow(self).to receive(:project_search_tabs?).with(:merge_requests).and_return(project_search_tabs) + + expect(search_navigation[:merge_requests][:condition]).to eq(condition) + end + end + end + + context 'wiki' do + where(:project_search_tabs, :show_elasticsearch_tabs, :condition) do + false | false | false + true | true | true + true | false | true + false | true | true + end + + with_them do + it 'data item condition is set correctly' do + allow(search_service).to receive(:show_elasticsearch_tabs?).and_return(show_elasticsearch_tabs) + allow(self).to receive(:project_search_tabs?).with(:wiki).and_return(project_search_tabs) + + expect(search_navigation[:wiki_blobs][:condition]).to eq(condition) + end + end + end + + context 'commits' do + where(:feature_flag_tab_enabled, :show_elasticsearch_tabs, :project_search_tabs, :condition) do + false | false | false | false + true | true | true | true + true | false | false | false + false | true | true | true + end + + with_them do + it 'data item condition is set correctly' do + allow(search_service).to receive(:show_elasticsearch_tabs?).and_return(show_elasticsearch_tabs) + allow(self).to receive(:feature_flag_tab_enabled?).with(:global_search_commits_tab).and_return(feature_flag_tab_enabled) + allow(self).to receive(:project_search_tabs?).with(:commits).and_return(project_search_tabs) + + expect(search_navigation[:commits][:condition]).to eq(condition) + end + end + end + + context 'comments' do + where(:show_elasticsearch_tabs, :project_search_tabs, :condition) do + true | true | true + false | false | false + true | false | true + false | true | true + end + + with_them do + it 'data item condition is set correctly' do + allow(search_service).to receive(:show_elasticsearch_tabs?).and_return(show_elasticsearch_tabs) + allow(self).to receive(:project_search_tabs?).with(:notes).and_return(project_search_tabs) + + expect(search_navigation[:notes][:condition]).to eq(condition) + end + end + end + + context 'milestones' do + where(:global_project, :project_search_tabs, :condition) do + ref(:project) | true | true + nil | false | true + ref(:project) | false | false + nil | true | true + end + + with_them do + it 'data item condition is set correctly' do + @project = global_project + allow(self).to receive(:project_search_tabs?).with(:milestones).and_return(project_search_tabs) + + expect(search_navigation[:milestones][:condition]).to eq(condition) + end + end + end + + context 'users' do + where(:show_user_search_tab, :condition) do + true | true + false | false + end + + with_them do + it 'data item condition is set correctly' do + allow(self).to receive(:show_user_search_tab?).and_return(show_user_search_tab) + + expect(search_navigation[:users][:condition]).to eq(condition) + end + end + end + + context 'snippet_titles' do + where(:global_project, :global_show_snippets, :condition) do + ref(:project) | true | false + nil | false | false + ref(:project) | false | false + nil | true | true + end + + with_them do + it 'data item condition is set correctly' do + @show_snippets = global_show_snippets + @project = global_project + + expect(search_navigation[:snippet_titles][:condition]).to eq(condition) + end + end + end + end + + describe '.search_navigation_json' do + using RSpec::Parameterized::TableSyntax + context 'with data' do + example_data_1 = { + projects: { label: _("Projects"), condition: true }, + blobs: { label: _("Code"), condition: false } + } + + example_data_2 = { + projects: { label: _("Projects"), condition: false }, + blobs: { label: _("Code"), condition: false } + } + + example_data_3 = { + projects: { label: _("Projects"), condition: true }, + blobs: { label: _("Code"), condition: true }, + epics: { label: _("Epics"), condition: true } + } + + where(:data, :matcher) do + example_data_1 | -> { include("projects") } + example_data_2 | -> { eq("{}") } + example_data_3 | -> { include("projects", "blobs", "epics") } + end + + with_them do + it 'converts correctly' do + allow(self).to receive(:search_navigation).with(no_args).and_return(data) + + expect(search_navigation_json).to instance_exec(&matcher) + end + end + end + end + + describe '.search_filter_link_json' do + using RSpec::Parameterized::TableSyntax + + context 'data' do + where(:scope, :label, :data, :search, :active_scope) do + "projects" | "Projects" | { qa_selector: 'projects_tab' } | nil | "projects" + "snippet_titles" | "Titles and Descriptions" | nil | { snippets: "test" } | "code" + "projects" | "Projects" | { qa_selector: 'projects_tab' } | nil | "issue" + "snippet_titles" | "Titles and Descriptions" | nil | { snippets: "test" } | "snippet_titles" + end + + with_them do + it 'converts correctly' do + @timeout = false + @scope = active_scope + @search_results = double + dummy_count = 1000 + allow(self).to receive(:search_path).with(any_args).and_return("link test") + + allow(@search_results).to receive(:formatted_count).with(scope).and_return(dummy_count) + allow(self).to receive(:search_count_path).with(any_args).and_return("test count link") + + current_scope = scope == active_scope + + expected = { + label: label, + scope: scope, + data: data, + link: "link test", + active: current_scope + } + + expected[:count] = dummy_count if current_scope + expected[:count_link] = "test count link" unless current_scope + + expect(search_filter_link_json(scope, label, data, search)).to eq(expected) + end + end + end + end + + describe 'show_elasticsearch_tabs' do + subject { search_service.show_elasticsearch_tabs? } + + let(:user) { build(:user) } + + before do + allow(self).to receive(:current_user).and_return(user) + end + + it { is_expected.to eq(false) } + end + + describe 'show_epics' do + subject { search_service.show_epics? } + + let(:user) { build(:user) } + + before do + allow(self).to receive(:current_user).and_return(user) + end + + it { is_expected.to eq(false) } + end end diff --git a/spec/helpers/sessions_helper_spec.rb b/spec/helpers/sessions_helper_spec.rb index 15424425060..c7b8225b866 100644 --- a/spec/helpers/sessions_helper_spec.rb +++ b/spec/helpers/sessions_helper_spec.rb @@ -92,6 +92,12 @@ RSpec.describe SessionsHelper do end context 'when an email address is very short' do + let(:email) { 'a@b.c' } + + it { is_expected.to eq('a@b.c') } + end + + context 'when an email address is even shorter' do let(:email) { 'a@b' } it { is_expected.to eq('a@b') } diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb index a8945424877..c64d5990cd9 100644 --- a/spec/helpers/todos_helper_spec.rb +++ b/spec/helpers/todos_helper_spec.rb @@ -292,4 +292,22 @@ RSpec.describe TodosHelper do it { is_expected.to eq(result) } end end + + describe '#todos_filter_params' do + using RSpec::Parameterized::TableSyntax + + where(:state, :result) do + 'done' | 'done' + 'pending' | 'pending' + '' | nil + end + + with_them do + before do + allow(helper).to receive(:params).and_return({ state: state }) + end + + it { expect(helper.todos_filter_params[:state]).to eq(result) } + end + end end diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 617a796781e..c2c78be6a0f 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -204,11 +204,12 @@ RSpec.describe UsersHelper do badges = helper.user_badges_in_admin_section(user) - expect(badges).to match_array([ - { text: s_("AdminUsers|Blocked"), variant: "danger" }, - { text: s_("AdminUsers|Admin"), variant: "success" }, - { text: s_("AdminUsers|External"), variant: "secondary" } - ]) + expect(badges).to match_array( + [ + { text: s_("AdminUsers|Blocked"), variant: "danger" }, + { text: s_("AdminUsers|Admin"), variant: "success" }, + { text: s_("AdminUsers|External"), variant: "secondary" } + ]) end end diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb index 75128d758f9..59624dc0682 100644 --- a/spec/helpers/wiki_helper_spec.rb +++ b/spec/helpers/wiki_helper_spec.rb @@ -75,41 +75,38 @@ RSpec.describe WikiHelper do describe '#wiki_sort_controls' do let(:wiki) { create(:project_wiki) } - let(:wiki_link) { helper.wiki_sort_controls(wiki, sort, direction) } + let(:wiki_link) { helper.wiki_sort_controls(wiki, direction) } let(:classes) { "gl-button btn btn-default btn-icon has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort" } - def expected_link(sort, direction, icon_class) - path = "/#{wiki.project.full_path}/-/wikis/pages?direction=#{direction}&sort=#{sort}" - - helper.link_to(path, type: 'button', class: classes, title: 'Sort direction') do + def expected_link(direction, icon_class) + path = "/#{wiki.project.full_path}/-/wikis/pages?direction=#{direction}" + title = direction == 'desc' ? _('Sort direction: Ascending') : _('Sort direction: Descending') + helper.link_to(path, type: 'button', class: classes, title: title) do helper.sprite_icon("sort-#{icon_class}") end end context 'initial call' do - let(:sort) { nil } let(:direction) { nil } it 'renders with default values' do - expect(wiki_link).to eq(expected_link('title', 'desc', 'lowest')) + expect(wiki_link).to eq(expected_link('desc', 'lowest')) end end - context 'sort by title' do - let(:sort) { 'title' } + context 'sort by asc order' do let(:direction) { 'asc' } it 'renders a link with opposite direction' do - expect(wiki_link).to eq(expected_link('title', 'desc', 'lowest')) + expect(wiki_link).to eq(expected_link('desc', 'lowest')) end end - context 'sort by created_at' do - let(:sort) { 'created_at' } + context 'sort by desc order' do let(:direction) { 'desc' } it 'renders a link with opposite direction' do - expect(wiki_link).to eq(expected_link('created_at', 'asc', 'highest')) + expect(wiki_link).to eq(expected_link('asc', 'highest')) end end end |