def test_no_dupes(self, mock_post: mock.MagicMock) -> None: """Test that we do not send duplicate emails if we run the script twice.""" _db = pymongo.MongoClient('mongodb://my-db/db').db _db.user.drop() _db.user.insert_one(_USER_PENDING_NPS_DICT) mail_nps.main(self._now, '1') self.assertTrue(mailjetmock.get_all_sent_messages()) mailjetmock.clear_sent_messages() # Running the script again 10 minutes later. mail_nps.main(self._now + datetime.timedelta(minutes=10), '1') self.assertFalse(mailjetmock.get_all_sent_messages()) calls = [ mock.call( 'https://slack.example.com/webhook', json={ 'text': "Report for NPS blast: I've sent 1 emails (with 0 errors)." }, ), mock.call( 'https://slack.example.com/webhook', json={ 'text': "Report for NPS blast: I've sent 0 emails (with 0 errors)." }, ) ] self.assertEqual(calls, mock_post.mock_calls)
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')))
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')))
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)
def test_reset_password(self) -> None: """Full flow to reset user's password.""" user_id, auth_token = self.authenticate_new_user_token( first_name='Sil', email='*****@*****.**', password='******') # Ask to reset user's password. self.app.post( '/api/user/reset-password', data=f'{{"email": "*****@*****.**", "authToken":"{auth_token}"}}', content_type='application/json') # Retrieve the reset token from the sent email. mails_sent = mailjetmock.get_all_sent_messages() self.assertEqual(1, len(mails_sent), msg=mails_sent) self.assertEqual('*****@*****.**', mails_sent[0].recipient['Email']) data = mails_sent[0].properties['Variables'] self.assertTrue(data['resetLink']) reset_token = parse.parse_qs(parse.urlparse( data['resetLink']).query).get('resetToken', [])[0] mailjetmock.clear_sent_messages() # Reset password. request = f'{{"email": "*****@*****.**", "authToken":"{reset_token}", ' \ f'"hashedPassword": "******"*****@*****.**", "new password")}", "firstName": "Sil"}}' response = self.app.post('/api/user/authenticate', data=request) self.assertEqual(200, response.status_code, msg=response.get_data(as_text=True)) self.assertEqual([user_id], list( str(u['_id']) for u in self._user_db.user.find())) mails_sent = mailjetmock.get_all_sent_messages() self.assertEqual(1, len(mails_sent), msg=mails_sent) self.assertEqual('*****@*****.**', mails_sent[0].recipient['Email']) self.assertEqual(3643543, mails_sent[0].properties['TemplateID']) data = mails_sent[0].properties['Variables'] self.assertIn('senderName', data.keys()) self._assert_all_template_variables(data) self.assertEqual('Sil', data['firstName'])
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())
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)
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')