import json from django.test import TestCase from vbv_lernwelt.core.models import User from vbv_lernwelt.core.tests.factories import UserFactory from vbv_lernwelt.notify.email.email_services import EmailTemplate from vbv_lernwelt.notify.models import ( Notification, NotificationCategory, NotificationTrigger, ) from vbv_lernwelt.notify.services import NotificationService class TestNotificationService(TestCase): def _on_send_email(self, *_, **__) -> bool: self._emails_sent += 1 return True def _has_sent_emails(self) -> bool: return self._emails_sent != 0 def setUp(self) -> None: self._emails_sent = 0 self.notification_service = NotificationService self.notification_service._send_email = self._on_send_email self.admin = UserFactory(username="admin", email="admin") self.sender_username = "Bob" UserFactory(username=self.sender_username, email="bob@example.com") self.sender = User.objects.get(username=self.sender_username) self.recipient_username = "Alice" UserFactory(username=self.recipient_username, email="alice@example.com") self.recipient = User.objects.get(username=self.recipient_username) self.recipient.save() self.client.login(username=self.recipient, password="pw") def test_send_notification_without_email(self): verb = "Anne hat deinen Auftrag bewertet" target_url = "https://www.vbv.ch" result = self.notification_service._send_notification( sender=self.sender, recipient=self.recipient, verb=verb, target_url=target_url, notification_category=NotificationCategory.USER_INTERACTION, notification_trigger=NotificationTrigger.CASEWORK_SUBMITTED, fail_silently=False, ) self.assertEqual(result, "USER_INTERACTION_CASEWORK_SUBMITTED_success") self.assertEqual(1, Notification.objects.count()) notification: Notification = Notification.objects.first() self.assertEqual(self.sender, notification.actor) self.assertEqual(verb, notification.verb) self.assertEqual(target_url, notification.target_url) self.assertEqual( str(NotificationCategory.USER_INTERACTION), notification.notification_category, ) self.assertFalse(notification.emailed) def test_send_notification_with_email(self): self.recipient.additional_json_data[ "email_notification_categories" ] = json.dumps(["USER_INTERACTION"]) self.recipient.save() verb = "Anne hat deinen Auftrag bewertet" target_url = "https://www.vbv.ch" result = self.notification_service._send_notification( sender=self.sender, recipient=self.recipient, verb=verb, target_url=target_url, notification_category=NotificationCategory.USER_INTERACTION, notification_trigger=NotificationTrigger.CASEWORK_SUBMITTED, email_template=EmailTemplate.CASEWORK_SUBMITTED, fail_silently=False, ) self.assertEqual(result, "USER_INTERACTION_CASEWORK_SUBMITTED_emailed_success") self.assertEqual(1, Notification.objects.count()) notification: Notification = Notification.objects.first() self.assertEqual(self.sender, notification.actor) self.assertEqual(verb, notification.verb) self.assertEqual(target_url, notification.target_url) self.assertEqual( str(NotificationCategory.USER_INTERACTION), notification.notification_category, ) self.assertTrue(notification.emailed) def test_does_not_send_duplicate_notification(self): verb = "Anne hat deinen Auftrag bewertet" target_url = "https://www.vbv.ch" result = self.notification_service._send_notification( sender=self.sender, recipient=self.recipient, verb=verb, target_url=target_url, notification_category=NotificationCategory.USER_INTERACTION, notification_trigger=NotificationTrigger.CASEWORK_SUBMITTED, email_template=EmailTemplate.CASEWORK_SUBMITTED, template_data={ "blah": 123, "foo": "ich habe hunger", }, ) self.assertEqual(result, "USER_INTERACTION_CASEWORK_SUBMITTED_success") result = self.notification_service._send_notification( sender=self.sender, recipient=self.recipient, verb=verb, target_url=target_url, notification_category=NotificationCategory.USER_INTERACTION, notification_trigger=NotificationTrigger.CASEWORK_SUBMITTED, email_template=EmailTemplate.CASEWORK_SUBMITTED, template_data={ "blah": 123, "foo": "ich habe hunger", }, ) self.assertEqual(result, "USER_INTERACTION_CASEWORK_SUBMITTED_duplicate") self.assertEqual(1, Notification.objects.count()) notification: Notification = Notification.objects.first() self.assertEqual(self.sender, notification.actor) self.assertEqual(verb, notification.verb) self.assertEqual(target_url, notification.target_url) self.assertEqual( str(NotificationCategory.USER_INTERACTION), notification.notification_category, ) self.assertEqual( str(NotificationTrigger.CASEWORK_SUBMITTED), notification.notification_trigger, ) self.assertFalse(notification.emailed) # when the email was not sent, yet it will still send it afterwards... self.recipient.additional_json_data[ "email_notification_categories" ] = json.dumps(["USER_INTERACTION"]) self.recipient.save() result = self.notification_service._send_notification( sender=self.sender, recipient=self.recipient, verb=verb, target_url=target_url, notification_category=NotificationCategory.USER_INTERACTION, notification_trigger=NotificationTrigger.CASEWORK_SUBMITTED, email_template=EmailTemplate.CASEWORK_SUBMITTED, template_data={ "blah": 123, "foo": "ich habe hunger", }, ) self.assertEqual( result, "USER_INTERACTION_CASEWORK_SUBMITTED_emailed_duplicate" ) self.assertEqual(1, Notification.objects.count()) notification: Notification = Notification.objects.first() self.assertTrue(notification.emailed) def test_only_sends_email_if_enabled(self): # Assert no mail is sent if corresponding email notification type is not enabled self.notification_service._send_notification( sender=self.sender, recipient=self.recipient, verb="should not be sent", target_url="", notification_category=NotificationCategory.USER_INTERACTION, notification_trigger=NotificationTrigger.CASEWORK_SUBMITTED, email_template=EmailTemplate.CASEWORK_SUBMITTED, template_data={}, ) self.assertEqual(1, Notification.objects.count()) self.assertFalse(self._has_sent_emails()) # Assert mail is sent if corresponding email notification type is enabled self.recipient.additional_json_data[ "email_notification_categories" ] = json.dumps(["USER_INTERACTION"]) self.recipient.save() self.notification_service._send_notification( sender=self.sender, recipient=self.recipient, verb="should be sent", target_url="", notification_category=NotificationCategory.USER_INTERACTION, notification_trigger=NotificationTrigger.CASEWORK_SUBMITTED, email_template=EmailTemplate.CASEWORK_SUBMITTED, template_data={}, ) self.assertEqual(2, Notification.objects.count()) self.assertTrue(self._has_sent_emails())