Exemplo n.º 1
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}'
        )
Exemplo n.º 2
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'
        )
Exemplo n.º 3
0
    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')
Exemplo n.º 4
0
    def test_incoherent_policy_durations(self,
                                         mock_error: mock.MagicMock) -> None:
        """Log an error when flags to define policy are not coherent."""

        mail_blast.main([
            'focus-network', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10', '--disable-sentry',
            '--days-since-same-campaign', '7',
            '--days-since-same-campaign-unread', '15'
        ])

        self.assertFalse(mailjetmock.get_all_sent_messages())
        mock_error.assert_called_with(
            'Please use coherent values in the policy durations.')
Exemplo n.º 5
0
    def test_fake_secret_salt(self) -> None:
        """Raise an error when using the fake secret salt when trying to send."""

        auth_token = mail_blast.auth_token

        with mock.patch(auth_token.__name__ + '.SECRET_SALT',
                        new=auth_token.FAKE_SECRET_SALT):
            with self.assertRaises(ValueError):
                mail_blast.main([
                    'focus-network', 'send', '--registered-from', '2017-04-01',
                    '--registered-to', '2017-07-10', '--disable-sentry'
                ])

        self.assertFalse(mailjetmock.get_all_sent_messages())
Exemplo n.º 6
0
    def test_no_reply(self) -> None:
        """Set sender as no-reply."""

        product.bob.load_from_env()

        mock_db = pymongo.MongoClient('mongodb://mydata.com/test').test
        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_db.job_group_info.drop()
        mock_db.job_group_info.insert_one({
            '_id': 'A1234',
            'inDomain': 'dans la vie',
        })
        mock_user_db.user.drop()
        mock_user_db.user.insert_many([{
            '_id':
            objectid.ObjectId(f'7b18313aa35d807e631ea3d{month}'),
            'registeredAt':
            f'2017-{month:02d}-15T00:00:00Z',
            'profile': {
                'name': f'{month} user',
                'email': f'email{month}@corpet.net',
            },
            'projects': [
                {
                    'networkEstimate': 1,
                    'targetJob': {
                        'jobGroup': {
                            'romeId': 'A1234'
                        }
                    }
                },
            ],
        } for month in range(2, 9)])
        mail_blast.main([
            'focus-network', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10', '--disable-sentry'
        ])

        mails_sent = mailjetmock.get_all_sent_messages()
        self.assertEqual(
            ['*****@*****.**', '*****@*****.**', '*****@*****.**'],
            sorted(m.recipient['Email'] for m in mails_sent),
            msg=
            f'3 emails expected: one per month from April to June\n{mails_sent}'
        )
        self.assertEqual({'*****@*****.**'},
                         {m.properties['From']['Email']
                          for m in mails_sent})
Exemplo n.º 7
0
    def test_wrong_email(self) -> None:
        """Users with wrong email don't get sent an email."""

        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_user_db.user.drop()
        mock_user_db.user.insert_many([
            {
                'registeredAt':
                '2017-05-15T00:00:00Z',
                'profile': {
                    'name': 'The user',
                    'email': 'the-user@gmail .com',
                },
                'projects': [
                    {
                        'networkEstimate': 1,
                        'targetJob': {
                            'jobGroup': {
                                'romeId': 'A1234'
                            }
                        }
                    },
                ],
            },
            {
                'registeredAt':
                '2017-05-15T00:00:00Z',
                'profile': {
                    'name': 'The user',
                    'email': 'the-user@gmail',
                },
                'projects': [
                    {
                        'networkEstimate': 1,
                        'targetJob': {
                            'jobGroup': {
                                'romeId': 'A1234'
                            }
                        }
                    },
                ],
            },
        ])
        mail_blast.main([
            'focus-network', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10', '--disable-sentry'
        ])
        self.assertFalse(mailjetmock.get_all_sent_messages())
Exemplo n.º 8
0
    def test_error_while_sending(self, mock_warning: mock.MagicMock,
                                 mock_send_template: mock.MagicMock) -> None:
        """Error when sending an email get caught and logged as warning."""

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

        mock_db = pymongo.MongoClient('mongodb://mydata.com/test').test
        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_db.job_group_info.drop()
        mock_db.job_group_info.insert_one({
            '_id': 'A1234',
            'inDomain': 'dans la vie',
        })
        mock_user_db.user.drop()
        mock_user_db.user.insert_one({
            'registeredAt':
            '2017-05-15T00:00:00Z',
            'profile': {
                'name': 'The user',
                'email': '*****@*****.**',
            },
            'projects': [
                {
                    'networkEstimate': 1,
                    'targetJob': {
                        'jobGroup': {
                            'romeId': 'A1234'
                        }
                    }
                },
            ],
        })

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

        self.assertFalse(mailjetmock.get_all_sent_messages())
        user = mock_user_db.user.find_one({})
        assert user
        self.assertEqual(
            [], [e.get('campaignId') for e in user.get('emailsSent', [])])

        mock_warning.assert_called_once()
        self.assertEqual('Error while sending an email: %s',
                         mock_warning.call_args[0][0])
Exemplo n.º 9
0
    def test_days_from(self) -> None:
        """Compute from and to date relatively to today."""

        mock_db = pymongo.MongoClient('mongodb://mydata.com/test').test
        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_db.job_group_info.drop()
        mock_db.job_group_info.insert_one({
            '_id': 'A1234',
            'inDomain': 'dans la vie',
        })
        mock_user_db.user.drop()
        mock_user_db.user.insert_one({
            'registeredAt':
            '2017-05-15T00:00:00Z',
            'profile': {
                'name': 'The user',
                'email': '*****@*****.**',
            },
            'projects': [
                {
                    'networkEstimate': 1,
                    'targetJob': {
                        'jobGroup': {
                            'romeId': 'A1234'
                        }
                    }
                },
            ],
        })
        with nowmock.patch() as mock_now:
            mock_now.return_value = datetime.datetime(2017, 7, 11, 12, 0, 0, 0)
            mail_blast.main([
                'focus-network', 'send', '--registered-from-days-ago', '90',
                '--registered-to-days-ago', '1', '--disable-sentry'
            ])

        self.assertEqual(['*****@*****.**'], [
            m.recipient['Email'] for m in mailjetmock.get_all_sent_messages()
        ])
        user = mock_user_db.user.find_one({})
        assert user
        self.assertEqual(
            ['focus-network'],
            [e.get('campaignId') for e in user.get('emailsSent', [])])
Exemplo n.º 10
0
    def test_hard_bounced(self) -> None:
        """Do not send emails if the user had a hard bounce."""

        mock_db = pymongo.MongoClient('mongodb://mydata.com/test').test
        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_db.job_group_info.drop()
        mock_db.job_group_info.insert_one({
            '_id': 'A1234',
            'inDomain': 'dans la vie',
        })
        mock_user_db.user.drop()
        mock_user_db.user.insert_one({
            'registeredAt':
            '2017-05-15T00:00:00Z',
            'profile': {
                'name': 'The user',
                'email': '*****@*****.**',
            },
            'projects': [
                {
                    'networkEstimate': 1,
                    'targetJob': {
                        'jobGroup': {
                            'romeId': 'A1234'
                        }
                    }
                },
            ],
            'emailsSent': [{
                'campaignId': 'other-email',
                'status': 'EMAIL_SENT_HARDBOUNCED'
            }],
        })
        mail_blast.main([
            'focus-network', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10', '--disable-sentry'
        ])

        self.assertFalse(mailjetmock.get_all_sent_messages())
        user = mock_user_db.user.find_one({})
        assert user
        self.assertEqual(
            ['other-email'],
            [e.get('campaignId') for e in user.get('emailsSent', [])])
Exemplo n.º 11
0
    def test_change_policy(self, mock_now: mock.MagicMock) -> None:
        """Test with non-default emailing policy."""

        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_user_db.user.drop()
        mock_now.return_value = datetime.datetime(2017, 5, 24)
        mock_user_db.user.insert_many([
            {
                'registeredAt':
                '2017-05-15T00:00:00Z',
                'profile': {
                    'name': 'Sent other mail recently',
                    'email': '*****@*****.**',
                    'frustrations': ['MOTIVATION'],
                },
                'projects': [{}],
                'emailsSent': [{
                    'campaignId': 'focus-network',
                    'sentAt': '2017-05-15T00:00:00Z',
                }],
            },
            {
                'registeredAt':
                '2017-04-15T00:00:00Z',
                'profile': {
                    'name': 'Sent other mail less recently',
                    'email': '*****@*****.**',
                    'frustrations': ['MOTIVATION'],
                },
                'projects': [{}],
                'emailsSent': [{
                    'campaignId': 'focus-network',
                    'sentAt': '2017-04-15T00:00:00Z',
                }],
            },
        ])
        mail_blast.main([
            'galita-1', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10', '--days-since-any-email', '10',
            '--disable-sentry'
        ])

        emails_sent = mailjetmock.get_all_sent_messages()
        self.assertEqual(1, len(emails_sent), msg=emails_sent)
Exemplo n.º 12
0
    def test_stop_seeking(self, unused_mock_logging: mock.MagicMock) -> None:
        """Basic test."""

        mock_db = pymongo.MongoClient('mongodb://mydata.com/test').test
        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_db.job_group_info.drop()
        mock_db.job_group_info.insert_one({
            '_id': 'A1234',
            'inDomain': 'dans la vie',
        })
        mock_user_db.user.drop()
        mock_user_db.user.insert_many([{
            'registeredAt':
            '2017-04-15T00:00:00Z',
            'profile': {
                'name': f'{seeking} user',
                'email': f'email{seeking}@corpet.net',
            },
            'projects': [
                {
                    'networkEstimate': 1,
                    'targetJob': {
                        'jobGroup': {
                            'romeId': 'A1234'
                        }
                    }
                },
            ],
            'employmentStatus': [{
                'seeking': seeking,
                'createdAt': '2017-06-15T00:00:00Z'
            }]
        } for seeking in ('STILL_SEEKING', 'STOP_SEEKING')])

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

        self.assertEqual(['*****@*****.**'], [
            m.recipient['Email'] for m in mailjetmock.get_all_sent_messages()
        ])
Exemplo n.º 13
0
    def test_collection_prefix(self) -> None:
        """Test the --user-collection-prefix option."""

        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_user_db.jobflix_user.insert_many([
            {
                'registeredAt':
                '2017-05-15T00:00:00Z',
                'profile': {
                    'name': 'The user',
                    'email': '*****@*****.**',
                },
                'projects': [
                    {
                        'networkEstimate': 1,
                        'targetJob': {
                            'jobGroup': {
                                'romeId': 'A1234'
                            }
                        }
                    },
                ],
            },
        ])
        user_collection = list(mock_user_db.user.find({}))
        mail_blast.main([
            'focus-network', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10', '--user-collection-prefix',
            'jobflix_', '--disable-sentry'
        ])
        messages = mailjetmock.get_all_sent_messages()
        self.assertEqual(['*****@*****.**'],
                         [m.recipient['Email'] for m in messages],
                         msg=messages)
        self.assertEqual(user_collection, list(mock_user_db.user.find({})))
Exemplo n.º 14
0
    def test_wrong_id(self) -> None:
        """Filter based on ID."""

        mock_db = pymongo.MongoClient('mongodb://mydata.com/test').test
        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_db.job_group_info.drop()
        mock_db.job_group_info.insert_one({
            '_id': 'A1234',
            'inDomain': 'dans la vie',
        })
        mock_user_db.user.drop()
        mock_user_db.user.insert_many([
            {
                '_id':
                objectid.ObjectId('444444444444444444444444'),
                'registeredAt':
                '2017-05-15T00:00:00Z',
                'profile': {
                    'name': 'The user',
                    'email': '*****@*****.**',
                },
                'projects': [
                    {
                        'networkEstimate': 1,
                        'targetJob': {
                            'jobGroup': {
                                'romeId': 'A1234'
                            }
                        }
                    },
                ],
            },
            {
                '_id':
                objectid.ObjectId('5b2173b9362bf80840db6c2a'),
                'registeredAt':
                '2017-05-15T00:00:00Z',
                'profile': {
                    'name': 'The filtered user',
                    'email': '*****@*****.**',
                },
                'projects': [
                    {
                        'networkEstimate': 1,
                        'targetJob': {
                            'jobGroup': {
                                'romeId': 'A1234'
                            }
                        }
                    },
                ],
            },
        ])
        mail_blast.main([
            'focus-network', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10', '--disable-sentry',
            '--user-id-start', '44'
        ])

        self.assertEqual(['*****@*****.**'], [
            m.recipient['Email'] for m in mailjetmock.get_all_sent_messages()
        ])
        users = mock_user_db.user.find({})
        self.assertEqual(
            {
                '*****@*****.**': ['focus-network'],
                '*****@*****.**': [],
            }, {
                u['profile']['email']:
                [e.get('campaignId') for e in u.get('emailsSent', [])]
                for u in users
            })
Exemplo n.º 15
0
    def test_blast_campaign(self, mock_logging: mock.MagicMock) -> None:
        """Basic test."""

        mock_db = pymongo.MongoClient('mongodb://mydata.com/test').test
        mock_user_db = pymongo.MongoClient(
            'mongodb://myprivatedata.com/user_test').user_test
        mock_db.job_group_info.drop()
        mock_db.job_group_info.insert_one({
            '_id': 'A1234',
            'inDomain': 'dans la vie',
        })
        mock_user_db.user.drop()
        mock_user_db.user.insert_many([{
            '_id':
            objectid.ObjectId(f'7b18313aa35d807e631ea3d{month}'),
            'registeredAt':
            f'2017-{month:02d}-15T00:00:00Z',
            'profile': {
                'name': f'{month} user',
                'email': f'email{month}@corpet.net',
            },
            'projects': [
                {
                    'networkEstimate': 1,
                    'targetJob': {
                        'jobGroup': {
                            'romeId': 'A1234'
                        }
                    }
                },
            ],
        } for month in range(2, 9)])
        mock_user_db.user.insert_many([
            {
                'registeredAt':
                '2017-05-15T00:00:00Z',
                'profile': {
                    'name': 'Already sent',
                    'email': '*****@*****.**',
                },
                'projects': [
                    {
                        'networkEstimate': 1,
                        'targetJob': {
                            'jobGroup': {
                                'romeId': 'A1234'
                            }
                        }
                    },
                ],
                'emailsSent': [{
                    'campaignId': 'focus-network'
                }],
            },
            {
                'registeredAt':
                '2017-05-15T00:00:00Z',
                'profile': {
                    'name': 'Test user',
                    'email': '*****@*****.**',
                },
                'projects': [
                    {
                        'networkEstimate': 1,
                        'targetJob': {
                            'jobGroup': {
                                'romeId': 'A1234'
                            }
                        }
                    },
                ],
            },
            {
                'registeredAt':
                '2017-05-15T00:00:00Z',
                'profile': {
                    'name': 'REDACTED',
                    'email': 'REDACTED',
                },
                'projects': [
                    {
                        'networkEstimate': 1,
                        'targetJob': {
                            'jobGroup': {
                                'romeId': 'A1234'
                            }
                        }
                    },
                ],
            },
        ])
        mail_blast.main([
            'focus-network', 'send', '--registered-from', '2017-04-01',
            '--registered-to', '2017-07-10', '--disable-sentry'
        ])

        mails_sent = mailjetmock.get_all_sent_messages()
        self.assertEqual(
            ['*****@*****.**', '*****@*****.**', '*****@*****.**'],
            sorted(m.recipient['Email'] for m in mails_sent),
            msg=
            f'3 emails expected: one per month from April to June\n{mails_sent}'
        )
        self.assertEqual({'*****@*****.**'},
                         {m.properties['From']['Email']
                          for m in mails_sent})
        february_user = mock_user_db.user.find_one(
            {'_id': objectid.ObjectId('7b18313aa35d807e631ea3d2')})
        assert february_user
        self.assertFalse(february_user.get('emailsSent'))

        april_user = mock_user_db.user.find_one(
            {'_id': objectid.ObjectId('7b18313aa35d807e631ea3d4')})
        assert april_user
        self.assertEqual([{
            'sentAt',
            'mailjetTemplate',
            'campaignId',
            'mailjetMessageId',
            'subject',
            'isCoaching',
        }], [e.keys() for e in april_user.get('emailsSent', [])])
        self.assertEqual('focus-network',
                         april_user['emailsSent'][0]['campaignId'])
        self.assertEqual(
            next(mailjetmock.get_messages_sent_to(
                '*****@*****.**')).message_id,
            int(april_user['emailsSent'][0]['mailjetMessageId']))

        mock_logging.assert_any_call('Email sent to %s',
                                     '7b18313aa35d807e631ea3d4')
        mailjet_campaign_id = mailjetmock.get_mailjet_campaign_id(
            'focus-network')
        mock_logging.assert_any_call(
            "Report for %s blast: I've sent %d emails (and got %d errors).%s",
            'focus-network', 3, 0, ' You can check opening and click stats on '
            f'<https://app.mailjet.com/stats/campaigns/{mailjet_campaign_id}/overview|Mailjet>'
        )
        mock_logging.assert_called_with('%d emails sent.', 3)