diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index 25eef5416a3..32a0d22ebda 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,3 +1,17 @@ +* Added `deliver_enqueued_emails` to `ActionMailer::TestHelper`. This method + delivers all enqueued email jobs. + + Example: + + ```ruby + def test_deliver_enqueued_emails + deliver_enqueued_emails do + ContactMailer.welcome.deliver_later + end + assert_emails 1 + end + ``` + * The `deliver_later_queue_name` used by the default mailer job can now be configured on a per-mailer basis. Previously this was only configurable for all mailers via `ActionMailer::Base`. diff --git a/actionmailer/lib/action_mailer/test_helper.rb b/actionmailer/lib/action_mailer/test_helper.rb index feacf04f008..039f46d064a 100644 --- a/actionmailer/lib/action_mailer/test_helper.rb +++ b/actionmailer/lib/action_mailer/test_helper.rb @@ -50,7 +50,7 @@ module ActionMailer def assert_emails(number, &block) if block_given? original_count = ActionMailer::Base.deliveries.size - perform_enqueued_jobs(only: ->(job) { delivery_job_filter(job) }, &block) + deliver_enqueued_emails(&block) new_count = ActionMailer::Base.deliveries.size diff = new_count - original_count assert_equal number, diff, "#{number} emails expected, but #{diff} were sent" @@ -208,6 +208,45 @@ module ActionMailer assert_enqueued_emails 0, &block end + # Delivers all enqueued emails. If a block is given, delivers all of the emails + # that were enqueued throughout the duration of the block. If a block is + # not given, delivers all the enqueued emails up to this point in the test. + # + # def test_deliver_enqueued_emails + # deliver_enqueued_emails do + # ContactMailer.welcome.deliver_later + # end + # assert_emails 1 + # end + # + # def test_deliver_enqueued_emails_without_block + # ContactMailer.welcome.deliver_later + # + # deliver_enqueued_emails + # + # assert_emails 1 + # + # end + # + # If the +:queue+ option is specified, + # then only the emails(s) enqueued to a specific queue will be performed. + # + # def test_deliver_enqueued_emails_with_queue + # deliver_enqueued_emails queue: :external_mailers do + # CustomerMailer.deliver_later_queue_name = :external_mailers + # CustomerMailer.welcome.deliver_later # will be performed + # EmployeeMailer.deliver_later_queue_name = :internal_mailers + # EmployeeMailer.welcome.deliver_later # will not be performed + # end + # assert_emails 1 + # end + # + # If the +:at+ option is specified, then only delivers emails enqueued to deliver + # immediately or before the given time + def deliver_enqueued_emails(queue: nil, at: nil, &block) + perform_enqueued_jobs(only: ->(job) { delivery_job_filter(job) }, queue: queue, at: at, &block) + end + private def delivery_job_filter(job) job_class = job.is_a?(Hash) ? job.fetch(:job) : job.class diff --git a/actionmailer/test/test_helper_test.rb b/actionmailer/test/test_helper_test.rb index d63a7bba10e..648289a3fd3 100644 --- a/actionmailer/test/test_helper_test.rb +++ b/actionmailer/test/test_helper_test.rb @@ -487,6 +487,68 @@ class TestHelperMailerTest < ActionMailer::TestCase end end end + + def test_deliver_enqueued_emails_with_no_block + assert_nothing_raised do + silence_stream($stdout) do + TestHelperMailer.test.deliver_later + deliver_enqueued_emails + end + end + + assert_emails(1) + end + + def test_deliver_enqueued_emails_with_a_block + assert_nothing_raised do + deliver_enqueued_emails do + silence_stream($stdout) do + TestHelperMailer.test.deliver_later + end + end + end + + assert_emails(1) + end + + def test_deliver_enqueued_emails_with_custom_delivery_job + assert_nothing_raised do + deliver_enqueued_emails do + silence_stream($stdout) do + CustomDeliveryMailer.test.deliver_later + end + end + end + + assert_emails(1) + end + + def test_deliver_enqueued_emails_with_custom_queue + assert_nothing_raised do + deliver_enqueued_emails(queue: CustomQueueMailer.deliver_later_queue_name) do + silence_stream($stdout) do + TestHelperMailer.test.deliver_later + CustomQueueMailer.test.deliver_later + end + end + end + + assert_emails(1) + assert_enqueued_email_with(TestHelperMailer, :test) + end + + def test_deliver_enqueued_emails_with_at + assert_nothing_raised do + deliver_enqueued_emails(at: 1.hour.from_now) do + silence_stream($stdout) do + TestHelperMailer.test.deliver_later + TestHelperMailer.test.deliver_later(wait: 2.hours) + end + end + end + + assert_emails(1) + end end class AnotherTestHelperMailerTest < ActionMailer::TestCase