Skip to content

Commit

Permalink
Fix state leaks in actionmailer/test/base_test.rb.
Browse files Browse the repository at this point in the history
  • Loading branch information
zuhao committed May 7, 2014
1 parent bf44fcc commit 1401637
Showing 1 changed file with 157 additions and 102 deletions.
259 changes: 157 additions & 102 deletions actionmailer/test/base_test.rb
Expand Up @@ -10,10 +10,15 @@
require 'mailers/asset_mailer'

class BaseTest < ActiveSupport::TestCase
def teardown
ActionMailer::Base.asset_host = nil
ActionMailer::Base.assets_dir = nil
ActionMailer::Base.preview_interceptors.clear
setup do
@original_asset_host = ActionMailer::Base.asset_host
@original_assets_dir = ActionMailer::Base.assets_dir
end

teardown do
ActionMailer::Base.asset_host = @original_asset_host
ActionMailer::Base.assets_dir = @original_assets_dir
BaseMailer.deliveries.clear
end

test "method call to mail does not raise error" do
Expand Down Expand Up @@ -104,6 +109,7 @@ def teardown
test "attachment gets content type from filename" do
email = BaseMailer.attachment_with_content
assert_equal('invoice.pdf', email.attachments[0].filename)
assert_equal('application/pdf', email.attachments[0].mime_type)
end

test "attachment with hash" do
Expand Down Expand Up @@ -201,25 +207,29 @@ def teardown
end

test "subject gets default from I18n" do
BaseMailer.default subject: nil
email = BaseMailer.welcome(subject: nil)
assert_equal "Welcome", email.subject
with_default BaseMailer, subject: nil do
email = BaseMailer.welcome(subject: nil)
assert_equal "Welcome", email.subject

I18n.backend.store_translations('en', base_mailer: {welcome: {subject: "New Subject!"}})
email = BaseMailer.welcome(subject: nil)
assert_equal "New Subject!", email.subject
with_translation 'en', base_mailer: {welcome: {subject: "New Subject!"}} do
email = BaseMailer.welcome(subject: nil)
assert_equal "New Subject!", email.subject
end
end
end

test 'default subject can have interpolations' do
I18n.backend.store_translations('en', base_mailer: {with_subject_interpolations: {subject: 'Will the real %{rapper_or_impersonator} please stand up?'}})
email = BaseMailer.with_subject_interpolations
assert_equal 'Will the real Slim Shady please stand up?', email.subject
with_translation 'en', base_mailer: {with_subject_interpolations: {subject: 'Will the real %{rapper_or_impersonator} please stand up?'}} do
email = BaseMailer.with_subject_interpolations
assert_equal 'Will the real Slim Shady please stand up?', email.subject
end
end

test "translations are scoped properly" do
I18n.backend.store_translations('en', base_mailer: {email_with_translations: {greet_user: "Hello %{name}!"}})
email = BaseMailer.email_with_translations
assert_equal 'Hello lifo!', email.body.encoded
with_translation 'en', base_mailer: {email_with_translations: {greet_user: "Hello %{name}!"}} do
email = BaseMailer.email_with_translations
assert_equal 'Hello lifo!', email.body.encoded
end
end

# Implicit multipart
Expand Down Expand Up @@ -407,22 +417,19 @@ def teardown
end

test "calling just the action should return the generated mail object" do
BaseMailer.deliveries.clear
email = BaseMailer.welcome
assert_equal(0, BaseMailer.deliveries.length)
assert_equal('The first email on new API!', email.subject)
end

test "calling deliver on the action should deliver the mail object" do
BaseMailer.deliveries.clear
BaseMailer.expects(:deliver_mail).once
mail = BaseMailer.welcome.deliver
assert_equal 'The first email on new API!', mail.subject
end

test "calling deliver on the action should increment the deliveries collection if using the test mailer" do
BaseMailer.delivery_method = :test
BaseMailer.deliveries.clear
BaseMailer.welcome.deliver
assert_equal(1, BaseMailer.deliveries.length)
end
Expand All @@ -442,7 +449,6 @@ def teardown
end

test "should raise if missing template in implicit render" do
BaseMailer.deliveries.clear
assert_raises ActionView::MissingTemplate do
BaseMailer.implicit_different_template('missing_template').deliver
end
Expand Down Expand Up @@ -479,18 +485,17 @@ def teardown
end

test "assets tags should use a Mailer's asset_host settings when available" do
begin
ActionMailer::Base.config.asset_host = "http://global.com"
ActionMailer::Base.config.assets_dir = "global/"
ActionMailer::Base.config.asset_host = "http://global.com"
ActionMailer::Base.config.assets_dir = "global/"

AssetMailer.asset_host = "http://local.com"
TempAssetMailer = Class.new(AssetMailer) do
self.mailer_name = "asset_mailer"
self.asset_host = "http://local.com"
end

mail = AssetMailer.welcome
mail = TempAssetMailer.welcome

assert_equal(%{<img alt="Dummy" src="http://local.com/images/dummy.png" />}, mail.body.to_s.strip)
ensure
AssetMailer.asset_host = ActionMailer::Base.config.asset_host
end
assert_equal(%{<img alt="Dummy" src="http://local.com/images/dummy.png" />}, mail.body.to_s.strip)
end

test 'the view is not rendered when mail was never called' do
Expand Down Expand Up @@ -518,32 +523,40 @@ def self.delivered_email(mail)
end

test "you can register an observer to the mail object that gets informed on email delivery" do
ActionMailer::Base.register_observer(MyObserver)
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
mail.deliver
mail_side_effects do
ActionMailer::Base.register_observer(MyObserver)
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
mail.deliver
end
end

test "you can register an observer using its stringified name to the mail object that gets informed on email delivery" do
ActionMailer::Base.register_observer("BaseTest::MyObserver")
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
mail.deliver
mail_side_effects do
ActionMailer::Base.register_observer("BaseTest::MyObserver")
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
mail.deliver
end
end

test "you can register an observer using its symbolized underscored name to the mail object that gets informed on email delivery" do
ActionMailer::Base.register_observer(:"base_test/my_observer")
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
mail.deliver
mail_side_effects do
ActionMailer::Base.register_observer(:"base_test/my_observer")
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
mail.deliver
end
end

test "you can register multiple observers to the mail object that both get informed on email delivery" do
ActionMailer::Base.register_observers("BaseTest::MyObserver", MySecondObserver)
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
MySecondObserver.expects(:delivered_email).with(mail)
mail.deliver
mail_side_effects do
ActionMailer::Base.register_observers("BaseTest::MyObserver", MySecondObserver)
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
MySecondObserver.expects(:delivered_email).with(mail)
mail.deliver
end
end

class MyInterceptor
Expand All @@ -556,72 +569,41 @@ def self.delivering_email(mail); end
def self.previewing_email(mail); end
end

class BaseMailerPreview < ActionMailer::Preview
def welcome
BaseMailer.welcome
end
end

test "you can register an interceptor to the mail object that gets passed the mail object before delivery" do
ActionMailer::Base.register_interceptor(MyInterceptor)
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
mail.deliver
mail_side_effects do
ActionMailer::Base.register_interceptor(MyInterceptor)
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
mail.deliver
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
ActionMailer::Base.register_interceptor("BaseTest::MyInterceptor")
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
mail.deliver
mail_side_effects do
ActionMailer::Base.register_interceptor("BaseTest::MyInterceptor")
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
mail.deliver
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
ActionMailer::Base.register_interceptor(:"base_test/my_interceptor")
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
mail.deliver
mail_side_effects do
ActionMailer::Base.register_interceptor(:"base_test/my_interceptor")
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
mail.deliver
end
end

test "you can register multiple interceptors to the mail object that both get passed the mail object before delivery" do
ActionMailer::Base.register_interceptors("BaseTest::MyInterceptor", MySecondInterceptor)
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
MySecondInterceptor.expects(:delivering_email).with(mail)
mail.deliver
end

test "you can register 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
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
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
ActionMailer::Base.register_preview_interceptor("BaseTest::MyInterceptor")
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
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
ActionMailer::Base.register_preview_interceptor(:"base_test/my_interceptor")
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
end

test "you can register multiple preview interceptors to the mail object that both get passed the mail object before previewing" do
ActionMailer::Base.register_preview_interceptors("BaseTest::MyInterceptor", MySecondInterceptor)
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
MySecondInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
mail_side_effects do
ActionMailer::Base.register_interceptors("BaseTest::MyInterceptor", MySecondInterceptor)
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
MySecondInterceptor.expects(:delivering_email).with(mail)
mail.deliver
end
end

test "being able to put proc's into the defaults hash and they get evaluated on mail sending" do
Expand Down Expand Up @@ -770,4 +752,77 @@ def with_default(klass, new_values)
ensure
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)
yield
ensure
Mail.class_variable_set(:@@delivery_notification_observers, old_observers)
Mail.class_variable_set(:@@delivery_interceptors, old_delivery_interceptors)
end

def with_translation(locale, data)
I18n.backend.store_translations(locale, data)
yield
ensure
I18n.backend.reload!
end
end

class BasePreviewInterceptorsTest < ActiveSupport::TestCase
teardown do
ActionMailer::Base.preview_interceptors.clear
end

class BaseMailerPreview < ActionMailer::Preview
def welcome
BaseMailer.welcome
end
end

class MyInterceptor
def self.delivering_email(mail); end
def self.previewing_email(mail); end
end

class MySecondInterceptor
def self.delivering_email(mail); end
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
ActionMailer::Base.register_preview_interceptor(MyInterceptor)
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
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
ActionMailer::Base.register_preview_interceptor("BasePreviewInterceptorsTest::MyInterceptor")
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
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
ActionMailer::Base.register_preview_interceptor(:"base_preview_interceptors_test/my_interceptor")
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
end

test "you can register 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
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
MySecondInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
end
end

0 comments on commit 1401637

Please sign in to comment.