Skip to content

Commit

Permalink
v2.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
GitRon committed May 27, 2024
1 parent 312cc54 commit 5ba94d5
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 81 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Added `ThreadEmailService` for simple async sending of emails
* Added basic logging with privacy configuration to mail class
* Restructured documentation
* Restructured unit-tests

* *2.0.0* (2024-04-11)
* Dropped Django 3.2 & 4.1 support (via `ambient-package-update`)
Expand Down
1 change: 0 additions & 1 deletion django_pony_express/services/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,6 @@ def _send_and_log_email(self, msg: EmailMultiAlternatives) -> bool:
"""
Method to be called by the thread. Enables logging since we won't have any sync return values.
"""
# TODO(RV): test me
result = False
recipients_as_string = " ".join(self.recipient_email_list)
try:
Expand Down
4 changes: 4 additions & 0 deletions settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,7 @@
TIME_ZONE = "UTC"

LOCALE_PATHS = [str(BASE_PATH) + "/django_pony_express/locale"]


# Pony express
DJANGO_PONY_EXPRESS_LOG_RECIPIENTS = False
Empty file added tests/services/__init__.py
Empty file.
Empty file added tests/services/base/__init__.py
Empty file.
82 changes: 82 additions & 0 deletions tests/services/base/test_base_mail_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from django.test import TestCase

from django_pony_express.errors import EmailServiceConfigError
from django_pony_express.services.base import BaseEmailService, BaseEmailServiceFactory


class BaseEmailServiceFactoryTest(TestCase):
class TestMailService(BaseEmailService):
subject = "My subject"
template_name = "testapp/test_email.html"

@classmethod
def setUpTestData(cls):
super().setUpTestData()

def test_init_recipient_list_is_set(self):
email = "[email protected]"
factory = BaseEmailServiceFactory([email])
self.assertEqual(factory.recipient_email_list, [email])

def test_is_valid_positive_case(self):
email = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email])
factory.service_class = BaseEmailService
self.assertTrue(factory.is_valid())

def test_is_valid_no_recipients(self):
factory = BaseEmailServiceFactory()
factory.service_class = BaseEmailService
with self.assertRaises(EmailServiceConfigError):
factory.is_valid()

def test_is_valid_no_service_class(self):
email = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email])
with self.assertRaises(EmailServiceConfigError):
factory.is_valid()

def test_is_valid_no_exception_raised(self):
factory = BaseEmailServiceFactory()
factory.is_valid(raise_exception=False)
self.assertEqual(len(factory.errors), 2)

def test_has_errors_positive_case(self):
factory = BaseEmailServiceFactory()
factory.is_valid(raise_exception=False)
self.assertTrue(factory.has_errors())

def test_has_errors_negative_case(self):
email = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email])
factory.service_class = BaseEmailService
self.assertFalse(factory.has_errors())

def test_get_recipient_list_regular(self):
email_1 = "[email protected]"
email_2 = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email_1, email_2])
self.assertEqual(factory.get_recipient_list(), [email_1, email_2])

def test_get_email_from_recipient_regular(self):
email_1 = "[email protected]"
email_2 = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email_1, email_2])
self.assertEqual(factory.get_email_from_recipient(factory.get_recipient_list()[1]), email_2)

def test_get_context_data_regular(self):
factory = BaseEmailServiceFactory()
self.assertEqual(factory.get_context_data(), {})

def test_process_regular(self):
email_1 = "[email protected]"
email_2 = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email_1, email_2])
factory.service_class = self.TestMailService
self.assertEqual(factory.process(), 2)

def test_process_with_exception(self):
factory = BaseEmailServiceFactory()
factory.service_class = self.TestMailService
with self.assertRaises(EmailServiceConfigError):
factory.process()
Original file line number Diff line number Diff line change
@@ -1,90 +1,14 @@
import logging
from os.path import basename
from unittest import mock

from django.conf import settings
from django.core.mail import EmailMultiAlternatives
from django.test import TestCase, override_settings
from freezegun import freeze_time

from django_pony_express.errors import EmailServiceAttachmentError, EmailServiceConfigError
from django_pony_express.services.base import BaseEmailService, BaseEmailServiceFactory


class BaseEmailServiceFactoryTest(TestCase):
class TestMailService(BaseEmailService):
subject = "My subject"
template_name = "testapp/test_email.html"

@classmethod
def setUpTestData(cls):
super().setUpTestData()

def test_init_recipient_list_is_set(self):
email = "[email protected]"
factory = BaseEmailServiceFactory([email])
self.assertEqual(factory.recipient_email_list, [email])

def test_is_valid_positive_case(self):
email = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email])
factory.service_class = BaseEmailService
self.assertTrue(factory.is_valid())

def test_is_valid_no_recipients(self):
factory = BaseEmailServiceFactory()
factory.service_class = BaseEmailService
with self.assertRaises(EmailServiceConfigError):
factory.is_valid()

def test_is_valid_no_service_class(self):
email = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email])
with self.assertRaises(EmailServiceConfigError):
factory.is_valid()

def test_is_valid_no_exception_raised(self):
factory = BaseEmailServiceFactory()
factory.is_valid(raise_exception=False)
self.assertEqual(len(factory.errors), 2)

def test_has_errors_positive_case(self):
factory = BaseEmailServiceFactory()
factory.is_valid(raise_exception=False)
self.assertTrue(factory.has_errors())

def test_has_errors_negative_case(self):
email = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email])
factory.service_class = BaseEmailService
self.assertFalse(factory.has_errors())

def test_get_recipient_list_regular(self):
email_1 = "[email protected]"
email_2 = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email_1, email_2])
self.assertEqual(factory.get_recipient_list(), [email_1, email_2])

def test_get_email_from_recipient_regular(self):
email_1 = "[email protected]"
email_2 = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email_1, email_2])
self.assertEqual(factory.get_email_from_recipient(factory.get_recipient_list()[1]), email_2)

def test_get_context_data_regular(self):
factory = BaseEmailServiceFactory()
self.assertEqual(factory.get_context_data(), {})

def test_process_regular(self):
email_1 = "[email protected]"
email_2 = "[email protected]"
factory = BaseEmailServiceFactory(recipient_email_list=[email_1, email_2])
factory.service_class = self.TestMailService
self.assertEqual(factory.process(), 2)

def test_process_with_excepetion(self):
factory = BaseEmailServiceFactory()
factory.service_class = self.TestMailService
with self.assertRaises(EmailServiceConfigError):
factory.process()
from django_pony_express.services.base import BaseEmailService


class BaseEmailServiceTest(TestCase):
Expand All @@ -102,6 +26,17 @@ def test_init_recipient_and_context_are_initialised_empty(self):
self.assertEqual(service.recipient_email_list, [])
self.assertEqual(service.context_data, {})

def test_get_logger_logger_not_set(self):
service = BaseEmailService()
email_logger = service._get_logger()
self.assertEqual(service._logger, email_logger)

def test_get_logger_logger_set(self):
service = BaseEmailService()
service._logger = logging.getLogger("my_logger")
email_logger = service._get_logger()
self.assertEqual(service._logger, email_logger)

def test_get_context_data_regular(self):
data = {"city": "Cologne"}
service = BaseEmailService(context_data=data)
Expand All @@ -114,7 +49,7 @@ def test_get_subject_no_prefix(self):
self.assertEqual(service.get_subject(), subject)

def test_get_subject_with_prefix(self):
prefix = "Ai: Core"
prefix = "Pony Express"
subject = "I am a subject!"
service = BaseEmailService()
service.SUBJECT_PREFIX = prefix
Expand Down Expand Up @@ -373,6 +308,57 @@ def test_has_errors_negative_case(self):
service.template_name = "testapp/test_email.html"
self.assertFalse(service.has_errors())

@mock.patch("django_pony_express.services.base.BaseEmailService._logger")
def test_send_and_log_email_success_privacy_active(self, mock_logger):
service = BaseEmailService(recipient_email_list=["[email protected]"])
result = service._send_and_log_email(
msg=EmailMultiAlternatives(subject="The Pony Express", to=["[email protected]"])
)

mock_logger.debug.assert_called_with('Email "%s" successfully sent.', "The Pony Express")
self.assertEqual(result, 1)

@mock.patch("django_pony_express.services.base.BaseEmailService._logger")
@mock.patch("django_pony_express.services.base.PONY_LOG_RECIPIENTS", True)
def test_send_and_log_success_privacy_inactive(self, mock_logger):
service = BaseEmailService(recipient_email_list=["[email protected]"])
result = service._send_and_log_email(
msg=EmailMultiAlternatives(subject="The Pony Express", to=["[email protected]"])
)

mock_logger.debug.assert_called_with(
'Email "%s" successfully sent to %s.', "The Pony Express", "[email protected]"
)
self.assertEqual(result, 1)

@mock.patch.object(EmailMultiAlternatives, "send", side_effect=Exception("Broken pony"))
@mock.patch("django_pony_express.services.base.BaseEmailService._logger")
def test_send_and_log_email_failure_privacy_active(self, mock_logger, *args):
service = BaseEmailService(recipient_email_list=["[email protected]"])
result = service._send_and_log_email(
msg=EmailMultiAlternatives(subject="The Pony Express", to=["[email protected]"])
)

mock_logger.error('An error occurred sending email "%s": %s', "The Pony Express", "Broken pony")
self.assertFalse(result)

@mock.patch.object(EmailMultiAlternatives, "send", side_effect=Exception("Broken pony"))
@mock.patch("django_pony_express.services.base.BaseEmailService._logger")
@mock.patch("django_pony_express.services.base.PONY_LOG_RECIPIENTS", True)
def test_send_and_log_success_privacy_inactive(self, mock_logger, *args):
service = BaseEmailService(recipient_email_list=["[email protected]"])
result = service._send_and_log_email(
msg=EmailMultiAlternatives(subject="The Pony Express", to=["[email protected]"])
)

mock_logger.error(
'An error occurred sending email "%s" to %s: %s',
"The Pony Express",
"[email protected]",
"Broken pony",
)
self.assertFalse(result)

def test_process_regular(self):
email = "[email protected]"
subject = "Test email"
Expand Down
Empty file.
File renamed without changes.

0 comments on commit 5ba94d5

Please sign in to comment.