mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
ActionMailer::Base can unregister observer(s) and interceptor(s). (#32207)
* ActionMailer::Base can unregister observer(s) and interceptor(s). One or multiple mail observers can be unregistered using `ActionMailer::Base.unregister_observers` or `ActionMailer::Base.unregister_observer`. One or multiple mail interceptors can be unregistered using `ActionMailer::Base.unregister_interceptors` or `ActionMailer::Base.unregister_interceptor`. For preview interceptors, it's possible to use `ActionMailer::Base.unregister_preview_interceptors` or `ActionMailer::Base.unregister_preview_interceptor`. * Ensure to be reset registered observer(s) and interceptor(s) * Add explanation to CHANGELOG * Add original author's name [Kota Miyake + Rafael Mendonça França + Claudio Ortolina]
This commit is contained in:
parent
e6ef1fe056
commit
b74edd37c5
4 changed files with 135 additions and 19 deletions
|
@ -6,6 +6,14 @@
|
|||
|
||||
*Gannon McGibbon*
|
||||
|
||||
* Add `Base.unregister_observer`, `Base.unregister_observers`,
|
||||
`Base.unregister_interceptor`, `Base.unregister_interceptors`,
|
||||
`Base.unregister_preview_interceptor` and `Base.unregister_preview_interceptors`.
|
||||
This makes it possible to dynamically add and remove email observers and
|
||||
interceptors at runtime in the same way they're registered.
|
||||
|
||||
*Claudio Ortolina*, *Kota Miyake*
|
||||
|
||||
* Rails 6 requires Ruby 2.4.1 or newer.
|
||||
|
||||
*Jeremy Daer*
|
||||
|
|
|
@ -475,11 +475,21 @@ module ActionMailer
|
|||
observers.flatten.compact.each { |observer| register_observer(observer) }
|
||||
end
|
||||
|
||||
# Unregister one or more previously registered Observers.
|
||||
def unregister_observers(*observers)
|
||||
observers.flatten.compact.each { |observer| unregister_observer(observer) }
|
||||
end
|
||||
|
||||
# Register one or more Interceptors which will be called before mail is sent.
|
||||
def register_interceptors(*interceptors)
|
||||
interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
|
||||
end
|
||||
|
||||
# Unregister one or more previously registered Interceptors.
|
||||
def unregister_interceptors(*interceptors)
|
||||
interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
|
||||
end
|
||||
|
||||
# Register an Observer which will be notified when mail is delivered.
|
||||
# Either a class, string or symbol can be passed in as the Observer.
|
||||
# If a string or symbol is passed in it will be camelized and constantized.
|
||||
|
@ -487,6 +497,13 @@ module ActionMailer
|
|||
Mail.register_observer(observer_class_for(observer))
|
||||
end
|
||||
|
||||
# Unregister a previously registered Observer.
|
||||
# Either a class, string or symbol can be passed in as the Observer.
|
||||
# If a string or symbol is passed in it will be camelized and constantized.
|
||||
def unregister_observer(observer)
|
||||
Mail.unregister_observer(observer_class_for(observer))
|
||||
end
|
||||
|
||||
# Register an Interceptor which will be called before mail is sent.
|
||||
# Either a class, string or symbol can be passed in as the Interceptor.
|
||||
# If a string or symbol is passed in it will be camelized and constantized.
|
||||
|
@ -494,6 +511,13 @@ module ActionMailer
|
|||
Mail.register_interceptor(observer_class_for(interceptor))
|
||||
end
|
||||
|
||||
# Unregister a previously registered Interceptor.
|
||||
# Either a class, string or symbol can be passed in as the Interceptor.
|
||||
# If a string or symbol is passed in it will be camelized and constantized.
|
||||
def unregister_interceptor(interceptor)
|
||||
Mail.unregister_interceptor(observer_class_for(interceptor))
|
||||
end
|
||||
|
||||
def observer_class_for(value) # :nodoc:
|
||||
case value
|
||||
when String, Symbol
|
||||
|
|
|
@ -31,22 +31,39 @@ module ActionMailer
|
|||
interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) }
|
||||
end
|
||||
|
||||
# Unregister one or more previously registered Interceptors.
|
||||
def unregister_preview_interceptors(*interceptors)
|
||||
interceptors.flatten.compact.each { |interceptor| unregister_preview_interceptor(interceptor) }
|
||||
end
|
||||
|
||||
# Register an Interceptor which will be called before mail is previewed.
|
||||
# Either a class or a string can be passed in as the Interceptor. If a
|
||||
# string is passed in it will be constantized.
|
||||
def register_preview_interceptor(interceptor)
|
||||
preview_interceptor = \
|
||||
preview_interceptor = interceptor_class_for(interceptor)
|
||||
|
||||
unless preview_interceptors.include?(preview_interceptor)
|
||||
preview_interceptors << preview_interceptor
|
||||
end
|
||||
end
|
||||
|
||||
# Unregister a previously registered Interceptor.
|
||||
# Either a class or a string can be passed in as the Interceptor. If a
|
||||
# string is passed in it will be constantized.
|
||||
def unregister_preview_interceptor(interceptor)
|
||||
preview_interceptors.delete(interceptor_class_for(interceptor))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def interceptor_class_for(interceptor)
|
||||
case interceptor
|
||||
when String, Symbol
|
||||
interceptor.to_s.camelize.constantize
|
||||
else
|
||||
interceptor
|
||||
end
|
||||
|
||||
unless preview_interceptors.include?(preview_interceptor)
|
||||
preview_interceptors << preview_interceptor
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -618,37 +618,52 @@ class BaseTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
test "you can register an observer to the mail object that gets informed on email delivery" do
|
||||
test "you can register and unregister an observer to the mail object that gets informed on email delivery" do
|
||||
mail_side_effects do
|
||||
ActionMailer::Base.register_observer(MyObserver)
|
||||
mail = BaseMailer.welcome
|
||||
assert_called_with(MyObserver, :delivered_email, [mail]) do
|
||||
mail.deliver_now
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_observer(MyObserver)
|
||||
assert_not_called(MyObserver, :delivered_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "you can register an observer using its stringified name to the mail object that gets informed on email delivery" do
|
||||
test "you can register and unregister an observer using its stringified name to the mail object that gets informed on email delivery" do
|
||||
mail_side_effects do
|
||||
ActionMailer::Base.register_observer("BaseTest::MyObserver")
|
||||
mail = BaseMailer.welcome
|
||||
assert_called_with(MyObserver, :delivered_email, [mail]) do
|
||||
mail.deliver_now
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_observer("BaseTest::MyObserver")
|
||||
assert_not_called(MyObserver, :delivered_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "you can register an observer using its symbolized underscored name to the mail object that gets informed on email delivery" do
|
||||
test "you can register and unregister an observer using its symbolized underscored name to the mail object that gets informed on email delivery" do
|
||||
mail_side_effects do
|
||||
ActionMailer::Base.register_observer(:"base_test/my_observer")
|
||||
mail = BaseMailer.welcome
|
||||
assert_called_with(MyObserver, :delivered_email, [mail]) do
|
||||
mail.deliver_now
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_observer(:"base_test/my_observer")
|
||||
assert_not_called(MyObserver, :delivered_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "you can register multiple observers to the mail object that both get informed on email delivery" do
|
||||
test "you can register and unregister multiple observers to the mail object that both get informed on email delivery" do
|
||||
mail_side_effects do
|
||||
ActionMailer::Base.register_observers("BaseTest::MyObserver", MySecondObserver)
|
||||
mail = BaseMailer.welcome
|
||||
|
@ -657,6 +672,14 @@ class BaseTest < ActiveSupport::TestCase
|
|||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_observers("BaseTest::MyObserver", MySecondObserver)
|
||||
assert_not_called(MyObserver, :delivered_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
assert_not_called(MySecondObserver, :delivered_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -670,37 +693,52 @@ class BaseTest < ActiveSupport::TestCase
|
|||
def self.previewing_email(mail); end
|
||||
end
|
||||
|
||||
test "you can register an interceptor to the mail object that gets passed the mail object before delivery" do
|
||||
test "you can register and unregister an interceptor to the mail object that gets passed the mail object before delivery" do
|
||||
mail_side_effects do
|
||||
ActionMailer::Base.register_interceptor(MyInterceptor)
|
||||
mail = BaseMailer.welcome
|
||||
assert_called_with(MyInterceptor, :delivering_email, [mail]) do
|
||||
mail.deliver_now
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_interceptor(MyInterceptor)
|
||||
assert_not_called(MyInterceptor, :delivering_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "you can register an interceptor using its stringified name to the mail object that gets passed the mail object before delivery" do
|
||||
test "you can register and unregister an interceptor using its stringified name to the mail object that gets passed the mail object before delivery" do
|
||||
mail_side_effects do
|
||||
ActionMailer::Base.register_interceptor("BaseTest::MyInterceptor")
|
||||
mail = BaseMailer.welcome
|
||||
assert_called_with(MyInterceptor, :delivering_email, [mail]) do
|
||||
mail.deliver_now
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_interceptor("BaseTest::MyInterceptor")
|
||||
assert_not_called(MyInterceptor, :delivering_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "you can register an interceptor using its symbolized underscored name to the mail object that gets passed the mail object before delivery" do
|
||||
test "you can register and unregister an interceptor using its symbolized underscored name to the mail object that gets passed the mail object before delivery" do
|
||||
mail_side_effects do
|
||||
ActionMailer::Base.register_interceptor(:"base_test/my_interceptor")
|
||||
mail = BaseMailer.welcome
|
||||
assert_called_with(MyInterceptor, :delivering_email, [mail]) do
|
||||
mail.deliver_now
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_interceptor(:"base_test/my_interceptor")
|
||||
assert_not_called(MyInterceptor, :delivering_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "you can register multiple interceptors to the mail object that both get passed the mail object before delivery" do
|
||||
test "you can register and unregister multiple interceptors to the mail object that both get passed the mail object before delivery" do
|
||||
mail_side_effects do
|
||||
ActionMailer::Base.register_interceptors("BaseTest::MyInterceptor", MySecondInterceptor)
|
||||
mail = BaseMailer.welcome
|
||||
|
@ -709,6 +747,14 @@ class BaseTest < ActiveSupport::TestCase
|
|||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_interceptors("BaseTest::MyInterceptor", MySecondInterceptor)
|
||||
assert_not_called(MyInterceptor, :delivering_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
assert_not_called(MySecondInterceptor, :delivering_email, returns: mail) do
|
||||
mail.deliver_now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -888,8 +934,6 @@ class BaseTest < ActiveSupport::TestCase
|
|||
klass.default_params = old
|
||||
end
|
||||
|
||||
# A simple hack to restore the observers and interceptors for Mail, as it
|
||||
# does not have an unregister API yet.
|
||||
def mail_side_effects
|
||||
old_observers = Mail.class_variable_get(:@@delivery_notification_observers)
|
||||
old_delivery_interceptors = Mail.class_variable_get(:@@delivery_interceptors)
|
||||
|
@ -928,7 +972,7 @@ class BasePreviewInterceptorsTest < ActiveSupport::TestCase
|
|||
def self.previewing_email(mail); end
|
||||
end
|
||||
|
||||
test "you can register a preview interceptor to the mail object that gets passed the mail object before previewing" do
|
||||
test "you can register and unregister a preview interceptor to the mail object that gets passed the mail object before previewing" do
|
||||
ActionMailer::Base.register_preview_interceptor(MyInterceptor)
|
||||
mail = BaseMailer.welcome
|
||||
stub_any_instance(BaseMailerPreview) do |instance|
|
||||
|
@ -938,9 +982,14 @@ class BasePreviewInterceptorsTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_preview_interceptor(MyInterceptor)
|
||||
assert_not_called(MyInterceptor, :previewing_email, returns: mail) do
|
||||
BaseMailerPreview.call(:welcome)
|
||||
end
|
||||
end
|
||||
|
||||
test "you can register a preview interceptor using its stringified name to the mail object that gets passed the mail object before previewing" do
|
||||
test "you can register and unregister a preview interceptor using its stringified name to the mail object that gets passed the mail object before previewing" do
|
||||
ActionMailer::Base.register_preview_interceptor("BasePreviewInterceptorsTest::MyInterceptor")
|
||||
mail = BaseMailer.welcome
|
||||
stub_any_instance(BaseMailerPreview) do |instance|
|
||||
|
@ -950,9 +999,14 @@ class BasePreviewInterceptorsTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_preview_interceptor("BasePreviewInterceptorsTest::MyInterceptor")
|
||||
assert_not_called(MyInterceptor, :previewing_email, returns: mail) do
|
||||
BaseMailerPreview.call(:welcome)
|
||||
end
|
||||
end
|
||||
|
||||
test "you can register an interceptor using its symbolized underscored name to the mail object that gets passed the mail object before previewing" do
|
||||
test "you can register and unregister a preview interceptor using its symbolized underscored name to the mail object that gets passed the mail object before previewing" do
|
||||
ActionMailer::Base.register_preview_interceptor(:"base_preview_interceptors_test/my_interceptor")
|
||||
mail = BaseMailer.welcome
|
||||
stub_any_instance(BaseMailerPreview) do |instance|
|
||||
|
@ -962,9 +1016,14 @@ class BasePreviewInterceptorsTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_preview_interceptor(:"base_preview_interceptors_test/my_interceptor")
|
||||
assert_not_called(MyInterceptor, :previewing_email, returns: mail) do
|
||||
BaseMailerPreview.call(:welcome)
|
||||
end
|
||||
end
|
||||
|
||||
test "you can register multiple preview interceptors to the mail object that both get passed the mail object before previewing" do
|
||||
test "you can register and unregister multiple preview interceptors to the mail object that both get passed the mail object before previewing" do
|
||||
ActionMailer::Base.register_preview_interceptors("BasePreviewInterceptorsTest::MyInterceptor", MySecondInterceptor)
|
||||
mail = BaseMailer.welcome
|
||||
stub_any_instance(BaseMailerPreview) do |instance|
|
||||
|
@ -976,6 +1035,14 @@ class BasePreviewInterceptorsTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActionMailer::Base.unregister_preview_interceptors("BasePreviewInterceptorsTest::MyInterceptor", MySecondInterceptor)
|
||||
assert_not_called(MyInterceptor, :previewing_email, returns: mail) do
|
||||
BaseMailerPreview.call(:welcome)
|
||||
end
|
||||
assert_not_called(MySecondInterceptor, :previewing_email, returns: mail) do
|
||||
BaseMailerPreview.call(:welcome)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue