Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce #deliver_enqueued_emails method to ActionMailer::TestHelper #47520

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions 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`.
Expand Down
41 changes: 40 additions & 1 deletion actionmailer/lib/action_mailer/test_helper.rb
Expand Up @@ -50,7 +50,7 @@ module TestHelper
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"
Expand Down Expand Up @@ -208,6 +208,45 @@ def assert_no_enqueued_emails(&block)
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
Expand Down
62 changes: 62 additions & 0 deletions actionmailer/test/test_helper_test.rb
Expand Up @@ -487,6 +487,68 @@ def test_assert_enqueued_email_with_with_no_block_with_parameterized_args
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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you pass it a block, assert_emails delivers emails enqueued by the block. So to properly test this it needs to be called without a block.

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
Expand Down