Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/helpers')
-rw-r--r--spec/helpers/access_tokens_helper_spec.rb49
-rw-r--r--spec/helpers/application_helper_spec.rb14
-rw-r--r--spec/helpers/auth_helper_spec.rb239
-rw-r--r--spec/helpers/badges_helper_spec.rb129
-rw-r--r--spec/helpers/ci/jobs_helper_spec.rb25
-rw-r--r--spec/helpers/ide_helper_spec.rb4
-rw-r--r--spec/helpers/invite_members_helper_spec.rb174
-rw-r--r--spec/helpers/issues_helper_spec.rb9
-rw-r--r--spec/helpers/jira_connect_helper_spec.rb12
-rw-r--r--spec/helpers/learn_gitlab_helper_spec.rb6
-rw-r--r--spec/helpers/markup_helper_spec.rb6
-rw-r--r--spec/helpers/namespaces_helper_spec.rb33
-rw-r--r--spec/helpers/nav/new_dropdown_helper_spec.rb30
-rw-r--r--spec/helpers/notify_helper_spec.rb49
-rw-r--r--spec/helpers/numbers_helper_spec.rb31
-rw-r--r--spec/helpers/packages_helper_spec.rb30
-rw-r--r--spec/helpers/projects_helper_spec.rb27
-rw-r--r--spec/helpers/routing/pseudonymization_helper_spec.rb22
-rw-r--r--spec/helpers/sorting_helper_spec.rb73
-rw-r--r--spec/helpers/tab_helper_spec.rb83
-rw-r--r--spec/helpers/time_zone_helper_spec.rb36
-rw-r--r--spec/helpers/users/callouts_helper_spec.rb (renamed from spec/helpers/user_callouts_helper_spec.rb)111
-rw-r--r--spec/helpers/users/group_callouts_helper_spec.rb87
-rw-r--r--spec/helpers/version_check_helper_spec.rb4
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