Skip to content

Commit 771d404

Browse files
yourcelfmedmunds
authored andcommitted
Un-hardcode message_id in test backend; add console backend
* Un-hardcode status message_id in test backend For the test EmailBackend, get message ID's based on array position in `mail.outbox`, so that tests can predict the message ID. * Add a console backend for use in development Adds an EmailBackend derived from both Anymail's test backend and Django's console backend, to provide anymail statuses and signal handling while printing messages to the console. For use during development on localhost. Closes #87
1 parent 09def30 commit 771d404

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

anymail/backends/console.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import uuid
2+
from django.core.mail.backends.console import EmailBackend as DjangoConsoleBackend
3+
4+
from ..exceptions import AnymailError
5+
from .test import EmailBackend as AnymailTestBackend
6+
7+
8+
class EmailBackend(AnymailTestBackend, DjangoConsoleBackend):
9+
"""
10+
Anymail backend that prints messages to the console, while retaining
11+
anymail statuses and signals.
12+
"""
13+
14+
esp_name = "Console"
15+
16+
def get_esp_message_id(self, message):
17+
# Generate a guaranteed-unique ID for the message
18+
return str(uuid.uuid4())
19+
20+
def send_messages(self, email_messages):
21+
if not email_messages:
22+
return
23+
msg_count = 0
24+
with self._lock:
25+
try:
26+
stream_created = self.open()
27+
for message in email_messages:
28+
try:
29+
sent = self._send(message)
30+
except AnymailError:
31+
if self.fail_silently:
32+
sent = False
33+
else:
34+
raise
35+
if sent:
36+
self.write_message(message)
37+
self.stream.flush() # flush after each message
38+
msg_count += 1
39+
finally:
40+
if stream_created:
41+
self.close()
42+
43+
return msg_count

anymail/backends/test.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ def __init__(self, *args, **kwargs):
2727
if not hasattr(mail, 'outbox'):
2828
mail.outbox = [] # see django.core.mail.backends.locmem
2929

30+
def get_esp_message_id(self, message):
31+
# Get a unique ID for the message. The message must have been added to
32+
# the outbox first.
33+
return mail.outbox.index(message)
34+
3035
def build_message_payload(self, message, defaults):
3136
return TestPayload(backend=self, message=message, defaults=defaults)
3237

@@ -41,7 +46,10 @@ def post_to_esp(self, payload, message):
4146
raise response
4247
except AttributeError:
4348
# Default is to return 'sent' for each recipient
44-
status = AnymailRecipientStatus(message_id=1, status='sent')
49+
status = AnymailRecipientStatus(
50+
message_id=self.get_esp_message_id(message),
51+
status='sent'
52+
)
4553
response = {
4654
'recipient_status': {email: status for email in payload.recipient_emails}
4755
}

tests/test_send_signals.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ def handle_post_send(sender, message, status, esp_name, **kwargs):
6565
self.assertEqual(sender, TestEmailBackend)
6666
self.assertEqual(message, self.message)
6767
self.assertEqual(status.status, {'sent'})
68-
self.assertEqual(status.message_id, 1) # TestEmailBackend default message_id
68+
self.assertEqual(status.message_id, 0)
6969
self.assertEqual(status.recipients['[email protected]'].status, 'sent')
70-
self.assertEqual(status.recipients['[email protected]'].message_id, 1)
70+
self.assertEqual(status.recipients['[email protected]'].message_id, 0)
7171
self.assertEqual(esp_name, "Test") # the TestEmailBackend's ESP is named "Test"
7272
self.receiver_called = True
7373
self.addCleanup(post_send.disconnect, receiver=handle_post_send)

0 commit comments

Comments
 (0)