diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 16:37:47 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 16:37:47 +0300 |
commit | aee0a117a889461ce8ced6fcf73207fe017f1d99 (patch) | |
tree | 891d9ef189227a8445d83f35c1b0fc99573f4380 /spec/helpers | |
parent | 8d46af3258650d305f53b819eabf7ab18d22f59e (diff) |
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'spec/helpers')
24 files changed, 882 insertions, 401 deletions
diff --git a/spec/helpers/access_tokens_helper_spec.rb b/spec/helpers/access_tokens_helper_spec.rb index 28041203447..c2c918bc6b0 100644 --- a/spec/helpers/access_tokens_helper_spec.rb +++ b/spec/helpers/access_tokens_helper_spec.rb @@ -15,4 +15,53 @@ RSpec.describe AccessTokensHelper do it { expect(helper.scope_description(prefix)).to eq(description_location) } end end + + describe '#tokens_app_data' do + let_it_be(:feed_token) { 'DUKu345VD73Py7zz3z89' } + let_it_be(:incoming_email_token) { 'az4a2l5f8ssa0zvdfbhidbzlx' } + let_it_be(:static_object_token) { 'QHXwGHYioHTgxQnAcyZ-' } + let_it_be(:feed_token_reset_path) { '/-/profile/reset_feed_token' } + let_it_be(:incoming_email_token_reset_path) { '/-/profile/reset_incoming_email_token' } + let_it_be(:static_object_token_reset_path) { '/-/profile/reset_static_object_token' } + let_it_be(:user) do + build( + :user, + feed_token: feed_token, + incoming_email_token: incoming_email_token, + static_object_token: static_object_token + ) + end + + it 'returns expected json' do + allow(Gitlab::CurrentSettings).to receive_messages( + disable_feed_token: false, + static_objects_external_storage_enabled?: true + ) + allow(Gitlab::IncomingEmail).to receive(:supports_issue_creation?).and_return(true) + allow(helper).to receive_messages( + current_user: user, + reset_feed_token_profile_path: feed_token_reset_path, + reset_incoming_email_token_profile_path: incoming_email_token_reset_path, + reset_static_object_token_profile_path: static_object_token_reset_path + ) + + expect(helper.tokens_app_data).to eq({ + feed_token: { + enabled: true, + token: feed_token, + reset_path: feed_token_reset_path + }, + incoming_email_token: { + enabled: true, + token: incoming_email_token, + reset_path: incoming_email_token_reset_path + }, + static_object_token: { + enabled: true, + token: static_object_token, + reset_path: static_object_token_reset_path + } + }.to_json) + end + end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 7e3f665a99c..7390b9b3f58 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -192,20 +192,6 @@ RSpec.describe ApplicationHelper do end end - describe '#contact_sales_url' do - subject { helper.contact_sales_url } - - it 'returns the url' do - is_expected.to eq("https://#{helper.promo_host}/sales") - end - - it 'changes if promo_url changes' do - allow(helper).to receive(:promo_url).and_return('https://somewhere.else') - - is_expected.to eq('https://somewhere.else/sales') - 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/auth_helper_spec.rb b/spec/helpers/auth_helper_spec.rb index c1c961c5cbb..b481c214ca1 100644 --- a/spec/helpers/auth_helper_spec.rb +++ b/spec/helpers/auth_helper_spec.rb @@ -283,35 +283,84 @@ RSpec.describe AuthHelper do before do allow(Gitlab).to receive(:com?).and_return(is_gitlab_com) - stub_config(extra: { google_tag_manager_id: 'key' }) allow(helper).to receive(:current_user).and_return(user) end - subject(:google_tag_manager_enabled?) { helper.google_tag_manager_enabled? } - - context 'on gitlab.com and a key set without a current user' do - it { is_expected.to be_truthy } - end + subject(:google_tag_manager_enabled) { helper.google_tag_manager_enabled? } context 'when not on gitlab.com' do let(:is_gitlab_com) { false } - it { is_expected.to be_falsey } + it { is_expected.to eq(false) } end - context 'when current user is set' do - let(:user) { instance_double('User') } + context 'regular and nonce versions' do + using RSpec::Parameterized::TableSyntax - it { is_expected.to be_falsey } + where(:gtm_nonce_enabled, :gtm_key) do + false | 'google_tag_manager_id' + true | 'google_tag_manager_nonce_id' + end + + with_them do + before do + stub_feature_flags(gtm_nonce: gtm_nonce_enabled) + stub_config(extra: { gtm_key => 'key' }) + end + + context 'on gitlab.com and a key set without a current user' do + it { is_expected.to be_truthy } + end + + context 'when current user is set' do + let(:user) { instance_double('User') } + + it { is_expected.to eq(false) } + end + + context 'when no key is set' do + before do + stub_config(extra: {}) + end + + it { is_expected.to eq(false) } + end + end end + end + + describe '#google_tag_manager_id' do + subject(:google_tag_manager_id) { helper.google_tag_manager_id } - context 'when no key is set' do + before do + stub_config(extra: { 'google_tag_manager_nonce_id': 'nonce', 'google_tag_manager_id': 'gtm' }) + end + + context 'when google tag manager is disabled' do before do - stub_config(extra: {}) + allow(helper).to receive(:google_tag_manager_enabled?).and_return(false) end it { is_expected.to be_falsey } end + + context 'when google tag manager is enabled' do + before do + allow(helper).to receive(:google_tag_manager_enabled?).and_return(true) + end + + context 'when nonce feature flag is enabled' do + it { is_expected.to eq('nonce') } + end + + context 'when nonce feature flag is disabled' do + before do + stub_feature_flags(gtm_nonce: false) + end + + it { is_expected.to eq('gtm') } + end + end end describe '#auth_app_owner_text' do @@ -346,4 +395,170 @@ RSpec.describe AuthHelper do end end end + + describe '#auth_strategy_class' do + subject(:auth_strategy_class) { helper.auth_strategy_class(name) } + + context 'when configuration specifies no provider' do + let(:name) { 'does_not_exist' } + + before do + allow(Gitlab.config.omniauth).to receive(:providers).and_return([]) + end + + it 'returns false' do + expect(auth_strategy_class).to be_falsey + end + end + + context 'when configuration specifies a provider with args but without strategy_class' do + let(:name) { 'google_oauth2' } + let(:provider) do + Struct.new(:name, :args).new( + name, + 'app_id' => 'YOUR_APP_ID' + ) + end + + before do + allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) + end + + it 'returns false' do + expect(auth_strategy_class).to be_falsey + end + end + + context 'when configuration specifies a provider with args and strategy_class' do + let(:name) { 'provider1' } + let(:strategy) { 'OmniAuth::Strategies::LDAP' } + let(:provider) do + Struct.new(:name, :args).new( + name, + 'strategy_class' => strategy + ) + end + + before do + allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) + end + + it 'returns the class' do + expect(auth_strategy_class).to eq(strategy) + end + end + + context 'when configuration specifies another provider with args and another strategy_class' do + let(:name) { 'provider1' } + let(:strategy) { 'OmniAuth::Strategies::LDAP' } + let(:provider) do + Struct.new(:name, :args).new( + 'another_name', + 'strategy_class' => strategy + ) + end + + before do + allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider]) + end + + it 'returns false' do + expect(auth_strategy_class).to be_falsey + end + end + end + + describe '#saml_providers' do + subject(:saml_providers) { helper.saml_providers } + + let(:saml_strategy) { 'OmniAuth::Strategies::SAML' } + + let(:saml_provider_1_name) { 'saml_provider_1' } + let(:saml_provider_1) do + Struct.new(:name, :args).new( + saml_provider_1_name, + 'strategy_class' => saml_strategy + ) + end + + let(:saml_provider_2_name) { 'saml_provider_2' } + let(:saml_provider_2) do + Struct.new(:name, :args).new( + saml_provider_2_name, + 'strategy_class' => saml_strategy + ) + end + + let(:ldap_provider_name) { 'ldap_provider' } + let(:ldap_strategy) { 'OmniAuth::Strategies::LDAP' } + let(:ldap_provider) do + Struct.new(:name, :args).new( + ldap_provider_name, + 'strategy_class' => ldap_strategy + ) + end + + let(:google_oauth2_provider_name) { 'google_oauth2' } + let(:google_oauth2_provider) do + Struct.new(:name, :args).new( + google_oauth2_provider_name, + 'app_id' => 'YOUR_APP_ID' + ) + end + + context 'when configuration specifies no provider' do + before do + allow(Devise).to receive(:omniauth_providers).and_return([]) + allow(Gitlab.config.omniauth).to receive(:providers).and_return([]) + end + + it 'returns an empty list' do + expect(saml_providers).to be_empty + end + end + + context 'when configuration specifies a provider with a SAML strategy_class' do + before do + allow(Devise).to receive(:omniauth_providers).and_return([saml_provider_1_name]) + allow(Gitlab.config.omniauth).to receive(:providers).and_return([saml_provider_1]) + end + + it 'returns the provider' do + expect(saml_providers).to match_array([saml_provider_1_name]) + end + end + + context 'when configuration specifies two providers with a SAML strategy_class' do + before do + allow(Devise).to receive(:omniauth_providers).and_return([saml_provider_1_name, saml_provider_2_name]) + allow(Gitlab.config.omniauth).to receive(:providers).and_return([saml_provider_1, saml_provider_2]) + end + + it 'returns the provider' do + expect(saml_providers).to match_array([saml_provider_1_name, saml_provider_2_name]) + end + end + + context 'when configuration specifies a provider with a non-SAML strategy_class' do + before do + allow(Devise).to receive(:omniauth_providers).and_return([ldap_provider_name]) + allow(Gitlab.config.omniauth).to receive(:providers).and_return([ldap_provider]) + end + + it 'returns an empty list' do + expect(saml_providers).to be_empty + end + end + + context 'when configuration specifies four providers but only two with SAML strategy_class' do + before do + allow(Devise).to receive(:omniauth_providers).and_return([saml_provider_1_name, ldap_provider_name, saml_provider_2_name, google_oauth2_provider_name]) + allow(Gitlab.config.omniauth).to receive(:providers).and_return([saml_provider_1, ldap_provider, saml_provider_2, google_oauth2_provider]) + end + + it 'returns the provider' do + expect(saml_providers).to match_array([saml_provider_1_name, saml_provider_2_name]) + end + end + end end diff --git a/spec/helpers/badges_helper_spec.rb b/spec/helpers/badges_helper_spec.rb new file mode 100644 index 00000000000..5be3b4a737b --- /dev/null +++ b/spec/helpers/badges_helper_spec.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe BadgesHelper do + let(:label) { "Test" } + + describe '#gl_badge_tag' do + it 'creates a badge with given text' do + expect(helper.gl_badge_tag(label)).to match(%r{<span .*>Test</span>}) + end + + describe 'block content' do + it 'renders block content' do + expect(helper.gl_badge_tag { label }).to match(%r{<span .*>Test</span>}) + end + + it 'changes the function signature' do + options = { variant: :danger } + html_options = { class: 'foo-bar' } + + tag = helper.gl_badge_tag(label, options, html_options) + tag_with_block = helper.gl_badge_tag options, html_options do + label + end + + expect(tag).to eql(tag_with_block) + end + end + + it 'adds style classes' do + expect(helper.gl_badge_tag(label)).to match(%r{class="gl-badge badge badge-pill badge-muted md"}) + end + + it 'adds custom classes' do + expect(helper.gl_badge_tag(label, nil, class: "test-class" )).to match(%r{class=".*test-class.*"}) + end + + describe 'variants' do + where(:variant) do + [ + [:muted], + [:neutral], + [:info], + [:success], + [:warning], + [:danger] + ] + end + + with_them do + it 'sets the variant class' do + expected_class = "badge-#{variant}" + expect(helper.gl_badge_tag(label, variant: variant)).to match(%r{class=".*#{expected_class}.*"}) + end + end + + it 'defaults to muted' do + expect(helper.gl_badge_tag(label)).to match(%r{class=".*badge-muted.*"}) + end + + it 'falls back to default given an unknown variant' do + expect(helper.gl_badge_tag(label, variant: :foo)).to match(%r{class=".*badge-muted.*"}) + end + end + + describe 'sizes' do + where(:size) do + [[:sm], [:md], [:lg]] + end + + with_them do + it 'sets the size class' do + expect(helper.gl_badge_tag(label, size: size)).to match(%r{class=".*#{size}.*"}) + end + end + + it 'defaults to md' do + expect(helper.gl_badge_tag(label)).to match(%r{class=".*md.*"}) + end + + it 'falls back to default given an unknown size' do + expect(helper.gl_badge_tag(label, size: :foo)).to match(%r{class=".*md.*"}) + end + end + + it 'applies custom html attributes' do + expect(helper.gl_badge_tag(label, nil, data: { foo: "bar" })).to match(%r{<span .*data-foo="bar".*>}) + end + + describe 'icons' do + let(:spacing_class_regex) { %r{<svg .*class=".*gl-mr-2.*".*>.*</svg>} } + + describe 'with text' do + subject { helper.gl_badge_tag(label, icon: "question-o") } + + it 'renders an icon' do + expect(subject).to match(%r{<svg .*#question-o".*>.*</svg>}) + end + + it 'adds a spacing class to the icon' do + expect(subject).to match(spacing_class_regex) + end + end + + describe 'icon only' do + subject { helper.gl_badge_tag(label, icon: 'question-o', icon_only: true) } + + it 'adds an img role to element' do + expect(subject).to match(%r{<span .*role="img".*>}) + end + + it 'adds aria-label to element' do + expect(subject).to match(%r{<span .*aria-label="#{label}".*>}) + end + + it 'does not add a spacing class to the icon' do + expect(subject).not_to match(spacing_class_regex) + end + end + end + + describe 'given an href' do + it 'creates a badge link' do + expect(helper.gl_badge_tag(label, nil, href: 'foo')).to match(%r{<a .*href="foo".*>}) + end + end + end +end diff --git a/spec/helpers/ci/jobs_helper_spec.rb b/spec/helpers/ci/jobs_helper_spec.rb new file mode 100644 index 00000000000..e5ef362e91b --- /dev/null +++ b/spec/helpers/ci/jobs_helper_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::JobsHelper do + describe 'jobs data' do + let(:project) { create(:project, :repository) } + let(:bridge) { create(:ci_bridge, status: :pending) } + + subject(:bridge_data) { helper.bridge_data(bridge) } + + before do + allow(helper) + .to receive(:image_path) + .and_return('/path/to/illustration') + end + + it 'returns bridge data' do + expect(bridge_data).to eq({ + "build_name" => bridge.name, + "empty-state-illustration-path" => '/path/to/illustration' + }) + end + end +end diff --git a/spec/helpers/ide_helper_spec.rb b/spec/helpers/ide_helper_spec.rb index 503ad3ad66d..dc0a234f981 100644 --- a/spec/helpers/ide_helper_spec.rb +++ b/spec/helpers/ide_helper_spec.rb @@ -34,7 +34,7 @@ RSpec.describe IdeHelper do self.instance_variable_set(:@fork_info, fork_info) self.instance_variable_set(:@project, project) - serialized_project = API::Entities::Project.represent(project).to_json + serialized_project = API::Entities::Project.represent(project, current_user: project.creator).to_json expect(helper.ide_data) .to include( @@ -61,7 +61,7 @@ RSpec.describe IdeHelper do context 'and the callout has been dismissed' do it 'disables environment guidance' do - callout = create(:user_callout, feature_name: :web_ide_ci_environments_guidance, user: project.creator) + 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') diff --git a/spec/helpers/invite_members_helper_spec.rb b/spec/helpers/invite_members_helper_spec.rb index 02f0416a17a..d8a97b93bc9 100644 --- a/spec/helpers/invite_members_helper_spec.rb +++ b/spec/helpers/invite_members_helper_spec.rb @@ -6,6 +6,7 @@ RSpec.describe InviteMembersHelper do include Devise::Test::ControllerHelpers let_it_be(:project) { create(:project) } + let_it_be(:group) { create(:group, projects: [project]) } let_it_be(:developer) { create(:user, developer_projects: [project]) } let(:owner) { project.owner } @@ -15,97 +16,24 @@ RSpec.describe InviteMembersHelper do end describe '#common_invite_modal_dataset' do - context 'when member_areas_of_focus is enabled', :experiment do - context 'with control experience' do - before do - stub_experiments(member_areas_of_focus: :control) - end - - it 'has expected attributes' do - attributes = { - areas_of_focus_options: [], - no_selection_areas_of_focus: [] - } - - expect(helper.common_invite_modal_dataset(project)).to include(attributes) - end - end - - context 'with candidate experience' do - before do - stub_experiments(member_areas_of_focus: :candidate) - end - - it 'has expected attributes', :aggregate_failures do - output = helper.common_invite_modal_dataset(project) - - expect(output[:no_selection_areas_of_focus]).to eq ['no_selection'] - expect(Gitlab::Json.parse(output[:areas_of_focus_options]).first['value']).to eq 'Contribute to the codebase' - end - end - end - - context 'when member_areas_of_focus is disabled' do - before do - stub_feature_flags(member_areas_of_focus: false) - end - - it 'has expected attributes' do - attributes = { - id: project.id, - name: project.name, - default_access_level: Gitlab::Access::GUEST, - areas_of_focus_options: [], - no_selection_areas_of_focus: [] - } - - expect(helper.common_invite_modal_dataset(project)).to include(attributes) - end + it 'has expected common attributes' do + attributes = { + id: project.id, + name: project.name, + default_access_level: Gitlab::Access::GUEST + } + + expect(helper.common_invite_modal_dataset(project)).to include(attributes) end context 'tasks_to_be_done' do - subject(:output) { helper.common_invite_modal_dataset(source) } - - let_it_be(:source) { project } - - before do - stub_experiments(invite_members_for_task: true) - end - - context 'when not logged in' do - before do - allow(helper).to receive(:params).and_return({ open_modal: 'invite_members_for_task' }) - end - - it "doesn't have the tasks to be done attributes" do - expect(output[:tasks_to_be_done_options]).to be_nil - expect(output[:projects]).to be_nil - expect(output[:new_project_path]).to be_nil - end - end + using RSpec::Parameterized::TableSyntax - context 'when logged in but the open_modal param is not present' do - before do - allow(helper).to receive(:current_user).and_return(developer) - end - - it "doesn't have the tasks to be done attributes" do - expect(output[:tasks_to_be_done_options]).to be_nil - expect(output[:projects]).to be_nil - expect(output[:new_project_path]).to be_nil - end - end - - context 'when logged in and the open_modal param is present' do - before do - allow(helper).to receive(:current_user).and_return(developer) - allow(helper).to receive(:params).and_return({ open_modal: 'invite_members_for_task' }) - end - - context 'for a group' do - let_it_be(:source) { create(:group, projects: [project]) } + subject(:output) { helper.common_invite_modal_dataset(source) } - it 'has the expected attributes', :aggregate_failures do + shared_examples_for 'including the tasks to be done attributes' do + it 'includes the tasks to be done attributes when expected' do + if expected? expect(output[:tasks_to_be_done_options]).to eq( [ { value: :code, text: 'Create/import code into a project (repository)' }, @@ -117,24 +45,70 @@ RSpec.describe InviteMembersHelper do [{ id: project.id, title: project.title }].to_json ) expect(output[:new_project_path]).to eq( - new_project_path(namespace_id: source.id) + source.is_a?(Project) ? '' : new_project_path(namespace_id: group.id) ) + else + expect(output[:tasks_to_be_done_options]).to be_nil + expect(output[:projects]).to be_nil + expect(output[:new_project_path]).to be_nil end end + end - context 'for a project' do - it 'has the expected attributes', :aggregate_failures do - expect(output[:tasks_to_be_done_options]).to eq( - [ - { value: :code, text: 'Create/import code into a project (repository)' }, - { value: :ci, text: 'Set up CI/CD pipelines to build, test, deploy, and monitor code' }, - { value: :issues, text: 'Create/import issues (tickets) to collaborate on ideas and plan work' } - ].to_json - ) - expect(output[:projects]).to eq( - [{ id: project.id, title: project.title }].to_json - ) - expect(output[:new_project_path]).to eq('') + context 'inviting members for tasks' do + where(:open_modal_param_present?, :logged_in?, :expected?) do + true | true | true + true | false | false + false | true | false + false | false | false + end + + with_them do + before do + allow(helper).to receive(:current_user).and_return(developer) if logged_in? + allow(helper).to receive(:params).and_return({ open_modal: 'invite_members_for_task' }) if open_modal_param_present? + end + + context 'when the source is a project' do + let_it_be(:source) { project } + + it_behaves_like 'including the tasks to be done attributes' + end + + context 'when the source is a group' do + let_it_be(:source) { group } + + it_behaves_like 'including the tasks to be done attributes' + end + end + end + + context 'the invite_for_help_continuous_onboarding experiment' do + where(:invite_for_help_continuous_onboarding?, :logged_in?, :expected?) do + true | true | true + true | false | false + false | true | false + false | false | false + end + + with_them do + before do + allow(helper).to receive(:current_user).and_return(developer) if logged_in? + stub_experiments(invite_for_help_continuous_onboarding: :candidate) if invite_for_help_continuous_onboarding? + end + + context 'when the source is a project' do + let_it_be(:source) { project } + + it_behaves_like 'including the tasks to be done attributes' + end + + context 'when the source is a group' do + let_it_be(:source) { group } + + let(:expected?) { false } + + it_behaves_like 'including the tasks to be done attributes' end end end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 43b27dded3b..ad0ea6911f1 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -278,11 +278,13 @@ RSpec.describe IssuesHelper do it 'returns expected result' do expected = { can_create_issue: 'true', + can_destroy_issue: 'true', can_reopen_issue: 'true', can_report_spam: 'false', can_update_issue: 'true', iid: issue.iid, is_issue_author: 'false', + issue_path: issue_path(issue), issue_type: 'issue', new_issue_path: new_project_issue_path(project, { issue: { description: "Related to \##{issue.iid}.\n\n" } }), project_path: project.full_path, @@ -302,6 +304,7 @@ RSpec.describe IssuesHelper do allow(helper).to receive(:can?).and_return(true) allow(helper).to receive(:image_path).and_return('#') allow(helper).to receive(:import_csv_namespace_project_issues_path).and_return('#') + allow(helper).to receive(:issue_repositioning_disabled?).and_return(true) allow(helper).to receive(:url_for).and_return('#') expected = { @@ -318,6 +321,8 @@ RSpec.describe IssuesHelper do has_any_issues: project_issues(project).exists?.to_s, import_csv_issues_path: '#', initial_email: project.new_issuable_address(current_user, 'issue'), + is_anonymous_search_disabled: 'true', + is_issue_repositioning_disabled: 'true', is_project: 'true', is_signed_in: current_user.present?.to_s, jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'), @@ -338,6 +343,10 @@ RSpec.describe IssuesHelper do end describe '#project_issues_list_data' do + before do + stub_feature_flags(disable_anonymous_search: true) + end + context 'when user is signed in' do it_behaves_like 'issues list data' do let(:current_user) { double.as_null_object } diff --git a/spec/helpers/jira_connect_helper_spec.rb b/spec/helpers/jira_connect_helper_spec.rb index 55a5c724665..0f78185dc7d 100644 --- a/spec/helpers/jira_connect_helper_spec.rb +++ b/spec/helpers/jira_connect_helper_spec.rb @@ -19,7 +19,9 @@ RSpec.describe JiraConnectHelper do is_expected.to include( :groups_path, :subscriptions_path, - :users_path + :users_path, + :subscriptions, + :gitlab_user_path ) end @@ -32,6 +34,10 @@ RSpec.describe JiraConnectHelper do expect(subject[:groups_path]).to include("#{skip_groups_param}=#{subscription.namespace.id}") end + + it 'assigns gitlab_user_path to nil' do + expect(subject[:gitlab_user_path]).to be_nil + end end context 'user is logged in' do @@ -42,6 +48,10 @@ RSpec.describe JiraConnectHelper do it 'assigns users_path to nil' do expect(subject[:users_path]).to be_nil end + + it 'assigns gitlab_user_path correctly' do + expect(subject[:gitlab_user_path]).to eq(user_path(user)) + end end end end diff --git a/spec/helpers/learn_gitlab_helper_spec.rb b/spec/helpers/learn_gitlab_helper_spec.rb index b9f34853a77..9d13fc65de7 100644 --- a/spec/helpers/learn_gitlab_helper_spec.rb +++ b/spec/helpers/learn_gitlab_helper_spec.rb @@ -60,6 +60,7 @@ RSpec.describe LearnGitlabHelper do let(:onboarding_actions_data) { Gitlab::Json.parse(learn_gitlab_data[:actions]).deep_symbolize_keys } let(:onboarding_sections_data) { Gitlab::Json.parse(learn_gitlab_data[:sections]).deep_symbolize_keys } + let(:onboarding_project_data) { Gitlab::Json.parse(learn_gitlab_data[:project]).deep_symbolize_keys } shared_examples 'has all data' do it 'has all actions' do @@ -82,6 +83,11 @@ RSpec.describe LearnGitlabHelper do expect(onboarding_sections_data.keys).to contain_exactly(:deploy, :plan, :workspace) expect(onboarding_sections_data.values.map { |section| section.keys }).to match_array([[:svg]] * 3) end + + it 'has all project data', :aggregate_failures do + expect(onboarding_project_data.keys).to contain_exactly(:name) + expect(onboarding_project_data.values).to match_array([project.name]) + end end it_behaves_like 'has all data' diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb index e946857ac77..ab2f6fa5b7e 100644 --- a/spec/helpers/markup_helper_spec.rb +++ b/spec/helpers/markup_helper_spec.rb @@ -321,7 +321,7 @@ RSpec.describe MarkupHelper do let(:context) do { pipeline: :wiki, project: project, wiki: wiki, - page_slug: 'nested/page', issuable_state_filter_enabled: true, + page_slug: 'nested/page', issuable_reference_expansion_enabled: true, repository: wiki_repository } end @@ -584,9 +584,9 @@ FooBar it 'preserves code color scheme' do object = create_object("```ruby\ndef test\n 'hello world'\nend\n```") - expected = "<pre class=\"code highlight js-syntax-highlight language-ruby\">" \ + expected = "\n<pre class=\"code highlight js-syntax-highlight language-ruby\">" \ "<code><span class=\"line\"><span class=\"k\">def</span> <span class=\"nf\">test</span>...</span>\n" \ - "</code></pre>" + "</code></pre>\n" expect(first_line_in_markdown(object, attribute, 150, project: project)).to eq(expected) end diff --git a/spec/helpers/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb index 68bc19cb429..6eb560e3f5c 100644 --- a/spec/helpers/namespaces_helper_spec.rb +++ b/spec/helpers/namespaces_helper_spec.rb @@ -45,6 +45,39 @@ 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 64f4d5ff797..ab206152e3d 100644 --- a/spec/helpers/nav/new_dropdown_helper_spec.rb +++ b/spec/helpers/nav/new_dropdown_helper_spec.rb @@ -13,8 +13,6 @@ RSpec.describe Nav::NewDropdownHelper do let(:with_can_create_project) { false } let(:with_can_create_group) { false } let(:with_can_create_snippet) { false } - let(:with_invite_members_experiment) { false } - let(:with_invite_members_experiment_enabled) { false } let(:subject) { helper.new_dropdown_view_model(project: current_project, group: current_group) } @@ -28,11 +26,6 @@ RSpec.describe Nav::NewDropdownHelper do end before do - allow(::Gitlab::Experimentation).to receive(:active?).with(:invite_members_new_dropdown) { with_invite_members_experiment } - allow(helper).to receive(:experiment_enabled?).with(:invite_members_new_dropdown) { with_invite_members_experiment_enabled } - allow(helper).to receive(:tracking_label) { 'test_tracking_label' } - allow(helper).to receive(:experiment_tracking_category_and_group) { |x| x } - allow(helper).to receive(:current_user) { current_user } allow(helper).to receive(:can?) { false } @@ -42,38 +35,23 @@ RSpec.describe Nav::NewDropdownHelper do end shared_examples 'invite member link shared example' do - it 'shows invite member link' do + it 'shows invite member link with emoji' do expect(subject[:menu_sections]).to eq( expected_menu_section( title: expected_title, menu_item: ::Gitlab::Nav::TopNavMenuItem.build( id: 'invite', title: 'Invite members', + emoji: 'shaking_hands', href: expected_href, data: { - track_action: 'click_link', - track_label: 'test_tracking_label', - track_property: :invite_members_new_dropdown + track_action: 'click_link_invite_members', + track_label: 'plus_menu_dropdown' } ) ) ) end - - context 'with experiment enabled' do - let(:with_invite_members_experiment_enabled) { true } - - it 'shows emoji with invite member link' do - expect(subject[:menu_sections]).to match( - expected_menu_section( - title: expected_title, - menu_item: a_hash_including( - emoji: 'shaking_hands' - ) - ) - ) - end - end end it 'has title' do diff --git a/spec/helpers/notify_helper_spec.rb b/spec/helpers/notify_helper_spec.rb index a4193444528..e2a7a212b1b 100644 --- a/spec/helpers/notify_helper_spec.rb +++ b/spec/helpers/notify_helper_spec.rb @@ -55,53 +55,4 @@ RSpec.describe NotifyHelper do def reference_link(entity, url) "<a href=\"#{url}\">#{entity.to_reference}</a>" end - - describe '#invited_join_url' do - let_it_be(:member) { create(:project_member) } - - let(:token) { '_token_' } - - context 'when invite_email_preview_text is enabled', :experiment do - before do - stub_experiments(invite_email_preview_text: :control) - end - - it 'has correct params' do - expect(helper.invited_join_url(token, member)) - .to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_preview_text&invite_type=initial_email") - end - - context 'when invite_email_from is enabled' do - before do - stub_experiments(invite_email_from: :control) - end - - it 'has correct params' do - expect(helper.invited_join_url(token, member)) - .to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_from&invite_type=initial_email") - end - end - end - - context 'when invite_email_from is enabled' do - before do - stub_experiments(invite_email_from: :control) - end - - it 'has correct params' do - expect(helper.invited_join_url(token, member)) - .to eq("http://test.host/-/invites/#{token}?experiment_name=invite_email_from&invite_type=initial_email") - end - end - - context 'when invite_email_preview_text is disabled' do - before do - stub_feature_flags(invite_email_preview_text: false) - end - - it 'has correct params' do - expect(helper.invited_join_url(token, member)).to eq("http://test.host/-/invites/#{token}?invite_type=initial_email") - end - end - end end diff --git a/spec/helpers/numbers_helper_spec.rb b/spec/helpers/numbers_helper_spec.rb new file mode 100644 index 00000000000..a546f625ce8 --- /dev/null +++ b/spec/helpers/numbers_helper_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe NumbersHelper do + describe '#limited_counter_with_delimiter' do + using RSpec::Parameterized::TableSyntax + + subject { limited_counter_with_delimiter(resource, **options) } + + where(:count, :options, :expected_result) do + # Using explicit limit + 9 | { limit: 10 } | '9' + 10 | { limit: 10 } | '10' + 11 | { limit: 10 } | '10+' + 12 | { limit: 10 } | '10+' + # Using default limit + 999 | {} | '999' + 1000 | {} | '1,000' + 1001 | {} | '1,000+' + 1002 | {} | '1,000+' + end + + with_them do + let(:page) { double('page', total_count_with_limit: [count, options.fetch(:limit, 1000) + 1].min) } + let(:resource) { class_double(Ci::Runner, page: page) } + + it { is_expected.to eq(expected_result) } + end + end +end diff --git a/spec/helpers/packages_helper_spec.rb b/spec/helpers/packages_helper_spec.rb index 2af572850da..06c6cccd488 100644 --- a/spec/helpers/packages_helper_spec.rb +++ b/spec/helpers/packages_helper_spec.rb @@ -260,34 +260,4 @@ RSpec.describe PackagesHelper do end end end - - describe '#packages_list_data' do - let_it_be(:resource) { project } - let_it_be(:type) { 'project' } - - let(:expected_result) do - { - resource_id: resource.id, - full_path: resource.full_path, - page_type: type - } - end - - subject(:result) { helper.packages_list_data(type, resource) } - - context 'at a project level' do - it 'populates presenter data' do - expect(result).to match(hash_including(expected_result)) - end - end - - context 'at a group level' do - let_it_be(:resource) { create(:group) } - let_it_be(:type) { 'group' } - - it 'populates presenter data' do - expect(result).to match(hash_including(expected_result)) - end - end - end end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 5d2af567549..cc443afee6e 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -991,4 +991,31 @@ RSpec.describe ProjectsHelper do expect(subject).to eq(project.path_with_namespace) end end + + describe '#fork_button_disabled_tooltip' do + using RSpec::Parameterized::TableSyntax + + subject { helper.fork_button_disabled_tooltip(project) } + + where(:has_user, :can_fork_project, :can_create_fork, :expected) do + false | false | false | nil + true | true | true | nil + true | false | true | 'You don\'t have permission to fork this project' + true | true | false | 'You have reached your project limit' + end + + with_them do + before do + current_user = user if has_user + + allow(helper).to receive(:current_user).and_return(current_user) + allow(user).to receive(:can?).with(:fork_project, project).and_return(can_fork_project) + allow(user).to receive(:can?).with(:create_fork).and_return(can_create_fork) + end + + it 'returns tooltip text when user lacks privilege' do + expect(subject).to eq(expected) + end + end + end end diff --git a/spec/helpers/routing/pseudonymization_helper_spec.rb b/spec/helpers/routing/pseudonymization_helper_spec.rb index 82ed893289d..d7905edb098 100644 --- a/spec/helpers/routing/pseudonymization_helper_spec.rb +++ b/spec/helpers/routing/pseudonymization_helper_spec.rb @@ -11,15 +11,15 @@ RSpec.describe ::Routing::PseudonymizationHelper do let(:merge_request) { create(:merge_request, source_project: project) } + let(:subject) { helper.masked_page_url(group: group, project: project) } + before do stub_feature_flags(mask_page_urls: true) - allow(helper).to receive(:group).and_return(group) - allow(helper).to receive(:project).and_return(project) end shared_examples 'masked url' do it 'generates masked page url' do - expect(helper.masked_page_url).to eq(masked_url) + expect(subject).to eq(masked_url) end end @@ -72,6 +72,8 @@ RSpec.describe ::Routing::PseudonymizationHelper do context 'with controller for groups with subgroups and project' do let(:masked_url) { "http://localhost/namespace#{subgroup.id}/project#{subproject.id}"} + let(:group) { subgroup } + let(:project) { subproject } let(:request) do double(:Request, path_parameters: { @@ -86,8 +88,6 @@ RSpec.describe ::Routing::PseudonymizationHelper do end before do - allow(helper).to receive(:group).and_return(subgroup) - allow(helper).to receive(:project).and_return(subproject) allow(helper).to receive(:request).and_return(request) end @@ -96,6 +96,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do context 'with controller for groups and subgroups' do let(:masked_url) { "http://localhost/groups/namespace#{subgroup.id}/-/shared"} + let(:group) { subgroup } let(:request) do double(:Request, path_parameters: { @@ -109,7 +110,6 @@ RSpec.describe ::Routing::PseudonymizationHelper do end before do - allow(helper).to receive(:group).and_return(subgroup) allow(helper).to receive(:request).and_return(request) end @@ -160,7 +160,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do end context 'when author_username is present' do - let(:masked_url) { "http://localhost/dashboard/issues?author_username=masked_author_username&scope=masked_scope&state=masked_state" } + let(:masked_url) { "http://localhost/dashboard/issues?author_username=masked_author_username&scope=all&state=opened" } let(:request) do double(:Request, path_parameters: { @@ -201,7 +201,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do end context 'when query string has keys with the same names as path params' do - let(:masked_url) { "http://localhost/dashboard/issues?action=masked_action&scope=masked_scope&state=masked_state" } + let(:masked_url) { "http://localhost/dashboard/issues?action=masked_action&scope=all&state=opened" } let(:request) do double(:Request, path_parameters: { @@ -230,7 +230,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do end it 'masked_page_url' do - expect(helper.masked_page_url).to eq(root_url) + expect(subject).to eq(root_url) end end end @@ -262,7 +262,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do ActionController::RoutingError, url: '/dashboard/issues?assignee_username=root').and_call_original - expect(helper.masked_page_url).to be_nil + expect(subject).to be_nil end end end @@ -273,7 +273,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do end it 'returns nil' do - expect(helper.masked_page_url).to be_nil + expect(subject).to be_nil end end end diff --git a/spec/helpers/sorting_helper_spec.rb b/spec/helpers/sorting_helper_spec.rb index f976fb098a8..b49b4ad6e7e 100644 --- a/spec/helpers/sorting_helper_spec.rb +++ b/spec/helpers/sorting_helper_spec.rb @@ -191,4 +191,77 @@ RSpec.describe SortingHelper do end end end + + describe 'with `forks` controller' do + before do + stub_controller_path 'forks' + end + + describe '#forks_sort_options_hash' do + it 'returns a hash of available sorting options' do + expect(forks_sort_options_hash).to include({ + sort_value_recently_created => sort_title_created_date, + sort_value_oldest_created => sort_title_created_date, + sort_value_latest_activity => sort_title_latest_activity, + sort_value_oldest_activity => sort_title_latest_activity + }) + end + end + + describe '#forks_reverse_sort_options_hash' do + context 'for each sort option' do + using RSpec::Parameterized::TableSyntax + + where(:sort_key, :reverse_sort_title) do + sort_value_recently_created | sort_value_oldest_created + sort_value_oldest_created | sort_value_recently_created + sort_value_latest_activity | sort_value_oldest_activity + sort_value_oldest_activity | sort_value_latest_activity + end + + with_them do + it 'returns the correct reversed hash' do + reverse_hash = forks_reverse_sort_options_hash + + expect(reverse_hash).to include(sort_key) + expect(reverse_hash[sort_key]).to eq(reverse_sort_title) + end + end + end + end + + describe '#forks_sort_direction_button' do + context 'for each sort option' do + using RSpec::Parameterized::TableSyntax + + sort_lowest_icon = 'sort-lowest' + sort_highest_icon = 'sort-highest' + + where(:selected_sort, :icon) do + sort_value_recently_created | sort_highest_icon + sort_value_latest_activity | sort_highest_icon + sort_value_oldest_created | sort_lowest_icon + sort_value_oldest_activity | sort_lowest_icon + end + + with_them do + it 'returns the correct icon' do + set_sorting_url selected_sort + + expect(forks_sort_direction_button(selected_sort)).to include(icon) + end + end + end + + it 'returns the correct link to reverse the current sort option' do + sort_options_links = forks_reverse_sort_options_hash + + sort_options_links.each do |selected_sort, reverse_sort| + set_sorting_url selected_sort + + expect(forks_sort_direction_button(selected_sort)).to include(reverse_sort) + end + end + end + end end diff --git a/spec/helpers/tab_helper_spec.rb b/spec/helpers/tab_helper_spec.rb index e5e88466946..f338eddedfd 100644 --- a/spec/helpers/tab_helper_spec.rb +++ b/spec/helpers/tab_helper_spec.rb @@ -7,62 +7,58 @@ RSpec.describe TabHelper do describe 'gl_tabs_nav' do it 'creates a tabs navigation' do - expect(gl_tabs_nav).to match(%r{<ul class=".*" role="tablist"><\/ul>}) + expect(helper.gl_tabs_nav).to match(%r{<ul class="nav gl-tabs-nav"><\/ul>}) end it 'captures block output' do - expect(gl_tabs_nav { "block content" }).to match(/block content/) - end - - it 'adds styles classes' do - expect(gl_tabs_nav).to match(/class="nav gl-tabs-nav"/) + expect(helper.gl_tabs_nav { "block content" }).to match(/block content/) end it 'adds custom class' do - expect(gl_tabs_nav(class: 'my-class' )).to match(/class=".*my-class.*"/) + expect(helper.gl_tabs_nav(class: 'my-class' )).to match(/class=".*my-class.*"/) end end describe 'gl_tab_link_to' do before do - allow(self).to receive(:current_page?).and_return(false) + allow(helper).to receive(:current_page?).and_return(false) end it 'creates a tab' do - expect(gl_tab_link_to('Link', '/url')).to eq('<li class="nav-item" role="presentation"><a class="nav-link gl-tab-nav-item" href="/url">Link</a></li>') + expect(helper.gl_tab_link_to('Link', '/url')).to eq('<li class="nav-item"><a class="nav-link gl-tab-nav-item" href="/url">Link</a></li>') end it 'creates a tab with block output' do - expect(gl_tab_link_to('/url') { 'block content' }).to match(/block content/) + expect(helper.gl_tab_link_to('/url') { 'block content' }).to match(/block content/) end it 'creates a tab with custom classes for enclosing list item without content block provided' do - expect(gl_tab_link_to('Link', '/url', { tab_class: 'my-class' })).to match(/<li class=".*my-class.*"/) + expect(helper.gl_tab_link_to('Link', '/url', { tab_class: 'my-class' })).to match(/<li class=".*my-class.*"/) end it 'creates a tab with custom classes for enclosing list item with content block provided' do - expect(gl_tab_link_to('/url', { tab_class: 'my-class' }) { 'Link' }).to match(/<li class=".*my-class.*"/) + expect(helper.gl_tab_link_to('/url', { tab_class: 'my-class' }) { 'Link' }).to match(/<li class=".*my-class.*"/) end it 'creates a tab with custom classes for anchor element' do - expect(gl_tab_link_to('Link', '/url', { class: 'my-class' })).to match(/<a class=".*my-class.*"/) + expect(helper.gl_tab_link_to('Link', '/url', { class: 'my-class' })).to match(/<a class=".*my-class.*"/) end it 'creates an active tab with item_active = true' do - expect(gl_tab_link_to('Link', '/url', { item_active: true })).to match(/<a class=".*active gl-tab-nav-item-active gl-tab-nav-item-active-indigo.*"/) + expect(helper.gl_tab_link_to('Link', '/url', { item_active: true })).to match(/<a class=".*active gl-tab-nav-item-active gl-tab-nav-item-active-indigo.*"/) end context 'when on the active page' do before do - allow(self).to receive(:current_page?).and_return(true) + allow(helper).to receive(:current_page?).and_return(true) end it 'creates an active tab' do - expect(gl_tab_link_to('Link', '/url')).to match(/<a class=".*active gl-tab-nav-item-active gl-tab-nav-item-active-indigo.*"/) + expect(helper.gl_tab_link_to('Link', '/url')).to match(/<a class=".*active gl-tab-nav-item-active gl-tab-nav-item-active-indigo.*"/) end it 'creates an inactive tab with item_active = false' do - expect(gl_tab_link_to('Link', '/url', { item_active: false })).not_to match(/<a class=".*active.*"/) + expect(helper.gl_tab_link_to('Link', '/url', { item_active: false })).not_to match(/<a class=".*active.*"/) end end end @@ -72,18 +68,18 @@ RSpec.describe TabHelper do before do allow(controller).to receive(:controller_name).and_return('foo') - allow(self).to receive(:action_name).and_return('foo') + allow(helper).to receive(:action_name).and_return('foo') end context 'with the content of the li' do it 'captures block output' do - expect(nav_link { "Testing Blocks" }).to match(/Testing Blocks/) + expect(helper.nav_link { "Testing Blocks" }).to match(/Testing Blocks/) end end it 'passes extra html options to the list element' do - expect(nav_link(action: :foo, html_options: { class: 'home' })).to match(/<li class="home active">/) - expect(nav_link(html_options: { class: 'active' })).to match(/<li class="active">/) + expect(helper.nav_link(action: :foo, html_options: { class: 'home' })).to match(/<li class="home active">/) + expect(helper.nav_link(html_options: { class: 'active' })).to match(/<li class="active">/) end where(:controller_param, :action_param, :path_param, :active) do @@ -120,13 +116,26 @@ RSpec.describe TabHelper do with_them do specify do - result = nav_link(controller: controller_param, action: action_param, path: path_param) + result = helper.nav_link(controller: controller_param, action: action_param, path: path_param) - if active - expect(result).to match(/active/) - else - expect(result).not_to match(/active/) - end + expect(result.include?('active')).to eq(active) + end + end + + where(:page, :excluded_page, :active) do + nil | nil | false + '_some_page_' | nil | true + '_some_page_' | '_excluded_page_' | true + '_some_page_' | '_some_page_' | false + end + + with_them do + specify do + allow(helper).to receive(:route_matches_pages?).and_return(page.present?, page == excluded_page) + + result = helper.nav_link(page: page, exclude_page: excluded_page) + + expect(result.include?('active')).to eq(active) end end @@ -147,13 +156,9 @@ RSpec.describe TabHelper do with_them do specify do - result = nav_link(controller: controller_param, action: action_param, path: path_param) + result = helper.nav_link(controller: controller_param, action: action_param, path: path_param) - if active - expect(result).to match(/active/) - else - expect(result).not_to match(/active/) - end + expect(result.include?('active')).to eq(active) end end end @@ -161,18 +166,24 @@ RSpec.describe TabHelper do describe 'gl_tab_counter_badge' do it 'creates a tab counter badge' do - expect(gl_tab_counter_badge(1)).to eq('<span class="badge badge-muted badge-pill gl-badge sm gl-tab-counter-badge">1</span>') + expect(helper.gl_tab_counter_badge(1)).to eq( + '<span class="gl-badge badge badge-pill badge-muted sm gl-tab-counter-badge">1</span>' + ) end context 'with extra classes' do it 'creates a tab counter badge with the correct class attribute' do - expect(gl_tab_counter_badge(1, { class: 'js-test' })).to eq('<span class="js-test badge badge-muted badge-pill gl-badge sm gl-tab-counter-badge">1</span>') + expect(helper.gl_tab_counter_badge(1, { class: 'js-test' })).to eq( + '<span class="gl-badge badge badge-pill badge-muted sm gl-tab-counter-badge js-test">1</span>' + ) end end context 'with data attributes' do it 'creates a tab counter badge with the data attributes' do - expect(gl_tab_counter_badge(1, { data: { some_attribute: 'foo' } })).to eq('<span class="badge badge-muted badge-pill gl-badge sm gl-tab-counter-badge" data-some-attribute="foo">1</span>') + expect(helper.gl_tab_counter_badge(1, { data: { some_attribute: 'foo' } })).to eq( + '<span data-some-attribute="foo" class="gl-badge badge badge-pill badge-muted sm gl-tab-counter-badge">1</span>' + ) end end end diff --git a/spec/helpers/time_zone_helper_spec.rb b/spec/helpers/time_zone_helper_spec.rb index 006fae5b814..e8d96ee0700 100644 --- a/spec/helpers/time_zone_helper_spec.rb +++ b/spec/helpers/time_zone_helper_spec.rb @@ -30,6 +30,30 @@ RSpec.describe TimeZoneHelper, :aggregate_failures do end end + context 'with abbr format' do + subject(:timezone_data) { helper.timezone_data(format: :abbr) } + + it 'matches schema' do + expect(timezone_data).not_to be_empty + + timezone_data.each_with_index do |timezone_hash, i| + expect(timezone_hash.keys).to contain_exactly( + :identifier, + :abbr + ), "Failed at index #{i}" + end + end + + it 'formats for display' do + tz = ActiveSupport::TimeZone.all[0] + + expect(timezone_data[0]).to eq( + identifier: tz.tzinfo.identifier, + abbr: tz.tzinfo.strftime('%Z') + ) + end + end + context 'with full format' do subject(:timezone_data) { helper.timezone_data(format: :full) } @@ -64,7 +88,7 @@ RSpec.describe TimeZoneHelper, :aggregate_failures do subject(:timezone_data) { helper.timezone_data(format: :unknown) } it 'raises an exception' do - expect { timezone_data }.to raise_error ArgumentError, 'Invalid format :unknown. Valid formats are :short, :full.' + expect { timezone_data }.to raise_error ArgumentError, 'Invalid format :unknown. Valid formats are :short, :abbr, :full.' end end end @@ -101,7 +125,7 @@ RSpec.describe TimeZoneHelper, :aggregate_failures do end end - describe '#local_time_instance' do + describe '#local_timezone_instance' do let_it_be(:timezone) { 'UTC' } before do @@ -110,25 +134,25 @@ RSpec.describe TimeZoneHelper, :aggregate_failures do context 'when timezone is `nil`' do it 'returns the system timezone instance' do - expect(helper.local_time_instance(nil).name).to eq(timezone) + expect(helper.local_timezone_instance(nil).name).to eq(timezone) end end context 'when timezone is blank' do it 'returns the system timezone instance' do - expect(helper.local_time_instance('').name).to eq(timezone) + expect(helper.local_timezone_instance('').name).to eq(timezone) end end context 'when a valid timezone is passed' do it 'returns the local time instance' do - expect(helper.local_time_instance('America/Los_Angeles').name).to eq('America/Los_Angeles') + expect(helper.local_timezone_instance('America/Los_Angeles').name).to eq('America/Los_Angeles') end end context 'when an invalid timezone is passed' do it 'returns the system timezone instance' do - expect(helper.local_time_instance('Foo/Bar').name).to eq(timezone) + expect(helper.local_timezone_instance('Foo/Bar').name).to eq(timezone) end end end diff --git a/spec/helpers/user_callouts_helper_spec.rb b/spec/helpers/users/callouts_helper_spec.rb index 7abc67e29a4..85e11c2ed3b 100644 --- a/spec/helpers/user_callouts_helper_spec.rb +++ b/spec/helpers/users/callouts_helper_spec.rb @@ -2,7 +2,7 @@ require "spec_helper" -RSpec.describe UserCalloutsHelper do +RSpec.describe Users::CalloutsHelper do let_it_be(:user, refind: true) { create(:user) } before do @@ -61,36 +61,6 @@ RSpec.describe UserCalloutsHelper do end end - describe '.show_customize_homepage_banner?' do - subject { helper.show_customize_homepage_banner? } - - context 'when user has not dismissed' do - before do - allow(helper).to receive(:user_dismissed?).with(described_class::CUSTOMIZE_HOMEPAGE) { false } - end - - context 'when user is on the default dashboard' do - it { is_expected.to be true } - end - - context 'when user is not on the default dashboard' do - before do - user.dashboard = 'stars' - end - - it { is_expected.to be false } - end - end - - context 'when user dismissed' do - before do - allow(helper).to receive(:user_dismissed?).with(described_class::CUSTOMIZE_HOMEPAGE) { true } - end - - it { is_expected.to be false } - end - end - describe '.render_flash_user_callout' do it 'renders the flash_user_callout partial' do expect(helper).to receive(:render) @@ -115,7 +85,7 @@ RSpec.describe UserCalloutsHelper do context 'when the feature flags new version has been dismissed' do before do - create(:user_callout, user: user, feature_name: described_class::FEATURE_FLAGS_NEW_VERSION) + create(:callout, user: user, feature_name: described_class::FEATURE_FLAGS_NEW_VERSION) end it { is_expected.to be_falsy } @@ -203,83 +173,6 @@ RSpec.describe UserCalloutsHelper do end end - describe '.show_invite_banner?' do - let_it_be(:group) { create(:group) } - - subject { helper.show_invite_banner?(group) } - - context 'when user has the admin ability for the group' do - before do - group.add_owner(user) - end - - context 'when the invite_members_banner has not been dismissed' do - it { is_expected.to eq(true) } - - context 'when the group was just created' do - before do - flash[:notice] = "Group #{group.name} was successfully created" - end - - it { is_expected.to eq(false) } - end - - context 'with concerning multiple members' do - let_it_be(:user_2) { create(:user) } - - context 'on current group' do - before do - group.add_guest(user_2) - end - - it { is_expected.to eq(false) } - end - - context 'on current group that is a subgroup' do - let_it_be(:subgroup) { create(:group, parent: group) } - - subject { helper.show_invite_banner?(subgroup) } - - context 'with only one user on parent and this group' do - it { is_expected.to eq(true) } - end - - context 'when another user is on this group' do - before do - subgroup.add_guest(user_2) - end - - it { is_expected.to eq(false) } - end - - context 'when another user is on the parent group' do - before do - group.add_guest(user_2) - end - - it { is_expected.to eq(false) } - end - end - end - end - - context 'when the invite_members_banner has been dismissed' do - before do - create(:group_callout, - user: user, - group: group, - feature_name: described_class::INVITE_MEMBERS_BANNER) - end - - it { is_expected.to eq(false) } - end - end - - context 'when user does not have admin ability for the group' do - it { is_expected.to eq(false) } - end - end - describe '.show_security_newsletter_user_callout?' do let_it_be(:admin) { create(:user, :admin) } diff --git a/spec/helpers/users/group_callouts_helper_spec.rb b/spec/helpers/users/group_callouts_helper_spec.rb new file mode 100644 index 00000000000..da67c4921b3 --- /dev/null +++ b/spec/helpers/users/group_callouts_helper_spec.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Users::GroupCalloutsHelper do + let_it_be(:user, refind: true) { create(:user) } + let_it_be(:group) { create(:group) } + + before do + allow(helper).to receive(:current_user).and_return(user) + end + + describe '.show_invite_banner?' do + subject { helper.show_invite_banner?(group) } + + context 'when user has the admin ability for the group' do + before do + group.add_owner(user) + end + + context 'when the invite_members_banner has not been dismissed' do + it { is_expected.to eq(true) } + + context 'when the group was just created' do + before do + flash[:notice] = "Group #{group.name} was successfully created" + end + + it { is_expected.to eq(false) } + end + + context 'with concerning multiple members' do + let_it_be(:user_2) { create(:user) } + + context 'on current group' do + before do + group.add_guest(user_2) + end + + it { is_expected.to eq(false) } + end + + context 'on current group that is a subgroup' do + let_it_be(:subgroup) { create(:group, parent: group) } + + subject { helper.show_invite_banner?(subgroup) } + + context 'with only one user on parent and this group' do + it { is_expected.to eq(true) } + end + + context 'when another user is on this group' do + before do + subgroup.add_guest(user_2) + end + + it { is_expected.to eq(false) } + end + + context 'when another user is on the parent group' do + before do + group.add_guest(user_2) + end + + it { is_expected.to eq(false) } + end + end + end + end + + context 'when the invite_members_banner has been dismissed' do + before do + create(:group_callout, + user: user, + group: group, + feature_name: described_class::INVITE_MEMBERS_BANNER) + end + + it { is_expected.to eq(false) } + end + end + + context 'when user does not have admin ability for the group' do + it { is_expected.to eq(false) } + end + end +end diff --git a/spec/helpers/version_check_helper_spec.rb b/spec/helpers/version_check_helper_spec.rb index 6d849d0720e..bd52eda8a65 100644 --- a/spec/helpers/version_check_helper_spec.rb +++ b/spec/helpers/version_check_helper_spec.rb @@ -15,7 +15,7 @@ RSpec.describe VersionCheckHelper do before do stub_rails_env('production') allow(Gitlab::CurrentSettings.current_application_settings).to receive(:version_check_enabled) { true } - allow(VersionCheck).to receive(:url) { 'https://version.host.com/check.svg?gitlab_info=xxx' } + allow(VersionCheck).to receive(:image_url) { 'https://version.host.com/check.svg?gitlab_info=xxx' } end it 'returns an image tag' do @@ -27,7 +27,7 @@ RSpec.describe VersionCheckHelper do .to match(/class="js-version-status-badge lazy"/) end - it 'has a VersionCheck url as the src' do + it 'has a VersionCheck image_url as the src' do expect(helper.version_status_badge) .to include(%{src="https://version.host.com/check.svg?gitlab_info=xxx"}) end |