import datetime import logging from django.conf import settings from django.core import mail from django.core.management import call_command from django.utils import timezone from unittest.mock import patch from openach.digest import create_digest_email, send_digest_emails from openach.models import Evidence, Hypothesis, BoardFollower, DigestFrequency from openach.views.notifications import notify_add from .common import PrimaryUserTestCase, create_board logger = logging.getLogger(__name__) DEFAULT_FROM_EMAIL = getattr(settings, 'DEFAULT_FROM_EMAIL', 'admin@localhost') class DigestTests(PrimaryUserTestCase): def setUp(self): super().setUp() self.daily = self.user self.weekly = self.other def setup_user(user, freq): user.date_joined = timezone.now() + datetime.timedelta(days=-2) user.save() user.settings.digest_frequency = freq.key user.settings.save() setup_user(self.daily, DigestFrequency.daily) setup_user(self.weekly, DigestFrequency.weekly) def test_can_create_first_digest(self): """Test that we can create a digest if the user hasn't received a digest before.""" run_timestamp = timezone.now() create_board(board_title='New Board', days=-1) email = create_digest_email(self.daily, DigestFrequency.daily, run_timestamp) self.assertListEqual(email.to, [self.daily.email]) logger.debug(email.subject) self.assertGreater(len(email.alternatives), 0, 'No HTML body attached to digest email') self.assertTrue('daily' in email.subject, 'No digest frequency in subject: {}'.format(email.subject)) self.assertTrue('daily' in email.body) def test_can_email_first_daily_digest(self): """Test that we can email a digest if the user hasn't received a daily digest before.""" create_board(board_title='New Board', days=0) succeeded, passed, failed = send_digest_emails(DigestFrequency.daily) self.assertEqual(succeeded, 1) self.assertEqual(passed, 0) self.assertEqual(failed, 0) self.assertEqual(len(mail.outbox), 1, 'No digest email sent') self.assertGreater(len(mail.outbox[0].alternatives), 0, 'No HTML body attached to digest email') self.assertListEqual(mail.outbox[0].to, [self.daily.email]) self.assertEqual(mail.outbox[0].from_email, DEFAULT_FROM_EMAIL) def test_can_email_hypothesis_evidence_digest(self): """Test that we can email a digest containing new hypotheses and evidence.""" for x in [1, 2]: board = create_board(board_title='Board #{}'.format(x), days=0) BoardFollower.objects.create( board=board, user=self.daily, ) hypothesis = Hypothesis.objects.create( board=board, hypothesis_text='Hypothesis #{}'.format(x), creator=self.weekly, ) evidence = Evidence.objects.create( board=board, evidence_desc='Evidence #{}'.format(x), creator=self.weekly, ) notify_add(board, self.weekly, hypothesis) notify_add(board, self.weekly, evidence) succeeded, passed, failed = send_digest_emails(DigestFrequency.daily) self.assertEqual(succeeded, 1) self.assertEqual(len(mail.outbox), 1, 'No digest email sent') txt_body = mail.outbox[0].body logger.info(txt_body) for x in [1, 2]: self.assertTrue('Board #{}'.format(x) in txt_body) self.assertTrue('Hypothesis #{}'.format(x) in txt_body) self.assertTrue('Evidence #{}'.format(x) in txt_body) def test_email_digest_command(self): """Test that admin can send digest from a manage command.""" create_board(board_title='New Board', days=0) call_command('senddigest', 'daily') self.assertEqual(len(mail.outbox), 1, 'No weekly digest email sent') def test_email_weekly_command_digest_day(self): """Test that admin can send digest on the weekly digest day.""" setattr(settings, 'DIGEST_WEEKLY_DAY', 0) previous = timezone.now() static = previous # find the next scheduled digest day while static.weekday() != 0: static += timezone.timedelta(days=1) with patch('openach.management.commands.senddigest.timezone.now') as timezone_mock: timezone_mock.return_value = static logger.debug('Shifted timezone.now() from weekday %s to %s', previous.weekday(), static.weekday()) create_board(board_title='New Board', days=-1) call_command('senddigest', 'weekly') self.assertEqual(len(mail.outbox), 1, 'No weekly digest email sent') def test_email_weekly_command_other_day(self): """Test that admin cannot digest email not on weekly digest day unless forced.""" setattr(settings, 'DIGEST_WEEKLY_DAY', 0) previous = timezone.now() static = previous # make sure we're not on a scheduled digest day while static.weekday() == 0: static += timezone.timedelta(days=1) with patch('openach.management.commands.senddigest.timezone.now') as timezone_mock: timezone_mock.return_value = static logger.debug('Shifted timezone.now() from weekday %s to %s', previous.weekday(), static.weekday()) create_board(board_title='New Board', days=-1) call_command('senddigest', 'weekly') self.assertEqual(len(mail.outbox), 0, 'Weekly digest email sent on wrong day') call_command('senddigest', 'weekly', '--force') self.assertEqual(len(mail.outbox), 1, 'Weekly digest email not sent when forced')