Skip to content

Commit

Permalink
Fixed #35528 -- Added EmailMultiAlternatives.body_contains() helper m…
Browse files Browse the repository at this point in the history
…ethod.
  • Loading branch information
GitRon authored and sarahboyce committed Jun 21, 2024
1 parent 7a0cd09 commit 5fef6d2
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
13 changes: 13 additions & 0 deletions django/core/mail/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,3 +505,16 @@ def _create_alternatives(self, msg):
)
)
return msg

def body_contains(self, text):
"""
Checks that ``text`` occurs in the email body and in all attached MIME
type text/* alternatives.
"""
if text not in self.body:
return False

for content, mimetype in self.alternatives:
if mimetype.startswith("text/") and text not in content:
return False
return True
4 changes: 4 additions & 0 deletions docs/releases/5.2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ Email
<django.core.mail.EmailMultiAlternatives.alternatives>` is now a list of
named tuples, as opposed to regular tuples.

* The new :meth:`~django.core.mail.EmailMultiAlternatives.body_contains` method
returns a boolean indicating whether a provided text is contained in the
email ``body`` and in all attached MIME type ``text/*`` alternatives.

Error Reporting
~~~~~~~~~~~~~~~

Expand Down
20 changes: 20 additions & 0 deletions docs/topics/email.txt
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,26 @@ Django's email library, you can do this using the
msg.attach_alternative(html_content, "text/html")
msg.send()

.. method:: body_contains(text)

.. versionadded:: 5.2

Returns a boolean indicating whether the provided ``text`` is
contained in the email ``body`` and in all attached MIME type
``text/*`` alternatives.

This can be useful when testing emails. For example::

def test_contains_email_content(self):
subject = "Hello World"
from_email = "[email protected]"
to = "[email protected]"
msg = EmailMultiAlternatives(subject, "I am content.", from_email, [to])
msg.attach_alternative("<p>I am content.</p>", "text/html")

self.assertIs(msg.body_contains("I am content"), True)
self.assertIs(msg.body_contains("<p>I am content.</p>"), False)

Updating the default content type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
18 changes: 18 additions & 0 deletions tests/mail/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,24 @@ def test_email_multi_alternatives_content_mimetype_none(self):
with self.assertRaisesMessage(ValueError, msg):
email_msg.attach_alternative("<p>content</p>", None)

def test_body_contains(self):
email_msg = EmailMultiAlternatives()
email_msg.body = "I am content."
self.assertIs(email_msg.body_contains("I am"), True)
self.assertIs(email_msg.body_contains("I am content."), True)

email_msg.attach_alternative("<p>I am different content.</p>", "text/html")
self.assertIs(email_msg.body_contains("I am"), True)
self.assertIs(email_msg.body_contains("I am content."), False)
self.assertIs(email_msg.body_contains("<p>I am different content.</p>"), False)

def test_body_contains_alternative_non_text(self):
email_msg = EmailMultiAlternatives()
email_msg.body = "I am content."
email_msg.attach_alternative("I am content.", "text/html")
email_msg.attach_alternative(b"I am a song.", "audio/mpeg")
self.assertIs(email_msg.body_contains("I am content"), True)


@requires_tz_support
class MailTimeZoneTests(SimpleTestCase):
Expand Down

0 comments on commit 5fef6d2

Please sign in to comment.