From d4b55854257c48abe3c3e7bad76eac6c39f58884 Mon Sep 17 00:00:00 2001 From: Liav Koren Date: Mon, 19 Nov 2018 14:58:26 -0500 Subject: [PATCH] Add test for echo-to-stdout and update README. --- README.md | 2 ++ sendgrid_backend/mail.py | 25 ++++++++++++++----------- test/test_echo_to_stream.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 test/test_echo_to_stream.py diff --git a/README.md b/README.md index ed98820..64ff34f 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,5 @@ To use the backend, simply install the package (using pip), set the `EMAIL_BACKE 1. To toggle sandbox mode (when django is running in DEBUG mode), set `SENDGRID_SANDBOX_MODE_IN_DEBUG = True/False`. 1. To err on the side of caution, this defaults to True, so emails sent in DEBUG mode will not be delivered, unless this setting is explicitly set to False. +2. `SENDGRID_ECHO_TO_STDOUT` will echo to stdout or any other file-like + object that is passed to the backend via the `stream` kwarg. diff --git a/sendgrid_backend/mail.py b/sendgrid_backend/mail.py index d41066e..a30c64a 100644 --- a/sendgrid_backend/mail.py +++ b/sendgrid_backend/mail.py @@ -35,8 +35,6 @@ class SendgridBackend(BaseEmailBackend): """ def __init__(self, *args, **kwargs): super(SendgridBackend, self).__init__(*args, **kwargs) - self._lock = threading.RLock() - self.stream = kwargs.pop('stream', sys.stdout) if "api_key" in kwargs: self.sg = sendgrid.SendGridAPIClient(api_key=kwargs["api_key"]) elif hasattr(settings, "SENDGRID_API_KEY") and settings.SENDGRID_API_KEY: @@ -60,7 +58,15 @@ def __init__(self, *args, **kwargs): self.track_email = track_email - def write_message_to_console(self, message): + if hasattr(settings, "SENDGRID_ECHO_TO_STDOUT"): + self._lock = threading.RLock() + self.stream = kwargs.pop('stream', sys.stdout) + else: + self._lock = None + self.stream = None + + + def write_to_stream(self, message): msg = message.message() msg_data = msg.as_bytes() charset = msg.get_charset().get_output_charset() if msg.get_charset() else 'utf-8' @@ -69,28 +75,25 @@ def write_message_to_console(self, message): self.stream.write('-' * 79) self.stream.write('\n') - def send_to_console(self, email_messages): - """Write all messages to the stream in a thread-safe way.""" + def echo_to_output_stream(self, email_messages): + """ Write all messages to the stream in a thread-safe way. """ if not email_messages: return - msg_count = 0 with self._lock: try: stream_created = self.open() for message in email_messages: - self.write_message_to_console(message) + self.write_to_stream(message) self.stream.flush() # flush after each message - msg_count += 1 if stream_created: self.close() except Exception: if not self.fail_silently: raise - return msg_count def send_messages(self, email_messages): - if self.sandbox_mode: - self.send_to_console(email_messages) + if self.stream: + self.echo_to_output_stream(email_messages) success = 0 for msg in email_messages: data = self._build_sg_mail(msg) diff --git a/test/test_echo_to_stream.py b/test/test_echo_to_stream.py new file mode 100644 index 0000000..54863be --- /dev/null +++ b/test/test_echo_to_stream.py @@ -0,0 +1,32 @@ +import os +from unittest.mock import MagicMock + +from django.core.mail import EmailMessage +from django.test import override_settings +from django.test.testcases import SimpleTestCase + +from sendgrid_backend.mail import SendgridBackend + + +class TestEchoToOutput(SimpleTestCase): + # @patch('sendgrid_backend.mail.sys.stdout') + # def test_echo(self, patched_stdout): + def test_echo(self): + settings = { + "DEBUG": True, + "SENDGRID_API_KEY": os.environ["SENDGRID_API_KEY"], + "EMAIL_BACKEND": "sendgrid_backend.SendgridBackend", + "SENDGRID_ECHO_TO_STDOUT": True + } + with override_settings(**settings): + mocked_output_stream = MagicMock() + connection = SendgridBackend(stream=mocked_output_stream) + msg = EmailMessage( + subject="Hello, World!", + body="Hello, World!", + from_email="Sam Smith ", + to=["John Doe "], + connection=connection, + ) + msg.send() + self.assertTrue(mocked_output_stream.write.called)