def test_queued_message_custom_handler(self): '''A custom error should be able to pick up any random exception''' def raise_exception(*args, **kwargs): raise_exception.result = Exception('Random exception') raise raise_exception.result FakeConnection.set_overrides([raise_exception]) message = Message.objects.create(from_address='*****@*****.**', to_address='*****@*****.**', subject='Test', encoded_message='Test message') queued_message = QueuedMessage.objects.create(message=message) def error_handler(message, exception): self.assertEquals(raise_exception.result, exception) self.assertEquals(queued_message, message) error_handler.called = True return constants.RESULT_FAILED settings.CUSTOM_ERROR_HANDLER = error_handler send_queued_message(queued_message, self.connection) self.assertTrue(error_handler.called)
def test_queued_message_custom_handler(self): '''A custom error should be able to pick up any random exception''' def raise_exception(*args, **kwargs): raise_exception.result = Exception('Random exception') raise raise_exception.result FakeConnection.set_overrides([ raise_exception ]) message = Message.objects.create( from_address='*****@*****.**', to_address='*****@*****.**', subject='Test', encoded_message='Test message' ) queued_message = QueuedMessage.objects.create(message=message) def error_handler(message, exception): self.assertEquals(raise_exception.result, exception) self.assertEquals(queued_message, message) error_handler.called = True return constants.RESULT_FAILED settings.CUSTOM_ERROR_HANDLER = error_handler send_queued_message(queued_message, self.connection) self.assertTrue(error_handler.called)
def test_queue_not_deleted_on_error(self): """ Queued message instance shouldn't be deleted when error is raised during sending """ send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') engine.send_queued_message(queued_message) self.assertEqual(QueuedMessage.objects.count(), 1)
def test_log(self): """ All emails sent through django_mailer should be logged, even those having "now" priority """ send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') engine.send_queued_message(queued_message, self.connection) self.assertEqual(Log.objects.count(), 1) send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**'], priority=constants.PRIORITIES['now']) self.assertEqual(Log.objects.count(), 2)
def test_send_queued_message(self): """ Ensure that send_queued_message properly delivers email, regardless of whether connection is passed in. """ send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') send_queued_message(queued_message, self.connection) self.assertEqual(len(self.mail.outbox), 1) send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') send_queued_message(queued_message) self.assertEqual(len(self.mail.outbox), 2) send_html_mail('Subject', 'Body', '<p>HTML</p>', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') send_queued_message(queued_message, self.connection) self.assertEqual(len(self.mail.outbox), 3) send_html_mail('Subject', 'Body', '<p>HTML</p>', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') send_queued_message(queued_message) self.assertEqual(len(self.mail.outbox), 4)
def test_blacklist(self): """ Test that blacklist works properly """ Blacklist.objects.create(email='*****@*****.**') send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') send_queued_message(queued_message) self.assertEqual(len(self.mail.outbox), 0) # Explicitly passing in list of blacklisted addresses should also work send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') send_queued_message(queued_message, blacklist=['*****@*****.**']) self.assertEqual(len(self.mail.outbox), 0)
def test_defer_on_errors_setting(self): """ Defer queued mail on user defined exception. """ old_errors = settings.DEFER_ON_ERRORS settings.DEFER_ON_ERRORS = (DeferOnError,) # If we see some other random errors email shouldn't be deferred old_backend = django_settings.EMAIL_BACKEND django_settings.EMAIL_BACKEND = \ 'django_mailer.tests.base.DeferOnErrorBackend' send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') engine.send_queued_message(queued_message) queued_message = QueuedMessage.objects.latest('id') self.assertNotEqual(queued_message.deferred, None) settings.DEFER_ON_ERRORS = old_errors
def test_queued_message_socket_error(self): '''If a socket error is raised then the standard handling is that the message should be deferred''' def raise_socket_error(*args, **kwargs): raise SocketError() FakeConnection.set_overrides([raise_socket_error]) message = Message.objects.create(from_address='*****@*****.**', to_address='*****@*****.**', subject='Test', encoded_message='Test message') queued_message = QueuedMessage.objects.create(message=message) send_queued_message(queued_message, self.connection) queued_message = QueuedMessage.objects.get(id=queued_message.id) self.assertTrue(queued_message.deferred != None)
def test_queued_message_socket_error(self): '''If a socket error is raised then the standard handling is that the message should be deferred''' def raise_socket_error(*args, **kwargs): raise SocketError() FakeConnection.set_overrides([ raise_socket_error ]) message = Message.objects.create( from_address='*****@*****.**', to_address='*****@*****.**', subject='Test', encoded_message='Test message' ) queued_message = QueuedMessage.objects.create(message=message) send_queued_message(queued_message, self.connection) queued_message = QueuedMessage.objects.get(id=queued_message.id) self.assertTrue(queued_message.deferred != None)
def test_message_deferred(self): """ When error returned requires manual intervention to fix, emails should be deferred. """ send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') self.assertEqual(queued_message.deferred, None) engine.send_queued_message(queued_message) queued_message = QueuedMessage.objects.latest('id') self.assertNotEqual(queued_message.deferred, None) # If we see some other random errors email shouldn't be deferred django_settings.EMAIL_BACKEND = \ 'django_mailer.tests.base.OtherErrorBackend' send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') engine.send_queued_message(queued_message) self.assertEqual(queued_message.deferred, None)
def test_sending_email_uses_opened_connection(self): """ Test that send_queued_message command uses the connection that gets passed in as an argument. Connection stored in self is an instance of locmem email backend. If we override the email backend with a dummy backend but passed in the previously opened connection from locmem backend, we should still get the proper result since send_queued_message uses the connection we passed in. """ django_settings.EMAIL_BACKEND = \ 'django.core.mail.backends.dummy.EmailBackend' # Outbox should be empty because send_queued_message uses dummy backend send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') engine.send_queued_message(queued_message) self.assertEqual(len(self.mail.outbox), 0) # Outbox should be populated because send_queued_message uses # the connection we passed in (locmem) send_mail('Subject', 'Body', '*****@*****.**', ['*****@*****.**']) queued_message = QueuedMessage.objects.latest('id') engine.send_queued_message(queued_message, self.connection) self.assertEqual(len(self.mail.outbox), 1)
def queue_email_message(email_message, fail_silently=False, priority=None): """ Add new messages to the email queue. The ``email_message`` argument should be an instance of Django's core mail ``EmailMessage`` class. The messages can be assigned a priority in the queue by using the ``priority`` argument. The ``fail_silently`` argument is not used and is only provided to match the signature of the ``EmailMessage.send`` function which it may emulate (see ``queue_django_mail``). """ from django_mailer import constants, models, settings # Hold it hold_email = False if "hold_email" in email_message.extra_headers: hold_email = True # Replace from from_email = email_message.from_email if "replace_from_email" in email_message.extra_headers: from_email = email_message.extra_headers.pop("replace_from_email") # Send now if constants.PRIORITY_HEADER in email_message.extra_headers: priority = email_message.extra_headers.pop(constants.PRIORITY_HEADER) priority = constants.PRIORITIES.get(priority.lower()) if priority == constants.PRIORITY_EMAIL_NOW: if constants.EMAIL_BACKEND_SUPPORT: from django.core.mail import get_connection from django_mailer.engine import send_queued_message blacklist = models.Blacklist.objects.values_list("email", flat=True) connection = get_connection(backend=settings.USE_BACKEND) for to_email in email_message.recipients(): message = models.Message.objects.create( to_address=to_email, from_address=from_email, subject=email_message.subject, encoded_message=email_message.message().as_string(), ) queued_message = models.QueuedMessage(message=message) if priority: queued_message.priority = priority if hold_email: queued_message.hold = True queued_message.save() result = send_queued_message(queued_message, smtp_connection=connection, blacklist=blacklist, log=True) return result == constants.RESULT_SENT else: return email_message.send() count = 0 for to_email in email_message.recipients(): message = models.Message.objects.create( to_address=to_email, from_address=from_email, subject=email_message.subject, encoded_message=email_message.message().as_string(), ) queued_message = models.QueuedMessage(message=message) if priority: queued_message.priority = priority if hold_email: queued_message.hold = True queued_message.save() count += 1 return count