def test_validate_callback_data_returns_none_when_valid(): form = {'status': 'good', 'reference': 'send-sms-code'} fields = ['status', 'reference'] client_name = 'sms client' assert validate_callback_data(form, fields, client_name) is None
def test_validate_callback_data_can_handle_integers(): form = {'status': 00, 'cid': 'fsdfadfsdfas'} fields = ['status', 'cid'] client_name = 'sms client' result = validate_callback_data(form, fields, client_name) assert result is None
def process_sinch_response(): client_name = 'Sinch' data = json.loads(request.data) errors = validate_callback_data( data=data, fields=['id', 'from', 'to', 'body', 'received_at'], client_name=client_name) if errors: raise InvalidRequest(errors, status_code=400) short_number = data.get('to') service = fetch_potential_service(short_number, 'sinch') if not service: return jsonify({"status": "ok"}), 200 success, errors = process_shortnumber_keyword_client_response( service=service, short_number=short_number, from_number=data.get('from'), body=data.get('body'), received_at=data.get('received_at'), provider_ref=data.get('id'), client_name=client_name) redacted_data = dict(data.items()) current_app.logger.debug( "Keyword shortnumber acknowledge from {} \n{}".format( client_name, redacted_data)) if errors: raise InvalidRequest(errors, status_code=400) else: return jsonify(result='success', message=success), 200
def test_validate_callback_data_can_handle_integers(): form = {"status": 00, "cid": "fsdfadfsdfas"} fields = ["status", "cid"] client_name = "sms client" result = validate_callback_data(form, fields, client_name) assert result is None
def process_telstra_response(notification_id): client_name = 'telstra' data = request.json errors = validate_callback_data(data=data, fields=['messageId', 'deliveryStatus'], client_name=client_name) if errors: raise InvalidRequest(errors, status_code=400) success, errors = process_sms_client_response( status=str(data.get('deliveryStatus')), provider_reference=notification_id, client_name=client_name) redacted_data = data.copy() redacted_data.pop("to") current_app.logger.debug( "Full delivery response from {} for notification: {}\n{}".format( client_name, notification_id, redacted_data)) if errors: raise InvalidRequest(errors, status_code=400) return jsonify(result='success', message=success), 200
def process_twilio_response(notification_id): client_name = 'Twilio' data = request.values errors = validate_callback_data(data=data, fields=['MessageStatus', 'MessageSid'], client_name=client_name) if errors: raise InvalidRequest(errors, status_code=400) success, errors = process_sms_client_response( status=data.get('MessageStatus'), provider_reference=notification_id, client_name=client_name) redacted_data = dict(data.items()) redacted_data.pop('To', None) current_app.logger.debug( "Full delivery response from {} for notification: {}\n{}".format( client_name, notification_id, redacted_data)) if errors: raise InvalidRequest(errors, status_code=400) else: return jsonify(result='success', message=success), 200
def test_validate_callback_data_returns_error_for_empty_string(): form = {'status': '', 'cid': 'fsdfadfsdfas'} fields = ['status', 'cid'] client_name = 'sms client' result = validate_callback_data(form, fields, client_name) assert result is not None assert "{} callback failed: {} missing".format(client_name, 'status') in result
def test_validate_callback_data_returns_error_for_empty_string(): form = {"status": "", "cid": "fsdfadfsdfas"} fields = ["status", "cid"] client_name = "sms client" result = validate_callback_data(form, fields, client_name) assert result is not None assert "{} callback failed: {} missing".format(client_name, "status") in result
def test_validate_callback_data_return_errors_when_fields_are_empty(): form = {"monkey": "good"} fields = ["status", "cid"] client_name = "sms client" errors = validate_callback_data(form, fields, client_name) assert len(errors) == 2 assert "{} callback failed: {} missing".format(client_name, "status") in errors assert "{} callback failed: {} missing".format(client_name, "cid") in errors
def test_validate_callback_data_returns_none_when_valid(): form = { 'status': 'good', 'reference': '67f9b762-061d-407e-9111-9addb6a96d60' } fields = ['status', 'reference'] client_name = 'sms client' assert validate_callback_data(form, fields, client_name) is None
def test_validate_callback_data_return_errors_when_fields_are_empty(): form = {'monkey': 'good'} fields = ['status', 'cid'] client_name = 'sms client' errors = validate_callback_data(form, fields, client_name) assert len(errors) == 2 assert "{} callback failed: {} missing".format(client_name, 'status') in errors assert "{} callback failed: {} missing".format(client_name, 'cid') in errors
def process_firetext_response(): client_name = 'Firetext' errors = validate_callback_data(data=request.form, fields=['status', 'reference'], client_name=client_name) if errors: raise InvalidRequest(errors, status_code=400) safe_to_log = dict(request.form).copy() safe_to_log.pop('mobile') current_app.logger.debug( "Full delivery response from {} for notification: {}\n{}".format(client_name, request.form.get('reference'), safe_to_log)) success, errors = process_sms_client_response(status=request.form.get('status'), provider_reference=request.form.get('reference'), client_name=client_name) if errors: raise InvalidRequest(errors, status_code=400) else: return jsonify(result='success', message=success), 200
def process_twilio_reply(): client_name = 'Twilio' current_app.logger.info('reply is called ') data = request.values errors = validate_callback_data(data=data, fields=['SmsStatus', 'MessageSid'], client_name=client_name) response = MessagingResponse() current_app.logger.info('validate_callback_data passed') if errors: raise InvalidRequest(errors, status_code=400) current_app.logger.info("Full {} body from {}: {}".format( client_name, data.get('From'), data.get('Body'))) if errors: raise InvalidRequest(errors, status_code=400) else: response.message('notification test got it') return str(response)
def process_mmg_response(): client_name = 'MMG' data = json.loads(request.data) errors = validate_callback_data(data=data, fields=['status', 'CID'], client_name=client_name) if errors: raise InvalidRequest(errors, status_code=400) success, errors = process_sms_client_response(status=str(data.get('status')), provider_reference=data.get('CID'), client_name=client_name) safe_to_log = data.copy() safe_to_log.pop("MSISDN") current_app.logger.debug( "Full delivery response from {} for notification: {}\n{}".format(client_name, request.form.get('CID'), safe_to_log)) if errors: raise InvalidRequest(errors, status_code=400) else: return jsonify(result='success', message=success), 200
def _process_sap_response(client_name, notification_id, data): errors = validate_callback_data(data=data, fields=['messageId', 'status'], client_name=client_name) if errors: raise InvalidRequest(errors, status_code=400) success, errors = process_sms_client_response( status=str(data.get('status')), provider_reference=notification_id, client_name=client_name) redacted_data = data.copy() redacted_data.pop("recipient") redacted_data.pop("message") current_app.logger.debug( "Full delivery response from {} for notification: {}\n{}".format( client_name, notification_id, redacted_data)) if errors: raise InvalidRequest(errors, status_code=400) return success
def process_ses_response(ses_request): client_name = 'SES' try: errors = validate_callback_data(data=ses_request, fields=['Message'], client_name=client_name) if errors: return errors ses_message = json.loads(ses_request['Message']) errors = validate_callback_data(data=ses_message, fields=['notificationType'], client_name=client_name) if errors: return errors notification_type = ses_message['notificationType'] if notification_type == 'Bounce': notification_type = determine_notification_bounce_type( notification_type, ses_message) elif notification_type == 'Complaint': complaint, notification, recipient = handle_complaint(ses_message) _check_and_queue_complaint_callback_task(complaint, notification, recipient) return try: aws_response_dict = get_aws_responses(notification_type) except KeyError: error = "{} callback failed: status {} not found".format( client_name, notification_type) return error notification_status = aws_response_dict['notification_status'] try: reference = ses_message['mail']['messageId'] notification = notifications_dao.update_notification_status_by_reference( reference, notification_status) if not notification: warning = "SES callback failed: notification either not found or already updated " \ "from sending. Status {} for notification reference {}".format(notification_status, reference) current_app.logger.warning(warning) return if not aws_response_dict['success']: current_app.logger.info( "SES delivery failed: notification id {} and reference {} has error found. Status {}" .format(notification.id, reference, aws_response_dict['message'])) else: current_app.logger.info( '{} callback return status of {} for notification: {}'. format(client_name, notification_status, notification.id)) statsd_client.incr('callback.ses.{}'.format(notification_status)) if notification.sent_at: statsd_client.timing_with_dates( 'callback.ses.elapsed-time'.format(client_name.lower()), datetime.utcnow(), notification.sent_at) _check_and_queue_callback_task(notification) return except KeyError: error = "SES callback failed: messageId missing" return error except ValueError: error = "{} callback failed: invalid json".format(client_name) return error
def test_validate_callback_data_returns_none_when_valid(): form = {"status": "good", "reference": "send-sms-code"} fields = ["status", "reference"] client_name = "sms client" assert validate_callback_data(form, fields, client_name) is None