diff options
Diffstat (limited to 'actionmailer/test')
27 files changed, 799 insertions, 306 deletions
diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb index 706249a2f6..82f03f5cba 100644 --- a/actionmailer/test/abstract_unit.rb +++ b/actionmailer/test/abstract_unit.rb @@ -1,5 +1,4 @@ -require File.expand_path('../../../load_paths', __FILE__) -require 'active_support/core_ext/kernel/reporting' +require "active_support/core_ext/kernel/reporting" # These are the normal settings that will be set up by Railties # TODO: Have these tests support other combinations of these values @@ -8,12 +7,19 @@ silence_warnings do Encoding.default_external = "UTF-8" end -require 'active_support/testing/autorun' -require 'action_mailer' -require 'action_mailer/test_case' +module Rails + def self.root + File.expand_path("../", File.dirname(__FILE__)) + end +end + +require "active_support/testing/autorun" +require "active_support/testing/method_call_assertions" +require "action_mailer" +require "action_mailer/test_case" # Emulate AV railtie -require 'action_view' +require "action_view" ActionMailer::Base.include(ActionView::Layouts) # Show backtraces for deprecated behavior for quicker cleanup. @@ -22,22 +28,18 @@ ActiveSupport::Deprecation.debug = true # Disable available locale checks to avoid warnings running the test suite. I18n.enforce_available_locales = false -FIXTURE_LOAD_PATH = File.expand_path('fixtures', File.dirname(__FILE__)) +FIXTURE_LOAD_PATH = File.expand_path("fixtures", File.dirname(__FILE__)) ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH -module Rails - def self.root - File.expand_path('../', File.dirname(__FILE__)) - end -end - # Skips the current run on Rubinius using Minitest::Assertions#skip -def rubinius_skip(message = '') - skip message if RUBY_ENGINE == 'rbx' +def rubinius_skip(message = "") + skip message if RUBY_ENGINE == "rbx" end # Skips the current run on JRuby using Minitest::Assertions#skip -def jruby_skip(message = '') +def jruby_skip(message = "") skip message if defined?(JRUBY_VERSION) end -require 'mocha/setup' # FIXME: stop using mocha +class ActiveSupport::TestCase + include ActiveSupport::Testing::MethodCallAssertions +end diff --git a/actionmailer/test/assert_select_email_test.rb b/actionmailer/test/assert_select_email_test.rb index cae2e20abd..bf14fe0853 100644 --- a/actionmailer/test/assert_select_email_test.rb +++ b/actionmailer/test/assert_select_email_test.rb @@ -1,4 +1,4 @@ -require 'abstract_unit' +require "abstract_unit" class AssertSelectEmailTest < ActionMailer::TestCase class AssertSelectMailer < ActionMailer::Base @@ -11,8 +11,8 @@ class AssertSelectEmailTest < ActionMailer::TestCase class AssertMultipartSelectMailer < ActionMailer::Base def test(options) mail subject: "Test e-mail", from: "test@test.host", to: "test <test@test.host>" do |format| - format.text { render text: options[:text] } - format.html { render text: options[:html] } + format.text { render plain: options[:text] } + format.html { render plain: options[:html] } end end end @@ -36,7 +36,7 @@ class AssertSelectEmailTest < ActionMailer::TestCase end def test_assert_select_email_multipart - AssertMultipartSelectMailer.test(html: "<div><p>foo</p><p>bar</p></div>", text: 'foo bar').deliver_now + AssertMultipartSelectMailer.test(html: "<div><p>foo</p><p>bar</p></div>", text: "foo bar").deliver_now assert_select_email do assert_select "div:root" do assert_select "p:first-child", "foo" diff --git a/actionmailer/test/asset_host_test.rb b/actionmailer/test/asset_host_test.rb index 10cfdcf693..812df01a34 100644 --- a/actionmailer/test/asset_host_test.rb +++ b/actionmailer/test/asset_host_test.rb @@ -1,11 +1,11 @@ -require 'abstract_unit' -require 'action_controller' +require "abstract_unit" +require "action_controller" class AssetHostMailer < ActionMailer::Base def email_with_asset - mail to: 'test@localhost', - subject: 'testing email containing asset path while asset_host is set', - from: 'tester@example.com' + mail to: "test@localhost", + subject: "testing email containing asset path while asset_host is set", + from: "tester@example.com" end end @@ -22,16 +22,16 @@ class AssetHostTest < ActionMailer::TestCase def test_asset_host_as_string mail = AssetHostMailer.email_with_asset - assert_dom_equal %Q{<img alt="Somelogo" src="http://www.example.com/images/somelogo.png" />}, mail.body.to_s.strip + assert_dom_equal '<img alt="Somelogo" src="http://www.example.com/images/somelogo.png" />', mail.body.to_s.strip end def test_asset_host_as_one_argument_proc AssetHostMailer.config.asset_host = Proc.new { |source| - if source.starts_with?('/images') - 'http://images.example.com' + if source.starts_with?("/images") + "http://images.example.com" end } mail = AssetHostMailer.email_with_asset - assert_dom_equal %Q{<img alt="Somelogo" src="http://images.example.com/images/somelogo.png" />}, mail.body.to_s.strip + assert_dom_equal '<img alt="Somelogo" src="http://images.example.com/images/somelogo.png" />', mail.body.to_s.strip end end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 59c5638f96..91049e33f9 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -1,12 +1,12 @@ -require 'abstract_unit' -require 'set' +require "abstract_unit" +require "set" -require 'action_dispatch' -require 'active_support/time' +require "action_dispatch" +require "active_support/time" -require 'mailers/base_mailer' -require 'mailers/proc_mailer' -require 'mailers/asset_mailer' +require "mailers/base_mailer" +require "mailers/proc_mailer" +require "mailers/asset_mailer" class BaseTest < ActiveSupport::TestCase include Rails::Dom::Testing::Assertions::DomAssertions @@ -32,33 +32,33 @@ class BaseTest < ActiveSupport::TestCase # Basic mail usage without block test "mail() should set the headers of the mail message" do email = BaseMailer.welcome - assert_equal(['system@test.lindsaar.net'], email.to) - assert_equal(['jose@test.plataformatec.com'], email.from) - assert_equal('The first email on new API!', email.subject) + assert_equal(["system@test.lindsaar.net"], email.to) + assert_equal(["jose@test.plataformatec.com"], email.from) + assert_equal("The first email on new API!", email.subject) end test "mail() with from overwrites the class level default" do - email = BaseMailer.welcome(from: 'someone@example.com', - to: 'another@example.org') - assert_equal(['someone@example.com'], email.from) - assert_equal(['another@example.org'], email.to) + email = BaseMailer.welcome(from: "someone@example.com", + to: "another@example.org") + assert_equal(["someone@example.com"], email.from) + assert_equal(["another@example.org"], email.to) end test "mail() with bcc, cc, content_type, charset, mime_version, reply_to and date" do time = Time.now.beginning_of_day.to_datetime - email = BaseMailer.welcome(bcc: 'bcc@test.lindsaar.net', - cc: 'cc@test.lindsaar.net', - content_type: 'multipart/mixed', - charset: 'iso-8559-1', - mime_version: '2.0', - reply_to: 'reply-to@test.lindsaar.net', + email = BaseMailer.welcome(bcc: "bcc@test.lindsaar.net", + cc: "cc@test.lindsaar.net", + content_type: "multipart/mixed", + charset: "iso-8559-1", + mime_version: "2.0", + reply_to: "reply-to@test.lindsaar.net", date: time) - assert_equal(['bcc@test.lindsaar.net'], email.bcc) - assert_equal(['cc@test.lindsaar.net'], email.cc) - assert_equal('multipart/mixed; charset=iso-8559-1', email.content_type) - assert_equal('iso-8559-1', email.charset) - assert_equal('2.0', email.mime_version) - assert_equal(['reply-to@test.lindsaar.net'], email.reply_to) + assert_equal(["bcc@test.lindsaar.net"], email.bcc) + assert_equal(["cc@test.lindsaar.net"], email.cc) + assert_equal("multipart/mixed; charset=iso-8559-1", email.content_type) + assert_equal("iso-8559-1", email.charset) + assert_equal("2.0", email.mime_version) + assert_equal(["reply-to@test.lindsaar.net"], email.reply_to) assert_equal(time, email.date) end @@ -75,63 +75,63 @@ class BaseTest < ActiveSupport::TestCase test "should set template content type if mail has only one part" do mail = BaseMailer.html_only - assert_equal('text/html', mail.mime_type) + assert_equal("text/html", mail.mime_type) mail = BaseMailer.plain_text_only - assert_equal('text/plain', mail.mime_type) + assert_equal("text/plain", mail.mime_type) end # Custom headers test "custom headers" do email = BaseMailer.welcome - assert_equal("Not SPAM", email['X-SPAM'].decoded) + assert_equal("Not SPAM", email["X-SPAM"].decoded) end test "can pass random headers in as a hash to mail" do - hash = {'X-Special-Domain-Specific-Header' => "SecretValue", - 'In-Reply-To' => '1234@mikel.me.com' } + hash = { "X-Special-Domain-Specific-Header" => "SecretValue", + "In-Reply-To" => "1234@mikel.me.com" } mail = BaseMailer.welcome(hash) - assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded) - assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded) + assert_equal("SecretValue", mail["X-Special-Domain-Specific-Header"].decoded) + assert_equal("1234@mikel.me.com", mail["In-Reply-To"].decoded) end test "can pass random headers in as a hash to headers" do - hash = {'X-Special-Domain-Specific-Header' => "SecretValue", - 'In-Reply-To' => '1234@mikel.me.com' } + hash = { "X-Special-Domain-Specific-Header" => "SecretValue", + "In-Reply-To" => "1234@mikel.me.com" } mail = BaseMailer.welcome_with_headers(hash) - assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded) - assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded) + assert_equal("SecretValue", mail["X-Special-Domain-Specific-Header"].decoded) + assert_equal("1234@mikel.me.com", mail["In-Reply-To"].decoded) end # Attachments test "attachment with content" do email = BaseMailer.attachment_with_content assert_equal(1, email.attachments.length) - assert_equal('invoice.pdf', email.attachments[0].filename) - assert_equal('This is test File content', email.attachments['invoice.pdf'].decoded) + assert_equal("invoice.pdf", email.attachments[0].filename) + assert_equal("This is test File content", email.attachments["invoice.pdf"].decoded) end 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) + assert_equal("invoice.pdf", email.attachments[0].filename) + assert_equal("application/pdf", email.attachments[0].mime_type) end test "attachment with hash" do email = BaseMailer.attachment_with_hash assert_equal(1, email.attachments.length) - assert_equal('invoice.jpg', email.attachments[0].filename) + assert_equal("invoice.jpg", email.attachments[0].filename) expected = "\312\213\254\232)b" expected.force_encoding(Encoding::BINARY) - assert_equal expected, email.attachments['invoice.jpg'].decoded + assert_equal expected, email.attachments["invoice.jpg"].decoded end test "attachment with hash using default mail encoding" do email = BaseMailer.attachment_with_hash_default_encoding assert_equal(1, email.attachments.length) - assert_equal('invoice.jpg', email.attachments[0].filename) + assert_equal("invoice.jpg", email.attachments[0].filename) expected = "\312\213\254\232)b" expected.force_encoding(Encoding::BINARY) - assert_equal expected, email.attachments['invoice.jpg'].decoded + assert_equal expected, email.attachments["invoice.jpg"].decoded end test "sets mime type to multipart/mixed when attachment is included" do @@ -215,24 +215,24 @@ class BaseTest < ActiveSupport::TestCase email = BaseMailer.welcome(subject: nil) assert_equal "Welcome", email.subject - with_translation 'en', base_mailer: {welcome: {subject: "New Subject!"}} do + 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 - with_translation 'en', base_mailer: {with_subject_interpolations: {subject: 'Will the real %{rapper_or_impersonator} please stand up?'}} do + test "default subject can have interpolations" do + 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 + assert_equal "Will the real Slim Shady please stand up?", email.subject end end test "translations are scoped properly" do - with_translation 'en', base_mailer: {email_with_translations: {greet_user: "Hello %{name}!"}} do + 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 + assert_equal "Hello lifo!", email.body.encoded end end @@ -240,7 +240,7 @@ class BaseTest < ActiveSupport::TestCase class LateAttachmentMailer < ActionMailer::Base def welcome mail body: "yay", from: "welcome@example.com", to: "to@example.com" - attachments['invoice.pdf'] = 'This is test File content' + attachments["invoice.pdf"] = "This is test File content" end end @@ -252,7 +252,7 @@ class BaseTest < ActiveSupport::TestCase class LateInlineAttachmentMailer < ActionMailer::Base def welcome mail body: "yay", from: "welcome@example.com", to: "to@example.com" - attachments.inline['invoice.pdf'] = 'This is test File content' + attachments.inline["invoice.pdf"] = "This is test File content" end end @@ -271,13 +271,13 @@ class BaseTest < ActiveSupport::TestCase assert_nothing_raised { mail.message } assert_equal ["image/jpeg; filename=controller_attachments.jpg", - "image/jpeg; filename=attachments.jpg"], mail.attachments.inline.map {|a| a['Content-Type'].to_s } + "image/jpeg; filename=attachments.jpg"], mail.attachments.inline.map { |a| a["Content-Type"].to_s } end test "accessing attachments works after mail was called" do class LateAttachmentAccessorMailer < ActionMailer::Base def welcome - attachments['invoice.pdf'] = 'This is test File content' + attachments["invoice.pdf"] = "This is test File content" mail body: "yay", from: "welcome@example.com", to: "to@example.com" unless attachments.map(&:filename) == ["invoice.pdf"] @@ -366,7 +366,7 @@ class BaseTest < ActiveSupport::TestCase I18n.backend = fallback_backend.new I18n.fallbacks[:"de-AT"] = [:de] - swap I18n, locale: 'de-AT' do + swap I18n, locale: "de-AT" do email = BaseMailer.implicit_with_locale assert_equal(2, email.parts.size) assert_equal("multipart/alternative", email.mime_type) @@ -380,7 +380,6 @@ class BaseTest < ActiveSupport::TestCase end end - test "implicit multipart with several view paths uses the first one with template" do old = BaseMailer.view_paths begin @@ -449,6 +448,13 @@ class BaseTest < ActiveSupport::TestCase assert_equal("Format with any!", email.parts[1].body.encoded) end + test "explicit without specifying format with format.any" do + error = assert_raises(ArgumentError) do + BaseMailer.explicit_without_specifying_format_with_any.parts + end + assert_equal "You have to supply at least one format", error.message + end + test "explicit multipart with format(Hash)" do email = BaseMailer.explicit_multipart_with_options(true) email.ready_to_send! @@ -501,13 +507,14 @@ class BaseTest < ActiveSupport::TestCase test "calling just the action should return the generated mail object" do email = BaseMailer.welcome assert_equal(0, BaseMailer.deliveries.length) - assert_equal('The first email on new API!', email.subject) + assert_equal("The first email on new API!", email.subject) end test "calling deliver on the action should deliver the mail object" do - BaseMailer.expects(:deliver_mail).once - mail = BaseMailer.welcome.deliver_now - assert_equal 'The first email on new API!', mail.subject + assert_called(BaseMailer, :deliver_mail) do + mail = BaseMailer.welcome.deliver_now + assert_equal "The first email on new API!", mail.subject + end end test "calling deliver on the action should increment the deliveries collection if using the test mailer" do @@ -517,42 +524,44 @@ class BaseTest < ActiveSupport::TestCase test "calling deliver, ActionMailer should yield back to mail to let it call :do_delivery on itself" do mail = Mail::Message.new - mail.expects(:do_delivery).once - BaseMailer.expects(:welcome).returns(mail) - BaseMailer.welcome.deliver + assert_called(mail, :do_delivery) do + assert_called(BaseMailer, :welcome, returns: mail) do + BaseMailer.welcome.deliver + end + end end # Rendering test "you can specify a different template for implicit render" do - mail = BaseMailer.implicit_different_template('implicit_multipart').deliver_now + mail = BaseMailer.implicit_different_template("implicit_multipart").deliver_now assert_equal("HTML Implicit Multipart", mail.html_part.body.decoded) assert_equal("TEXT Implicit Multipart", mail.text_part.body.decoded) end test "should raise if missing template in implicit render" do assert_raises ActionView::MissingTemplate do - BaseMailer.implicit_different_template('missing_template').deliver_now + BaseMailer.implicit_different_template("missing_template").deliver_now end assert_equal(0, BaseMailer.deliveries.length) end test "you can specify a different template for explicit render" do - mail = BaseMailer.explicit_different_template('explicit_multipart_templates').deliver_now + mail = BaseMailer.explicit_different_template("explicit_multipart_templates").deliver_now assert_equal("HTML Explicit Multipart Templates", mail.html_part.body.decoded) assert_equal("TEXT Explicit Multipart Templates", mail.text_part.body.decoded) end test "you can specify a different layout" do - mail = BaseMailer.different_layout('different_layout').deliver_now + mail = BaseMailer.different_layout("different_layout").deliver_now assert_equal("HTML -- HTML", mail.html_part.body.decoded) assert_equal("PLAIN -- PLAIN", mail.text_part.body.decoded) end test "you can specify the template path for implicit lookup" do - mail = BaseMailer.welcome_from_another_path('another.path/base_mailer').deliver_now + mail = BaseMailer.welcome_from_another_path("another.path/base_mailer").deliver_now assert_equal("Welcome from another path", mail.body.encoded) - mail = BaseMailer.welcome_from_another_path(['unknown/invalid', 'another.path/base_mailer']).deliver_now + mail = BaseMailer.welcome_from_another_path(["unknown/invalid", "another.path/base_mailer"]).deliver_now assert_equal("Welcome from another path", mail.body.encoded) end @@ -579,15 +588,15 @@ class BaseTest < ActiveSupport::TestCase assert_dom_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 + test "the view is not rendered when mail was never called" do mail = BaseMailer.without_mail_call - assert_equal('', mail.body.to_s.strip) + assert_equal("", mail.body.to_s.strip) mail.deliver_now end - test 'the return value of mailer methods is not relevant' do + test "the return value of mailer methods is not relevant" do mail = BaseMailer.with_nil_as_return_value - assert_equal('Welcome', mail.body.to_s.strip) + assert_equal("Welcome", mail.body.to_s.strip) mail.deliver_now end @@ -607,8 +616,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_observer(MyObserver) mail = BaseMailer.welcome - MyObserver.expects(:delivered_email).with(mail) - mail.deliver_now + assert_called_with(MyObserver, :delivered_email, [mail]) do + mail.deliver_now + end end end @@ -616,8 +626,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_observer("BaseTest::MyObserver") mail = BaseMailer.welcome - MyObserver.expects(:delivered_email).with(mail) - mail.deliver_now + assert_called_with(MyObserver, :delivered_email, [mail]) do + mail.deliver_now + end end end @@ -625,8 +636,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_observer(:"base_test/my_observer") mail = BaseMailer.welcome - MyObserver.expects(:delivered_email).with(mail) - mail.deliver_now + assert_called_with(MyObserver, :delivered_email, [mail]) do + mail.deliver_now + end end end @@ -634,9 +646,11 @@ class BaseTest < ActiveSupport::TestCase 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_now + assert_called_with(MyObserver, :delivered_email, [mail]) do + assert_called_with(MySecondObserver, :delivered_email, [mail]) do + mail.deliver_now + end + end end end @@ -654,8 +668,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_interceptor(MyInterceptor) mail = BaseMailer.welcome - MyInterceptor.expects(:delivering_email).with(mail) - mail.deliver_now + assert_called_with(MyInterceptor, :delivering_email, [mail]) do + mail.deliver_now + end end end @@ -663,8 +678,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_interceptor("BaseTest::MyInterceptor") mail = BaseMailer.welcome - MyInterceptor.expects(:delivering_email).with(mail) - mail.deliver_now + assert_called_with(MyInterceptor, :delivering_email, [mail]) do + mail.deliver_now + end end end @@ -672,8 +688,9 @@ class BaseTest < ActiveSupport::TestCase mail_side_effects do ActionMailer::Base.register_interceptor(:"base_test/my_interceptor") mail = BaseMailer.welcome - MyInterceptor.expects(:delivering_email).with(mail) - mail.deliver_now + assert_called_with(MyInterceptor, :delivering_email, [mail]) do + mail.deliver_now + end end end @@ -681,22 +698,25 @@ class BaseTest < ActiveSupport::TestCase 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_now + assert_called_with(MyInterceptor, :delivering_email, [mail]) do + assert_called_with(MySecondInterceptor, :delivering_email, [mail]) do + mail.deliver_now + end + end end end test "being able to put proc's into the defaults hash and they get evaluated on mail sending" do - mail1 = ProcMailer.welcome['X-Proc-Method'] + mail1 = ProcMailer.welcome["X-Proc-Method"] yesterday = 1.day.ago - Time.stubs(:now).returns(yesterday) - mail2 = ProcMailer.welcome['X-Proc-Method'] - assert(mail1.to_s.to_i > mail2.to_s.to_i) + Time.stub(:now, yesterday) do + mail2 = ProcMailer.welcome["X-Proc-Method"] + assert(mail1.to_s.to_i > mail2.to_s.to_i) + end end - test 'default values which have to_proc (e.g. symbols) should not be considered procs' do - assert(ProcMailer.welcome['x-has-to-proc'].to_s == 'symbol') + test "default values which have to_proc (e.g. symbols) should not be considered procs" do + assert(ProcMailer.welcome["x-has-to-proc"].to_s == "symbol") end test "we can call other defined methods on the class as needed" do @@ -711,12 +731,12 @@ class BaseTest < ActiveSupport::TestCase def welcome ; mail ; end private - def add_special_header! - headers('X-Special-Header' => 'Wow, so special') - end + def add_special_header! + headers("X-Special-Header" => "Wow, so special") + end end - assert_equal('Wow, so special', BeforeActionMailer.welcome['X-Special-Header'].to_s) + assert_equal("Wow, so special", BeforeActionMailer.welcome["X-Special-Header"].to_s) end test "modifying the mail message with an after_action" do @@ -726,12 +746,12 @@ class BaseTest < ActiveSupport::TestCase def welcome ; mail ; end private - def add_special_header! - headers('X-Special-Header' => 'Testing') - end + def add_special_header! + headers("X-Special-Header" => "Testing") + end end - assert_equal('Testing', AfterActionMailer.welcome['X-Special-Header'].to_s) + assert_equal("Testing", AfterActionMailer.welcome["X-Special-Header"].to_s) end test "adding an inline attachment using a before_action" do @@ -741,19 +761,19 @@ class BaseTest < ActiveSupport::TestCase def welcome ; mail ; end private - def add_inline_attachment! - attachments.inline["footer.jpg"] = 'hey there' - end + def add_inline_attachment! + attachments.inline["footer.jpg"] = "hey there" + end end mail = DefaultInlineAttachmentMailer.welcome - assert_equal('image/jpeg; filename=footer.jpg', mail.attachments.inline.first['Content-Type'].to_s) + assert_equal("image/jpeg; filename=footer.jpg", mail.attachments.inline.first["Content-Type"].to_s) end test "action methods should be refreshed after defining new method" do class FooMailer < ActionMailer::Base - # this triggers action_methods - self.respond_to?(:foo) + # This triggers action_methods. + respond_to?(:foo) def notify end @@ -777,8 +797,8 @@ class BaseTest < ActiveSupport::TestCase test "default_from can be set" do class DefaultFromMailer < ActionMailer::Base - default to: 'system@test.lindsaar.net' - self.default_options = {from: "robert.pankowecki@gmail.com"} + default to: "system@test.lindsaar.net" + self.default_options = { from: "robert.pankowecki@gmail.com" } def welcome mail(subject: "subject", body: "hello world") @@ -793,7 +813,7 @@ class BaseTest < ActiveSupport::TestCase after_action :a_callback def welcome - headers('X-Special-Header' => 'special indeed!') + headers("X-Special-Header" => "special indeed!") mail subject: "subject", body: "hello world", to: ["joe@example.com"] end @@ -809,7 +829,7 @@ class BaseTest < ActiveSupport::TestCase assert_equal "special indeed!", mail["X-Special-Header"].to_s end - protected + private # Execute the block setting the given values and restoring old values after # the block is executed. @@ -877,33 +897,50 @@ class BasePreviewInterceptorsTest < ActiveSupport::TestCase 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) + stub_any_instance(BaseMailerPreview) do |instance| + instance.stub(:welcome, mail) do + assert_called_with(MyInterceptor, :previewing_email, [mail]) do + BaseMailerPreview.call(:welcome) + end + end + 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 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) + stub_any_instance(BaseMailerPreview) do |instance| + instance.stub(:welcome, mail) do + assert_called_with(MyInterceptor, :previewing_email, [mail]) do + BaseMailerPreview.call(:welcome) + end + 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 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) + stub_any_instance(BaseMailerPreview) do |instance| + instance.stub(:welcome, mail) do + assert_called_with(MyInterceptor, :previewing_email, [mail]) do + BaseMailerPreview.call(:welcome) + end + end + end 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) + stub_any_instance(BaseMailerPreview) do |instance| + instance.stub(:welcome, mail) do + assert_called_with(MyInterceptor, :previewing_email, [mail]) do + assert_called_with(MySecondInterceptor, :previewing_email, [mail]) do + BaseMailerPreview.call(:welcome) + end + end + end + end end end diff --git a/actionmailer/test/caching_test.rb b/actionmailer/test/caching_test.rb new file mode 100644 index 0000000000..cff49c8894 --- /dev/null +++ b/actionmailer/test/caching_test.rb @@ -0,0 +1,273 @@ +require "fileutils" +require "abstract_unit" +require "mailers/base_mailer" +require "mailers/caching_mailer" + +CACHE_DIR = "test_cache" +# Don't change '/../temp/' cavalierly or you might hose something you don't want hosed +FILE_STORE_PATH = File.join(File.dirname(__FILE__), "/../temp/", CACHE_DIR) + +class FragmentCachingMailer < ActionMailer::Base + abstract! + + def some_action; end +end + +class BaseCachingTest < ActiveSupport::TestCase + def setup + super + @store = ActiveSupport::Cache::MemoryStore.new + @mailer = FragmentCachingMailer.new + @mailer.perform_caching = true + @mailer.cache_store = @store + end + + def test_fragment_cache_key + assert_equal "views/what a key", @mailer.fragment_cache_key("what a key") + end +end + +class FragmentCachingTest < BaseCachingTest + def test_read_fragment_with_caching_enabled + @store.write("views/name", "value") + assert_equal "value", @mailer.read_fragment("name") + end + + def test_read_fragment_with_caching_disabled + @mailer.perform_caching = false + @store.write("views/name", "value") + assert_nil @mailer.read_fragment("name") + end + + def test_fragment_exist_with_caching_enabled + @store.write("views/name", "value") + assert @mailer.fragment_exist?("name") + assert !@mailer.fragment_exist?("other_name") + end + + def test_fragment_exist_with_caching_disabled + @mailer.perform_caching = false + @store.write("views/name", "value") + assert !@mailer.fragment_exist?("name") + assert !@mailer.fragment_exist?("other_name") + end + + def test_write_fragment_with_caching_enabled + assert_nil @store.read("views/name") + assert_equal "value", @mailer.write_fragment("name", "value") + assert_equal "value", @store.read("views/name") + end + + def test_write_fragment_with_caching_disabled + assert_nil @store.read("views/name") + @mailer.perform_caching = false + assert_equal "value", @mailer.write_fragment("name", "value") + assert_nil @store.read("views/name") + end + + def test_expire_fragment_with_simple_key + @store.write("views/name", "value") + @mailer.expire_fragment "name" + assert_nil @store.read("views/name") + end + + def test_expire_fragment_with_regexp + @store.write("views/name", "value") + @store.write("views/another_name", "another_value") + @store.write("views/primalgrasp", "will not expire ;-)") + + @mailer.expire_fragment(/name/) + + assert_nil @store.read("views/name") + assert_nil @store.read("views/another_name") + assert_equal "will not expire ;-)", @store.read("views/primalgrasp") + end + + def test_fragment_for + @store.write("views/expensive", "fragment content") + fragment_computed = false + + view_context = @mailer.view_context + + buffer = "generated till now -> ".html_safe + buffer << view_context.send(:fragment_for, "expensive") { fragment_computed = true } + + assert !fragment_computed + assert_equal "generated till now -> fragment content", buffer + end + + def test_html_safety + assert_nil @store.read("views/name") + content = "value".html_safe + assert_equal content, @mailer.write_fragment("name", content) + + cached = @store.read("views/name") + assert_equal content, cached + assert_equal String, cached.class + + html_safe = @mailer.read_fragment("name") + assert_equal content, html_safe + assert html_safe.html_safe? + end +end + +class FunctionalFragmentCachingTest < BaseCachingTest + def setup + super + @store = ActiveSupport::Cache::MemoryStore.new + @mailer = CachingMailer.new + @mailer.perform_caching = true + @mailer.cache_store = @store + end + + def test_fragment_caching + email = @mailer.fragment_cache + expected_body = "\"Welcome\"" + + assert_match expected_body, email.body.encoded + assert_match expected_body, + @store.read("views/caching/#{template_digest("caching_mailer/fragment_cache")}") + end + + def test_fragment_caching_in_partials + email = @mailer.fragment_cache_in_partials + expected_body = "Old fragment caching in a partial" + assert_match(expected_body, email.body.encoded) + + assert_match(expected_body, + @store.read("views/caching/#{template_digest("caching_mailer/_partial")}")) + end + + def test_skip_fragment_cache_digesting + email = @mailer.skip_fragment_cache_digesting + expected_body = "No Digest" + + assert_match expected_body, email.body.encoded + assert_match expected_body, @store.read("views/no_digest") + end + + def test_fragment_caching_options + time = Time.now + email = @mailer.fragment_caching_options + expected_body = "No Digest" + + assert_match expected_body, email.body.encoded + Time.stub(:now, time + 11) do + assert_nil @store.read("views/no_digest") + end + end + + def test_multipart_fragment_caching + email = @mailer.multipart_cache + + expected_text_body = "\"Welcome text\"" + expected_html_body = "\"Welcome html\"" + encoded_body = email.body.encoded + assert_match expected_text_body, encoded_body + assert_match expected_html_body, encoded_body + assert_match expected_text_body, + @store.read("views/text_caching") + assert_match expected_html_body, + @store.read("views/html_caching") + end + + def test_fragment_cache_instrumentation + @mailer.enable_fragment_cache_logging = true + payload = nil + + subscriber = proc do |*args| + event = ActiveSupport::Notifications::Event.new(*args) + payload = event.payload + end + + ActiveSupport::Notifications.subscribed(subscriber, "read_fragment.action_mailer") do + @mailer.fragment_cache + end + + assert_equal "caching_mailer", payload[:mailer] + assert_equal "views/caching/#{template_digest("caching_mailer/fragment_cache")}", payload[:key] + ensure + @mailer.enable_fragment_cache_logging = true + end + + private + + def template_digest(name) + ActionView::Digestor.digest(name: name, finder: @mailer.lookup_context) + end +end + +class CacheHelperOutputBufferTest < BaseCachingTest + class MockController + def read_fragment(name, options) + return false + end + + def write_fragment(name, fragment, options) + fragment + end + end + + def setup + super + end + + def test_output_buffer + output_buffer = ActionView::OutputBuffer.new + controller = MockController.new + cache_helper = Class.new do + def self.controller; end; + def self.output_buffer; end; + def self.output_buffer=; end; + end + cache_helper.extend(ActionView::Helpers::CacheHelper) + + cache_helper.stub :controller, controller do + cache_helper.stub :output_buffer, output_buffer do + assert_called_with cache_helper, :output_buffer=, [output_buffer.class.new(output_buffer)] do + assert_nothing_raised do + cache_helper.send :fragment_for, "Test fragment name", "Test fragment", &Proc.new { nil } + end + end + end + end + end + + def test_safe_buffer + output_buffer = ActiveSupport::SafeBuffer.new + controller = MockController.new + cache_helper = Class.new do + def self.controller; end; + def self.output_buffer; end; + def self.output_buffer=; end; + end + cache_helper.extend(ActionView::Helpers::CacheHelper) + + cache_helper.stub :controller, controller do + cache_helper.stub :output_buffer, output_buffer do + assert_called_with cache_helper, :output_buffer=, [output_buffer.class.new(output_buffer)] do + assert_nothing_raised do + cache_helper.send :fragment_for, "Test fragment name", "Test fragment", &Proc.new { nil } + end + end + end + end + end +end + +class ViewCacheDependencyTest < BaseCachingTest + class NoDependenciesMailer < ActionMailer::Base + end + class HasDependenciesMailer < ActionMailer::Base + view_cache_dependency { "trombone" } + view_cache_dependency { "flute" } + end + + def test_view_cache_dependencies_are_empty_by_default + assert NoDependenciesMailer.new.view_cache_dependencies.empty? + end + + def test_view_cache_dependencies_are_listed_in_declaration_order + assert_equal %w(trombone flute), HasDependenciesMailer.new.view_cache_dependencies + end +end diff --git a/actionmailer/test/delivery_methods_test.rb b/actionmailer/test/delivery_methods_test.rb index 78507ce7dc..f64a69019f 100644 --- a/actionmailer/test/delivery_methods_test.rb +++ b/actionmailer/test/delivery_methods_test.rb @@ -1,4 +1,4 @@ -require 'abstract_unit' +require "abstract_unit" class MyCustomDelivery end @@ -23,7 +23,7 @@ class DefaultsDeliveryMethodsTest < ActiveSupport::TestCase test "default smtp settings" do settings = { address: "localhost", port: 25, - domain: 'localhost.localdomain', + domain: "localhost.localdomain", user_name: nil, password: nil, authentication: nil, @@ -31,15 +31,15 @@ class DefaultsDeliveryMethodsTest < ActiveSupport::TestCase assert_equal settings, ActionMailer::Base.smtp_settings end - test "default file delivery settings" do - settings = {location: "#{Dir.tmpdir}/mails"} + test "default file delivery settings (with Rails.root)" do + settings = { location: "#{Rails.root}/tmp/mails" } assert_equal settings, ActionMailer::Base.file_settings end test "default sendmail settings" do settings = { - location: '/usr/sbin/sendmail', - arguments: '-i -t' + location: "/usr/sbin/sendmail", + arguments: "-i" } assert_equal settings, ActionMailer::Base.sendmail_settings end @@ -83,11 +83,11 @@ end class MailDeliveryTest < ActiveSupport::TestCase class DeliveryMailer < ActionMailer::Base DEFAULT_HEADERS = { - to: 'mikel@test.lindsaar.net', - from: 'jose@test.plataformatec.com' + to: "mikel@test.lindsaar.net", + from: "jose@test.plataformatec.com" } - def welcome(hash={}) + def welcome(hash = {}) mail(DEFAULT_HEADERS.merge(hash)) end end @@ -102,16 +102,21 @@ class MailDeliveryTest < ActiveSupport::TestCase end test "ActionMailer should be told when Mail gets delivered" do - DeliveryMailer.expects(:deliver_mail).once - DeliveryMailer.welcome.deliver_now + DeliveryMailer.delivery_method = :test + assert_called(DeliveryMailer, :deliver_mail) do + DeliveryMailer.welcome.deliver_now + end end test "delivery method can be customized per instance" do - Mail::SMTP.any_instance.expects(:deliver!) - email = DeliveryMailer.welcome.deliver_now - assert_instance_of Mail::SMTP, email.delivery_method - email = DeliveryMailer.welcome(delivery_method: :test).deliver_now - assert_instance_of Mail::TestMailer, email.delivery_method + stub_any_instance(Mail::SMTP, instance: Mail::SMTP.new({})) do |instance| + assert_called(instance, :deliver!) do + email = DeliveryMailer.welcome.deliver_now + assert_instance_of Mail::SMTP, email.delivery_method + email = DeliveryMailer.welcome(delivery_method: :test).deliver_now + assert_instance_of Mail::TestMailer, email.delivery_method + end + end end test "delivery method can be customized in subclasses not changing the parent" do @@ -122,16 +127,16 @@ class MailDeliveryTest < ActiveSupport::TestCase end test "delivery method options default to class level options" do - default_options = {a: "b"} + default_options = { a: "b" } ActionMailer::Base.add_delivery_method :optioned, MyOptionedDelivery, default_options mail_instance = DeliveryMailer.welcome(delivery_method: :optioned) assert_equal default_options, mail_instance.delivery_method.options end test "delivery method options can be overridden per mail instance" do - default_options = {a: "b"} + default_options = { a: "b" } ActionMailer::Base.add_delivery_method :optioned, MyOptionedDelivery, default_options - overridden_options = {a: "a"} + overridden_options = { a: "a" } mail_instance = DeliveryMailer.welcome(delivery_method: :optioned, delivery_method_options: overridden_options) assert_equal overridden_options, mail_instance.delivery_method.options end @@ -140,14 +145,14 @@ class MailDeliveryTest < ActiveSupport::TestCase settings = { address: "localhost", port: 25, - domain: 'localhost.localdomain', + domain: "localhost.localdomain", user_name: nil, password: nil, authentication: nil, enable_starttls_auto: true } assert_equal settings, ActionMailer::Base.smtp_settings - overridden_options = {user_name: "overridden", password: "somethingobtuse"} + overridden_options = { user_name: "overridden", password: "somethingobtuse" } mail_instance = DeliveryMailer.welcome(delivery_method_options: overridden_options) delivery_method_instance = mail_instance.delivery_method assert_equal "overridden", delivery_method_instance.settings[:user_name] @@ -160,24 +165,29 @@ class MailDeliveryTest < ActiveSupport::TestCase test "non registered delivery methods raises errors" do DeliveryMailer.delivery_method = :unknown - assert_raise RuntimeError do + error = assert_raise RuntimeError do DeliveryMailer.welcome.deliver_now end + assert_equal "Invalid delivery method :unknown", error.message end test "undefined delivery methods raises errors" do DeliveryMailer.delivery_method = nil - assert_raise RuntimeError do + error = assert_raise RuntimeError do DeliveryMailer.welcome.deliver_now end + assert_equal "Delivery method cannot be nil", error.message end test "does not perform deliveries if requested" do old_perform_deliveries = DeliveryMailer.perform_deliveries begin DeliveryMailer.perform_deliveries = false - Mail::Message.any_instance.expects(:deliver!).never - DeliveryMailer.welcome.deliver_now + stub_any_instance(Mail::Message) do |instance| + assert_not_called(instance, :deliver!) do + DeliveryMailer.welcome.deliver_now + end + end ensure DeliveryMailer.perform_deliveries = old_perform_deliveries end diff --git a/actionmailer/test/fixtures/async_mailer/welcome.erb b/actionmailer/test/fixtures/async_mailer/welcome.erb deleted file mode 100644 index 01f3f00c63..0000000000 --- a/actionmailer/test/fixtures/async_mailer/welcome.erb +++ /dev/null @@ -1 +0,0 @@ -Welcome
\ No newline at end of file diff --git a/actionmailer/test/fixtures/caching_mailer/_partial.html.erb b/actionmailer/test/fixtures/caching_mailer/_partial.html.erb new file mode 100644 index 0000000000..8e965f52b4 --- /dev/null +++ b/actionmailer/test/fixtures/caching_mailer/_partial.html.erb @@ -0,0 +1,3 @@ +<% cache :caching do %> + Old fragment caching in a partial +<% end %> diff --git a/actionmailer/test/fixtures/caching_mailer/fragment_cache.html.erb b/actionmailer/test/fixtures/caching_mailer/fragment_cache.html.erb new file mode 100644 index 0000000000..90189627da --- /dev/null +++ b/actionmailer/test/fixtures/caching_mailer/fragment_cache.html.erb @@ -0,0 +1,3 @@ +<% cache :caching do %> +"Welcome" +<% end %> diff --git a/actionmailer/test/fixtures/caching_mailer/fragment_cache_in_partials.html.erb b/actionmailer/test/fixtures/caching_mailer/fragment_cache_in_partials.html.erb new file mode 100644 index 0000000000..2957d083e8 --- /dev/null +++ b/actionmailer/test/fixtures/caching_mailer/fragment_cache_in_partials.html.erb @@ -0,0 +1 @@ +<%= render "partial" %> diff --git a/actionmailer/test/fixtures/caching_mailer/fragment_caching_options.html.erb b/actionmailer/test/fixtures/caching_mailer/fragment_caching_options.html.erb new file mode 100644 index 0000000000..0541ac321b --- /dev/null +++ b/actionmailer/test/fixtures/caching_mailer/fragment_caching_options.html.erb @@ -0,0 +1,3 @@ +<%= cache :no_digest, skip_digest: true, expires_in: 0 do %> + No Digest +<% end %> diff --git a/actionmailer/test/fixtures/caching_mailer/multipart_cache.html.erb b/actionmailer/test/fixtures/caching_mailer/multipart_cache.html.erb new file mode 100644 index 0000000000..0d26baa2d7 --- /dev/null +++ b/actionmailer/test/fixtures/caching_mailer/multipart_cache.html.erb @@ -0,0 +1,3 @@ +<% cache :html_caching, skip_digest: true do %> + "Welcome html" +<% end %> diff --git a/actionmailer/test/fixtures/caching_mailer/multipart_cache.text.erb b/actionmailer/test/fixtures/caching_mailer/multipart_cache.text.erb new file mode 100644 index 0000000000..ef97326e03 --- /dev/null +++ b/actionmailer/test/fixtures/caching_mailer/multipart_cache.text.erb @@ -0,0 +1,3 @@ +<% cache :text_caching, skip_digest: true do %> + "Welcome text" +<% end %> diff --git a/actionmailer/test/fixtures/caching_mailer/skip_fragment_cache_digesting.html.erb b/actionmailer/test/fixtures/caching_mailer/skip_fragment_cache_digesting.html.erb new file mode 100644 index 0000000000..0d52429a81 --- /dev/null +++ b/actionmailer/test/fixtures/caching_mailer/skip_fragment_cache_digesting.html.erb @@ -0,0 +1,3 @@ +<%= cache :no_digest, skip_digest: true do %> + No Digest +<% end %> diff --git a/actionmailer/test/i18n_with_controller_test.rb b/actionmailer/test/i18n_with_controller_test.rb index 010e44d045..a87a9c9861 100644 --- a/actionmailer/test/i18n_with_controller_test.rb +++ b/actionmailer/test/i18n_with_controller_test.rb @@ -1,10 +1,10 @@ -require 'abstract_unit' -require 'action_view' -require 'action_controller' +require "abstract_unit" +require "action_view" +require "action_controller" class I18nTestMailer < ActionMailer::Base configure do |c| - c.assets_dir = '' + c.assets_dir = "" end def mail_with_i18n_subject(recipient) @@ -18,14 +18,16 @@ end class TestController < ActionController::Base def send_mail email = I18nTestMailer.mail_with_i18n_subject("test@localhost").deliver_now - render text: "Mail sent - Subject: #{email.subject}" + render plain: "Mail sent - Subject: #{email.subject}" end end class ActionMailerI18nWithControllerTest < ActionDispatch::IntegrationTest Routes = ActionDispatch::Routing::RouteSet.new Routes.draw do - get ':controller(/:action(/:id))' + ActiveSupport::Deprecation.silence do + get ":controller(/:action(/:id))" + end end class RoutedRackApp @@ -52,19 +54,24 @@ class ActionMailerI18nWithControllerTest < ActionDispatch::IntegrationTest end def test_send_mail - Mail::SMTP.any_instance.expects(:deliver!) - with_translation 'de', email_subject: '[Anmeldung] Willkommen' do - get '/test/send_mail' - assert_equal "Mail sent - Subject: [Anmeldung] Willkommen", @response.body + stub_any_instance(Mail::SMTP, instance: Mail::SMTP.new({})) do |instance| + assert_called(instance, :deliver!) do + with_translation "de", email_subject: "[Anmeldung] Willkommen" do + ActiveSupport::Deprecation.silence do + get "/test/send_mail" + end + assert_equal "Mail sent - Subject: [Anmeldung] Willkommen", @response.body + end + end end end - protected + private - def with_translation(locale, data) - I18n.backend.store_translations(locale, data) - yield - ensure - I18n.backend.reload! - end + def with_translation(locale, data) + I18n.backend.store_translations(locale, data) + yield + ensure + I18n.backend.reload! + end end diff --git a/actionmailer/test/log_subscriber_test.rb b/actionmailer/test/log_subscriber_test.rb index 3871b16840..d864c3acca 100644 --- a/actionmailer/test/log_subscriber_test.rb +++ b/actionmailer/test/log_subscriber_test.rb @@ -1,7 +1,7 @@ -require 'abstract_unit' -require 'mailers/base_mailer' -require 'active_support/log_subscriber/test_helper' -require 'action_mailer/log_subscriber' +require "abstract_unit" +require "mailers/base_mailer" +require "active_support/log_subscriber/test_helper" +require "action_mailer/log_subscriber" class AMLogSubscriberTest < ActionMailer::TestCase include ActiveSupport::LogSubscriber::TestHelper diff --git a/actionmailer/test/mail_helper_test.rb b/actionmailer/test/mail_helper_test.rb index ff6b25b0c7..a2e04b5f48 100644 --- a/actionmailer/test/mail_helper_test.rb +++ b/actionmailer/test/mail_helper_test.rb @@ -1,4 +1,4 @@ -require 'abstract_unit' +require "abstract_unit" class HelperMailer < ActionMailer::Base def use_mail_helper @@ -65,12 +65,12 @@ The second end end - protected + private - def mail_with_defaults(&block) - mail(to: "test@localhost", from: "tester@example.com", - subject: "using helpers", &block) - end + def mail_with_defaults(&block) + mail(to: "test@localhost", from: "tester@example.com", + subject: "using helpers", &block) + end end class MailerHelperTest < ActionMailer::TestCase diff --git a/actionmailer/test/mail_layout_test.rb b/actionmailer/test/mail_layout_test.rb index 166dd096d4..73059d782d 100644 --- a/actionmailer/test/mail_layout_test.rb +++ b/actionmailer/test/mail_layout_test.rb @@ -1,7 +1,7 @@ -require 'abstract_unit' +require "abstract_unit" class AutoLayoutMailer < ActionMailer::Base - default to: 'test@localhost', + default to: "test@localhost", subject: "You have a mail", from: "tester@example.com" @@ -11,7 +11,7 @@ class AutoLayoutMailer < ActionMailer::Base def spam @world = "Earth" - mail(body: render(inline: "Hello, <%= @world %>", layout: 'spam')) + mail(body: render(inline: "Hello, <%= @world %>", layout: "spam")) end def nolayout @@ -28,9 +28,9 @@ class AutoLayoutMailer < ActionMailer::Base end class ExplicitLayoutMailer < ActionMailer::Base - layout 'spam', except: [:logout] + layout "spam", except: [:logout] - default to: 'test@localhost', + default to: "test@localhost", subject: "You have a mail", from: "tester@example.com" @@ -54,10 +54,10 @@ class LayoutMailerTest < ActiveSupport::TestCase assert_equal "multipart/alternative", mail.mime_type assert_equal 2, mail.parts.size - assert_equal 'text/plain', mail.parts.first.mime_type + assert_equal "text/plain", mail.parts.first.mime_type assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s - assert_equal 'text/html', mail.parts.last.mime_type + assert_equal "text/html", mail.parts.last.mime_type assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s end @@ -66,10 +66,10 @@ class LayoutMailerTest < ActiveSupport::TestCase assert_equal "multipart/mixed", mail.mime_type assert_equal 2, mail.parts.size - assert_equal 'text/plain', mail.parts.first.mime_type + assert_equal "text/plain", mail.parts.first.mime_type assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s - assert_equal 'text/html', mail.parts.last.mime_type + assert_equal "text/html", mail.parts.last.mime_type assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s end diff --git a/actionmailer/test/mailers/asset_mailer.rb b/actionmailer/test/mailers/asset_mailer.rb index f54a50d00d..1cf15128d2 100644 --- a/actionmailer/test/mailers/asset_mailer.rb +++ b/actionmailer/test/mailers/asset_mailer.rb @@ -2,6 +2,6 @@ class AssetMailer < ActionMailer::Base self.mailer_name = "asset_mailer" def welcome - mail + mail end end diff --git a/actionmailer/test/mailers/base_mailer.rb b/actionmailer/test/mailers/base_mailer.rb index bd991e209e..2a8884959c 100644 --- a/actionmailer/test/mailers/base_mailer.rb +++ b/actionmailer/test/mailers/base_mailer.rb @@ -1,13 +1,13 @@ class BaseMailer < ActionMailer::Base self.mailer_name = "base_mailer" - default to: 'system@test.lindsaar.net', - from: 'jose@test.plataformatec.com', - reply_to: 'mikel@test.lindsaar.net' + default to: "system@test.lindsaar.net", + from: "jose@test.plataformatec.com", + reply_to: "mikel@test.lindsaar.net" def welcome(hash = {}) - headers['X-SPAM'] = "Not SPAM" - mail({subject: "The first email on new API!"}.merge!(hash)) + headers["X-SPAM"] = "Not SPAM" + mail({ subject: "The first email on new API!" }.merge!(hash)) end def welcome_with_headers(hash = {}) @@ -28,30 +28,30 @@ class BaseMailer < ActionMailer::Base end def inline_attachment - attachments.inline['logo.png'] = "\312\213\254\232" + attachments.inline["logo.png"] = "\312\213\254\232" mail end def attachment_with_content(hash = {}) - attachments['invoice.pdf'] = 'This is test File content' + attachments["invoice.pdf"] = "This is test File content" mail(hash) end def attachment_with_hash - attachments['invoice.jpg'] = { data: ::Base64.encode64("\312\213\254\232)b"), + attachments["invoice.jpg"] = { data: ::Base64.encode64("\312\213\254\232)b"), mime_type: "image/x-jpg", transfer_encoding: "base64" } mail end def attachment_with_hash_default_encoding - attachments['invoice.jpg'] = { data: "\312\213\254\232)b", + attachments["invoice.jpg"] = { data: "\312\213\254\232)b", mime_type: "image/x-jpg" } mail end def implicit_multipart(hash = {}) - attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) + attachments["invoice.pdf"] = "This is test File content" if hash.delete(:attachments) mail(hash) end @@ -60,10 +60,10 @@ class BaseMailer < ActionMailer::Base end def explicit_multipart(hash = {}) - attachments['invoice.pdf'] = 'This is test File content' if hash.delete(:attachments) + attachments["invoice.pdf"] = "This is test File content" if hash.delete(:attachments) mail(hash) do |format| - format.text { render text: "TEXT Explicit Multipart" } - format.html { render text: "HTML Explicit Multipart" } + format.text { render plain: "TEXT Explicit Multipart" } + format.html { render plain: "HTML Explicit Multipart" } end end @@ -76,14 +76,20 @@ class BaseMailer < ActionMailer::Base def explicit_multipart_with_any(hash = {}) mail(hash) do |format| - format.any(:text, :html){ render text: "Format with any!" } + format.any(:text, :html) { render plain: "Format with any!" } + end + end + + def explicit_without_specifying_format_with_any(hash = {}) + mail(hash) do |format| + format.any end end def explicit_multipart_with_options(include_html = false) mail do |format| - format.text(content_transfer_encoding: "base64"){ render "welcome" } - format.html{ render "welcome" } if include_html + format.text(content_transfer_encoding: "base64") { render "welcome" } + format.html { render "welcome" } if include_html end end @@ -94,18 +100,18 @@ class BaseMailer < ActionMailer::Base end end - def implicit_different_template(template_name='') + def implicit_different_template(template_name = "") mail(template_name: template_name) end - def explicit_different_template(template_name='') + def explicit_different_template(template_name = "") mail do |format| format.text { render template: "#{mailer_name}/#{template_name}" } format.html { render template: "#{mailer_name}/#{template_name}" } end end - def different_layout(layout_name='') + def different_layout(layout_name = "") mail do |format| format.text { render layout: layout_name } format.html { render layout: layout_name } @@ -125,6 +131,6 @@ class BaseMailer < ActionMailer::Base end def with_subject_interpolations - mail(subject: default_i18n_subject(rapper_or_impersonator: 'Slim Shady'), body: '') + mail(subject: default_i18n_subject(rapper_or_impersonator: "Slim Shady"), body: "") end end diff --git a/actionmailer/test/mailers/caching_mailer.rb b/actionmailer/test/mailers/caching_mailer.rb new file mode 100644 index 0000000000..92d3cff7c9 --- /dev/null +++ b/actionmailer/test/mailers/caching_mailer.rb @@ -0,0 +1,23 @@ +class CachingMailer < ActionMailer::Base + self.mailer_name = "caching_mailer" + + def fragment_cache + mail(subject: "welcome", template_name: "fragment_cache") + end + + def fragment_cache_in_partials + mail(subject: "welcome", template_name: "fragment_cache_in_partials") + end + + def skip_fragment_cache_digesting + mail(subject: "welcome", template_name: "skip_fragment_cache_digesting") + end + + def fragment_caching_options + mail(subject: "welcome", template_name: "fragment_caching_options") + end + + def multipart_cache + mail(subject: "welcome", template_name: "multipart_cache") + end +end diff --git a/actionmailer/test/mailers/delayed_mailer.rb b/actionmailer/test/mailers/delayed_mailer.rb index 62d4baa434..cae4ec2f48 100644 --- a/actionmailer/test/mailers/delayed_mailer.rb +++ b/actionmailer/test/mailers/delayed_mailer.rb @@ -1,6 +1,26 @@ +require "active_job/arguments" + +class DelayedMailerError < StandardError; end + class DelayedMailer < ActionMailer::Base + cattr_accessor :last_error + cattr_accessor :last_rescue_from_instance + + rescue_from DelayedMailerError do |error| + @@last_error = error + @@last_rescue_from_instance = self + end + + rescue_from ActiveJob::DeserializationError do |error| + @@last_error = error + @@last_rescue_from_instance = self + end def test_message(*) - mail(from: 'test-sender@test.com', to: 'test-receiver@test.com', subject: 'Test Subject', body: 'Test Body') + mail(from: "test-sender@test.com", to: "test-receiver@test.com", subject: "Test Subject", body: "Test Body") + end + + def test_raise(klass_name) + raise klass_name.constantize, "boom" end end diff --git a/actionmailer/test/mailers/proc_mailer.rb b/actionmailer/test/mailers/proc_mailer.rb index 7e189d861f..2487db9eb9 100644 --- a/actionmailer/test/mailers/proc_mailer.rb +++ b/actionmailer/test/mailers/proc_mailer.rb @@ -1,8 +1,8 @@ class ProcMailer < ActionMailer::Base - default to: 'system@test.lindsaar.net', - 'X-Proc-Method' => Proc.new { Time.now.to_i.to_s }, + default to: "system@test.lindsaar.net", + "X-Proc-Method" => Proc.new { Time.now.to_i.to_s }, subject: Proc.new { give_a_greeting }, - 'x-has-to-proc' => :symbol + "x-has-to-proc" => :symbol def welcome mail @@ -10,8 +10,7 @@ class ProcMailer < ActionMailer::Base private - def give_a_greeting - "Thanks for signing up this afternoon" - end - + def give_a_greeting + "Thanks for signing up this afternoon" + end end diff --git a/actionmailer/test/message_delivery_test.rb b/actionmailer/test/message_delivery_test.rb index 862ce26187..a79d77e1e5 100644 --- a/actionmailer/test/message_delivery_test.rb +++ b/actionmailer/test/message_delivery_test.rb @@ -1,7 +1,6 @@ -require 'abstract_unit' -require 'active_job' -require 'minitest/mock' -require 'mailers/delayed_mailer' +require "abstract_unit" +require "active_job" +require "mailers/delayed_mailer" class MessageDeliveryTest < ActiveSupport::TestCase include ActiveJob::TestHelper @@ -13,39 +12,46 @@ class MessageDeliveryTest < ActiveSupport::TestCase ActionMailer::Base.deliver_later_queue_name = :test_queue ActionMailer::Base.delivery_method = :test ActiveJob::Base.logger = Logger.new(nil) - @mail = DelayedMailer.test_message(1, 2, 3) ActionMailer::Base.deliveries.clear ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = true ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true + + DelayedMailer.last_error = nil + DelayedMailer.last_rescue_from_instance = nil + + @mail = DelayedMailer.test_message(1, 2, 3) end teardown do ActiveJob::Base.logger = @previous_logger ActionMailer::Base.delivery_method = @previous_delivery_method ActionMailer::Base.deliver_later_queue_name = @previous_deliver_later_queue_name + + DelayedMailer.last_error = nil + DelayedMailer.last_rescue_from_instance = nil end - test 'should have a message' do + test "should have a message" do assert @mail.message end - test 'its message should be a Mail::Message' do + test "its message should be a Mail::Message" do assert_equal Mail::Message , @mail.message.class end - test 'should respond to .deliver_later' do + test "should respond to .deliver_later" do assert_respond_to @mail, :deliver_later end - test 'should respond to .deliver_later!' do + test "should respond to .deliver_later!" do assert_respond_to @mail, :deliver_later! end - test 'should respond to .deliver_now' do + test "should respond to .deliver_now" do assert_respond_to @mail, :deliver_now end - test 'should respond to .deliver_now!' do + test "should respond to .deliver_now!" do assert_respond_to @mail, :deliver_now! end @@ -56,42 +62,92 @@ class MessageDeliveryTest < ActiveSupport::TestCase ActionMailer::Base.deliveries.clear end - test 'should enqueue the email with :deliver_now delivery method' do - assert_performed_with(job: ActionMailer::DeliveryJob, args: ['DelayedMailer', 'test_message', 'deliver_now', 1, 2, 3]) do + test "should enqueue the email with :deliver_now delivery method" do + assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", 1, 2, 3]) do @mail.deliver_later end end - test 'should enqueue the email with :deliver_now! delivery method' do - assert_performed_with(job: ActionMailer::DeliveryJob, args: ['DelayedMailer', 'test_message', 'deliver_now!', 1, 2, 3]) do + test "should enqueue the email with :deliver_now! delivery method" do + assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now!", 1, 2, 3]) do @mail.deliver_later! end end - test 'should enqueue a delivery with a delay' do + test "should enqueue a delivery with a delay" do travel_to Time.new(2004, 11, 24, 01, 04, 44) do - assert_performed_with(job: ActionMailer::DeliveryJob, at: Time.current.to_f+600.seconds, args: ['DelayedMailer', 'test_message', 'deliver_now', 1, 2, 3]) do + assert_performed_with(job: ActionMailer::DeliveryJob, at: Time.current.to_f + 600.seconds, args: ["DelayedMailer", "test_message", "deliver_now", 1, 2, 3]) do @mail.deliver_later wait: 600.seconds end end end - test 'should enqueue a delivery at a specific time' do + test "should enqueue a delivery at a specific time" do later_time = Time.now.to_f + 3600 - assert_performed_with(job: ActionMailer::DeliveryJob, at: later_time, args: ['DelayedMailer', 'test_message', 'deliver_now', 1, 2, 3]) do + assert_performed_with(job: ActionMailer::DeliveryJob, at: later_time, args: ["DelayedMailer", "test_message", "deliver_now", 1, 2, 3]) do @mail.deliver_later wait_until: later_time end end - test 'should enqueue the job on the correct queue' do - assert_performed_with(job: ActionMailer::DeliveryJob, args: ['DelayedMailer', 'test_message', 'deliver_now', 1, 2, 3], queue: "test_queue") do + test "should enqueue the job on the correct queue" do + assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", 1, 2, 3], queue: "test_queue") do @mail.deliver_later end end - test 'can override the queue when enqueuing mail' do - assert_performed_with(job: ActionMailer::DeliveryJob, args: ['DelayedMailer', 'test_message', 'deliver_now', 1, 2, 3], queue: "another_queue") do + test "can override the queue when enqueuing mail" do + assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", 1, 2, 3], queue: "another_queue") do @mail.deliver_later(queue: :another_queue) end end + + test "deliver_later after accessing the message is disallowed" do + @mail.message # Load the message, which calls the mailer method. + + assert_raise RuntimeError do + @mail.deliver_later + end + end + + test "job delegates error handling to mailer" do + # Superclass not rescued by mailer's rescue_from RuntimeError + message = DelayedMailer.test_raise("StandardError") + assert_raise(StandardError) { message.deliver_later } + assert_nil DelayedMailer.last_error + assert_nil DelayedMailer.last_rescue_from_instance + + # Rescued by mailer's rescue_from RuntimeError + message = DelayedMailer.test_raise("DelayedMailerError") + assert_nothing_raised { message.deliver_later } + assert_equal "boom", DelayedMailer.last_error.message + assert_kind_of DelayedMailer, DelayedMailer.last_rescue_from_instance + end + + class DeserializationErrorFixture + include GlobalID::Identification + + def self.find(id) + raise "boom, missing find" + end + + attr_reader :id + def initialize(id = 1) + @id = id + end + + def to_global_id(options = {}) + super app: "foo" + end + end + + test "job delegates deserialization errors to mailer class" do + # Inject an argument that can't be deserialized. + message = DelayedMailer.test_message(DeserializationErrorFixture.new) + + # DeserializationError is raised, rescued, and delegated to the handler + # on the mailer class. + assert_nothing_raised { message.deliver_later } + assert_equal DelayedMailer, DelayedMailer.last_rescue_from_instance + assert_equal "Error while trying to deserialize arguments: boom, missing find", DelayedMailer.last_error.message + end end diff --git a/actionmailer/test/test_case_test.rb b/actionmailer/test/test_case_test.rb index 86fd37bea6..193d107b0a 100644 --- a/actionmailer/test/test_case_test.rb +++ b/actionmailer/test/test_case_test.rb @@ -1,8 +1,46 @@ -require 'abstract_unit' +require "abstract_unit" class TestTestMailer < ActionMailer::Base end +class ClearTestDeliveriesMixinTest < ActiveSupport::TestCase + include ActionMailer::TestCase::ClearTestDeliveries + + def before_setup + ActionMailer::Base.delivery_method, @original_delivery_method = :test, ActionMailer::Base.delivery_method + ActionMailer::Base.deliveries << "better clear me, setup" + super + end + + def after_teardown + super + assert_equal [], ActionMailer::Base.deliveries + ActionMailer::Base.delivery_method = @original_delivery_method + end + + def test_deliveries_are_cleared_on_setup_and_teardown + assert_equal [], ActionMailer::Base.deliveries + ActionMailer::Base.deliveries << "better clear me, teardown" + end +end + +class MailerDeliveriesClearingTest < ActionMailer::TestCase + def before_setup + ActionMailer::Base.deliveries << "better clear me, setup" + super + end + + def after_teardown + super + assert_equal [], ActionMailer::Base.deliveries + end + + def test_deliveries_are_cleared_on_setup_and_teardown + assert_equal [], ActionMailer::Base.deliveries + ActionMailer::Base.deliveries << "better clear me, teardown" + end +end + class CrazyNameMailerTest < ActionMailer::TestCase tests TestTestMailer @@ -20,7 +58,7 @@ class CrazySymbolNameMailerTest < ActionMailer::TestCase end class CrazyStringNameMailerTest < ActionMailer::TestCase - tests 'test_test_mailer' + tests "test_test_mailer" def test_set_mailer_class_manual_using_string assert_equal TestTestMailer, self.class.mailer_class diff --git a/actionmailer/test/test_helper_test.rb b/actionmailer/test/test_helper_test.rb index 0a4bc75d3e..31ac5a5211 100644 --- a/actionmailer/test/test_helper_test.rb +++ b/actionmailer/test/test_helper_test.rb @@ -1,5 +1,5 @@ -require 'abstract_unit' -require 'active_support/testing/stream' +require "abstract_unit" +require "active_support/testing/stream" class TestHelperMailer < ActionMailer::Base def test @@ -40,11 +40,11 @@ class TestHelperMailerTest < ActionMailer::TestCase end def test_encode - assert_equal '=?UTF-8?Q?This_is_=E3=81=82_string?=', encode('This is あ string') + assert_equal "=?UTF-8?Q?This_is_=E3=81=82_string?=", encode("This is あ string") end def test_read_fixture - assert_equal ['Welcome!'], read_fixture('welcome') + assert_equal ["Welcome!"], read_fixture("welcome") end def test_assert_emails @@ -198,6 +198,6 @@ class AnotherTestHelperMailerTest < ActionMailer::TestCase def test_setup_shouldnt_conflict_with_mailer_setup assert_kind_of Mail::Message, @expected - assert_equal 'a value', @test_var + assert_equal "a value", @test_var end end diff --git a/actionmailer/test/url_test.rb b/actionmailer/test/url_test.rb index 7928fe9542..6dbfb3a1ff 100644 --- a/actionmailer/test/url_test.rb +++ b/actionmailer/test/url_test.rb @@ -1,5 +1,5 @@ -require 'abstract_unit' -require 'action_controller' +require "abstract_unit" +require "action_controller" class WelcomeController < ActionController::Base end @@ -11,10 +11,10 @@ class ActionMailer::Base end class UrlTestMailer < ActionMailer::Base - default_url_options[:host] = 'www.basecamphq.com' + default_url_options[:host] = "www.basecamphq.com" configure do |c| - c.assets_dir = '' # To get the tests to pass + c.assets_dir = "" # To get the tests to pass end def signed_up_with_url(recipient) @@ -27,14 +27,14 @@ class UrlTestMailer < ActionMailer::Base def exercise_url_for(options) @options = options @url = url_for(@options) - mail(from: 'from@example.com', to: 'to@example.com', subject: 'subject') + mail(from: "from@example.com", to: "to@example.com", subject: "subject") end end class ActionMailerUrlTest < ActionMailer::TestCase class DummyModel def self.model_name - OpenStruct.new(route_key: 'dummy_model') + OpenStruct.new(route_key: "dummy_model") end def persisted? @@ -50,11 +50,11 @@ class ActionMailerUrlTest < ActionMailer::TestCase end end - def encode( text, charset="UTF-8" ) - quoted_printable( text, charset ) + def encode(text, charset = "UTF-8") + quoted_printable(text, charset) end - def new_mail( charset="UTF-8" ) + def new_mail(charset = "UTF-8") mail = Mail.new mail.mime_version = "1.0" if charset @@ -64,7 +64,7 @@ class ActionMailerUrlTest < ActionMailer::TestCase end def assert_url_for(expected, options, relative = false) - expected = "http://www.basecamphq.com#{expected}" if expected.start_with?('/') && !relative + expected = "http://www.basecamphq.com#{expected}" if expected.start_with?("/") && !relative urls = UrlTestMailer.exercise_url_for(options).body.to_s.chomp.split assert_equal expected, urls.first @@ -72,44 +72,48 @@ class ActionMailerUrlTest < ActionMailer::TestCase end def setup - @recipient = 'test@localhost' + @recipient = "test@localhost" end def test_url_for UrlTestMailer.delivery_method = :test AppRoutes.draw do - get ':controller(/:action(/:id))' - get '/welcome' => 'foo#bar', as: 'welcome' - get '/dummy_model' => 'foo#baz', as: 'dummy_model' + ActiveSupport::Deprecation.silence do + get ":controller(/:action(/:id))" + get "/welcome" => "foo#bar", as: "welcome" + get "/dummy_model" => "foo#baz", as: "dummy_model" + end end # string - assert_url_for 'http://foo/', 'http://foo/' + assert_url_for "http://foo/", "http://foo/" # symbol - assert_url_for '/welcome', :welcome + assert_url_for "/welcome", :welcome # hash - assert_url_for '/a/b/c', controller: 'a', action: 'b', id: 'c' - assert_url_for '/a/b/c', {controller: 'a', action: 'b', id: 'c', only_path: true}, true + assert_url_for "/a/b/c", controller: "a", action: "b", id: "c" + assert_url_for "/a/b/c", { controller: "a", action: "b", id: "c", only_path: true }, true # model - assert_url_for '/dummy_model', DummyModel.new + assert_url_for "/dummy_model", DummyModel.new # class - assert_url_for '/dummy_model', DummyModel + assert_url_for "/dummy_model", DummyModel # array - assert_url_for '/dummy_model' , [DummyModel] + assert_url_for "/dummy_model" , [DummyModel] end def test_signed_up_with_url UrlTestMailer.delivery_method = :test AppRoutes.draw do - get ':controller(/:action(/:id))' - get '/welcome' => "foo#bar", as: "welcome" + ActiveSupport::Deprecation.silence do + get ":controller(/:action(/:id))" + get "/welcome" => "foo#bar", as: "welcome" + end end expected = new_mail @@ -124,15 +128,15 @@ class ActionMailerUrlTest < ActionMailer::TestCase assert_nothing_raised { created = UrlTestMailer.signed_up_with_url(@recipient) } assert_not_nil created - expected.message_id = '<123@456>' - created.message_id = '<123@456>' + expected.message_id = "<123@456>" + created.message_id = "<123@456>" assert_dom_equal expected.encoded, created.encoded assert_nothing_raised { UrlTestMailer.signed_up_with_url(@recipient).deliver_now } assert_not_nil ActionMailer::Base.deliveries.first delivered = ActionMailer::Base.deliveries.first - delivered.message_id = '<123@456>' + delivered.message_id = "<123@456>" assert_dom_equal expected.encoded, delivered.encoded end end |