Skip to content

Commit

Permalink
feat(Email): Enhance transactional email handling with disabled email…
Browse files Browse the repository at this point in the history
… group
  • Loading branch information
SebastienReuiller committed Jan 9, 2025
1 parent 65a2fe6 commit e3a27aa
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 27 deletions.
46 changes: 24 additions & 22 deletions lemarche/conversations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ class EmailGroup(models.Model):
def __str__(self):
return f"{self.display_name} ({self.relevant_user_kind if self.relevant_user_kind else 'Tous'})"

def disabled_for_user(self, user):
return DisabledEmail.objects.filter(user=user, group=self).exists()
def disabled_for_email(self, email):
return DisabledEmail.objects.filter(user__email=email, group=self).exists()


class TemplateTransactionalQuerySet(models.QuerySet):
Expand Down Expand Up @@ -324,27 +324,29 @@ def send_transactional_email(
parent_content_object=None,
):
if self.is_active:
args = {
"template_id": self.get_template_id,
"recipient_email": recipient_email,
"recipient_name": recipient_name,
"variables": variables,
"subject": subject,
"from_email": from_email,
"from_name": from_name,
}

# create log
self.create_send_log(
recipient_content_object=recipient_content_object,
parent_content_object=parent_content_object,
extra_data={"source": self.source, "args": args}, # "response": result()
)
# recipient email doesn't associated to a user or associated user doesn't disable this email group
if not self.group or not self.group.disabled_for_email(recipient_email):
args = {
"template_id": self.get_template_id,
"recipient_email": recipient_email,
"recipient_name": recipient_name,
"variables": variables,
"subject": subject,
"from_email": from_email,
"from_name": from_name,
}

# create log
self.create_send_log(
recipient_content_object=recipient_content_object,
parent_content_object=parent_content_object,
extra_data={"source": self.source, "args": args}, # "response": result()
)

if self.source == conversation_constants.SOURCE_MAILJET:
api_mailjet.send_transactional_email_with_template(**args)
elif self.source == conversation_constants.SOURCE_BREVO:
api_brevo.send_transactional_email_with_template(**args)
if self.source == conversation_constants.SOURCE_MAILJET:
api_mailjet.send_transactional_email_with_template(**args)
elif self.source == conversation_constants.SOURCE_BREVO:
api_brevo.send_transactional_email_with_template(**args)


class TemplateTransactionalSendLog(models.Model):
Expand Down
91 changes: 86 additions & 5 deletions lemarche/conversations/tests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import datetime
from unittest import mock
from unittest.mock import patch

from django.core.exceptions import ValidationError
Expand All @@ -10,8 +11,9 @@
from lemarche.conversations import constants as conversation_constants
from lemarche.conversations.constants import ATTRIBUTES_TO_NOT_ANONYMIZE_FOR_INBOUND, ATTRIBUTES_TO_SAVE_FOR_INBOUND
from lemarche.conversations.factories import ConversationFactory, TemplateTransactionalFactory
from lemarche.conversations.models import Conversation, TemplateTransactional
from lemarche.conversations.models import Conversation, DisabledEmail, EmailGroup, TemplateTransactional
from lemarche.siaes.factories import SiaeFactory
from lemarche.users.factories import UserFactory


class ConversationModelTest(TestCase):
Expand Down Expand Up @@ -113,17 +115,40 @@ def test_anonymize_command(self):
class TemplateTransactionalModelTest(TestCase):
@classmethod
def setUpTestData(cls):
cls.email_group = EmailGroup.objects.first()
cls.tt_inactive = TemplateTransactional(
code="EMAIL_1", mailjet_id=10, brevo_id=11, source=conversation_constants.SOURCE_MAILJET, is_active=False
name="Email 1",
code="EMAIL_1",
mailjet_id=10,
brevo_id=11,
source=conversation_constants.SOURCE_MAILJET,
is_active=False,
group=cls.email_group,
)
cls.tt_active_empty = TemplateTransactional(
code="EMAIL_2", source=conversation_constants.SOURCE_MAILJET, is_active=False
name="Email 2",
code="EMAIL_2",
source=conversation_constants.SOURCE_MAILJET,
is_active=False,
group=cls.email_group,
)
cls.tt_active_mailjet = TemplateTransactional(
code="EMAIL_3", mailjet_id=30, brevo_id=31, source=conversation_constants.SOURCE_MAILJET, is_active=True
name="Email 3",
code="EMAIL_3",
mailjet_id=30,
brevo_id=31,
source=conversation_constants.SOURCE_MAILJET,
is_active=True,
group=cls.email_group,
)
cls.tt_active_brevo = TemplateTransactional(
code="EMAIL_4", mailjet_id=40, brevo_id=41, source=conversation_constants.SOURCE_BREVO, is_active=True
name="Email 4",
code="EMAIL_4",
mailjet_id=40,
brevo_id=41,
source=conversation_constants.SOURCE_BREVO,
is_active=True,
group=cls.email_group,
)

def test_get_template_id(self):
Expand All @@ -132,6 +157,62 @@ def test_get_template_id(self):
self.assertEqual(self.tt_active_mailjet.get_template_id, self.tt_active_mailjet.mailjet_id)
self.assertEqual(self.tt_active_brevo.get_template_id, self.tt_active_brevo.brevo_id)

def test_send_transactional_email_mailjet(self):
with mock.patch(
"lemarche.conversations.models.api_mailjet.send_transactional_email_with_template"
) as mock_send_transactional_email_mailjet:
self.tt_active_mailjet.save()
self.tt_active_mailjet.send_transactional_email(
recipient_email="test@example.com", recipient_name="test", variables={}
)
mock_send_transactional_email_mailjet.assert_called_once()

def test_send_transactional_email_brevo(self):
with mock.patch(
"lemarche.conversations.models.api_brevo.send_transactional_email_with_template"
) as mock_send_transactional_email_brevo:
self.tt_active_brevo.save()
self.tt_active_brevo.send_transactional_email(
recipient_email="test@example.com", recipient_name="test", variables={}
)
mock_send_transactional_email_brevo.assert_called_once()

def test_send_transactional_email_inactive(self):
with mock.patch(
"lemarche.conversations.models.api_mailjet.send_transactional_email_with_template"
) as mock_send_transactional_email_mailjet:
with mock.patch(
"lemarche.conversations.models.api_brevo.send_transactional_email_with_template"
) as mock_send_transactional_email_brevo:
self.tt_inactive.save()
self.tt_inactive.send_transactional_email(
recipient_email="test@example.com", recipient_name="test", variables={}
)

mock_send_transactional_email_mailjet.assert_not_called()
mock_send_transactional_email_brevo.assert_not_called()

def test_disabled_email_group(self):
email_test = "test@example.com"
user = UserFactory(email=email_test)
with mock.patch(
"lemarche.conversations.models.api_brevo.send_transactional_email_with_template"
) as mock_send_transactional_email_brevo:
self.tt_active_brevo.save()
self.tt_active_brevo.send_transactional_email(
recipient_email=email_test, recipient_name="test", variables={}
)
mock_send_transactional_email_brevo.assert_called_once()

DisabledEmail.objects.create(user=user, group=self.email_group)
with mock.patch(
"lemarche.conversations.models.api_brevo.send_transactional_email_with_template"
) as mock_send_transactional_email_brevo:
self.tt_active_brevo.send_transactional_email(
recipient_email=email_test, recipient_name="test", variables={}
)
mock_send_transactional_email_brevo.assert_not_called()


class TemplateTransactionalModelSaveTest(TransactionTestCase):
reset_sequences = True
Expand Down

0 comments on commit e3a27aa

Please sign in to comment.