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

Allow easily testing multi-part emails in ActionMailbox #36856

Merged
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 4 additions & 0 deletions actionmailbox/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
* Allow easier creation of multi-part emails from the `create_inbound_email_from_mail` and `receive_inbound_email_from_mail` test helpers.

*Michael Herold*

* Fix Bcc header not being included with emails from `create_inbound_email_from` test helpers.

*jduff*
Expand Down
62 changes: 55 additions & 7 deletions actionmailbox/lib/action_mailbox/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,58 @@ def create_inbound_email_from_fixture(fixture_name, status: :processing)
create_inbound_email_from_source file_fixture(fixture_name).read, status: status
end

# Create an +InboundEmail+ by specifying it using +Mail.new+ options. Example:
# Creates an +InboundEmail+ by specifying through options or a block.
#
# ==== Options
#
# * <tt>:status</tt> - The +status+ to set for the created +InboundEmail+.
# For possible statuses, see {its documentation}[rdoc-ref:ActionMailbox::InboundEmail].
#
# ==== Creating a simple email
#
# When you only need to set basic fields like +from+, +to+, +subject+, and
# +body+, you can pass them directly as options.
#
# create_inbound_email_from_mail(from: "david@loudthinking.com", subject: "Hello!")
def create_inbound_email_from_mail(status: :processing, **mail_options)
mail = Mail.new(mail_options)
#
# ==== Creating a multi-part email
#
# When you need to create a more intricate email, like a multi-part email
# that contains both a plaintext version and an HTML version, you can pass a
# block.
#
# create_inbound_email_from_mail do
# to "David Heinemeier Hansson <david@loudthinking.com>"
# from "Bilbo Baggins <bilbo@bagend.com>"
# subject "Come down to the Shire!"
#
# text_part do
# body "Please join us for a party at Bag End"
# end
#
# html_part do
# body "<h1>Please join us for a party at Bag End</h1>"
# end
# end
#
# As with +Mail.new+, you can also use a block parameter to define the parts
# of the message:
#
# create_inbound_email_from_mail do |mail|
# mail.to "David Heinemeier Hansson <david@loudthinking.com>"
# mail.from "Bilbo Baggins <bilbo@bagend.com>"
# mail.subject "Come down to the Shire!"
#
# mail.text_part do |part|
# part.body "Please join us for a party at Bag End"
# end
#
# mail.html_part do |part|
# part.body "<h1>Please join us for a party at Bag End</h1>"
# end
# end
def create_inbound_email_from_mail(status: :processing, **mail_options, &block)
mail = Mail.new(mail_options, &block)
# Bcc header is not encoded by default
mail[:bcc].include_in_headers = true if mail[:bcc]

Expand All @@ -33,10 +80,11 @@ def receive_inbound_email_from_fixture(*args)
create_inbound_email_from_fixture(*args).tap(&:route)
end

# Create an +InboundEmail+ using the same arguments as +create_inbound_email_from_mail+ and immediately route it to
# processing.
def receive_inbound_email_from_mail(**kwargs)
create_inbound_email_from_mail(**kwargs).tap(&:route)
# Create an +InboundEmail+ using the same options or block as
# {create_inbound_email_from_mail}[rdoc-ref:#create_inbound_email_from_mail],
# then immediately route it for processing.
def receive_inbound_email_from_mail(**kwargs, &block)
create_inbound_email_from_mail(**kwargs, &block).tap(&:route)
end

# Create an +InboundEmail+ using the same arguments as +create_inbound_email_from_source+ and immediately route it
Expand Down
33 changes: 33 additions & 0 deletions actionmailbox/test/unit/inbound_email_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,39 @@ class InboundEmailTest < ActiveSupport::TestCase
assert_equal file_fixture("welcome.eml").read, create_inbound_email_from_fixture("welcome.eml").source
end

test "multi-part mail can be built in tests using a block" do
inbound_email = create_inbound_email_from_mail do
to "test@example.com"
from "hello@example.com"

text_part do
body "Hello, world"
end

html_part do
body "<h1>Hello, world</h1>"
end
end

mail = inbound_email.mail

assert_equal mail.parts.length, 2
assert_equal mail.text_part.to_s, <<~TEXT.chomp
Content-Type: text/plain;\r
charset=UTF-8\r
Content-Transfer-Encoding: 7bit\r
\r
Hello, world
TEXT
assert_equal mail.html_part.to_s, <<~HTML.chomp
Content-Type: text/html;\r
charset=UTF-8\r
Content-Transfer-Encoding: 7bit\r
\r
<h1>Hello, world</h1>
HTML
end
Copy link
Contributor

Choose a reason for hiding this comment

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

This test case is for ActionMailbox::InboundEmail. How about adding ActionMailbox::TestHelperTest in test/unit/test_helper_test.rb?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point! I put it here since there wasn't an explicit test for TestHelper, but that makes a lot of sense to me.


test "email with message id is processed only once when received multiple times" do
mail = Mail.from_source(file_fixture("welcome.eml").read)
assert mail.message_id
Expand Down