diff options
Diffstat (limited to 'actionmailer')
-rw-r--r-- | actionmailer/CHANGELOG.md | 6 | ||||
-rw-r--r-- | actionmailer/actionmailer.gemspec | 2 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer.rb | 1 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 2 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/delivery_job.rb | 13 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/mail_delivery_job.rb | 38 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/message_delivery.rb | 10 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/parameterized.rb | 18 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/test_helper.rb | 4 | ||||
-rw-r--r-- | actionmailer/test/base_test.rb | 34 | ||||
-rw-r--r-- | actionmailer/test/legacy_delivery_job_test.rb | 86 | ||||
-rw-r--r-- | actionmailer/test/message_delivery_test.rb | 16 | ||||
-rw-r--r-- | actionmailer/test/parameterized_test.rb | 11 | ||||
-rw-r--r-- | actionmailer/test/test_helper_test.rb | 2 |
14 files changed, 199 insertions, 44 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index 9d2a1928c5..5f3fc44e6e 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,4 +1,4 @@ -* Deliver parameterized mail with `ActionMailer::DeliveryJob` and remove `ActionMailer::Parameterized::DeliveryJob`. +* Add `MailDeliveryJob` for delivering both regular and parameterized mail. Deprecate using `DeliveryJob` and `Parameterized::DeliveryJob`. *Gannon McGibbon* @@ -57,9 +57,9 @@ *Claudio Ortolina*, *Kota Miyake* -* Rails 6 requires Ruby 2.4.1 or newer. +* Rails 6 requires Ruby 2.5.0 or newer. - *Jeremy Daer* + *Jeremy Daer*, *Kasper Timm Hansen* Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/actionmailer/CHANGELOG.md) for previous changes. diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index 6f8d6d0699..a6c482f1a0 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.summary = "Email composition, delivery, and receiving framework (part of Rails)." s.description = "Email on Rails. Compose, deliver, receive, and test emails using the familiar controller/view pattern. First-class support for multipart email and attachments." - s.required_ruby_version = ">= 2.4.1" + s.required_ruby_version = ">= 2.5.0" s.license = "MIT" diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 69eae65d60..48f16180be 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -52,6 +52,7 @@ module ActionMailer autoload :TestHelper autoload :MessageDelivery autoload :DeliveryJob + autoload :MailDeliveryJob def self.eager_load! super diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 5d41e5ff2a..8ddc90b9df 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -461,7 +461,7 @@ module ActionMailer helper ActionMailer::MailHelper - class_attribute :delivery_job, default: ::ActionMailer::DeliveryJob + class_attribute :delivery_job, default: ::ActionMailer::MailDeliveryJob class_attribute :default_params, default: { mime_version: "1.0", charset: "UTF-8", diff --git a/actionmailer/lib/action_mailer/delivery_job.rb b/actionmailer/lib/action_mailer/delivery_job.rb index 8af2097819..f228006920 100644 --- a/actionmailer/lib/action_mailer/delivery_job.rb +++ b/actionmailer/lib/action_mailer/delivery_job.rb @@ -12,9 +12,16 @@ module ActionMailer rescue_from StandardError, with: :handle_exception_with_mailer_class - def perform(mailer, mail_method, delivery_method, params, *args) #:nodoc: - mailer_class = params ? mailer.constantize.with(params) : mailer.constantize - mailer_class.public_send(mail_method, *args).send(delivery_method) + before_perform do + ActiveSupport::Deprecation.warn <<~MSG.squish + Sending mail with DeliveryJob and Parameterized::DeliveryJob + is deprecated and will be removed in Rails 6.1. + Please use MailDeliveryJob instead. + MSG + end + + def perform(mailer, mail_method, delivery_method, *args) #:nodoc: + mailer.constantize.public_send(mail_method, *args).send(delivery_method) end private diff --git a/actionmailer/lib/action_mailer/mail_delivery_job.rb b/actionmailer/lib/action_mailer/mail_delivery_job.rb new file mode 100644 index 0000000000..93778edfce --- /dev/null +++ b/actionmailer/lib/action_mailer/mail_delivery_job.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require "active_job" + +module ActionMailer + # The <tt>ActionMailer::NewDeliveryJob</tt> class is used when you + # want to send emails outside of the request-response cycle. It supports + # sending either parameterized or normal mail. + # + # Exceptions are rescued and handled by the mailer class. + class MailDeliveryJob < ActiveJob::Base # :nodoc: + queue_as { ActionMailer::Base.deliver_later_queue_name } + + rescue_from StandardError, with: :handle_exception_with_mailer_class + + def perform(mailer, mail_method, delivery_method, args:, params: nil) #:nodoc: + mailer_class = params ? mailer.constantize.with(params) : mailer.constantize + mailer_class.public_send(mail_method, *args).send(delivery_method) + end + + private + # "Deserialize" the mailer class name by hand in case another argument + # (like a Global ID reference) raised DeserializationError. + def mailer_class + if mailer = Array(@serialized_arguments).first || Array(arguments).first + mailer.constantize + end + end + + def handle_exception_with_mailer_class(exception) + if klass = mailer_class + klass.handle_exception exception + else + raise exception + end + end + end +end diff --git a/actionmailer/lib/action_mailer/message_delivery.rb b/actionmailer/lib/action_mailer/message_delivery.rb index 6b02076422..1e5cab6d47 100644 --- a/actionmailer/lib/action_mailer/message_delivery.rb +++ b/actionmailer/lib/action_mailer/message_delivery.rb @@ -135,10 +135,18 @@ module ActionMailer "#deliver_later, 2. only touch the message *within your mailer " \ "method*, or 3. use a custom Active Job instead of #deliver_later." else - args = @mailer_class.name, @action.to_s, delivery_method.to_s, nil, *@args job = @mailer_class.delivery_job + args = arguments_for(job, delivery_method) job.set(options).perform_later(*args) end end + + def arguments_for(delivery_job, delivery_method) + if delivery_job <= MailDeliveryJob + [@mailer_class.name, @action.to_s, delivery_method.to_s, args: @args] + else + [@mailer_class.name, @action.to_s, delivery_method.to_s, *@args] + end + end end end diff --git a/actionmailer/lib/action_mailer/parameterized.rb b/actionmailer/lib/action_mailer/parameterized.rb index 0b0afd6ad4..999435919e 100644 --- a/actionmailer/lib/action_mailer/parameterized.rb +++ b/actionmailer/lib/action_mailer/parameterized.rb @@ -121,6 +121,12 @@ module ActionMailer end end + class DeliveryJob < ActionMailer::DeliveryJob # :nodoc: + def perform(mailer, mail_method, delivery_method, params, *args) + mailer.constantize.with(params).public_send(mail_method, *args).send(delivery_method) + end + end + class MessageDelivery < ActionMailer::MessageDelivery # :nodoc: def initialize(mailer_class, action, params, *args) super(mailer_class, action, *args) @@ -139,11 +145,19 @@ module ActionMailer if processed? super else - args = @mailer_class.name, @action.to_s, delivery_method.to_s, @params, *@args - job = @mailer_class.delivery_job + job = @mailer_class.delivery_job + args = arguments_for(job, delivery_method) job.set(options).perform_later(*args) end end + + def arguments_for(delivery_job, delivery_method) + if delivery_job <= MailDeliveryJob + [@mailer_class.name, @action.to_s, delivery_method.to_s, params: @params, args: @args] + else + [@mailer_class.name, @action.to_s, delivery_method.to_s, @params, *@args] + end + end end end end diff --git a/actionmailer/lib/action_mailer/test_helper.rb b/actionmailer/lib/action_mailer/test_helper.rb index 3eb61c2363..e222301dff 100644 --- a/actionmailer/lib/action_mailer/test_helper.rb +++ b/actionmailer/lib/action_mailer/test_helper.rb @@ -125,9 +125,9 @@ module ActionMailer # end def assert_enqueued_email_with(mailer, method, args: nil, queue: "mailers", &block) args = if args.is_a?(Hash) - [mailer.to_s, method.to_s, "deliver_now", args] + [mailer.to_s, method.to_s, "deliver_now", params: args, args: []] else - [mailer.to_s, method.to_s, "deliver_now", nil, *args] + [mailer.to_s, method.to_s, "deliver_now", args: Array(args)] end assert_enqueued_with(job: mailer.delivery_job, args: args, queue: queue, &block) end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index 86c0172772..d0c4f189fd 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -90,18 +90,18 @@ class BaseTest < ActiveSupport::TestCase 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" } + "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("<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" } + "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("<1234@mikel.me.com>", mail["In-Reply-To"].decoded) end # Attachments @@ -897,22 +897,20 @@ class BaseTest < ActiveSupport::TestCase end test "notification for process" do - begin - events = [] - ActiveSupport::Notifications.subscribe("process.action_mailer") do |*args| - events << ActiveSupport::Notifications::Event.new(*args) - end + events = [] + ActiveSupport::Notifications.subscribe("process.action_mailer") do |*args| + events << ActiveSupport::Notifications::Event.new(*args) + end - BaseMailer.welcome(body: "Hello there").deliver_now + BaseMailer.welcome(body: "Hello there").deliver_now - assert_equal 1, events.length - assert_equal "process.action_mailer", events[0].name - assert_equal "BaseMailer", events[0].payload[:mailer] - assert_equal :welcome, events[0].payload[:action] - assert_equal [{ body: "Hello there" }], events[0].payload[:args] - ensure - ActiveSupport::Notifications.unsubscribe "process.action_mailer" - end + assert_equal 1, events.length + assert_equal "process.action_mailer", events[0].name + assert_equal "BaseMailer", events[0].payload[:mailer] + assert_equal :welcome, events[0].payload[:action] + assert_equal [{ body: "Hello there" }], events[0].payload[:args] + ensure + ActiveSupport::Notifications.unsubscribe "process.action_mailer" end private diff --git a/actionmailer/test/legacy_delivery_job_test.rb b/actionmailer/test/legacy_delivery_job_test.rb new file mode 100644 index 0000000000..112c842beb --- /dev/null +++ b/actionmailer/test/legacy_delivery_job_test.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +require "abstract_unit" +require "active_job" +require "mailers/params_mailer" +require "mailers/delayed_mailer" + +class LegacyDeliveryJobTest < ActiveSupport::TestCase + include ActiveJob::TestHelper + + class LegacyDeliveryJob < ActionMailer::DeliveryJob + end + + class LegacyParmeterizedDeliveryJob < ActionMailer::Parameterized::DeliveryJob + end + + setup do + @previous_logger = ActiveJob::Base.logger + ActiveJob::Base.logger = Logger.new(nil) + + @previous_delivery_method = ActionMailer::Base.delivery_method + ActionMailer::Base.delivery_method = :test + + @previous_deliver_later_queue_name = ActionMailer::Base.deliver_later_queue_name + ActionMailer::Base.deliver_later_queue_name = :test_queue + end + + teardown do + ActiveJob::Base.logger = @previous_logger + ParamsMailer.deliveries.clear + + ActionMailer::Base.delivery_method = @previous_delivery_method + ActionMailer::Base.deliver_later_queue_name = @previous_deliver_later_queue_name + end + + test "should send parameterized mail correctly" do + mail = ParamsMailer.with(inviter: "david@basecamp.com", invitee: "jason@basecamp.com").invitation + args = [ + "ParamsMailer", + "invitation", + "deliver_now", + { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" }, + ] + + with_delivery_job(LegacyParmeterizedDeliveryJob) do + assert_deprecated do + assert_performed_with(job: LegacyParmeterizedDeliveryJob, args: args) do + mail.deliver_later + end + end + end + end + + test "should send mail correctly" do + mail = DelayedMailer.test_message(1, 2, 3) + args = [ + "DelayedMailer", + "test_message", + "deliver_now", + 1, + 2, + 3, + ] + + with_delivery_job(LegacyDeliveryJob) do + assert_deprecated do + assert_performed_with(job: LegacyDeliveryJob, args: args) do + mail.deliver_later + end + end + end + end + + private + + def with_delivery_job(job) + old_params_delivery_job = ParamsMailer.delivery_job + old_regular_delivery_job = DelayedMailer.delivery_job + ParamsMailer.delivery_job = job + DelayedMailer.delivery_job = job + yield + ensure + ParamsMailer.delivery_job = old_params_delivery_job + DelayedMailer.delivery_job = old_regular_delivery_job + end +end diff --git a/actionmailer/test/message_delivery_test.rb b/actionmailer/test/message_delivery_test.rb index 8d5c473faf..46260f6414 100644 --- a/actionmailer/test/message_delivery_test.rb +++ b/actionmailer/test/message_delivery_test.rb @@ -64,20 +64,20 @@ class MessageDeliveryTest < ActiveSupport::TestCase end test "should enqueue the email with :deliver_now delivery method" do - assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", nil, 1, 2, 3]) do + assert_performed_with(job: ActionMailer::MailDeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", args: [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!", nil, 1, 2, 3]) do + assert_performed_with(job: ActionMailer::MailDeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now!", args: [1, 2, 3]]) do @mail.deliver_later! end end 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 + 10.minutes, args: ["DelayedMailer", "test_message", "deliver_now", nil, 1, 2, 3]) do + assert_performed_with(job: ActionMailer::MailDeliveryJob, at: Time.current + 10.minutes, args: ["DelayedMailer", "test_message", "deliver_now", args: [1, 2, 3]]) do @mail.deliver_later wait: 10.minutes end end @@ -85,13 +85,13 @@ class MessageDeliveryTest < ActiveSupport::TestCase test "should enqueue a delivery at a specific time" do later_time = Time.current + 1.hour - assert_performed_with(job: ActionMailer::DeliveryJob, at: later_time, args: ["DelayedMailer", "test_message", "deliver_now", nil, 1, 2, 3]) do + assert_performed_with(job: ActionMailer::MailDeliveryJob, at: later_time, args: ["DelayedMailer", "test_message", "deliver_now", args: [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", nil, 1, 2, 3], queue: "test_queue") do + assert_performed_with(job: ActionMailer::MailDeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", args: [1, 2, 3]], queue: "test_queue") do @mail.deliver_later end end @@ -100,17 +100,17 @@ class MessageDeliveryTest < ActiveSupport::TestCase old_delivery_job = DelayedMailer.delivery_job DelayedMailer.delivery_job = DummyJob - assert_performed_with(job: DummyJob, args: ["DelayedMailer", "test_message", "deliver_now", nil, 1, 2, 3]) do + assert_performed_with(job: DummyJob, args: ["DelayedMailer", "test_message", "deliver_now", args: [1, 2, 3]]) do @mail.deliver_later end DelayedMailer.delivery_job = old_delivery_job end - class DummyJob < ActionMailer::DeliveryJob; end + class DummyJob < ActionMailer::MailDeliveryJob; end test "can override the queue when enqueuing mail" do - assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", nil, 1, 2, 3], queue: "another_queue") do + assert_performed_with(job: ActionMailer::MailDeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", args: [1, 2, 3]], queue: "another_queue") do @mail.deliver_later(queue: :another_queue) end end diff --git a/actionmailer/test/parameterized_test.rb b/actionmailer/test/parameterized_test.rb index 3713dc3e3e..7dd6156744 100644 --- a/actionmailer/test/parameterized_test.rb +++ b/actionmailer/test/parameterized_test.rb @@ -7,7 +7,7 @@ require "mailers/params_mailer" class ParameterizedTest < ActiveSupport::TestCase include ActiveJob::TestHelper - class DummyDeliveryJob < ActionMailer::DeliveryJob + class DummyDeliveryJob < ActionMailer::MailDeliveryJob end setup do @@ -42,9 +42,10 @@ class ParameterizedTest < ActiveSupport::TestCase "ParamsMailer", "invitation", "deliver_now", - { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" }, + params: { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" }, + args: [], ] - assert_performed_with(job: ActionMailer::DeliveryJob, args: args) do + assert_performed_with(job: ActionMailer::MailDeliveryJob, args: args) do @mail.deliver_later end end @@ -68,7 +69,8 @@ class ParameterizedTest < ActiveSupport::TestCase "ParamsMailer", "invitation", "deliver_now", - { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" }, + params: { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" }, + args: [], ] with_delivery_job DummyDeliveryJob do @@ -83,6 +85,7 @@ class ParameterizedTest < ActiveSupport::TestCase def with_delivery_job(job) old_delivery_job = ParamsMailer.delivery_job ParamsMailer.delivery_job = job + yield ensure ParamsMailer.delivery_job = old_delivery_job end diff --git a/actionmailer/test/test_helper_test.rb b/actionmailer/test/test_helper_test.rb index 4e21ab0a69..60e2389aa8 100644 --- a/actionmailer/test/test_helper_test.rb +++ b/actionmailer/test/test_helper_test.rb @@ -24,7 +24,7 @@ class TestHelperMailer < ActionMailer::Base end end -class CustomDeliveryJob < ActionMailer::DeliveryJob +class CustomDeliveryJob < ActionMailer::MailDeliveryJob end class CustomDeliveryMailer < TestHelperMailer |