Exemplo n.º 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())
Exemplo n.º 2
0
    def test_error_no_secret_salt(self) -> None:
        """Error when trying to send without a secret salt."""

        with mock.patch(focus.auth_token.__name__ + '.SECRET_SALT',
                        new=focus.auth_token.FAKE_SECRET_SALT):
            with self.assertRaises(ValueError):
                focus.main(['send', '--disable-sentry'])
Exemplo n.º 3
0
    def test_slack(self, mock_notify_slack: mock.MagicMock) -> None:
        """Send message to slack."""

        self._db.test.focus_emails.drop()
        self._db.test.focus_emails.insert_many([
            {
                'campaignId': 'first-one',
                'scoringModel': 'constant(3)'
            },
            {
                'campaignId': 'third-one',
                'scoringModel': 'constant(.1)'
            },
        ])

        # Note that random will not be flaky:
        #  the diff score is (3 - .1) / 3 * _SCORES_WEIGHT = 5 * 2.9 / 3
        #  the max random diff is _RANDOM_WEIGHTS = 4
        # So the difference in score will always be bigger than the random diff and thus first-one
        # will always be selected.
        focus.main([
            'send',
            '--disable-sentry',
        ])

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

        mock_notify_slack.assert_called_once_with(
            textwrap.dedent('''\
            Focus emails sent today:
             • *first-one*: 1 email
             • *third-one*: 0 email'''))
Exemplo n.º 4
0
    def test_send_shuffle(self, mock_random_random: mock.MagicMock) -> None:
        """Send the mail with a better score first."""

        mock_random_random.return_value = 0

        self._db.test.focus_emails.drop()
        self._db.test.focus_emails.insert_many([
            {
                'campaignId': 'just-big',
                'scoringModel': 'constant(0.5)'
            },
            {
                'campaignId': 'small-very-important',
                'scoringModel': 'constant(3)'
            },
        ])

        focus.main([
            'send',
            '--disable-sentry',
            '--restrict-campaigns',
            'just-big',
            'small-very-important',
        ])

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

        user_data = self._db.user_test.user.find_one()
        assert user_data
        self.assertEqual(1, len(user_data.get('emailsSent')))
        self.assertEqual('small-very-important',
                         user_data['emailsSent'][0]['campaignId'])
Exemplo n.º 5
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.assert_called()

        self.assertFalse(mailjetmock.get_all_sent_messages())
Exemplo n.º 6
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())
Exemplo n.º 7
0
    def test_restrict_campaign(self) -> None:
        """Restrict to only one campaign."""

        self._db.test.focus_emails.drop()
        self._db.test.focus_emails.insert_one({'campaignId': 'galita-2'})

        focus.main(['send', '--disable-sentry'])
        user_data = self._db.user_test.user.find_one()
        assert user_data
        self.assertEqual('galita-2', user_data['emailsSent'][0]['campaignId'])
Exemplo n.º 8
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()
        assert user_data
        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]))
Exemplo n.º 9
0
    def test_dont_send_to_example(self, mock_warning: mock.MagicMock) -> None:
        """Do not send focus emails to users with an example email address."""

        self._db.user_test.user.update_one(
            {}, {'$set': {
                'profile.email': '*****@*****.**',
            }})

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

        self.assertFalse(mailjetmock.get_all_sent_messages())
        mock_warning.assert_not_called()
Exemplo n.º 10
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())
Exemplo n.º 11
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()
        assert user_data
        self.assertFalse(user_data.get('emailsSent'))
Exemplo n.º 12
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()
        assert user_data
        self.assertEqual(1, len(user_data.get('emailsSent')))
        self.assertIn(user_data['emailsSent'][0]['campaignId'],
                      _GOLDEN_FOCUS_CAMPAIGNS)
Exemplo n.º 13
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()
        assert user_data
        self.assertEqual(1, len(user_data.get('emailsSent')))
Exemplo n.º 14
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()
        assert user_data
        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])
Exemplo n.º 15
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()
        assert user_data
        self.assertFalse(user_data.get('emailsSent'))
        self.assertEqual('2018-06-02T14:22:00Z',
                         user_data.get('sendCoachingEmailAfter'))
Exemplo n.º 16
0
    def test_send_priority(self, mock_random_random: mock.MagicMock) -> None:
        """Send priority focus emails first."""

        # Avoid random influence in the order calculation
        mock_random_random.return_value = 0
        self._db.test.focus_emails.drop()
        self._db.test.focus_emails.insert_many([
            {
                'campaignId': 'big-important',
                'scoringModel': 'constant(2.5)'
            },
            {
                'campaignId': 'small-very-important',
                'scoringModel': 'constant(3)'
            },
            {
                'campaignId': 'big-no-priority'
            },
            {
                'campaignId': 'big-less-important',
                'scoringModel': 'constant(1)'
            },
        ])

        focus.main([
            'send',
            '--disable-sentry',
            '--restrict-campaigns',
            'big-important',
            'small-very-important',
            'big-no-priority',
            'big-less-important',
        ])

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

        user_data = self._db.user_test.user.find_one()
        assert user_data
        self.assertEqual(1, len(user_data.get('emailsSent')))
        self.assertEqual('big-important',
                         user_data['emailsSent'][0]['campaignId'])
Exemplo n.º 17
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.')
Exemplo n.º 18
0
    def test_dont_send_to_mistyped_emails(self) -> None:
        """Do not send focus emails to users with an incorrect email address."""

        self._db.user_test.user.update_one(
            {}, {'$set': {
                'profile.email': 'pascal@ corpet.net',
            }})

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

        self.assertFalse(mailjetmock.get_all_sent_messages())

        self._db.user_test.user.update_one(
            {}, {'$set': {
                'profile.email': 'pascal@corpet',
            }})

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

        self.assertFalse(mailjetmock.get_all_sent_messages())
Exemplo n.º 19
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()
        assert user_data
        self.assertEqual(2, len(user_data.get('emailsSent')))
        self.assertIn(user_data['emailsSent'][1]['campaignId'],
                      _GOLDEN_FOCUS_CAMPAIGNS)
Exemplo n.º 20
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.user.insert_one(json_user)
     focus.main([
         'send',
         '--disable-sentry',
         '--restrict-campaigns',
         self.campaign_id,
     ])
     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']
     self._from = all_sent_messages[0].properties['From']
     self.assertEqual(self._from['Name'], self._variables.pop('senderName'))
Exemplo n.º 21
0
    def test_focus_with_project_score_zero(self) -> None:
        """Test no email sent if project score is 0"""

        self._db.test.focus_emails.drop()
        self._db.test.focus_emails.insert_many([
            {
                'campaignId': 'post-covid',
                'scoringModel': 'constant(0)'
            },
        ])

        mailjetmock.clear_sent_messages()

        user = user_pb2.User()
        user.profile.coaching_email_frequency = email_pb2.EMAIL_ONCE_A_MONTH
        user.profile.frustrations.append(user_profile_pb2.SELF_CONFIDENCE)
        user.projects.add()

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

        self.assertFalse(mailjetmock.get_all_sent_messages())
Exemplo n.º 22
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()
        assert user_data
        self.assertEqual(2, len(user_data.get('emailsSent')))
        self.assertIn(user_data['emailsSent'][1]['campaignId'],
                      _GOLDEN_FOCUS_CAMPAIGNS)
Exemplo n.º 23
0
    def test_send_shuffle_random(self,
                                 mock_random_random: mock.MagicMock) -> None:
        """Test random in shuffle."""

        mock_random_random.side_effect = real_random
        self._db.test.focus_emails.drop()
        self._db.test.focus_emails.insert_many([
            {
                'campaignId': 'just-big',
                'scoringModel': 'constant(0.5)'
            },
            {
                'campaignId': 'small-very-important',
                'scoringModel': 'constant(3)'
            },
        ])

        focus.main([
            'send',
            '--disable-sentry',
            '--restrict-campaigns',
            'just-big',
            'small-very-important',
        ])

        mock_random_random.assert_called()

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

        user_data = self._db.user_test.user.find_one()
        assert user_data
        self.assertEqual(1, len(user_data.get('emailsSent')))
        self.assertIn(user_data['emailsSent'][0]['campaignId'],
                      {'just-big', 'small-very-important'})
Exemplo n.º 24
0
    def test_focus_with_no_scoring_model(self) -> None:
        """Test email sent if there is no scoring model"""

        self._db.test.focus_emails.drop()
        self._db.test.focus_emails.insert_many([
            {
                'campaignId': 'post-covid'
            },
        ])

        mailjetmock.clear_sent_messages()

        user = user_pb2.User()
        user.profile.coaching_email_frequency = email_pb2.EMAIL_ONCE_A_MONTH
        user.profile.frustrations.append(user_profile_pb2.SELF_CONFIDENCE)
        user.projects.add()

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

        user_data = self._db.user_test.user.find_one()
        assert user_data
        self.assertEqual(1, len(user_data.get('emailsSent')))
        self.assertEqual(user_data['emailsSent'][0]['campaignId'],
                         'post-covid')
Exemplo n.º 25
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()
        assert user_data
        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()
        assert user_data
        self.assertEqual(2, len(user_data.get('emailsSent', [])))
        self.assertIn(user_data['emailsSent'][1]['campaignId'],
                      _GOLDEN_FOCUS_CAMPAIGNS)
Exemplo n.º 26
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()
        assert user_data
        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()
        assert user_data
        self.assertEqual(2, len(user_data.get('emailsSent')))