update V2 error response to

{status_code: 403,
 errors: [error: AuthError, message: token has expired}]
}
This commit is contained in:
Rebecca Law
2016-11-09 14:56:54 +00:00
parent 78e84801bd
commit 346d90e319
6 changed files with 128 additions and 25 deletions

View File

@@ -18,8 +18,12 @@ class AuthError(Exception):
def to_dict_v2(self):
return {
'status_code': self.code,
'message': self.short_message,
'fields': self.message
"errors": [
{
"error": "AuthError",
"message": self.short_message
}
]
}

View File

@@ -25,9 +25,13 @@ class InvalidRequest(Exception):
Version 2 of the public api error response.
'''
return {
"status_code": self.code,
"message": self.message,
"fields": self.fields
"status_code": self.status_code,
"errors": [
{
"error": self.__class__.__name__,
"message": self.message
}
]
}
def __str__(self):

View File

@@ -1,4 +1,6 @@
import json
from collections import OrderedDict
from jsonschema import Draft4Validator, ValidationError
@@ -16,12 +18,11 @@ def build_error_message(errors, schema):
field = "'{}' {}".format(e.path[0], e.schema.get('validationMessage')) if e.schema.get(
'validationMessage') else e.message
s = field.split("'")
field = {s[1]: s[2].strip()}
field = OrderedDict({"error": "ValidationError", "message": {s[1]: s[2].strip()}})
fields.append(field)
message = {
"status_code": 400,
"message": "Validation error occurred - {}".format(schema['title']),
"fields": fields
"errors": fields
}
return json.dumps(message)

View File

@@ -20,7 +20,7 @@ valid_json_with_optionals = {
@pytest.mark.parametrize("input", [valid_json, valid_json_with_optionals])
def test_post_sms_schema_is_valid(input):
validate(input, post_sms_request)
assert validate(input, post_sms_request) == input
def test_post_sms_json_schema_bad_uuid_and_missing_phone_number():
@@ -28,11 +28,13 @@ def test_post_sms_json_schema_bad_uuid_and_missing_phone_number():
with pytest.raises(ValidationError) as e:
validate(j, post_sms_request)
error = json.loads(e.value.message)
assert "POST v2/notifications/sms" in error['message']
assert len(error.get('fields')) == 2
assert {"phone_number": "is a required property"} in error['fields']
assert {"template_id": "not a valid UUID"} in error['fields']
assert len(error.keys()) == 2
assert error.get('status_code') == 400
assert len(error.get('errors')) == 2
assert {'error': 'ValidationError',
'message': {"phone_number": "is a required property"}} in error['errors']
assert {'error': 'ValidationError',
'message': {"template_id": "not a valid UUID"}} in error['errors']
def test_post_sms_schema_with_personalisation_that_is_not_a_dict():
@@ -45,10 +47,11 @@ def test_post_sms_schema_with_personalisation_that_is_not_a_dict():
with pytest.raises(ValidationError) as e:
validate(j, post_sms_request)
error = json.loads(e.value.message)
assert "POST v2/notifications/sms" in error['message']
assert len(error.get('fields')) == 1
assert error['fields'][0] == {"personalisation": "should contain key value pairs"}
assert len(error.get('errors')) == 1
assert error['errors'] == [{'error': 'ValidationError',
'message': {"personalisation": "should contain key value pairs"}}]
assert error.get('status_code') == 400
assert len(error.keys()) == 2
valid_response = {
@@ -75,7 +78,7 @@ valid_response_with_optionals = {
@pytest.mark.parametrize('input', [valid_response])
def test_post_sms_response_schema_is_valid(input):
validate(input, post_sms_response)
assert validate(input, post_sms_response) == input
def test_post_sms_response_schema_missing_uri():
@@ -85,5 +88,5 @@ def test_post_sms_response_schema_missing_uri():
validate(j, post_sms_response)
error = json.loads(e.value.message)
assert error['status_code'] == 400
assert 'Validation error occurred - response v2/notifications/sms' == error['message']
assert [{"uri": "is a required property"}] == error['fields']
assert error['errors'] == [{'error': 'ValidationError',
'message': {"uri": "is a required property"}}]

View File

@@ -55,8 +55,8 @@ def test_post_sms_notification_returns_404_and_missing_template(notify_api, samp
assert response.headers['Content-type'] == 'application/json'
error_json = json.loads(response.get_data(as_text=True))
assert error_json['message'] == 'Template not found'
assert error_json['fields'] == [{'template': 'Template not found'}]
assert error_json['errors'] == [{"error": "BadRequestError",
"message": 'Template not found'}]
def test_post_sms_notification_returns_403_and_well_formed_auth_error(notify_api, sample_template):
@@ -76,8 +76,8 @@ def test_post_sms_notification_returns_403_and_well_formed_auth_error(notify_api
assert response.headers['Content-type'] == 'application/json'
error_resp = json.loads(response.get_data(as_text=True))
assert error_resp['status_code'] == 401
assert error_resp['message'] == 'Unauthorized, authentication token must be provided'
assert error_resp['fields'] == {'token': ['Unauthorized, authentication token must be provided']}
assert error_resp['errors'] == [{'error': "AuthError",
'message': 'Unauthorized, authentication token must be provided'}]
def test_post_sms_notification_returns_400_and_for_schema_problems(notify_api, sample_template):
@@ -98,5 +98,7 @@ def test_post_sms_notification_returns_400_and_for_schema_problems(notify_api, s
assert response.headers['Content-type'] == 'application/json'
error_resp = json.loads(response.get_data(as_text=True))
assert error_resp['status_code'] == 400
assert error_resp['message'] == 'Validation error occurred - POST v2/notifications/sms'
assert error_resp['fields'] == [{"template_id": "is a required property"}]
print(error_resp['errors'])
assert error_resp['errors'] == [{'error': 'ValidationError',
'message': {"template_id": "is a required property"}
}]

View File

@@ -0,0 +1,89 @@
import json
import pytest
from flask import url_for
@pytest.fixture(scope='function')
def app_for_test(mocker):
import flask
from flask import Blueprint
from app.authentication.auth import AuthError
from app.v2.errors import BadRequestError, TooManyRequestsError
app = flask.Flask(__name__)
app.config['TESTING'] = True
from app.v2.errors import register_errors
blue = Blueprint("v2_under_test", __name__, url_prefix='/v2/under_test')
@blue.route("/raise_auth_error", methods=["GET"])
def raising_auth_error():
raise AuthError("some message", 403)
@blue.route("/raise_bad_request", methods=["GET"])
def raising_bad_request():
raise BadRequestError(message="you forgot the thing")
@blue.route("/raise_too_many_requests", methods=["GET"])
def raising_too_many_requests():
raise TooManyRequestsError(sending_limit="452")
@blue.route("/raise_validation_error", methods=["GET"])
def raising_validation_error():
from app.schema_validation import validate
from app.v2.notifications.notification_schemas import post_sms_request
validate({"template_id": "bad_uuid"}, post_sms_request)
register_errors(blue)
app.register_blueprint(blue)
return app
def test_auth_error(app_for_test):
with app_for_test.test_request_context():
with app_for_test.test_client() as client:
response = client.get(url_for('v2_under_test.raising_auth_error'))
assert response.status_code == 403
error = json.loads(response.get_data(as_text=True))
assert error == {"status_code": 403,
"errors": [{"error": "AuthError",
"message": "some message"}]}
def test_bad_request_error(app_for_test):
with app_for_test.test_request_context():
with app_for_test.test_client() as client:
response = client.get(url_for('v2_under_test.raising_bad_request'))
assert response.status_code == 400
error = json.loads(response.get_data(as_text=True))
assert error == {"status_code": 400,
"errors": [{"error": "BadRequestError",
"message": "you forgot the thing"}]}
def test_too_many_requests_error(app_for_test):
with app_for_test.test_request_context():
with app_for_test.test_client() as client:
response = client.get(url_for('v2_under_test.raising_too_many_requests'))
assert response.status_code == 429
error = json.loads(response.get_data(as_text=True))
assert error == {"status_code": 429,
"errors": [{"error": "TooManyRequestsError",
"message": "Exceeded send limits (452) for today"}]}
def test_validation_error(app_for_test):
with app_for_test.test_request_context():
with app_for_test.test_client() as client:
response = client.get(url_for('v2_under_test.raising_validation_error'))
assert response.status_code == 400
error = json.loads(response.get_data(as_text=True))
assert len(error.keys()) == 2
assert error['status_code'] == 400
assert len(error['errors']) == 2
assert {'error': 'ValidationError',
'message': {'phone_number': 'is a required property'}} in error['errors']
assert {'error': 'ValidationError',
'message': {'template_id': 'not a valid UUID'}} in error['errors']