Exemple #1
0
    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)
Exemple #2
0
    def test_no_comments(self) -> None:
        """Forwarded email has no #-starting lines."""

        user_id = self.create_user(email='*****@*****.**')

        parse_email = dict(
            self.parse_email, **{
                'Subject':
                f'{user_id} Merci pour votre retour',
                'Text-part':
                '''# This line will disappear
            # This line will disappear too, even though it has whitespace.
            This line will stay.'''
            })
        response = self.app.post('/api/eval/mailjet',
                                 data=json.dumps(parse_email))
        self.assertEqual(200, response.status_code)
        self.assertEqual(['*****@*****.**'], [
            msg.recipient['Email']
            for msg in mailjetmock.get_all_sent_messages()
        ])
        self.assertEqual(['Merci pour votre retour'], [
            msg.properties.get('Subject')
            for msg in mailjetmock.get_all_sent_messages()
        ])
        self.assertEqual(['This line will stay.'], [
            line.strip() for msg in mailjetmock.get_all_sent_messages()
            for line in msg.properties.get('TextPart', '').split('\n')
        ])
Exemple #3
0
    def test_send_email_to_everyone(self) -> None:
        """Send data to counselor and user when having both email adresses."""

        self.assertFalse(mailjetmock.get_all_sent_messages())
        response = self.app.post(
            '/api/ali/user',
            data=
            ('{"user_email": "*****@*****.**", "counselor_name": "Bobbie",'
             '"counselor_email": "*****@*****.**", "results_url": "http://www.foo.bar"}'
             ),
            content_type='application/json')

        post_response = self.json_from_response(response)
        mails_sent = mailjetmock.get_all_sent_messages()
        self.assertEqual(2, len(mails_sent), msg=mails_sent)
        self.assertEqual({
            'hasCounselorEmail': True,
            'hasUserEmail': True
        }, post_response)
        self.assertEqual('*****@*****.**', mails_sent[0].recipient['Email'])
        self.assertEqual('*****@*****.**', mails_sent[1].recipient['Email'])
        data = mails_sent[0].properties['Variables']
        self.assertEqual('*****@*****.**', data['userEmail'])
        self.assertEqual('*****@*****.**', data['counselorEmail'])
        self.assertEqual('Bobbie', data['counselorName'])
        self.assertIn('http://www.foo.bar', data['directLink'])
Exemple #4
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')))
Exemple #5
0
    def test_activation_email_for_guest_user(self,
                                             mock_now: mock.MagicMock) -> None:
        """Create an account with email + password from a guest user that has a diagnostic."""

        mock_now.return_value = datetime.datetime(2018, 6, 10)

        self._db.advice_modules.insert_many([
            {
                'adviceId': 'spontaneous-application',
                'categories': ['first'],
                'triggerScoringModel': 'constant(2)',
                'isReadyForProd': True,
            },
        ])

        user_id, auth_token = self.create_guest_user(
            first_name='Pascal', modifiers=[base_test.add_project])

        self.assertFalse(mailjetmock.get_all_sent_messages())

        # Create password.
        self.app.post(
            '/api/user/authenticate',
            data=
            f'{{"email": "*****@*****.**", "userId": "{user_id}", "authToken": "{auth_token}", '
            f'"hashedPassword": "******"*****@*****.**", "psswd")}"}}',
            content_type='application/json')

        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.assertEqual('10 juin 2018', data['date'])
        self.assertEqual('Pascal', data['firstName'])
Exemple #6
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]))
Exemple #7
0
    def test_recommend_advice_none(self, mock_logger: mock.MagicMock) -> None:
        """Test that the advisor does not recommend anyting if all modules score 0."""

        project = project_pb2.Project()
        self.database.advice_modules.insert_many([
            {
                'adviceId': 'spontaneous-application',
                'categories': ['first'],
                'triggerScoringModel': 'constant(0)',
                'isReadyForProd': True,
            },
            {
                'adviceId': 'other-work-env',
                'categories': ['first'],
                'triggerScoringModel': 'constant(0)',
                'isReadyForProd': True,
            },
        ])

        advisor.maybe_advise(self.user, project, self.database)

        self.assertFalse(project.advices)

        self.assertFalse(mailjetmock.get_all_sent_messages())

        mock_logger.assert_called_once()
Exemple #8
0
    def test_explained_advice(self, mock_scoring_models: Dict[str,
                                                              Any]) -> None:
        """Test that the advisor gives explanations for the advices."""

        mock_scoring_models['constant(1)'] = mock.MagicMock(
            spec=['get_advice_override', 'score_and_explain'])
        mock_scoring_models['constant(1)'].score_and_explain.return_value = \
            scoring.ExplainedScore(1, ['voilà pourquoi', 'explication genré%eFeminine'])
        mock_scoring_models[
            'constant(1)'].get_advice_override.return_value = None

        project = project_pb2.Project()
        self.database.advice_modules.insert_one({
            'adviceId': 'network',
            'categories': ['first'],
            'triggerScoringModel': 'constant(1)',
            'isReadyForProd': True,
        })
        self.user.profile.gender = user_pb2.FEMININE
        advisor.maybe_advise(self.user, project, self.database)

        self.assertEqual(['network'], [a.advice_id for a in project.advices])
        self.assertEqual(['voilà pourquoi', 'explication genrée'],
                         project.advices[0].explanations)
        self.assertEqual(1, len(mailjetmock.get_all_sent_messages()))
Exemple #9
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'])
Exemple #10
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'''))
Exemple #11
0
    def test_blast_hash_start(self, mock_hasher: mock.MagicMock,
                              unused_mock_logging: mock.MagicMock) -> None:
        """Send mail to users with given hash start."""

        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_user_db.user.drop()
        hash_values = ['12345', '01234']
        mock_hasher.reset_mock()
        mock_hasher().hexdigest.side_effect = hash_values

        mock_user_db.user.insert_many([{
            'registeredAt': '2017-04-15T00:00:00Z',
            'profile': {
                'name': f'user {hash_value}',
                'email': f'email{hash_value}@corpet.net',
            },
        } for hash_value in hash_values])

        mail_blast.main([
            'fake-user-campaign', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10', '--disable-sentry', '--user-hash',
            '1'
        ])

        sent_messages = mailjetmock.get_all_sent_messages()
        self.assertEqual(
            ['*****@*****.**'],
            [m.recipient['Email'] for m in sent_messages],
            msg=
            f'1 email expected: only for the user whith hash starting with 1\n{sent_messages}'
        )
Exemple #12
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())
Exemple #13
0
    def test_incompatible_advice_modules(self) -> None:
        """Test that the advisor discard incompatible advice modules."""

        project = project_pb2.Project()
        self.database.advice_modules.insert_many([
            {
                'adviceId': 'other-work-env',
                'airtableId': 'abc',
                'categories': ['first'],
                'triggerScoringModel': 'constant(2)',
                'isReadyForProd': True,
                'incompatibleAdviceIds': ['def'],
            },
            {
                'adviceId': 'spontaneous-application',
                'categories': ['first'],
                'airtableId': 'def',
                'triggerScoringModel': 'constant(3)',
                'isReadyForProd': True,
                'incompatibleAdviceIds': ['abc'],
            },
            {
                'adviceId': 'final-one',
                'categories': ['first'],
                'airtableId': 'ghi',
                'triggerScoringModel': 'constant(1)',
                'isReadyForProd': True,
            },
        ])

        advisor.maybe_advise(self.user, project, self.database)

        self.assertEqual(['spontaneous-application', 'final-one'],
                         [a.advice_id for a in project.advices])
        self.assertEqual(1, len(mailjetmock.get_all_sent_messages()))
Exemple #14
0
    def test_main(self, mock_post: mock.MagicMock) -> None:
        """Overall test."""

        _db = pymongo.MongoClient('mongodb://my-db/db').db
        _db.user.drop()
        _db.user.insert_one({
            '_id':
            mongomock.ObjectId('5daf2298484ae6c93351b822'),
            'profile': {
                'name': 'Pascal',
                'lastName': 'Corpet',
                'email': '*****@*****.**',
                'locale': 'en',
            },
            'registeredAt':
            datetime.datetime(2018, 1, 22, 10, 0, 0).isoformat() + 'Z',
            'projects': [{
                'title': 'Project Title',
            }],
        })

        mail_nps.main(self._now, '1')

        sent_messages = mailjetmock.get_all_sent_messages()
        self.assertEqual(['*****@*****.**'],
                         [m.recipient['Email'] for m in sent_messages])
        self.assertEqual(100819, sent_messages[0].properties['TemplateID'])
        template_vars = sent_messages[0].properties['Variables']
        nps_form_urlstring = template_vars.pop('npsFormUrl')
        self.assertEqual(
            {
                'baseUrl': 'http://localhost:3000',
                'firstName': 'Pascal',
            }, template_vars)
        nps_form_url = parse.urlparse(nps_form_urlstring)
        self.assertEqual(
            'http://localhost:3000/api/nps',
            parse.urlunparse(nps_form_url[:4] + ('', ) + nps_form_url[5:]))
        nps_form_args = parse.parse_qs(nps_form_url.query)
        self.assertEqual({'user', 'token', 'redirect'}, nps_form_args.keys())
        self.assertEqual(['5daf2298484ae6c93351b822'], nps_form_args['user'])
        auth.check_token('5daf2298484ae6c93351b822',
                         nps_form_args['token'][0],
                         role='nps')
        self.assertEqual(['http://localhost:3000/retours?hl=en'],
                         nps_form_args['redirect'])
        mock_post.assert_called_once_with(
            'https://slack.example.com/webhook',
            json={
                'text':
                "Report for NPS blast: I've sent 1 emails (with 0 errors)."
            },
        )

        modified_user = user_pb2.User()
        proto.parse_from_mongo(_db.user.find_one(), modified_user)
        self.assertEqual(
            [sent_messages[0].message_id],
            [m.mailjet_message_id for m in modified_user.emails_sent])
        self.assertEqual('nps', modified_user.emails_sent[0].campaign_id)
Exemple #15
0
    def test_no_incomplete(self, mock_post: mock.MagicMock) -> None:
        """Do not send if project is not complete."""

        _db = pymongo.MongoClient('mongodb://my-db/db').db
        _db.user.drop()
        _db.user.insert_one({
            'profile': {
                'name': 'Pascal',
                'lastName': 'Corpet',
                'email': '*****@*****.**',
            },
            'registeredAt':
            datetime.datetime(2018, 1, 22, 10, 0, 0).isoformat() + 'Z',
            'projects': [{
                'title': 'Project Title',
                'isIncomplete': True,
            }],
        })

        mail_nps.main(self._now, '1')
        self.assertFalse(mailjetmock.get_all_sent_messages())
        mock_post.assert_called_once_with(
            'https://slack.example.com/webhook',
            json={
                'text':
                "Report for NPS blast: I've sent 0 emails (with 0 errors)."
            },
        )
Exemple #16
0
    def test_no_missing_email(self, mock_post: mock.MagicMock) -> None:
        """Do not send if there's no email address."""

        _db = pymongo.MongoClient('mongodb://my-db/db').db
        _db.user.drop()
        _db.user.insert_one({
            '_id':
            '5daf2298484ae6c93351b822',
            'profile': {
                'name': 'Pascal',
                'lastName': 'Corpet',
            },
            'registeredAt':
            datetime.datetime(2018, 1, 22, 10, 0, 0).isoformat() + 'Z',
            'projects': [{
                'title': 'Project Title',
            }],
        })

        mail_nps.main(self._now, '1')
        self.assertFalse(mailjetmock.get_all_sent_messages())
        mock_post.assert_called_once_with(
            'https://slack.example.com/webhook',
            json={
                'text':
                "Report for NPS blast: I've sent 0 emails (with 0 errors)."
            },
        )
Exemple #17
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())
Exemple #18
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())
Exemple #19
0
    def test_list(self, mock_logging: mock.MagicMock) -> None:
        """Test a list for documents blast."""

        mail_blast.main(['fake-document', 'list'])
        messages = mailjetmock.get_all_sent_messages()
        self.assertFalse(messages)
        mock_logging.assert_any_call('%s: %s %s', 'fake-document',
                                     '5b2173b9362bf80840db6c2a',
                                     '*****@*****.**')
Exemple #20
0
    def test_send_template_not_to_example(self) -> None:
        """Do not send template to test addresses."""

        mail.send_template('12345',
                           _Recipient('REDACTED', 'Primary', 'Recipient'),
                           {'custom': 'var'})

        sent_emails = mailjetmock.get_all_sent_messages()

        self.assertEqual([], sorted(m.recipient['Email'] for m in sent_emails))

        mail.send_template(
            '12345', _Recipient('*****@*****.**', 'Primary', 'Recipient'),
            {'custom': 'var'})

        sent_emails = mailjetmock.get_all_sent_messages()

        self.assertEqual([], sorted(m.recipient['Email'] for m in sent_emails))
Exemple #21
0
    def test_no_advice_if_project_incomplete(self) -> None:
        """Test that the advice do not get populated when the project is marked as incomplete."""

        project = project_pb2.Project(is_incomplete=True)
        advisor.maybe_advise(self.user, project, self.database)

        self.assertEqual(len(project.advices), 0)

        self.assertFalse(mailjetmock.get_all_sent_messages())
Exemple #22
0
    def test_forward(self) -> None:
        """Basic usage of email-forwarder."""

        user_id = self.create_user(email='*****@*****.**')

        parse_email = dict(self.parse_email,
                           Subject=f'{user_id} Merci pour votre retour')
        response = self.app.post('/api/eval/mailjet',
                                 data=json.dumps(parse_email))
        self.assertEqual(200, response.status_code)
        self.assertEqual(['*****@*****.**'], [
            msg.recipient['Email']
            for msg in mailjetmock.get_all_sent_messages()
        ])
        self.assertEqual(['Merci pour votre retour'], [
            msg.properties.get('Subject')
            for msg in mailjetmock.get_all_sent_messages()
        ])
Exemple #23
0
    def test_send(self) -> None:
        """Test really sending to a document owner."""

        mail_blast.main(['fake-document', 'send', '--disable-sentry'])
        messages = mailjetmock.get_all_sent_messages()
        self.assertTrue(messages)
        self.assertEqual(1, len(messages))
        message = messages.pop()
        self.assertEqual('Nathalie ', message.recipient['Name'])
        self.assertEqual('*****@*****.**', message.recipient['Email'])
Exemple #24
0
    def test_send_auth_email_to_guest_user(self) -> None:
        """Create an account with email from a guest user, then use this email to auth."""

        user_id, auth_token = self.create_guest_user(first_name='Lascap')
        # Add an email to the guest user.
        self.app.post(
            '/api/user/authenticate',
            data=
            f'{{"email": "*****@*****.**", "userId": "{user_id}", "authToken": "{auth_token}"}}',
            content_type='application/json')

        self.assertFalse(mailjetmock.get_all_sent_messages())

        # Try to connect with a password.
        salt = self._get_salt('*****@*****.**')
        request = \
            f'{{"email": "*****@*****.**", "hashSalt": "{salt}", ' \
            f'"hashedPassword": "******"*****@*****.**", "psswd"))}"}}'
        response = self.app.post('/api/user/authenticate',
                                 data=request,
                                 content_type='application/json')
        self.assertEqual(403, response.status_code)
        # Do not display the email in the error message.
        self.assertNotIn('*****@*****.**', response.get_data(as_text=True))

        # Open the auth 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._assert_all_template_variables(data)
        self.assertEqual('Lascap', data['firstname'])
        url_args = parse.parse_qs(parse.urlparse(data['authLink']).query)
        self.assertLessEqual({'userId', 'authToken'}, url_args.keys())
        self.assertEqual([user_id], url_args['userId'])
        auth_token = url_args['authToken'][0]

        # Log in from email.
        response = self.app.post(
            '/api/user/authenticate',
            data=f'{{"userId": "{user_id}", "authToken": "{auth_token}"}}',
            content_type='application/json')
        self.json_from_response(response)
Exemple #25
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())
Exemple #26
0
    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'])
Exemple #27
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()
Exemple #28
0
    def test_dry_run(self) -> None:
        """Test a dry run for documents."""

        mail_blast.main([
            'fake-document', 'dry-run', '--dry-run-email', '*****@*****.**'
        ])
        messages = mailjetmock.get_all_sent_messages()
        self.assertTrue(messages)
        self.assertEqual(1, len(messages))
        message = messages.pop()
        self.assertEqual('Nathalie ', message.recipient['Name'])
        self.assertEqual('*****@*****.**', message.recipient['Email'])
Exemple #29
0
    def test_missing_sentry_dsn(self, mock_error: mock.MagicMock) -> None:
        """Log an error when used without SENTRY_DSN env var."""

        mail_blast.main([
            'focus-network', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10'
        ])

        self.assertFalse(mailjetmock.get_all_sent_messages())
        mock_error.assert_called_with(
            'Please set SENTRY_DSN to enable logging to Sentry, or use --disable-sentry option'
        )
    def _assert_user_receives_campaign(
            self,
            should_be_sent: bool = True,
            blast_from: Optional[str] = None,
            blast_to: Optional[str] = None,
            extra_args: Optional[list[str]] = None) -> 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)
        year = self.user.registered_at.ToDatetime().year
        if self.now:
            now_patcher = nowmock.patch(new=mock.MagicMock(
                return_value=self.now))
            now_patcher.start()
            self.addCleanup(now_patcher.stop)
        mail_blast.main([
            self.campaign_id,
            'send',
            '--disable-sentry',
            '--registered-from',
            blast_from or str(year),
            '--registered-to',
            blast_to or str(year + 1),
            '--log-reason-on-error',
        ] + (extra_args or []))
        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'))

        # Test that variables used in the template are populated.
        template_id = str(all_sent_messages[0].properties['TemplateID'])
        template_path = campaign.get_campaign_folder(
            typing.cast(mailjet_templates.Id, self.campaign_id))
        self.assertTrue(template_path,
                        msg=f'No template for campaign "{self.campaign_id}"')
        assert template_path
        vars_filename = os.path.join(template_path, 'vars-example.json')
        with open(vars_filename, 'r', encoding='utf-8') as vars_file:
            template_vars = json.load(vars_file).keys()
        for template_var in template_vars:
            self.assertIn(
                template_var,
                self._variables,
                msg=f'Template error for campaign {self.campaign_id}, see '
                f'https://app.mailjet.com/template/{template_id}/build')