diff --git a/adminalerts/tests/test_views.py b/adminalerts/tests/test_views.py index 6be97a7f..37aff32b 100644 --- a/adminalerts/tests/test_views.py +++ b/adminalerts/tests/test_views.py @@ -7,19 +7,34 @@ from test_plus.test import TestCase +# Projectroles dependency +from projectroles.app_settings import AppSettingAPI + from adminalerts.models import AdminAlert from adminalerts.tests.test_models import AdminAlertMixin from adminalerts.views import EMAIL_SUBJECT +app_settings = AppSettingAPI() + + +# Local constants +ALERT_MSG = 'New alert' +ALERT_MSG_UPDATED = 'Updated alert' +ALERT_DESC = 'Description' +ALERT_DESC_UPDATED = 'Updated description' +ALERT_DESC_MARKDOWN = '## Description' +EMAIL_DESC_LEGEND = 'Additional details' + + class AdminalertsViewTestBase(AdminAlertMixin, TestCase): """Base class for adminalerts view testing""" def _make_alert(self): return self.make_alert( - message='alert', + message=ALERT_MSG, user=self.superuser, - description='description', + description=ALERT_DESC, active=True, require_auth=True, ) @@ -30,7 +45,7 @@ def setUp(self): self.superuser.is_superuser = True self.superuser.is_staff = True self.superuser.save() - self.regular_user = self.make_user('regular_user') + self.user_regular = self.make_user('user_regular') # No user self.anonymous = None self.expiry_str = ( @@ -92,11 +107,12 @@ def test_post(self): self.assertEqual(AdminAlert.objects.all().count(), 0) self.assertEqual(len(mail.outbox), 0) post_data = { - 'message': 'new alert', - 'description': 'description', + 'message': ALERT_MSG, + 'description': ALERT_DESC, 'date_expire': self.expiry_str, - 'active': 1, - 'require_auth': 1, + 'active': True, + 'require_auth': True, + 'send_email': True, } with self.login(self.superuser): response = self.client.post(self.url, post_data) @@ -105,18 +121,175 @@ def test_post(self): self.assertEqual(AdminAlert.objects.all().count(), 1) self.assertEqual(len(mail.outbox), 1) self.assertIn( - EMAIL_SUBJECT.format(state='New', message='new alert'), + EMAIL_SUBJECT.format(state='New', message=ALERT_MSG), mail.outbox[0].subject, ) self.assertEqual( mail.outbox[0].recipients(), - [settings.EMAIL_SENDER, self.regular_user.email], + [settings.EMAIL_SENDER, self.user_regular.email], + ) + self.assertEqual(mail.outbox[0].to, [settings.EMAIL_SENDER]) + self.assertEqual(mail.outbox[0].bcc, [self.user_regular.email]) + self.assertIn(ALERT_MSG, mail.outbox[0].body) + self.assertIn(EMAIL_DESC_LEGEND, mail.outbox[0].body) + self.assertIn(ALERT_DESC, mail.outbox[0].body) + + def test_post_no_description(self): + """Test POST with no description""" + self.assertEqual(len(mail.outbox), 0) + post_data = { + 'message': ALERT_MSG, + 'description': '', + 'date_expire': self.expiry_str, + 'active': True, + 'require_auth': True, + 'send_email': True, + } + with self.login(self.superuser): + response = self.client.post(self.url, post_data) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 1) + self.assertIn(ALERT_MSG, mail.outbox[0].body) + self.assertNotIn(EMAIL_DESC_LEGEND, mail.outbox[0].body) + + def test_post_markdown_description(self): + """Test POST with markdown description""" + self.assertEqual(len(mail.outbox), 0) + post_data = { + 'message': ALERT_MSG, + 'description': ALERT_DESC_MARKDOWN, + 'date_expire': self.expiry_str, + 'active': True, + 'require_auth': True, + 'send_email': True, + } + with self.login(self.superuser): + response = self.client.post(self.url, post_data) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 1) + self.assertIn(ALERT_MSG, mail.outbox[0].body) + self.assertIn(EMAIL_DESC_LEGEND, mail.outbox[0].body) + # Description should be provided in raw format + self.assertIn(ALERT_DESC_MARKDOWN, mail.outbox[0].body) + + def test_post_no_email(self): + """Test POST with no email to be sent""" + self.assertEqual(len(mail.outbox), 0) + post_data = { + 'message': ALERT_MSG, + 'description': ALERT_DESC, + 'date_expire': self.expiry_str, + 'active': True, + 'require_auth': True, + 'send_email': False, + } + with self.login(self.superuser): + response = self.client.post(self.url, post_data) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 0) + + def test_post_inactive(self): + """Test POST with inactive state""" + self.assertEqual(len(mail.outbox), 0) + post_data = { + 'message': ALERT_MSG, + 'description': ALERT_DESC, + 'date_expire': self.expiry_str, + 'active': False, + 'require_auth': True, + 'send_email': True, + } + with self.login(self.superuser): + response = self.client.post(self.url, post_data) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 0) + + def test_post_multiple_users(self): + """Test POST with multiple users""" + user_new = self.make_user('user_new') + self.assertEqual(len(mail.outbox), 0) + post_data = { + 'message': ALERT_MSG, + 'description': ALERT_DESC, + 'date_expire': self.expiry_str, + 'active': True, + 'require_auth': True, + 'send_email': True, + } + with self.login(self.superuser): + response = self.client.post(self.url, post_data) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 1) + self.assertEqual( + mail.outbox[0].recipients(), + [settings.EMAIL_SENDER, user_new.email, self.user_regular.email], + ) + self.assertIn(ALERT_MSG, mail.outbox[0].body) + self.assertIn(EMAIL_DESC_LEGEND, mail.outbox[0].body) + self.assertIn(ALERT_DESC, mail.outbox[0].body) + + def test_post_alt_email_regular_user(self): + """Test POST with alt emails on regular user""" + alt_email = 'alt@example.com' + alt_email2 = 'alt2@example.com' + app_settings.set( + 'projectroles', + 'user_email_additional', + ';'.join([alt_email, alt_email2]), + user=self.user_regular, + ) + self.assertEqual(len(mail.outbox), 0) + post_data = { + 'message': ALERT_MSG, + 'description': ALERT_DESC, + 'date_expire': self.expiry_str, + 'active': True, + 'require_auth': True, + 'send_email': True, + } + with self.login(self.superuser): + response = self.client.post(self.url, post_data) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 1) + self.assertEqual( + mail.outbox[0].recipients(), + [ + settings.EMAIL_SENDER, + self.user_regular.email, + alt_email, + alt_email2, + ], + ) + + def test_post_alt_email_superuser(self): + """Test POST with alt emails on superuser""" + alt_email = 'alt@example.com' + alt_email2 = 'alt2@example.com' + app_settings.set( + 'projectroles', + 'user_email_additional', + ';'.join([alt_email, alt_email2]), + user=self.superuser, + ) + self.assertEqual(len(mail.outbox), 0) + post_data = { + 'message': ALERT_MSG, + 'description': ALERT_DESC, + 'date_expire': self.expiry_str, + 'active': True, + 'require_auth': True, + 'send_email': True, + } + with self.login(self.superuser): + response = self.client.post(self.url, post_data) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 1) + # Superuser alt emails should not be included + self.assertEqual( + mail.outbox[0].recipients(), + [settings.EMAIL_SENDER, self.user_regular.email], ) - # TODO: Assert message and description - # TODO: Test with no description - # TODO: Test with email set false - # TODO: Test with email set true and alt emails on user # TODO: Test with email notifications disabled def test_post_expired(self): @@ -126,11 +299,12 @@ def test_post_expired(self): '%Y-%m-%d' ) post_data = { - 'message': 'new alert', - 'description': 'description', + 'message': ALERT_MSG, + 'description': ALERT_DESC, 'date_expire': expiry_fail, - 'active': 1, - 'require_auth': 1, + 'active': True, + 'require_auth': True, + 'send_email': True, } with self.login(self.superuser): response = self.client.post(self.url, post_data) @@ -141,6 +315,8 @@ def test_post_expired(self): class TestAdminAlertUpdateView(AdminalertsViewTestBase): """Tests for AdminAlertUpdateView""" + # TODO: Update settings for email + def setUp(self): super().setUp() self.alert = self._make_alert() @@ -160,8 +336,8 @@ def test_post(self): self.assertEqual(AdminAlert.objects.all().count(), 1) self.assertEqual(len(mail.outbox), 0) post_data = { - 'message': 'updated alert', - 'description': 'updated description', + 'message': ALERT_MSG_UPDATED, + 'description': ALERT_DESC_UPDATED, 'date_expire': self.expiry_str, 'active': '', } @@ -171,8 +347,8 @@ def test_post(self): self.assertEqual(response.url, reverse('adminalerts:list')) self.assertEqual(AdminAlert.objects.all().count(), 1) self.alert.refresh_from_db() - self.assertEqual(self.alert.message, 'updated alert') - self.assertEqual(self.alert.description.raw, 'updated description') + self.assertEqual(self.alert.message, ALERT_MSG_UPDATED) + self.assertEqual(self.alert.description.raw, ALERT_DESC_UPDATED) self.assertEqual(self.alert.active, False) self.assertEqual(len(mail.outbox), 0) @@ -185,8 +361,8 @@ def test_post_user(self): superuser2.is_superuser = True superuser2.save() post_data = { - 'message': 'updated alert', - 'description': 'updated description', + 'message': ALERT_MSG_UPDATED, + 'description': ALERT_DESC_UPDATED, 'date_expire': self.expiry_str, 'active': '', } diff --git a/adminalerts/views.py b/adminalerts/views.py index 54a7d322..820c5610 100644 --- a/adminalerts/views.py +++ b/adminalerts/views.py @@ -152,7 +152,11 @@ def form_valid(self, form): self.object = form.save() email_count = 0 email_msg_suffix = '' - if settings.PROJECTROLES_SEND_EMAIL and self.object.active: + if ( + form.cleaned_data['send_email'] + and self.object.active + and settings.PROJECTROLES_SEND_EMAIL + ): email_count = self._send_email(form.instance, form_action) if email_count > 0: email_msg_suffix = ', {} email{} sent'.format( diff --git a/config/settings/test.py b/config/settings/test.py index 19c89d2a..57f435eb 100644 --- a/config/settings/test.py +++ b/config/settings/test.py @@ -31,6 +31,7 @@ # In-memory email backend stores messages in django.core.mail.outbox # for unit testing purposes EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend' +EMAIL_SENDER = 'noreply@example.com' # CACHING # ------------------------------------------------------------------------------