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/lib/gitlab/mailgun/webhook_processors/failure_logger_spec.rb')
-rw-r--r--spec/lib/gitlab/mailgun/webhook_processors/failure_logger_spec.rb92
1 files changed, 92 insertions, 0 deletions
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