diff --git a/app/jobs/inboxes/fetch_imap_emails_job.rb b/app/jobs/inboxes/fetch_imap_emails_job.rb index ef24ef4c2..eab5e4701 100644 --- a/app/jobs/inboxes/fetch_imap_emails_job.rb +++ b/app/jobs/inboxes/fetch_imap_emails_job.rb @@ -7,6 +7,8 @@ class Inboxes::FetchImapEmailsJob < ApplicationJob return unless should_fetch_email?(channel) process_mail_for_channel(channel) + # clearing old failures like timeouts since the mail is now successfully processed + channel.reauthorized! rescue Errno::ECONNREFUSED, Net::OpenTimeout, Net::IMAP::NoResponseError channel.authorization_error! rescue StandardError => e diff --git a/app/models/channel/email.rb b/app/models/channel/email.rb index 5b1cc0c91..c5a67c676 100644 --- a/app/models/channel/email.rb +++ b/app/models/channel/email.rb @@ -36,6 +36,8 @@ class Channel::Email < ApplicationRecord include Channelable include Reauthorizable + AUTHORIZATION_ERROR_THRESHOLD = 10 + self.table_name = 'channel_email' EDITABLE_ATTRS = [:email, :imap_enabled, :imap_login, :imap_password, :imap_address, :imap_port, :imap_enable_ssl, :imap_inbox_synced_at, :smtp_enabled, :smtp_login, :smtp_password, :smtp_address, :smtp_port, :smtp_domain, :smtp_enable_starttls_auto, diff --git a/app/models/concerns/reauthorizable.rb b/app/models/concerns/reauthorizable.rb index dc55d9b2e..cc78b56a0 100644 --- a/app/models/concerns/reauthorizable.rb +++ b/app/models/concerns/reauthorizable.rb @@ -29,7 +29,9 @@ module Reauthorizable # Implement in your exception handling logic for authorization errors def authorization_error! ::Redis::Alfred.incr(authorization_error_count_key) - prompt_reauthorization! if authorization_error_count >= AUTHORIZATION_ERROR_THRESHOLD + # we are giving precendence to the authorization error threshhold defined in the class + # so that channels can override the default value + prompt_reauthorization! if authorization_error_count >= self.class::AUTHORIZATION_ERROR_THRESHOLD end # Performed automatically if error threshold is breached diff --git a/spec/models/channel/email_spec.rb b/spec/models/channel/email_spec.rb new file mode 100644 index 000000000..af3a978f4 --- /dev/null +++ b/spec/models/channel/email_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' +require Rails.root.join 'spec/models/concerns/reauthorizable_shared.rb' + +RSpec.describe Channel::Email do + let(:channel) { create(:channel_email) } + + describe 'concerns' do + it_behaves_like 'reauthorizable' + + context 'when prompt_reauthorization!' do + it 'calls channel notifier mail for email' do + admin_mailer = double + mailer_double = double + expect(AdministratorNotifications::ChannelNotificationsMailer).to receive(:with).and_return(admin_mailer) + expect(admin_mailer).to receive(:email_disconnect).with(channel.inbox).and_return(mailer_double) + expect(mailer_double).to receive(:deliver_later) + channel.prompt_reauthorization! + end + end + end + + it 'has a valid name' do + expect(channel.name).to eq('Email') + end +end diff --git a/spec/models/concerns/reauthorizable_shared.rb b/spec/models/concerns/reauthorizable_shared.rb index 62b251367..212afd4af 100644 --- a/spec/models/concerns/reauthorizable_shared.rb +++ b/spec/models/concerns/reauthorizable_shared.rb @@ -12,12 +12,22 @@ shared_examples_for 'reauthorizable' do expect(obj.authorization_error_count).to eq 1 end + it 'prompts reauthorization when error threshold is passed' do + obj = FactoryBot.create(model.to_s.underscore.tr('/', '_').to_sym) + expect(obj.reauthorization_required?).to eq false + + obj.class::AUTHORIZATION_ERROR_THRESHOLD.times do + obj.authorization_error! + end + + expect(obj.reauthorization_required?).to eq true + end + it 'prompt_reauthorization!' do obj = FactoryBot.create(model.to_s.underscore.tr('/', '_').to_sym) expect(obj.reauthorization_required?).to eq false obj.prompt_reauthorization! - expect(obj.reauthorization_required?).to eq true end