diff --git a/anymail/message.py b/anymail/message.py index 7f8b35b..a19d6b7 100644 --- a/anymail/message.py +++ b/anymail/message.py @@ -88,6 +88,10 @@ class AnymailRecipientStatus: self.message_id = message_id # ESP message id self.status = status # one of ANYMAIL_STATUSES, or None for not yet sent to ESP + def __repr__(self): + return "AnymailRecipientStatus({message_id!r}, {status!r})".format( + message_id=self.message_id, status=self.status) + class AnymailStatus: """Information about an EmailMessage's send status for all recipients""" @@ -98,6 +102,21 @@ class AnymailStatus: self.recipients = {} # per-recipient: { email: AnymailRecipientStatus, ... } self.esp_response = None + def __repr__(self): + def _repr(o): + if isinstance(o, set): + # force sorted order, for reproducible testing + item_reprs = [repr(item) for item in sorted(o)] + return "{%s}" % ", ".join(item_reprs) + else: + return repr(o) + details = ["status={status}".format(status=_repr(self.status))] + if self.message_id: + details.append("message_id={message_id}".format(message_id=_repr(self.message_id))) + if self.recipients: + details.append("{num_recipients} recipients".format(num_recipients=len(self.recipients))) + return "AnymailStatus<{details}>".format(details=", ".join(details)) + def set_recipient_status(self, recipients): self.recipients.update(recipients) recipient_statuses = self.recipients.values() diff --git a/tests/test_message.py b/tests/test_message.py index 328e1fb..c87286b 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -2,7 +2,7 @@ from django.core.mail import EmailMultiAlternatives from django.test import SimpleTestCase from mock import patch -from anymail.message import attach_inline_image +from anymail.message import AnymailRecipientStatus, AnymailStatus, attach_inline_image from .utils import AnymailTestMixin, sample_image_content @@ -29,3 +29,50 @@ class InlineImageTests(AnymailTestMixin, SimpleTestCase): domain="example.org") self.assertRegex(cid, r"[\w.]+@example\.org", "Content-ID should be a valid Message-ID @example.org") + + +class AnymailStatusTests(AnymailTestMixin, SimpleTestCase): + def test_single_recipient(self): + recipients = { + "one@example.com": AnymailRecipientStatus("12345", "sent"), + } + status = AnymailStatus() + status.set_recipient_status(recipients) + self.assertEqual(status.status, {"sent"}) + self.assertEqual(status.message_id, "12345") + self.assertEqual(status.recipients, recipients) + self.assertEqual(repr(status), + "AnymailStatus") + self.assertEqual(repr(status.recipients["one@example.com"]), + "AnymailRecipientStatus('12345', 'sent')") + + def test_multiple_recipients(self): + recipients = { + "one@example.com": AnymailRecipientStatus("12345", "sent"), + "two@example.com": AnymailRecipientStatus("45678", "queued"), + } + status = AnymailStatus() + status.set_recipient_status(recipients) + self.assertEqual(status.status, {"queued", "sent"}) + self.assertEqual(status.message_id, {"12345", "45678"}) + self.assertEqual(status.recipients, recipients) + self.assertEqual(repr(status), + "AnymailStatus") + + def test_multiple_recipients_same_message_id(self): + # status.message_id collapses when it's the same for all recipients + recipients = { + "one@example.com": AnymailRecipientStatus("12345", "sent"), + "two@example.com": AnymailRecipientStatus("12345", "queued"), + } + status = AnymailStatus() + status.set_recipient_status(recipients) + self.assertEqual(status.message_id, "12345") + self.assertEqual(repr(status), + "AnymailStatus") + + def test_none(self): + status = AnymailStatus() + self.assertIsNone(status.status) + self.assertIsNone(status.message_id) + self.assertEqual(repr(status), "AnymailStatus")