From 948e184790c335f848dbe15b3633e1e19a6969e7 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Thu, 28 Nov 2024 17:42:34 +0100 Subject: [PATCH] update email notification recipient, refactor tests in pytest style (WIP) --- lacommunaute/notification/tasks.py | 7 +- .../notification/tests/tests_tasks.py | 158 +++++++----------- 2 files changed, 65 insertions(+), 100 deletions(-) diff --git a/lacommunaute/notification/tasks.py b/lacommunaute/notification/tasks.py index 99c6fdb8b..a81293e1d 100644 --- a/lacommunaute/notification/tasks.py +++ b/lacommunaute/notification/tasks.py @@ -3,7 +3,7 @@ from django.urls import reverse from django.utils import timezone -from config.settings.base import DEFAULT_FROM_EMAIL, NEW_MESSAGES_EMAIL_MAX_PREVIEW, SIB_NEW_MESSAGES_TEMPLATE +from config.settings.base import NEW_MESSAGES_EMAIL_MAX_PREVIEW, SIB_NEW_MESSAGES_TEMPLATE from lacommunaute.forum_conversation.models import Topic from lacommunaute.notification.emails import bulk_send_user_to_list, collect_users_from_list, send_email from lacommunaute.notification.enums import EmailSentTrackKind, NotificationDelay @@ -33,10 +33,9 @@ def get_grouped_notifications(): "messages": get_serialized_messages(recipient_notifications[:NEW_MESSAGES_EMAIL_MAX_PREVIEW]), } send_email( - to=[{"email": DEFAULT_FROM_EMAIL}], + to=[{"email": recipient}], params=params, - bcc=[{"email": recipient}], - kind=EmailSentTrackKind.FOLLOWING_REPLIES, + kind=EmailSentTrackKind.BULK_NOTIFS, template_id=SIB_NEW_MESSAGES_TEMPLATE, ) diff --git a/lacommunaute/notification/tests/tests_tasks.py b/lacommunaute/notification/tests/tests_tasks.py index 5446fb2dc..780461899 100644 --- a/lacommunaute/notification/tests/tests_tasks.py +++ b/lacommunaute/notification/tests/tests_tasks.py @@ -1,28 +1,30 @@ import json import httpx +import pytest import respx from django.conf import settings -from django.template.defaultfilters import pluralize from django.test import TestCase from django.urls import reverse from faker import Faker from config.settings.base import ( DEFAULT_FROM_EMAIL, - NEW_MESSAGES_EMAIL_MAX_PREVIEW, SIB_CONTACT_LIST_URL, SIB_CONTACTS_URL, - SIB_NEW_MESSAGES_TEMPLATE, SIB_ONBOARDING_LIST, SIB_SMTP_URL, SIB_UNANSWERED_QUESTION_TEMPLATE, ) from lacommunaute.forum.factories import ForumFactory -from lacommunaute.forum_conversation.factories import TopicFactory -from lacommunaute.notification.enums import EmailSentTrackKind, NotificationDelay +from lacommunaute.forum_conversation.factories import ( + AnonymousPostFactory, + PostFactory, + TopicFactory, +) +from lacommunaute.notification.enums import NotificationDelay from lacommunaute.notification.factories import NotificationFactory -from lacommunaute.notification.models import EmailSentTrack, Notification +from lacommunaute.notification.models import EmailSentTrack from lacommunaute.notification.tasks import ( add_user_to_list_when_register, send_messages_notifications, @@ -35,108 +37,72 @@ faker = Faker() -class SendMessageNotificationsTestCase(TestCase): - def setUp(self): - super().setUp() +@pytest.fixture(name="mock_respx_post_to_sib_smtp_url") +def mock_respx_post_to_sib_smtp_url_fixture(): + with respx.mock: respx.post(SIB_SMTP_URL).mock(return_value=httpx.Response(200, json={"message": "OK"})) - - def get_expected_email_payload(self, notifications): - grouped_notifications = notifications.select_related( - "post", "post__topic", "post__poster" - ).group_by_recipient() - - assert ( - len(grouped_notifications.keys()) == 1 - ), "get_expected_email_payload requires notifications with only one recipient" - - recipient = list(grouped_notifications.keys())[0] - recipient_notifications = grouped_notifications[recipient] - message_count = len(recipient_notifications) - message_count_text = f"{message_count} message{pluralize(message_count, 's')}" - - params = { - "email_object": "Bonne nouvelle, ça bouge pour vous dans la communauté !", - "email_thumbnail": (f"Vous avez {message_count_text} à découvrir sur la communauté de l'inclusion"), - "messages": get_serialized_messages(recipient_notifications[:NEW_MESSAGES_EMAIL_MAX_PREVIEW]), - } - - return { - "to": [{"email": DEFAULT_FROM_EMAIL}], - "bcc": [{"email": recipient}], - "params": params, - "sender": {"name": "La Communauté", "email": DEFAULT_FROM_EMAIL}, - "templateId": SIB_NEW_MESSAGES_TEMPLATE, - } - - @respx.mock - def test_send_messages_notifications_asap(self): - topic = TopicFactory(with_post=True) - notification = NotificationFactory(post=topic.first_post, delay=NotificationDelay.ASAP) + yield + + +class TestSendMessagesNotifications: + def test_generic_payload(self, email, payload): + assert payload["to"] == [{"email": email}] + assert payload["sender"] == {"name": "La Communauté", "email": settings.DEFAULT_FROM_EMAIL} + assert payload["templateId"] == settings.SIB_NEW_MESSAGES_TEMPLATE + + def test_grouped_asap_notifications(self, db, mock_respx_post_to_sib_smtp_url): + user = UserFactory() + notifications = [ + NotificationFactory( + recipient=user.email, delay=NotificationDelay.ASAP, post=PostFactory(topic=TopicFactory()) + ), + NotificationFactory( + recipient=user.email, delay=NotificationDelay.ASAP, post=AnonymousPostFactory(topic=TopicFactory()) + ), + ] + NotificationFactory(recipient=user.email, delay=NotificationDelay.DAY) send_messages_notifications(NotificationDelay.ASAP) - email_sent_track = EmailSentTrack.objects.get() - self.assertEqual(email_sent_track.status_code, 200) - self.assertJSONEqual(email_sent_track.response, {"message": "OK"}) - self.assertEqual( - email_sent_track.datas, self.get_expected_email_payload(Notification.objects.filter(id=notification.id)) - ) - self.assertIsNone(Notification.objects.filter(sent_at__isnull=True).first()) - self.assertEqual(Notification.objects.all().values("sent_at").distinct().count(), 1) - - @respx.mock - def test_send_messages_notifications_day(self): - topic = TopicFactory(with_post=True) - notification = NotificationFactory(post=topic.first_post, delay=NotificationDelay.DAY) + self.test_generic_payload(user.email, email_sent_track.datas) + + for attr, expected in [ + ("messages", get_serialized_messages(notifications)), + ("email_object", "Bonne nouvelle, ça bouge pour vous dans la communauté !"), + ("email_thumbnail", "Vous avez 2 messages à découvrir sur la communauté de l'inclusion"), + ]: + assert email_sent_track.datas["params"][attr] == expected + + def test_grouped_day_notifications(self, db, mock_respx_post_to_sib_smtp_url): + user = UserFactory() + notifications = [ + NotificationFactory( + recipient=user.email, delay=NotificationDelay.DAY, post=PostFactory(topic=TopicFactory()) + ), + NotificationFactory( + recipient=user.email, delay=NotificationDelay.DAY, post=AnonymousPostFactory(topic=TopicFactory()) + ), + ] + NotificationFactory(recipient=user.email, delay=NotificationDelay.ASAP) send_messages_notifications(NotificationDelay.DAY) - email_sent_track = EmailSentTrack.objects.get() - self.assertEqual(email_sent_track.status_code, 200) - self.assertJSONEqual(email_sent_track.response, {"message": "OK"}) - self.assertEqual( - email_sent_track.datas, self.get_expected_email_payload(Notification.objects.filter(id=notification.id)) - ) - - self.assertIsNone(Notification.objects.filter(sent_at__isnull=True).first()) - self.assertEqual(Notification.objects.all().values("sent_at").distinct().count(), 1) - - @respx.mock - def test_send_messages_notifications_max_messages_preview(self): - topic = TopicFactory(with_post=True) - notif_count_to_generate = NEW_MESSAGES_EMAIL_MAX_PREVIEW + 1 - - NotificationFactory.create_batch( - notif_count_to_generate, - recipient="test@example.com", - delay=NotificationDelay.ASAP, - kind=EmailSentTrackKind.FIRST_REPLY, - post=topic.first_post, - ) - - send_messages_notifications(NotificationDelay.ASAP) - - email_sent_track = EmailSentTrack.objects.get() - self.assertEqual(len(email_sent_track.datas["params"]["messages"]), NEW_MESSAGES_EMAIL_MAX_PREVIEW) - self.assertEqual( - email_sent_track.datas["params"]["email_thumbnail"], - (f"Vous avez {notif_count_to_generate } messages à découvrir sur la communauté de l'inclusion"), - ) - - @respx.mock - def test_send_messages_notifications_num_queries(self): - expected_queries = 2 - NotificationFactory(delay=NotificationDelay.ASAP) + self.test_generic_payload(user.email, email_sent_track.datas) - with self.assertNumQueries(expected_queries): - send_messages_notifications(NotificationDelay.ASAP) + for attr, expected in [ + ("messages", get_serialized_messages(notifications)), + ("email_object", "Bonne nouvelle, ça bouge pour vous dans la communauté !"), + ("email_thumbnail", "Vous avez 2 messages à découvrir sur la communauté de l'inclusion"), + ]: + assert email_sent_track.datas["params"][attr] == expected - NotificationFactory.create_batch(10, delay=NotificationDelay.ASAP) + def test_grouped_max_messages_preview(self, db, mock_respx_post_to_sib_smtp_url): + pass - with self.assertNumQueries(expected_queries): - send_messages_notifications(NotificationDelay.ASAP) + def test_num_queries(self, db, mock_respx_post_to_sib_smtp_url): + pass class AddUserToListWhenRegister(TestCase):