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
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-06 21:09:02 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-06 21:09:02 +0300
commit2d181003830956f5e690cce74be50bb4d96048f8 (patch)
treecd72c53f6cb3753fc1bd28521e89af66c420f08a /spec
parentc79da5142f46e6e9187f75c329e2c81a8568c581 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/components/pajamas/banner_component_spec.rb169
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb2
-rw-r--r--spec/events/pages/page_deleted_event_spec.rb34
-rw-r--r--spec/graphql/types/ci/pipeline_merge_request_event_type_enum_spec.rb14
-rw-r--r--spec/graphql/types/ci/pipeline_type_spec.rb2
-rw-r--r--spec/lib/gitlab/mailgun/webhook_processors/failure_logger_spec.rb92
-rw-r--r--spec/lib/gitlab/mailgun/webhook_processors/member_invites_spec.rb74
-rw-r--r--spec/serializers/deploy_keys/basic_deploy_key_entity_spec.rb (renamed from spec/serializers/deploy_key_entity_spec.rb)18
-rw-r--r--spec/serializers/deploy_keys/deploy_key_entity_spec.rb51
-rw-r--r--spec/services/members/mailgun/process_webhook_service_spec.rb72
-rw-r--r--spec/services/pages/delete_service_spec.rb6
-rw-r--r--spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb60
12 files changed, 479 insertions, 115 deletions
diff --git a/spec/components/pajamas/banner_component_spec.rb b/spec/components/pajamas/banner_component_spec.rb
new file mode 100644
index 00000000000..5969f06dbad
--- /dev/null
+++ b/spec/components/pajamas/banner_component_spec.rb
@@ -0,0 +1,169 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Pajamas::BannerComponent, type: :component do
+ subject do
+ described_class.new(**options)
+ end
+
+ let(:title) { "Banner title" }
+ let(:content) { "Banner content"}
+ let(:options) { {} }
+
+ describe 'basic usage' do
+ before do
+ render_inline(subject) do |c|
+ c.title { title }
+ content
+ end
+ end
+
+ it 'renders its content' do
+ expect(rendered_component).to have_text content
+ end
+
+ it 'renders its title' do
+ expect(rendered_component).to have_css "h1[class='gl-banner-title']", text: title
+ end
+
+ it 'renders a close button' do
+ expect(rendered_component).to have_css "button.gl-banner-close"
+ end
+
+ describe 'button_text and button_link' do
+ let(:options) { { button_text: 'Learn more', button_link: '/learn-more' } }
+
+ it 'define the primary action' do
+ expect(rendered_component).to have_css "a.btn-confirm.gl-button[href='/learn-more']", text: 'Learn more'
+ end
+ end
+
+ describe 'banner_options' do
+ let(:options) { { banner_options: { class: "baz", data: { foo: "bar" } } } }
+
+ it 'are on the banner' do
+ expect(rendered_component).to have_css ".gl-banner.baz[data-foo='bar']"
+ end
+
+ context 'with custom classes' do
+ let(:options) { { variant: :introduction, banner_options: { class: 'extra special' } } }
+
+ it 'don\'t conflict with internal banner_classes' do
+ expect(rendered_component).to have_css '.extra.special.gl-banner-introduction.gl-banner'
+ end
+ end
+ end
+
+ describe 'close_options' do
+ let(:options) { { close_options: { class: "js-foo", data: { uid: "123" } } } }
+
+ it 'are on the close button' do
+ expect(rendered_component).to have_css "button.gl-banner-close.js-foo[data-uid='123']"
+ end
+ end
+
+ describe 'embedded' do
+ context 'by default (false)' do
+ it 'keeps the banner\'s borders' do
+ expect(rendered_component).not_to have_css ".gl-banner.gl-border-none"
+ end
+ end
+
+ context 'when set to true' do
+ let(:options) { { embedded: true } }
+
+ it 'removes the banner\'s borders' do
+ expect(rendered_component).to have_css ".gl-banner.gl-border-none"
+ end
+ end
+ end
+
+ describe 'variant' do
+ context 'by default (promotion)' do
+ it 'applies no variant class' do
+ expect(rendered_component).to have_css "[class='gl-banner']"
+ end
+ end
+
+ context 'when set to introduction' do
+ let(:options) { { variant: :introduction } }
+
+ it "applies the introduction class to the banner" do
+ expect(rendered_component).to have_css ".gl-banner.gl-banner-introduction"
+ end
+
+ it "applies the confirm class to the close button" do
+ expect(rendered_component).to have_css ".gl-banner-close.btn-confirm.btn-confirm-tertiary"
+ end
+ end
+
+ context 'when set to unknown variant' do
+ let(:options) { { variant: :foobar } }
+
+ it 'ignores the unknown variant' do
+ expect(rendered_component).to have_css "[class='gl-banner']"
+ end
+ end
+ end
+
+ describe 'illustration' do
+ it 'has none by default' do
+ expect(rendered_component).not_to have_css ".gl-banner-illustration"
+ end
+
+ context 'with svg_path' do
+ let(:options) { { svg_path: 'logo.svg' } }
+
+ it 'renders an image as illustration' do
+ expect(rendered_component).to have_css ".gl-banner-illustration img"
+ end
+ end
+ end
+ end
+
+ context 'with illustration slot' do
+ before do
+ render_inline(subject) do |c|
+ c.title { title }
+ c.illustration { "<svg></svg>".html_safe }
+ content
+ end
+ end
+
+ it 'renders the slot content as illustration' do
+ expect(rendered_component).to have_css ".gl-banner-illustration svg"
+ end
+
+ context 'and conflicting svg_path' do
+ let(:options) { { svg_path: 'logo.svg' } }
+
+ it 'uses the slot content' do
+ expect(rendered_component).to have_css ".gl-banner-illustration svg"
+ expect(rendered_component).not_to have_css ".gl-banner-illustration img"
+ end
+ end
+ end
+
+ context 'with primary_action slot' do
+ before do
+ render_inline(subject) do |c|
+ c.title { title }
+ c.primary_action { "<a class='special' href='#'>Special</a>".html_safe }
+ content
+ end
+ end
+
+ it 'renders the slot content as the primary action' do
+ expect(rendered_component).to have_css "a.special", text: 'Special'
+ end
+
+ context 'and conflicting button_text and button_link' do
+ let(:options) { { button_text: 'Not special', button_link: '/' } }
+
+ it 'uses the slot content' do
+ expect(rendered_component).to have_css "a.special[href='#']", text: 'Special'
+ expect(rendered_component).not_to have_css "a.btn[href='/']"
+ end
+ end
+ end
+end
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index 0a809e80fcd..e874df62cd7 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -411,6 +411,7 @@ RSpec.describe AutocompleteController do
expect(json_response.count).to eq(1)
expect(json_response.first['title']).to eq(deploy_key.title)
expect(json_response.first['owner']['id']).to eq(deploy_key.user.id)
+ expect(json_response.first['deploy_keys_projects']).to be_nil
end
context 'with an unknown project' do
@@ -433,6 +434,7 @@ RSpec.describe AutocompleteController do
expect(json_response.count).to eq(1)
expect(json_response.first['title']).to eq(deploy_key.title)
expect(json_response.first['owner']).to be_nil
+ expect(json_response.first['deploy_keys_projects']).to be_nil
end
end
end
diff --git a/spec/events/pages/page_deleted_event_spec.rb b/spec/events/pages/page_deleted_event_spec.rb
new file mode 100644
index 00000000000..ee05b770c48
--- /dev/null
+++ b/spec/events/pages/page_deleted_event_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Pages::PageDeletedEvent do
+ where(:data, :valid) do
+ [
+ [{ project_id: 1, namespace_id: 2 }, true],
+ [{ project_id: 1 }, false],
+ [{ namespace_id: 1 }, false],
+ [{ project_id: 'foo', namespace_id: 2 }, false],
+ [{ project_id: 1, namespace_id: 'foo' }, false],
+ [{ project_id: [], namespace_id: 2 }, false],
+ [{ project_id: 1, namespace_id: [] }, false],
+ [{ project_id: {}, namespace_id: 2 }, false],
+ [{ project_id: 1, namespace_id: {} }, false],
+ ['foo', false],
+ [123, false],
+ [[], false]
+ ]
+ end
+
+ with_them do
+ it 'validates data' do
+ constructor = -> { described_class.new(data: data) }
+
+ if valid
+ expect { constructor.call }.not_to raise_error
+ else
+ expect { constructor.call }.to raise_error(Gitlab::EventStore::InvalidEvent)
+ end
+ end
+ end
+end
diff --git a/spec/graphql/types/ci/pipeline_merge_request_event_type_enum_spec.rb b/spec/graphql/types/ci/pipeline_merge_request_event_type_enum_spec.rb
new file mode 100644
index 00000000000..3a90e4f1fd9
--- /dev/null
+++ b/spec/graphql/types/ci/pipeline_merge_request_event_type_enum_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['PipelineMergeRequestEventType'] do
+ specify { expect(described_class.graphql_name).to eq('PipelineMergeRequestEventType') }
+
+ it 'has specific values' do
+ expect(described_class.values).to match a_hash_including(
+ 'MERGED_RESULT' => have_attributes(value: :merged_result),
+ 'DETACHED' => have_attributes(value: :detached)
+ )
+ end
+end
diff --git a/spec/graphql/types/ci/pipeline_type_spec.rb b/spec/graphql/types/ci/pipeline_type_spec.rb
index 94d1b42da37..9dee834d05f 100644
--- a/spec/graphql/types/ci/pipeline_type_spec.rb
+++ b/spec/graphql/types/ci/pipeline_type_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Types::Ci::PipelineType do
coverage created_at updated_at started_at finished_at committed_at
stages user retryable cancelable jobs source_job job job_artifacts downstream
upstream path project active user_permissions warnings commit commit_path uses_needs
- test_report_summary test_suite ref ref_path warning_messages
+ test_report_summary test_suite ref ref_path warning_messages merge_request_event_type
]
if Gitlab.ee?
diff --git a/spec/lib/gitlab/mailgun/webhook_processors/failure_logger_spec.rb b/spec/lib/gitlab/mailgun/webhook_processors/failure_logger_spec.rb
new file mode 100644
index 00000000000..a2286415e96
--- /dev/null
+++ b/spec/lib/gitlab/mailgun/webhook_processors/failure_logger_spec.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Mailgun::WebhookProcessors::FailureLogger do
+ describe '#execute', :freeze_time, :clean_gitlab_redis_rate_limiting do
+ let(:base_payload) do
+ {
+ 'id' => 'U2kZkAiuScqcMTq-8Atz-Q',
+ 'event' => 'failed',
+ 'recipient' => 'recipient@gitlab.com',
+ 'reason' => 'bounce',
+ 'delivery-status' => {
+ 'code' => '421',
+ 'message' => '4.4.2 mxfront9g.mail.example.com Error: timeout exceeded'
+ }
+ }
+ end
+
+ context 'on permanent failure' do
+ let(:processor) { described_class.new(base_payload.merge({ 'severity' => 'permanent' })) }
+
+ it 'logs the failure immediately' do
+ expect(Gitlab::ErrorTracking::Logger).to receive(:error).with(
+ event: 'email_delivery_failure',
+ mailgun_event_id: base_payload['id'],
+ recipient: base_payload['recipient'],
+ failure_type: 'permanent',
+ failure_reason: base_payload['reason'],
+ failure_code: base_payload['delivery-status']['code'],
+ failure_message: base_payload['delivery-status']['message']
+ )
+
+ processor.execute
+ end
+ end
+
+ context 'on temporary failure' do
+ let(:processor) { described_class.new(base_payload.merge({ 'severity' => 'temporary' })) }
+
+ before do
+ allow(Gitlab::ApplicationRateLimiter).to receive(:rate_limits)
+ .and_return(temporary_email_failure: { threshold: 1, interval: 1.minute })
+ end
+
+ context 'when threshold is not exceeded' do
+ it 'increments counter but does not log the failure' do
+ expect(Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(
+ :temporary_email_failure, scope: 'recipient@gitlab.com'
+ ).and_call_original
+ expect(Gitlab::ErrorTracking::Logger).not_to receive(:error)
+
+ processor.execute
+ end
+ end
+
+ context 'when threshold is exceeded' do
+ before do
+ processor.execute
+ end
+
+ it 'increments counter and logs the failure' do
+ expect(Gitlab::ApplicationRateLimiter).to receive(:throttled?).with(
+ :temporary_email_failure, scope: 'recipient@gitlab.com'
+ ).and_call_original
+ expect(Gitlab::ErrorTracking::Logger).to receive(:error).with(
+ event: 'email_delivery_failure',
+ mailgun_event_id: base_payload['id'],
+ recipient: base_payload['recipient'],
+ failure_type: 'temporary',
+ failure_reason: base_payload['reason'],
+ failure_code: base_payload['delivery-status']['code'],
+ failure_message: base_payload['delivery-status']['message']
+ )
+
+ processor.execute
+ end
+ end
+ end
+
+ context 'on other events' do
+ let(:processor) { described_class.new(base_payload.merge({ 'event' => 'delivered' })) }
+
+ it 'does nothing' do
+ expect(Gitlab::ErrorTracking::Logger).not_to receive(:error)
+ expect(Gitlab::ApplicationRateLimiter).not_to receive(:throttled?)
+
+ processor.execute
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/mailgun/webhook_processors/member_invites_spec.rb b/spec/lib/gitlab/mailgun/webhook_processors/member_invites_spec.rb
new file mode 100644
index 00000000000..3bd364b0d15
--- /dev/null
+++ b/spec/lib/gitlab/mailgun/webhook_processors/member_invites_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Mailgun::WebhookProcessors::MemberInvites do
+ describe '#execute', :aggregate_failures do
+ let_it_be(:member) { create(:project_member, :invited) }
+
+ let(:raw_invite_token) { member.raw_invite_token }
+ let(:payload) do
+ {
+ 'event' => 'failed',
+ 'severity' => 'permanent',
+ 'tags' => [Members::Mailgun::INVITE_EMAIL_TAG],
+ 'user-variables' => { ::Members::Mailgun::INVITE_EMAIL_TOKEN_KEY => raw_invite_token }
+ }
+ end
+
+ subject(:service) { described_class.new(payload).execute }
+
+ it 'marks the member invite email success as false' do
+ expect(Gitlab::AppLogger).to receive(:info).with(
+ message: /^UPDATED MEMBER INVITE_EMAIL_SUCCESS/,
+ event: 'updated_member_invite_email_success'
+ ).and_call_original
+
+ expect { service }.to change { member.reload.invite_email_success }.from(true).to(false)
+ end
+
+ context 'when invite token is not found in payload' do
+ before do
+ payload.delete('user-variables')
+ end
+
+ it 'does not change member status and logs an error' do
+ expect(Gitlab::AppLogger).not_to receive(:info)
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
+ an_instance_of(described_class::ProcessWebhookServiceError))
+
+ expect { service }.not_to change { member.reload.invite_email_success }
+ end
+ end
+
+ shared_examples 'does nothing' do
+ it 'does not change member status' do
+ expect(Gitlab::AppLogger).not_to receive(:info)
+
+ expect { service }.not_to change { member.reload.invite_email_success }
+ end
+ end
+
+ context 'when member can not be found' do
+ let(:raw_invite_token) { '_foobar_' }
+
+ it_behaves_like 'does nothing'
+ end
+
+ context 'when failure is temporary' do
+ before do
+ payload['severity'] = 'temporary'
+ end
+
+ it_behaves_like 'does nothing'
+ end
+
+ context 'when email is not a member invite' do
+ before do
+ payload.delete('tags')
+ end
+
+ it_behaves_like 'does nothing'
+ end
+ end
+end
diff --git a/spec/serializers/deploy_key_entity_spec.rb b/spec/serializers/deploy_keys/basic_deploy_key_entity_spec.rb
index e8d9701be67..c39eb14e339 100644
--- a/spec/serializers/deploy_key_entity_spec.rb
+++ b/spec/serializers/deploy_keys/basic_deploy_key_entity_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe DeployKeyEntity do
+RSpec.describe DeployKeys::BasicDeployKeyEntity do
include RequestAwareEntity
let(:user) { create(:user) }
@@ -18,7 +18,7 @@ RSpec.describe DeployKeyEntity do
project_private.deploy_keys << deploy_key
end
- describe 'returns deploy keys with projects a user can read' do
+ describe 'returns deploy keys' do
let(:expected_result) do
{
id: deploy_key.id,
@@ -30,19 +30,7 @@ RSpec.describe DeployKeyEntity do
almost_orphaned: false,
created_at: deploy_key.created_at,
updated_at: deploy_key.updated_at,
- can_edit: false,
- deploy_keys_projects: [
- {
- can_push: false,
- project:
- {
- id: project.id,
- name: project.name,
- full_path: project_path(project),
- full_name: project.full_name
- }
- }
- ]
+ can_edit: false
}
end
diff --git a/spec/serializers/deploy_keys/deploy_key_entity_spec.rb b/spec/serializers/deploy_keys/deploy_key_entity_spec.rb
new file mode 100644
index 00000000000..e989aa8656c
--- /dev/null
+++ b/spec/serializers/deploy_keys/deploy_key_entity_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe DeployKeys::DeployKeyEntity do
+ include RequestAwareEntity
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :internal)}
+ let(:project_private) { create(:project, :private)}
+ let(:deploy_key) { create(:deploy_key) }
+ let(:options) { { user: user } }
+
+ let(:entity) { described_class.new(deploy_key, options) }
+
+ before do
+ project.deploy_keys << deploy_key
+ project_private.deploy_keys << deploy_key
+ end
+
+ describe 'returns deploy keys with projects a user can read' do
+ let(:expected_result) do
+ {
+ id: deploy_key.id,
+ user_id: deploy_key.user_id,
+ title: deploy_key.title,
+ fingerprint: deploy_key.fingerprint,
+ fingerprint_sha256: deploy_key.fingerprint_sha256,
+ destroyed_when_orphaned: true,
+ almost_orphaned: false,
+ created_at: deploy_key.created_at,
+ updated_at: deploy_key.updated_at,
+ can_edit: false,
+ deploy_keys_projects: [
+ {
+ can_push: false,
+ project:
+ {
+ id: project.id,
+ name: project.name,
+ full_path: project_path(project),
+ full_name: project.full_name
+ }
+ }
+ ]
+ }
+ end
+
+ it { expect(entity.as_json).to eq(expected_result) }
+ end
+end
diff --git a/spec/services/members/mailgun/process_webhook_service_spec.rb b/spec/services/members/mailgun/process_webhook_service_spec.rb
deleted file mode 100644
index 3b657c05bd8..00000000000
--- a/spec/services/members/mailgun/process_webhook_service_spec.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Members::Mailgun::ProcessWebhookService do
- describe '#execute', :aggregate_failures do
- let_it_be(:member) { create(:project_member, :invited) }
-
- let(:raw_invite_token) { member.raw_invite_token }
- let(:payload) { { 'user-variables' => { ::Members::Mailgun::INVITE_EMAIL_TOKEN_KEY => raw_invite_token } } }
-
- subject(:service) { described_class.new(payload).execute }
-
- it 'marks the member invite email success as false' do
- expect(Gitlab::AppLogger).to receive(:info).with(/^UPDATED MEMBER INVITE_EMAIL_SUCCESS/).and_call_original
-
- expect { service }.to change { member.reload.invite_email_success }.from(true).to(false)
- end
-
- context 'when member can not be found' do
- let(:raw_invite_token) { '_foobar_' }
-
- it 'does not change member status' do
- expect(Gitlab::AppLogger).not_to receive(:info).with(/^UPDATED MEMBER INVITE_EMAIL_SUCCESS/)
-
- expect { service }.not_to change { member.reload.invite_email_success }
- end
- end
-
- context 'when invite token is not found in payload' do
- let(:payload) { {} }
-
- it 'does not change member status and logs an error' do
- expect(Gitlab::AppLogger).not_to receive(:info).with(/^UPDATED MEMBER INVITE_EMAIL_SUCCESS/)
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
- an_instance_of(described_class::ProcessWebhookServiceError))
-
- expect { service }.not_to change { member.reload.invite_email_success }
- end
- end
- end
-
- describe '#should_process?' do
- it 'processes permanent failures for member invite emails' do
- payload = { 'event' => 'failed', 'severity' => 'permanent', 'tags' => [Members::Mailgun::INVITE_EMAIL_TAG] }
- service = described_class.new(payload)
-
- expect(service.should_process?).to eq(true)
- end
-
- it 'does not process temporary failures' do
- payload = { 'event' => 'failed', 'severity' => 'temporary', 'tags' => [Members::Mailgun::INVITE_EMAIL_TAG] }
- service = described_class.new(payload)
-
- expect(service.should_process?).to eq(false)
- end
-
- it 'does not process non member invite emails' do
- payload = { 'event' => 'failed', 'severity' => 'permanent', 'tags' => [] }
- service = described_class.new(payload)
-
- expect(service.should_process?).to eq(false)
- end
-
- it 'does not process other types of events' do
- payload = { 'event' => 'delivered', 'tags' => [Members::Mailgun::INVITE_EMAIL_TAG] }
- service = described_class.new(payload)
-
- expect(service.should_process?).to eq(false)
- end
- end
-end
diff --git a/spec/services/pages/delete_service_spec.rb b/spec/services/pages/delete_service_spec.rb
index e02e8e72e0b..0c0b2c0431b 100644
--- a/spec/services/pages/delete_service_spec.rb
+++ b/spec/services/pages/delete_service_spec.rb
@@ -43,4 +43,10 @@ RSpec.describe Pages::DeleteService do
service.execute
end.to change { PagesDeployment.count }.by(-1)
end
+
+ it 'publishes a ProjectDeleted event with project id and namespace id' do
+ expected_data = { project_id: project.id, namespace_id: project.namespace_id }
+
+ expect { service.execute }.to publish_event(Pages::PageDeletedEvent).with(expected_data)
+ end
end
diff --git a/spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb b/spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb
index da9c5833926..ec10c66968d 100644
--- a/spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb
+++ b/spec/workers/projects/inactive_projects_deletion_cron_worker_spec.rb
@@ -5,6 +5,34 @@ require 'spec_helper'
RSpec.describe Projects::InactiveProjectsDeletionCronWorker do
include ProjectHelpers
+ shared_examples 'worker is running for more than 4 minutes' do
+ before do
+ subject.instance_variable_set(:@start_time, ::Gitlab::Metrics::System.monotonic_time - 5.minutes)
+ end
+
+ it 'stores the last processed inactive project_id in redis cache' do
+ Gitlab::Redis::Cache.with do |redis|
+ expect { worker.perform }
+ .to change { redis.get('last_processed_inactive_project_id') }.to(inactive_large_project.id.to_s)
+ end
+ end
+ end
+
+ shared_examples 'worker finishes processing in less than 4 minutes' do
+ before do
+ Gitlab::Redis::Cache.with do |redis|
+ redis.set('last_processed_inactive_project_id', inactive_large_project.id)
+ end
+ end
+
+ it 'clears the last processed inactive project_id from redis cache' do
+ Gitlab::Redis::Cache.with do |redis|
+ expect { worker.perform }
+ .to change { redis.get('last_processed_inactive_project_id') }.to(nil)
+ end
+ end
+ end
+
describe "#perform" do
subject(:worker) { described_class.new }
@@ -79,6 +107,9 @@ RSpec.describe Projects::InactiveProjectsDeletionCronWorker do
expect(inactive_large_project.reload.pending_delete).to eq(false)
end
+
+ it_behaves_like 'worker is running for more than 4 minutes'
+ it_behaves_like 'worker finishes processing in less than 4 minutes'
end
context 'when feature flag is enabled', :clean_gitlab_redis_shared_state, :sidekiq_inline do
@@ -130,33 +161,8 @@ RSpec.describe Projects::InactiveProjectsDeletionCronWorker do
end
end
- context 'when the worker is running for more than 4 minutes' do
- before do
- subject.instance_variable_set(:@start_time, ::Gitlab::Metrics::System.monotonic_time - 5.minutes)
- end
-
- it 'stores the last processed inactive project_id in redis cache' do
- Gitlab::Redis::Cache.with do |redis|
- expect { worker.perform }
- .to change { redis.get('last_processed_inactive_project_id') }.to(inactive_large_project.id.to_s)
- end
- end
- end
-
- context 'when the worker finishes processing in less than 4 minutes' do
- before do
- Gitlab::Redis::Cache.with do |redis|
- redis.set('last_processed_inactive_project_id', inactive_large_project.id)
- end
- end
-
- it 'clears the last processed inactive project_id from redis cache' do
- Gitlab::Redis::Cache.with do |redis|
- expect { worker.perform }
- .to change { redis.get('last_processed_inactive_project_id') }.to(nil)
- end
- end
- end
+ it_behaves_like 'worker is running for more than 4 minutes'
+ it_behaves_like 'worker finishes processing in less than 4 minutes'
end
it_behaves_like 'an idempotent worker'