예제 #1
0
    def test_setup_report(self, mock_setup_sentry: mock.MagicMock) -> None:
        """Make sure the report is setup."""

        focus.main(['send'])

        mock_setup_sentry.assert_called_once_with('fake-sentry')
        self.assertTrue(mailjetmock.get_all_sent_messages())
예제 #2
0
    def test_error_no_secret_salt(self) -> None:
        """Error when trying to send without a secret salt."""

        with mock.patch(focus.auth.__name__ + '.SECRET_SALT',
                        new=focus.auth.FAKE_SECRET_SALT):
            with self.assertRaises(ValueError):
                focus.main(['send', '--disable-sentry'])
예제 #3
0
    def test_list_emails(self, mock_logging: mock.MagicMock) -> None:
        """List uses logging extensively but does not send any email."""

        focus.main(['list'])

        mock_logging.info.assert_called()

        self.assertFalse(mailjetmock.get_all_sent_messages())
예제 #4
0
    def test_failed_setup_report(self, mock_error: mock.MagicMock) -> None:
        """Warn if the report is not correctly setup."""

        focus.main(['send'])

        mock_error.assert_called_once_with(
            'Please set SENTRY_DSN to enable logging to Sentry, or use --disable-sentry option'
        )
        self.assertFalse(mailjetmock.get_all_sent_messages())
예제 #5
0
    def test_send_all_focus_emails(
            self, unused_mock_logging: mock.MagicMock) -> None:
        """Sending all focus emails in 6 months."""

        days_without_email = 0
        sent_emails_count = 0

        # Try sending emails until there has been a month without any email sent.
        while days_without_email < 30 and sent_emails_count <= len(
                _GOLDEN_FOCUS_CAMPAIGNS):
            focus.main(['send', '--disable-sentry'])

            emails_sent = mailjetmock.get_all_sent_messages()
            if len(emails_sent) > sent_emails_count:
                sent_emails_count = len(emails_sent)
                days_without_email = 0
            else:
                days_without_email += 1

            self.mock_now.return_value += datetime.timedelta(days=1)

        emails_sent = mailjetmock.get_all_sent_messages()
        self.assertEqual({'*****@*****.**'},
                         {m.recipient['Email']
                          for m in emails_sent})
        self.assertLessEqual(len(emails_sent), len(_GOLDEN_FOCUS_CAMPAIGNS))

        user_data = self._db.user_test.user.find_one()
        campaigns_sent = [e.get('campaignId') for e in user_data['emailsSent']]
        self.assertCountEqual(set(campaigns_sent),
                              campaigns_sent,
                              msg='No duplicates')
        self.assertLessEqual(set(campaigns_sent), set(_GOLDEN_FOCUS_CAMPAIGNS))

        # Try sending emails until the next check.
        next_date = datetime.datetime.fromisoformat(
            user_data['sendCoachingEmailAfter'][:-1])
        while next_date >= self.mock_now.return_value:
            focus.main(['send', '--disable-sentry'])

            self.mock_now.return_value += datetime.timedelta(days=1)

        self.assertEqual(
            len(emails_sent),
            len(mailjetmock.get_all_sent_messages()),
            msg='No new messages.'
            ' There probably is an issue with time sensitive conditions on some emails'
        )
        user_data = self._db.user_test.user.find_one()
        # Next check should be at least a month from now.
        self.assertLessEqual(
            self.mock_now.return_value + datetime.timedelta(days=30),
            datetime.datetime.fromisoformat(
                user_data['sendCoachingEmailAfter'][:-1]))
예제 #6
0
    def test_error_while_dry_run(self,
                                 mock_send_template: mock.MagicMock) -> None:
        """Error when sending a focus email in dry run mode."""

        mock_send_template(
        ).raise_for_status.side_effect = requests.exceptions.HTTPError

        with self.assertRaises(requests.exceptions.HTTPError):
            focus.main(['dry-run', '--disable-sentry'])

        self.assertFalse(mailjetmock.get_all_sent_messages())
        user_data = self._db.user_test.user.find_one()
        self.assertFalse(user_data.get('emailsSent'))
예제 #7
0
    def test_dont_send_to_deleted(self) -> None:
        """Do not send focus emails to deleted users."""

        self._db.user_test.user.update_one({}, {
            '$set': {
                'profile.email': 'REDACTED',
                'deletedAt': '2018-06-01T15:24:34Z',
            }
        })

        focus.main(['send', '--disable-sentry'])

        self.assertFalse(mailjetmock.get_all_sent_messages())
예제 #8
0
    def test_send_first(self) -> None:
        """Sending a first focus email."""

        focus.main(['send', '--disable-sentry'])

        self.assertEqual(['*****@*****.**'], [
            m.recipient['Email'] for m in mailjetmock.get_all_sent_messages()
        ])

        user_data = self._db.user_test.user.find_one()
        self.assertEqual(1, len(user_data.get('emailsSent')))
        self.assertIn(user_data['emailsSent'][0]['campaignId'],
                      _GOLDEN_FOCUS_CAMPAIGNS)
예제 #9
0
    def test_send_shortly_after_another(self) -> None:
        """Sending a second focus email shortly after the first one."""

        focus.main(['send', '--disable-sentry'])

        self.mock_now.return_value += datetime.timedelta(hours=1)

        mailjetmock.clear_sent_messages()

        focus.main(['send', '--disable-sentry'])

        self.assertFalse(mailjetmock.get_all_sent_messages())

        user_data = self._db.user_test.user.find_one()
        self.assertEqual(1, len(user_data.get('emailsSent')))
예제 #10
0
    def test_error_while_sending(self, mock_warning: mock.MagicMock,
                                 mock_send_template: mock.MagicMock) -> None:
        """Error when sending a focus email get caught and logged as warning."""

        mock_send_template(
        ).raise_for_status.side_effect = requests.exceptions.HTTPError

        focus.main(['send', '--disable-sentry'])

        self.assertFalse(mailjetmock.get_all_sent_messages())
        user_data = self._db.user_test.user.find_one()
        self.assertFalse(user_data.get('emailsSent'))

        mock_warning.assert_called_once()
        self.assertEqual('Error while sending an email: %s',
                         mock_warning.call_args[0][0])
예제 #11
0
    def test_send_first_too_early(self) -> None:
        """Sending a first focus email too soon after a registration."""

        self._db.user_test.user.update_one(
            {}, {'$set': {
                'registeredAt': '2018-05-30T14:22:00Z'
            }})

        focus.main(['send', '--disable-sentry'])

        self.assertFalse(mailjetmock.get_all_sent_messages())

        user_data = self._db.user_test.user.find_one()
        self.assertFalse(user_data.get('emailsSent'))
        self.assertEqual('2018-06-02T14:22:00Z',
                         user_data.get('sendCoachingEmailAfter'))
예제 #12
0
    def test_send_a_week_after_another(self) -> None:
        """Sending a second focus email a week after the first one."""

        focus.main(['send', '--disable-sentry'])

        self.mock_now.return_value += datetime.timedelta(days=9)

        mailjetmock.clear_sent_messages()

        focus.main(['send', '--disable-sentry'])

        self.assertEqual(['*****@*****.**'], [
            m.recipient['Email'] for m in mailjetmock.get_all_sent_messages()
        ])

        user_data = self._db.user_test.user.find_one()
        self.assertEqual(2, len(user_data.get('emailsSent')))
        self.assertIn(user_data['emailsSent'][1]['campaignId'],
                      _GOLDEN_FOCUS_CAMPAIGNS)
예제 #13
0
 def _assert_user_receives_focus(self, should_be_sent: bool = True) -> None:
     json_user = json_format.MessageToDict(self.user)
     json_user['_id'] = mongomock.ObjectId(json_user.pop('userId'))
     self._user_database.get_collection(
         self.mongo_collection).insert_one(json_user)
     with mock.patch(focus.__name__ + '._POTENTIAL_CAMPAIGNS',
                     {self.campaign_id}):
         focus.main([
             'send',
             '--disable-sentry',
         ])
     all_sent_messages = mailjetmock.get_all_sent_messages()
     if not should_be_sent:
         self.assertFalse(all_sent_messages)
         return
     self.assertEqual(1, len(all_sent_messages), msg=all_sent_messages)
     self.assertEqual(self.campaign_id,
                      all_sent_messages[0].properties['CustomCampaign'])
     self._variables = all_sent_messages[0].properties['Variables']
예제 #14
0
    def test_list_campaigns(self, mock_logging: mock.MagicMock) -> None:
        """List existing focus email campaigns."""

        self._db.user_test.user.drop()

        focus.main(['list'])

        mock_logging.assert_called()
        for logging_call in mock_logging.call_args_list:
            if logging_call[0][0].startswith('Potential focus emails:'):
                self.assertEqual(
                    list(_GOLDEN_FOCUS_CAMPAIGNS),
                    logging_call[0][1],
                    msg=
                    "Update the golden focus campaigns as it's used in other tests."
                )
                break
        else:  # pragma: no-cover
            self.fail('No logging call about potential focus emails.')
예제 #15
0
    def test_send_only_once_a_month(self) -> None:
        """Sending focus emails to user on "once-a-month" frequency."""

        self._db.user_test.user.update_one(
            {},
            {'$set': {
                'profile.coachingEmailFrequency': 'EMAIL_ONCE_A_MONTH'
            }})

        focus.main(['send', '--disable-sentry'])

        self.mock_now.return_value += datetime.timedelta(days=15)

        mailjetmock.clear_sent_messages()

        focus.main(['send', '--disable-sentry'])

        # No email sent, even 15 days later.
        self.assertFalse(mailjetmock.get_all_sent_messages())

        user_data = self._db.user_test.user.find_one()
        self.assertEqual(1, len(user_data.get('emailsSent')))

        self.mock_now.return_value += datetime.timedelta(days=30)

        mailjetmock.clear_sent_messages()

        focus.main(['send', '--disable-sentry'])

        self.assertEqual(['*****@*****.**'], [
            m.recipient['Email'] for m in mailjetmock.get_all_sent_messages()
        ])

        user_data = self._db.user_test.user.find_one()
        self.assertEqual(2, len(user_data.get('emailsSent')))
예제 #16
0
    def test_send_after_not_focus(self) -> None:
        """Sending a second focus email shortly after another random email."""

        self._db.user_test.user.update_one({}, {
            '$push': {
                'emailsSent': {
                    'campaignId': 'not-a-focus',
                    'sentAt': '2018-05-30T23:12:00Z',
                }
            }
        })

        focus.main(['send', '--disable-sentry'])

        self.assertEqual(['*****@*****.**'], [
            m.recipient['Email'] for m in mailjetmock.get_all_sent_messages()
        ])

        user_data = self._db.user_test.user.find_one()
        self.assertEqual(2, len(user_data.get('emailsSent')))
        self.assertIn(user_data['emailsSent'][1]['campaignId'],
                      _GOLDEN_FOCUS_CAMPAIGNS)
예제 #17
0
    def test_change_setting(self, unused_mock_logging: mock.MagicMock) -> None:
        """Changing the settings after the first email has been sent."""

        focus.main(['send', '--disable-sentry'])
        mailjetmock.clear_sent_messages()

        # Change the email frequency setting right after the first email.
        self._db.user_test.user.update_one({}, {
            '$set': {
                'profile.coachingEmailFrequency': 'EMAIL_ONCE_A_MONTH'
            },
            '$unset': {
                'sendCoachingEmailAfter': 1
            },
        })

        # A week later, there should be no email.
        for unused_day in range(7):
            self.mock_now.return_value += datetime.timedelta(days=1)
            focus.main(['send', '--disable-sentry'])

        self.assertFalse(mailjetmock.get_all_sent_messages())
        user_data = self._db.user_test.user.find_one()
        self.assertEqual(1, len(user_data.get('emailsSent', [])))

        # A month later, there should be another email.
        for unused_data in range(30):
            self.mock_now.return_value += datetime.timedelta(days=1)
            focus.main(['send', '--disable-sentry'])

        self.assertEqual(['*****@*****.**'], [
            m.recipient['Email'] for m in mailjetmock.get_all_sent_messages()
        ])
        user_data = self._db.user_test.user.find_one()
        self.assertEqual(2, len(user_data.get('emailsSent', [])))
        self.assertIn(user_data['emailsSent'][1]['campaignId'],
                      _GOLDEN_FOCUS_CAMPAIGNS)
예제 #18
0
    def test_restrict_campaign(self) -> None:
        """Restrict to only one campaign."""

        focus.main(['send', '--disable-sentry'])
        user_data = self._db.user_test.user.find_one()
        self.assertEqual('galita-2', user_data['emailsSent'][0]['campaignId'])