diff options
Diffstat (limited to 'spec/lib')
10 files changed, 238 insertions, 25 deletions
diff --git a/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb index 3b274f98020..7557b9a118d 100644 --- a/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb @@ -213,7 +213,9 @@ RSpec.describe Banzai::Filter::References::ExternalIssueReferenceFilter do end context "ewm project" do - let_it_be(:service) { create(:ewm_service, project: project) } + let_it_be(:integration) { create(:ewm_integration, project: project) } + + let(:service) { integration } # TODO: remove when https://gitlab.com/gitlab-org/gitlab/-/issues/330300 is complete before do project.update!(issues_enabled: false) diff --git a/spec/lib/gitlab/ci/templates/templates_spec.rb b/spec/lib/gitlab/ci/templates/templates_spec.rb index 2e6df7da232..81fc66c4a11 100644 --- a/spec/lib/gitlab/ci/templates/templates_spec.rb +++ b/spec/lib/gitlab/ci/templates/templates_spec.rb @@ -27,16 +27,17 @@ RSpec.describe 'CI YML Templates' do end context 'that support autodevops' do - non_autodevops_templates = [ - 'Security/DAST-API.gitlab-ci.yml', - 'Security/API-Fuzzing.gitlab-ci.yml' + exceptions = [ + 'Security/DAST.gitlab-ci.yml', # DAST stage is defined inside AutoDevops yml + 'Security/DAST-API.gitlab-ci.yml', # no auto-devops + 'Security/API-Fuzzing.gitlab-ci.yml' # no auto-devops ] context 'when including available templates in a CI YAML configuration' do using RSpec::Parameterized::TableSyntax where(:template_name) do - all_templates - excluded_templates - non_autodevops_templates + all_templates - excluded_templates - exceptions end with_them do diff --git a/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb b/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb new file mode 100644 index 00000000000..8aac3ed67c6 --- /dev/null +++ b/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true +require 'spec_helper' + +RSpec.describe Gitlab::Database::Migrations::Observers::QueryDetails do + subject { described_class.new } + + let(:observation) { Gitlab::Database::Migrations::Observation.new(migration) } + let(:connection) { ActiveRecord::Base.connection } + let(:query) { "select date_trunc('day', $1::timestamptz) + $2 * (interval '1 hour')" } + let(:query_binds) { [Time.current, 3] } + let(:directory_path) { Dir.mktmpdir } + let(:log_file) { "#{directory_path}/#{migration}-query-details.json" } + let(:query_details) { Gitlab::Json.parse(File.read(log_file)) } + let(:migration) { 20210422152437 } + + before do + stub_const('Gitlab::Database::Migrations::Instrumentation::RESULT_DIR', directory_path) + end + + after do + FileUtils.remove_entry(directory_path) + end + + it 'records details of executed queries' do + observe + + expect(query_details.size).to eq(1) + + log_entry = query_details[0] + start_time, end_time, sql, binds = log_entry.values_at('start_time', 'end_time', 'sql', 'binds') + start_time = DateTime.parse(start_time) + end_time = DateTime.parse(end_time) + + aggregate_failures do + expect(sql).to include(query) + expect(start_time).to be_before(end_time) + expect(binds).to eq(query_binds.map { |b| connection.type_cast(b) }) + end + end + + it 'unsubscribes after the observation' do + observe + + expect(subject).not_to receive(:record_sql_event) + run_query + end + + def observe + subject.before + run_query + subject.after + subject.record(observation) + end + + def run_query + connection.exec_query(query, 'SQL', query_binds) + end +end diff --git a/spec/lib/gitlab/exclusive_lease_spec.rb b/spec/lib/gitlab/exclusive_lease_spec.rb index e730ddd6577..968d26e1c38 100644 --- a/spec/lib/gitlab/exclusive_lease_spec.rb +++ b/spec/lib/gitlab/exclusive_lease_spec.rb @@ -166,4 +166,82 @@ RSpec.describe Gitlab::ExclusiveLease, :clean_gitlab_redis_shared_state do expect(described_class.get_uuid(unique_key)).to be_falsey end end + + describe '.throttle' do + it 'prevents repeated execution of the block' do + number = 0 + + action = -> { described_class.throttle(1) { number += 1 } } + + action.call + action.call + + expect(number).to eq 1 + end + + it 'is distinct by block' do + number = 0 + + described_class.throttle(1) { number += 1 } + described_class.throttle(1) { number += 1 } + + expect(number).to eq 2 + end + + it 'is distinct by key' do + number = 0 + + action = ->(k) { described_class.throttle(k) { number += 1 } } + + action.call(:a) + action.call(:b) + action.call(:a) + + expect(number).to eq 2 + end + + it 'allows a group to be passed' do + number = 0 + + described_class.throttle(1, group: :a) { number += 1 } + described_class.throttle(1, group: :b) { number += 1 } + described_class.throttle(1, group: :a) { number += 1 } + described_class.throttle(1, group: :b) { number += 1 } + + expect(number).to eq 2 + end + + it 'defaults to a 60min timeout' do + expect(described_class).to receive(:new).with(anything, hash_including(timeout: 1.hour.to_i)).and_call_original + + described_class.throttle(1) {} + end + + it 'allows count to be specified' do + expect(described_class) + .to receive(:new) + .with(anything, hash_including(timeout: 15.minutes.to_i)) + .and_call_original + + described_class.throttle(1, count: 4) {} + end + + it 'allows period to be specified' do + expect(described_class) + .to receive(:new) + .with(anything, hash_including(timeout: 1.day.to_i)) + .and_call_original + + described_class.throttle(1, period: 1.day) {} + end + + it 'allows period and count to be specified' do + expect(described_class) + .to receive(:new) + .with(anything, hash_including(timeout: 30.minutes.to_i)) + .and_call_original + + described_class.throttle(1, count: 48, period: 1.day) {} + end + end end diff --git a/spec/lib/gitlab/git/remote_mirror_spec.rb b/spec/lib/gitlab/git/remote_mirror_spec.rb index 92504b7aafe..0954879f6bd 100644 --- a/spec/lib/gitlab/git/remote_mirror_spec.rb +++ b/spec/lib/gitlab/git/remote_mirror_spec.rb @@ -7,16 +7,29 @@ RSpec.describe Gitlab::Git::RemoteMirror do let(:project) { create(:project, :repository) } let(:repository) { project.repository } let(:ref_name) { 'foo' } + let(:url) { 'https://example.com' } let(:options) { { only_branches_matching: ['master'], ssh_key: 'KEY', known_hosts: 'KNOWN HOSTS', keep_divergent_refs: true } } - subject(:remote_mirror) { described_class.new(repository, ref_name, **options) } + subject(:remote_mirror) { described_class.new(repository, ref_name, url, **options) } - it 'delegates to the Gitaly client' do - expect(repository.gitaly_remote_client) - .to receive(:update_remote_mirror) - .with(ref_name, ['master'], ssh_key: 'KEY', known_hosts: 'KNOWN HOSTS', keep_divergent_refs: true) + shared_examples 'an update' do + it 'delegates to the Gitaly client' do + expect(repository.gitaly_remote_client) + .to receive(:update_remote_mirror) + .with(ref_name, url, ['master'], ssh_key: 'KEY', known_hosts: 'KNOWN HOSTS', keep_divergent_refs: true) + + remote_mirror.update # rubocop:disable Rails/SaveBang + end + end + + context 'with url' do + it_behaves_like 'an update' + end + + context 'without url' do + let(:url) { nil } - remote_mirror.update # rubocop:disable Rails/SaveBang + it_behaves_like 'an update' end it 'wraps gitaly errors' do diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 96a44575e24..3ee0310a9a2 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -440,6 +440,14 @@ RSpec.describe Gitlab::GitAccess do expect { pull_access_check }.to raise_forbidden("Your password expired. Please access GitLab from a web browser to update your password.") end + it 'allows ldap users with expired password to pull' do + project.add_maintainer(user) + user.update!(password_expires_at: 2.minutes.ago) + allow(user).to receive(:ldap_user?).and_return(true) + + expect { pull_access_check }.not_to raise_error + end + context 'when the project repository does not exist' do before do project.add_guest(user) @@ -979,12 +987,26 @@ RSpec.describe Gitlab::GitAccess do end it 'disallows users with expired password to push' do - project.add_maintainer(user) user.update!(password_expires_at: 2.minutes.ago) expect { push_access_check }.to raise_forbidden("Your password expired. Please access GitLab from a web browser to update your password.") end + it 'allows ldap users with expired password to push' do + user.update!(password_expires_at: 2.minutes.ago) + allow(user).to receive(:ldap_user?).and_return(true) + + expect { push_access_check }.not_to raise_error + end + + it 'disallows blocked ldap users with expired password to push' do + user.block + user.update!(password_expires_at: 2.minutes.ago) + allow(user).to receive(:ldap_user?).and_return(true) + + expect { push_access_check }.to raise_forbidden("Your account has been blocked.") + end + it 'cleans up the files' do expect(project.repository).to receive(:clean_stale_repository_files).and_call_original expect { push_access_check }.not_to raise_error diff --git a/spec/lib/gitlab/gitaly_client/remote_service_spec.rb b/spec/lib/gitlab/gitaly_client/remote_service_spec.rb index df9dde324a5..2ec5f70be76 100644 --- a/spec/lib/gitlab/gitaly_client/remote_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/remote_service_spec.rb @@ -67,13 +67,29 @@ RSpec.describe Gitlab::GitalyClient::RemoteService do let(:ssh_key) { 'KEY' } let(:known_hosts) { 'KNOWN HOSTS' } - it 'sends an update_remote_mirror message' do - expect_any_instance_of(Gitaly::RemoteService::Stub) - .to receive(:update_remote_mirror) - .with(kind_of(Enumerator), kind_of(Hash)) - .and_return(double(:update_remote_mirror_response)) + shared_examples 'an update' do + it 'sends an update_remote_mirror message' do + expect_any_instance_of(Gitaly::RemoteService::Stub) + .to receive(:update_remote_mirror) + .with(array_including(gitaly_request_with_params(expected_params)), kind_of(Hash)) + .and_return(double(:update_remote_mirror_response)) + + client.update_remote_mirror(ref_name, url, only_branches_matching, ssh_key: ssh_key, known_hosts: known_hosts, keep_divergent_refs: true) + end + end + + context 'with remote name' do + let(:url) { nil } + let(:expected_params) { { ref_name: ref_name } } + + it_behaves_like 'an update' + end + + context 'with remote URL' do + let(:url) { 'http:://git.example.com/my-repo.git' } + let(:expected_params) { { remote: Gitaly::UpdateRemoteMirrorRequest::Remote.new(url: url) } } - client.update_remote_mirror(ref_name, only_branches_matching, ssh_key: ssh_key, known_hosts: known_hosts, keep_divergent_refs: true) + it_behaves_like 'an update' end end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 781c55f8d9b..87a10b52b22 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -366,21 +366,21 @@ project: - datadog_integration - discord_integration - drone_ci_integration -- emails_on_push_service +- emails_on_push_integration - pipelines_email_service - mattermost_slash_commands_service - slack_slash_commands_service -- irker_service +- irker_integration - packagist_service - pivotaltracker_service - prometheus_service -- flowdock_service +- flowdock_integration - assembla_integration - asana_integration - slack_service - microsoft_teams_service - mattermost_service -- hangouts_chat_service +- hangouts_chat_integration - unify_circuit_service - buildkite_integration - bamboo_integration @@ -391,8 +391,8 @@ project: - youtrack_service - custom_issue_tracker_integration - bugzilla_integration -- ewm_service -- external_wiki_service +- ewm_integration +- external_wiki_integration - mock_ci_service - mock_monitoring_service - forked_to_members diff --git a/spec/lib/gitlab/pagination/keyset/paginator_spec.rb b/spec/lib/gitlab/pagination/keyset/paginator_spec.rb index 3c9a8913876..230ac01af31 100644 --- a/spec/lib/gitlab/pagination/keyset/paginator_spec.rb +++ b/spec/lib/gitlab/pagination/keyset/paginator_spec.rb @@ -117,4 +117,27 @@ RSpec.describe Gitlab::Pagination::Keyset::Paginator do expect { scope.keyset_paginate }.to raise_error(/does not support keyset pagination/) end end + + context 'when use_union_optimization option is true and ordering by two columns' do + let(:scope) { Project.order(name: :asc, id: :desc) } + + it 'uses UNION queries' do + paginator_first_page = scope.keyset_paginate( + per_page: 2, + keyset_order_options: { use_union_optimization: true } + ) + + paginator_second_page = scope.keyset_paginate( + per_page: 2, + cursor: paginator_first_page.cursor_for_next_page, + keyset_order_options: { use_union_optimization: true } + ) + + expect_next_instances_of(Gitlab::SQL::Union, 1) do |instance| + expect(instance.to_sql).to include(paginator_first_page.records.last.name) + end + + paginator_second_page.records.to_a + end + end end diff --git a/spec/lib/sidebars/projects/menus/external_wiki_menu_spec.rb b/spec/lib/sidebars/projects/menus/external_wiki_menu_spec.rb index 19efd2bbd6b..a8f4b039b8c 100644 --- a/spec/lib/sidebars/projects/menus/external_wiki_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/external_wiki_menu_spec.rb @@ -19,7 +19,7 @@ RSpec.describe Sidebars::Projects::Menus::ExternalWikiMenu do end context 'when active external issue tracker' do - let(:external_wiki) { build(:external_wiki_service, project: project) } + let(:external_wiki) { build(:external_wiki_integration, project: project) } context 'is present' do it 'returns true' do |