Make email_from and subject required attributes of the email_content schema.

Update the format_checkers to raise the specific exception that why the validator can handle multiple messages.
Which led to a refactor of build_error_message.
This commit is contained in:
Rebecca Law
2016-11-16 17:25:00 +00:00
parent 68537d960a
commit df62be421f
3 changed files with 36 additions and 18 deletions

View File

@@ -1,38 +1,45 @@
import json import json
from jsonschema import (Draft4Validator, ValidationError, FormatChecker) from jsonschema import (Draft4Validator, ValidationError, FormatChecker)
from notifications_utils.recipients import (validate_phone_number, validate_email_address) from notifications_utils.recipients import (validate_phone_number, validate_email_address, InvalidPhoneError,
InvalidEmailError)
def validate(json_to_validate, schema): def validate(json_to_validate, schema):
format_checker = FormatChecker() format_checker = FormatChecker()
@format_checker.checks('phone_number') @format_checker.checks('phone_number', raises=InvalidPhoneError)
def validate_schema_phone_number(instance): def validate_schema_phone_number(instance):
return validate_phone_number(instance) validate_phone_number(instance)
return True
@format_checker.checks('email_address') @format_checker.checks('email_address', raises=InvalidEmailError)
def validate_schema_email_address(instance): def validate_schema_email_address(instance):
return validate_email_address(instance) validate_email_address(instance)
return True
validator = Draft4Validator(schema, format_checker=format_checker) validator = Draft4Validator(schema, format_checker=format_checker)
errors = list(validator.iter_errors(json_to_validate)) errors = list(validator.iter_errors(json_to_validate))
if errors.__len__() > 0: if errors.__len__() > 0:
raise ValidationError(build_error_message(errors, schema)) raise ValidationError(build_error_message(errors))
return json_to_validate return json_to_validate
def build_error_message(errors, schema): def build_error_message(errors):
fields = [] fields = []
for e in errors: for e in errors:
field = "'{}' {}".format(e.path[0], e.schema.get('validationMessage')) if e.schema.get( field = "{} {}".format(e.path[0], e.schema.get('validationMessage')) if e.schema.get(
'validationMessage') else e.message 'validationMessage') else __format_message(e)
s = field.split("'") fields.append({"error": "ValidationError", "message": field})
field = {"error": "ValidationError", "message": "{}{}".format(s[1], s[2])}
fields.append(field)
message = { message = {
"status_code": 400, "status_code": 400,
"errors": fields "errors": fields
} }
return json.dumps(message) return json.dumps(message)
def __format_message(e):
s = e.message.split("'")
msg = "{}{}".format(s[1], s[2])
return msg if not e.cause else "'{}' {}".format(e.path[0], e.cause.message)

View File

@@ -80,7 +80,7 @@ email_content = {
"body": {"type": "string"}, "body": {"type": "string"},
"subject": {"type": "string"} "subject": {"type": "string"}
}, },
"required": ["body"] "required": ["body", "from_email", "subject"]
} }
post_email_response = { post_email_response = {

View File

@@ -57,14 +57,25 @@ def test_post_sms_schema_with_personalisation_that_is_not_a_dict():
@pytest.mark.parametrize('invalid_phone_number', @pytest.mark.parametrize('invalid_phone_number',
['notaphoneumber', '08515111111', '07515111*11']) ['08515111111', '07515111*11', 'notaphoneumber'])
def test_post_sms_request_invalid_phone_number(invalid_phone_number): def test_post_sms_request_invalid_phone_number(invalid_phone_number):
j = {"phone_number": invalid_phone_number, j = {"phone_number": invalid_phone_number,
"template_id": str(uuid.uuid4()) "template_id": str(uuid.uuid4())
} }
with pytest.raises(InvalidPhoneError): with pytest.raises(ValidationError):
validate(j, post_sms_request) validate(j, post_sms_request)
def test_post_sms_request_invalid_phone_number_and_missing_template():
j = {"phone_number": '08515111111',
}
with pytest.raises(ValidationError) as e:
validate(j, post_sms_request)
error = json.loads(e.value.message)
print(error)
assert len(error.get('errors')) == 2
valid_response = { valid_response = {
"id": str(uuid.uuid4()), "id": str(uuid.uuid4()),
"content": {"body": "contents of message", "content": {"body": "contents of message",
@@ -106,7 +117,7 @@ def test_post_sms_response_schema_missing_uri():
valid_post_email_json = {"email_address": "test@example.gov.uk", valid_post_email_json = {"email_address": "test@example.gov.uk",
"template_id": str(uuid.uuid4()) "template_id": str(uuid.uuid4())
} }
valid_post_emaiL_json_with_optionals = { valid_post_email_json_with_optionals = {
"email_address": "test@example.gov.uk", "email_address": "test@example.gov.uk",
"template_id": str(uuid.uuid4()), "template_id": str(uuid.uuid4()),
"reference": "reference from caller", "reference": "reference from caller",
@@ -114,7 +125,7 @@ valid_post_emaiL_json_with_optionals = {
} }
@pytest.mark.parametrize("input", [valid_post_email_json, valid_post_emaiL_json_with_optionals]) @pytest.mark.parametrize("input", [valid_post_email_json, valid_post_email_json_with_optionals])
def test_post_email_schema_is_valid(input): def test_post_email_schema_is_valid(input):
assert validate(input, post_email_request) == input assert validate(input, post_email_request) == input
@@ -128,7 +139,7 @@ def test_post_email_schema_bad_uuid_and_missing_email_address():
def test_post_email_schema_invalid_email_address(): def test_post_email_schema_invalid_email_address():
j = {"template_id": str(uuid.uuid4()), j = {"template_id": str(uuid.uuid4()),
"email_address": "notavalidemail@address"} "email_address": "notavalidemail@address"}
with pytest.raises(InvalidEmailError): with pytest.raises(ValidationError):
validate(j, post_email_request) validate(j, post_email_request)