def test_caching_bad_message_ids(self, mock_sfmc): """Bad message IDs are cached so we don't try to send to them again""" exc = NewsletterException() exc.message = 'Invalid Customer Key' mock_sfmc.send_mail.side_effect = exc message_id = "MESSAGE_ID" for i in range(10): send_message(message_id, 'email', 'token', 'format') mock_sfmc.send_mail.assert_called_once_with(message_id, 'email', 'token', 'format')
def test_caching_bad_message_ids(self, mock_sfmc): """Bad message IDs are cached so we don't try to send to them again""" exc = NewsletterException() exc.message = 'Invalid Customer Key' mock_sfmc.send_mail.side_effect = exc message_id = "MESSAGE_ID" for i in range(10): send_message(message_id, 'email', 'token', 'format') mock_sfmc.send_mail.assert_called_once_with(message_id, 'email', 'token', None)
def get_user_data(token=None, email=None, extra_fields=None): """Return a dictionary of the user's data from Exact Target. Look them up by their email if given, otherwise by the token. If the user was not found, return None instead of a dictionary. Some data fields are not returned by default. Those fields are listed in the IGNORE_USER_FIELDS list. If you need one of those fields then call this function with said field name in a list passed in the `extra_fields` argument. Review of results: None = user completely unknown, no errors talking to ET. otherwise, return value is:: { 'status': 'ok', # no errors talking to ET 'status': 'error', # errors talking to ET, see next field 'desc': 'error message' # details if status is error 'email': 'email@address', 'format': 'T'|'H', 'country': country code, 'lang': language code, 'token': UUID, 'created-date': date created, 'newsletters': list of slugs of newsletters subscribed to, 'confirmed': True if user has confirmed subscription (or was excepted), 'pending': True if we're waiting for user to confirm subscription 'master': True if we found them in the master subscribers table } """ try: user = sfdc.get(token, email) except sfapi.SalesforceResourceNotFound: return None except requests.exceptions.RequestException as e: raise NewsletterException(str(e), error_code=errors.BASKET_NETWORK_FAILURE, status_code=400) except sfapi.SalesforceAuthenticationFailed: raise NewsletterException( 'Email service provider auth failure', error_code=errors.BASKET_EMAIL_PROVIDER_AUTH_FAILURE, status_code=500) # don't send some of the returned data for fn in IGNORE_USER_FIELDS: if extra_fields and fn not in extra_fields: user.pop(fn, None) user['status'] = 'ok' return user
def test_caching_bad_message_ids(self, mock_ExactTarget): """Bad message IDs are cached so we don't try to send to them again""" mock_et = mock_ExactTarget() exc = NewsletterException() exc.message = 'Invalid Customer Key' mock_et.trigger_send.side_effect = exc message_id = "MESSAGE_ID" # Should only raise BaseketError once with self.assertRaises(BasketError): send_message(message_id, 'email', 'token', 'format') send_message(message_id, 'email', 'token', 'format')
def bulk_upsert_rows(self, de_name, values): url = self.rowset_api_url.format(de_name) response = requests.post(url, json=values, headers=self.auth_header, timeout=30) if response.status_code >= 500: raise NewsletterException('SFMC Server Error: {}'.format( response.content), status_code=response.status_code) if response.status_code >= 400: raise NewsletterException(response.content, status_code=response.status_code)
def test_caching_bad_message_ids(self, mock_ExactTarget): """Bad message IDs are cached so we don't try to send to them again""" mock_et = mock_ExactTarget() exc = NewsletterException() exc.message = 'Invalid Customer Key' mock_et.trigger_send.side_effect = exc message_id = "MESSAGE_ID" for i in range(10): send_message(message_id, 'email', 'token', 'format') mock_et.trigger_send.assert_called_once_with('MESSAGE_ID', { 'EMAIL_ADDRESS_': 'email', 'TOKEN': 'token', 'EMAIL_FORMAT_': 'format', })
def test_error(self, get_user_data, sfdc_mock): """ If user_data shows an error talking to ET, the task raises an exception so our task logic will retry """ get_user_data.side_effect = NewsletterException('Stuffs broke yo.') with self.assertRaises(NewsletterException): confirm_user('token') self.assertFalse(sfdc_mock.update.called)
def test_et_error(self): # Error calling Exact Target, return error code err_msg = "Mock error for testing" error = NewsletterException(err_msg) expected = { 'status': 'error', 'desc': err_msg, 'status_code': 400, 'code': errors.BASKET_NETWORK_FAILURE, } self.check_get_user(ANY, ANY, ANY, error, expected)
def request_token(self, payload): r = requests.post(self.auth_url, json=payload) try: token_response = r.json() except ValueError: raise NewsletterException('SFMC Error During Auth: ' + r.content, status_code=r.status_code) if 'accessToken' in token_response: return token_response # try again without refreshToken if 'refreshToken' in payload: # not strictly required, makes testing easier payload = payload.copy() del payload['refreshToken'] return self.request_token(payload) raise NewsletterException('SFMC Error During Auth: ' + r.content, status_code=r.status_code)
def send_sms(self, phone_numbers, message_id): data = { 'mobileNumbers': phone_numbers, 'Subscribe': True, 'Resubscribe': True, 'keyword': 'FFDROID', # TODO: Set keyword in arguments. } url = self.sms_api_url.format(message_id) response = requests.post(url, json=data, headers=self.auth_header, timeout=10) if response.status_code >= 500: raise NewsletterException('SFMC Server Error: {}'.format( response.content), status_code=response.status_code) if response.status_code >= 400: errors = response.json()['errors'] raise NewsletterException(errors, status_code=response.status_code)
def test_user_not_in_sf(self, sfdc_mock): """A user not found in SFDC should produce an error response.""" sfdc_mock.get.side_effect = NewsletterException('DANGER!') token = generate_token() resp = self.client.get('/news/user/{}/'.format(token)) self.assertEqual(resp.status_code, 400) resp_data = json.loads(resp.content) self.assertDictEqual( resp_data, { 'status': 'error', 'desc': 'DANGER!', 'code': errors.BASKET_UNKNOWN_ERROR, })
def test_user_not_in_et(self, et_ext): """A user not found in ET should produce an error response.""" data_ext = et_ext() data_ext.get_record.side_effect = NewsletterException('DANGER!') models.Subscriber.objects.create(email='*****@*****.**', token='asdfjkl') resp = self.client.get('/news/user/asdfjkl/') self.assertEqual(resp.status_code, 400) resp_data = json.loads(resp.content) self.assertDictEqual(resp_data, { 'status': 'error', 'desc': 'DANGER!', 'code': errors.BASKET_NETWORK_FAILURE, })
def assert_response(resp): if not resp.status: raise NewsletterException(str(resp.results))