From d3a1c2be6b7d83ff93a80c19993ea511c49e8498 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 25 Sep 2024 10:59:00 -0400 Subject: [PATCH] Use `before_action` to handle missing status scenario in `NotificationMailer` --- app/mailers/application_mailer.rb | 2 ++ app/mailers/notification_mailer.rb | 11 +++++------ spec/mailers/notification_mailer_spec.rb | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 9a209aa77b8..97270d13c52 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -9,6 +9,8 @@ class ApplicationMailer < ActionMailer::Base after_action :set_autoreply_headers! + rescue_from UncaughtThrowError, with: -> {} + protected def locale_for_account(account, &block) diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index 4c374f5d57f..7cc2c2804ff 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -11,6 +11,7 @@ class NotificationMailer < ApplicationMailer after_action :thread_by_conversation! end before_action :set_account, only: [:follow, :favourite, :reblog, :follow_request] + before_action :verify_status_presence, only: %i(favourite mention reblog) after_action :set_list_headers! before_deliver :verify_functional_user @@ -20,8 +21,6 @@ class NotificationMailer < ApplicationMailer layout 'mailer' def mention - return if @status.blank? - locale_for_account(@me) do mail subject: default_i18n_subject(name: @status.account.acct) end @@ -34,16 +33,12 @@ class NotificationMailer < ApplicationMailer end def favourite - return if @status.blank? - locale_for_account(@me) do mail subject: default_i18n_subject(name: @account.acct) end end def reblog - return if @status.blank? - locale_for_account(@me) do mail subject: default_i18n_subject(name: @account.acct) end @@ -77,6 +72,10 @@ class NotificationMailer < ApplicationMailer throw(:abort) unless @user.functional? end + def verify_status_presence + throw(:abort) if @status.blank? + end + def set_list_headers! headers( 'List-ID' => "<#{@type}.#{@me.username}.#{Rails.configuration.x.local_domain}>", diff --git a/spec/mailers/notification_mailer_spec.rb b/spec/mailers/notification_mailer_spec.rb index 4c6107d9f76..d97c01858da 100644 --- a/spec/mailers/notification_mailer_spec.rb +++ b/spec/mailers/notification_mailer_spec.rb @@ -14,6 +14,17 @@ RSpec.describe NotificationMailer do end end + shared_examples 'delivery without status' do + context 'when notification target_status is missing' do + before { allow(notification).to receive(:target_status).and_return(nil) } + + it 'does not deliver mail' do + emails = capture_emails { mail.deliver_now } + expect(emails).to be_empty + end + end + end + let(:receiver) { Fabricate(:user, account_attributes: { username: 'alice' }) } let(:sender) { Fabricate(:account, username: 'bob') } let(:foreign_status) { Fabricate(:status, account: sender, text: 'The body of the foreign status') } @@ -37,6 +48,7 @@ RSpec.describe NotificationMailer do end include_examples 'delivery to non functional user' + include_examples 'delivery without status' end describe 'follow' do @@ -75,6 +87,7 @@ RSpec.describe NotificationMailer do end include_examples 'delivery to non functional user' + include_examples 'delivery without status' end describe 'reblog' do @@ -95,6 +108,7 @@ RSpec.describe NotificationMailer do end include_examples 'delivery to non functional user' + include_examples 'delivery without status' end describe 'follow_request' do