diff options
Diffstat (limited to 'actionmailer')
-rw-r--r-- | actionmailer/CHANGELOG.md | 21 | ||||
-rw-r--r-- | actionmailer/actionmailer.gemspec | 3 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 12 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/delivery_job.rb | 5 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/message_delivery.rb | 2 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/parameterized.rb | 8 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/test_helper.rb | 25 | ||||
-rw-r--r-- | actionmailer/test/base_test.rb | 6 | ||||
-rw-r--r-- | actionmailer/test/mailers/base_mailer.rb | 7 | ||||
-rw-r--r-- | actionmailer/test/message_delivery_test.rb | 14 | ||||
-rw-r--r-- | actionmailer/test/parameterized_test.rb | 38 | ||||
-rw-r--r-- | actionmailer/test/test_helper_test.rb | 47 |
12 files changed, 139 insertions, 49 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index db6fc7ee9c..9d2a1928c5 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,13 +1,16 @@ -* Allow ActionMailer classes to configure the parameterized delivery job - Example: - ``` - class MyMailer < ApplicationMailer - self.parameterized_delivery_job = MyCustomDeliveryJob - ... - end - ``` +* Deliver parameterized mail with `ActionMailer::DeliveryJob` and remove `ActionMailer::Parameterized::DeliveryJob`. + + *Gannon McGibbon* + +* Fix ActionMailer assertions not working when a Mail defines + a custom delivery job class + + *Edouard Chin* + +* Mails with multipart `format` blocks with implicit render now also check for + a template name in options hash instead of only using the action name. - *Luke Pearce* + *Marcus Ilgner* * `ActionDispatch::IntegrationTest` includes `ActionMailer::TestHelper` module by default. diff --git a/actionmailer/actionmailer.gemspec b/actionmailer/actionmailer.gemspec index f2fb160bdd..6f8d6d0699 100644 --- a/actionmailer/actionmailer.gemspec +++ b/actionmailer/actionmailer.gemspec @@ -26,6 +26,9 @@ Gem::Specification.new do |s| "changelog_uri" => "https://github.com/rails/rails/blob/v#{version}/actionmailer/CHANGELOG.md" } + # NOTE: Please read our dependency guidelines before updating versions: + # https://edgeguides.rubyonrails.org/security.html#dependency-management-and-cves + s.add_dependency "actionpack", version s.add_dependency "actionview", version s.add_dependency "activejob", version diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 509d859ac3..5d41e5ff2a 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -462,7 +462,6 @@ module ActionMailer helper ActionMailer::MailHelper class_attribute :delivery_job, default: ::ActionMailer::DeliveryJob - class_attribute :parameterized_delivery_job, default: ::ActionMailer::Parameterized::DeliveryJob class_attribute :default_params, default: { mime_version: "1.0", charset: "UTF-8", @@ -942,9 +941,7 @@ module ActionMailer def collect_responses(headers) if block_given? - collector = ActionMailer::Collector.new(lookup_context) { render(action_name) } - yield(collector) - collector.responses + collect_responses_from_block(headers, &Proc.new) elsif headers[:body] collect_responses_from_text(headers) else @@ -952,6 +949,13 @@ module ActionMailer end end + def collect_responses_from_block(headers) + templates_name = headers[:template_name] || action_name + collector = ActionMailer::Collector.new(lookup_context) { render(templates_name) } + yield(collector) + collector.responses + end + def collect_responses_from_text(headers) [{ body: headers.delete(:body), diff --git a/actionmailer/lib/action_mailer/delivery_job.rb b/actionmailer/lib/action_mailer/delivery_job.rb index 40f26d8ad1..8af2097819 100644 --- a/actionmailer/lib/action_mailer/delivery_job.rb +++ b/actionmailer/lib/action_mailer/delivery_job.rb @@ -12,8 +12,9 @@ module ActionMailer rescue_from StandardError, with: :handle_exception_with_mailer_class - def perform(mailer, mail_method, delivery_method, *args) #:nodoc: - mailer.constantize.public_send(mail_method, *args).send(delivery_method) + 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) end private diff --git a/actionmailer/lib/action_mailer/message_delivery.rb b/actionmailer/lib/action_mailer/message_delivery.rb index a57980c322..6b02076422 100644 --- a/actionmailer/lib/action_mailer/message_delivery.rb +++ b/actionmailer/lib/action_mailer/message_delivery.rb @@ -135,7 +135,7 @@ 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, *@args + args = @mailer_class.name, @action.to_s, delivery_method.to_s, nil, *@args job = @mailer_class.delivery_job job.set(options).perform_later(*args) end diff --git a/actionmailer/lib/action_mailer/parameterized.rb b/actionmailer/lib/action_mailer/parameterized.rb index 0fe417affe..0b0afd6ad4 100644 --- a/actionmailer/lib/action_mailer/parameterized.rb +++ b/actionmailer/lib/action_mailer/parameterized.rb @@ -140,16 +140,10 @@ module ActionMailer super else args = @mailer_class.name, @action.to_s, delivery_method.to_s, @params, *@args - job = @mailer_class.parameterized_delivery_job + job = @mailer_class.delivery_job job.set(options).perform_later(*args) end 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 end end diff --git a/actionmailer/lib/action_mailer/test_helper.rb b/actionmailer/lib/action_mailer/test_helper.rb index a4751916af..3eb61c2363 100644 --- a/actionmailer/lib/action_mailer/test_helper.rb +++ b/actionmailer/lib/action_mailer/test_helper.rb @@ -34,7 +34,7 @@ module ActionMailer def assert_emails(number, &block) if block_given? original_count = ActionMailer::Base.deliveries.size - perform_enqueued_jobs(only: [ActionMailer::DeliveryJob, ActionMailer::Parameterized::DeliveryJob], &block) + perform_enqueued_jobs(only: ->(job) { delivery_job_filter(job) }, &block) new_count = ActionMailer::Base.deliveries.size assert_equal number, new_count - original_count, "#{number} emails expected, but #{new_count - original_count} were sent" else @@ -90,7 +90,7 @@ module ActionMailer # end # end def assert_enqueued_emails(number, &block) - assert_enqueued_jobs number, only: [ ActionMailer::DeliveryJob, ActionMailer::Parameterized::DeliveryJob ], &block + assert_enqueued_jobs(number, only: ->(job) { delivery_job_filter(job) }, &block) end # Asserts that a specific email has been enqueued, optionally @@ -124,15 +124,12 @@ module ActionMailer # end # end def assert_enqueued_email_with(mailer, method, args: nil, queue: "mailers", &block) - if args.is_a? Hash - job = ActionMailer::Parameterized::DeliveryJob - args = [mailer.to_s, method.to_s, "deliver_now", args] + args = if args.is_a?(Hash) + [mailer.to_s, method.to_s, "deliver_now", args] else - job = ActionMailer::DeliveryJob - args = [mailer.to_s, method.to_s, "deliver_now", *args] + [mailer.to_s, method.to_s, "deliver_now", nil, *args] end - - assert_enqueued_with(job: job, args: args, queue: queue, &block) + assert_enqueued_with(job: mailer.delivery_job, args: args, queue: queue, &block) end # Asserts that no emails are enqueued for later delivery. @@ -151,7 +148,15 @@ module ActionMailer # end # end def assert_no_enqueued_emails(&block) - assert_no_enqueued_jobs only: [ ActionMailer::DeliveryJob, ActionMailer::Parameterized::DeliveryJob ], &block + assert_enqueued_emails 0, &block end + + private + + def delivery_job_filter(job) + job_class = job.is_a?(Hash) ? job.fetch(:job) : job.class + + Base.descendants.map(&:delivery_job).include?(job_class) + end end end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index cbbee9fae8..86c0172772 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -544,6 +544,12 @@ class BaseTest < ActiveSupport::TestCase assert_equal("TEXT Implicit Multipart", mail.text_part.body.decoded) end + test "you can specify a different template for multipart render" do + mail = BaseMailer.implicit_different_template_with_block("explicit_multipart_templates").deliver + assert_equal("HTML Explicit Multipart Templates", mail.html_part.body.decoded) + assert_equal("TEXT Explicit Multipart Templates", 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 diff --git a/actionmailer/test/mailers/base_mailer.rb b/actionmailer/test/mailers/base_mailer.rb index a3101207dc..c1bb48cc96 100644 --- a/actionmailer/test/mailers/base_mailer.rb +++ b/actionmailer/test/mailers/base_mailer.rb @@ -111,6 +111,13 @@ class BaseMailer < ActionMailer::Base mail(template_name: template_name) end + def implicit_different_template_with_block(template_name = "") + mail(template_name: template_name) do |format| + format.text + format.html + end + end + def explicit_different_template(template_name = "") mail do |format| format.text { render template: "#{mailer_name}/#{template_name}" } diff --git a/actionmailer/test/message_delivery_test.rb b/actionmailer/test/message_delivery_test.rb index f8dcb3f4ba..8d5c473faf 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", 1, 2, 3]) do + assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", nil, 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 + assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now!", nil, 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", 1, 2, 3]) do + assert_performed_with(job: ActionMailer::DeliveryJob, at: Time.current + 10.minutes, args: ["DelayedMailer", "test_message", "deliver_now", nil, 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", 1, 2, 3]) do + assert_performed_with(job: ActionMailer::DeliveryJob, at: later_time, args: ["DelayedMailer", "test_message", "deliver_now", nil, 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 + assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", nil, 1, 2, 3], queue: "test_queue") do @mail.deliver_later end end @@ -100,7 +100,7 @@ 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", 1, 2, 3]) do + assert_performed_with(job: DummyJob, args: ["DelayedMailer", "test_message", "deliver_now", nil, 1, 2, 3]) do @mail.deliver_later end @@ -110,7 +110,7 @@ class MessageDeliveryTest < ActiveSupport::TestCase class DummyJob < ActionMailer::DeliveryJob; 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 + assert_performed_with(job: ActionMailer::DeliveryJob, args: ["DelayedMailer", "test_message", "deliver_now", nil, 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 d3b34fc3e3..3713dc3e3e 100644 --- a/actionmailer/test/parameterized_test.rb +++ b/actionmailer/test/parameterized_test.rb @@ -7,6 +7,9 @@ require "mailers/params_mailer" class ParameterizedTest < ActiveSupport::TestCase include ActiveJob::TestHelper + class DummyDeliveryJob < ActionMailer::DeliveryJob + end + setup do @previous_logger = ActiveJob::Base.logger ActiveJob::Base.logger = Logger.new(nil) @@ -35,7 +38,13 @@ class ParameterizedTest < ActiveSupport::TestCase end test "enqueue the email with params" do - assert_performed_with(job: ActionMailer::Parameterized::DeliveryJob, args: ["ParamsMailer", "invitation", "deliver_now", { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" } ]) do + args = [ + "ParamsMailer", + "invitation", + "deliver_now", + { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" }, + ] + assert_performed_with(job: ActionMailer::DeliveryJob, args: args) do @mail.deliver_later end end @@ -55,15 +64,26 @@ class ParameterizedTest < ActiveSupport::TestCase end test "should enqueue a parameterized request with the correct delivery job" do - old_delivery_job = ParamsMailer.parameterized_delivery_job - ParamsMailer.parameterized_delivery_job = ParameterizedDummyJob - - assert_performed_with(job: ParameterizedDummyJob, args: ["ParamsMailer", "invitation", "deliver_now", { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" } ]) do - @mail.deliver_later + args = [ + "ParamsMailer", + "invitation", + "deliver_now", + { inviter: "david@basecamp.com", invitee: "jason@basecamp.com" }, + ] + + with_delivery_job DummyDeliveryJob do + assert_performed_with(job: DummyDeliveryJob, args: args) do + @mail.deliver_later + end end - - ParamsMailer.parameterized_delivery_job = old_delivery_job end - class ParameterizedDummyJob < ActionMailer::Parameterized::DeliveryJob; end + private + + def with_delivery_job(job) + old_delivery_job = ParamsMailer.delivery_job + ParamsMailer.delivery_job = job + ensure + ParamsMailer.delivery_job = old_delivery_job + end end diff --git a/actionmailer/test/test_helper_test.rb b/actionmailer/test/test_helper_test.rb index d31170706b..4e21ab0a69 100644 --- a/actionmailer/test/test_helper_test.rb +++ b/actionmailer/test/test_helper_test.rb @@ -24,6 +24,13 @@ class TestHelperMailer < ActionMailer::Base end end +class CustomDeliveryJob < ActionMailer::DeliveryJob +end + +class CustomDeliveryMailer < TestHelperMailer + self.delivery_job = CustomDeliveryJob +end + class TestHelperMailerTest < ActionMailer::TestCase include ActiveSupport::Testing::Stream @@ -69,6 +76,26 @@ class TestHelperMailerTest < ActionMailer::TestCase end end + def test_assert_emails_with_custom_delivery_job + assert_nothing_raised do + assert_emails(1) do + silence_stream($stdout) do + CustomDeliveryMailer.test.deliver_later + end + end + end + end + + def test_assert_emails_with_custom_parameterized_delivery_job + assert_nothing_raised do + assert_emails(1) do + silence_stream($stdout) do + CustomDeliveryMailer.with(foo: "bar").test_parameter_args.deliver_later + end + end + end + end + def test_assert_emails_with_enqueued_emails assert_nothing_raised do assert_emails 1 do @@ -201,6 +228,16 @@ class TestHelperMailerTest < ActionMailer::TestCase assert_match(/2 .* but 1/, error.message) end + def test_assert_enqueued_emails_with_custom_delivery_job + assert_nothing_raised do + assert_enqueued_emails(1) do + silence_stream($stdout) do + CustomDeliveryMailer.test.deliver_later + end + end + end + end + def test_assert_enqueued_emails_too_many_sent error = assert_raise ActiveSupport::TestCase::Assertion do assert_enqueued_emails 1 do @@ -252,6 +289,16 @@ class TestHelperMailerTest < ActionMailer::TestCase end end + def test_assert_enqueued_email_with_when_mailer_has_custom_delivery_job + assert_nothing_raised do + assert_enqueued_email_with CustomDeliveryMailer, :test do + silence_stream($stdout) do + CustomDeliveryMailer.test.deliver_later + end + end + end + end + def test_assert_enqueued_email_with_with_no_block assert_nothing_raised do silence_stream($stdout) do |