validation endpoint implementation #7
3 changed files with 70 additions and 39 deletions
12
app.py
12
app.py
|
@ -35,10 +35,12 @@ class HealthHandler(tornado.web.RequestHandler, metaclass=ABCMeta):
|
|||
# if not available, try git
|
||||
if v is None:
|
||||
try:
|
||||
v = subprocess.check_output(["git", "describe", "--always", "--dirty"],
|
||||
v = subprocess.check_output(["git", "describe", "--always",
|
||||
"--dirty"],
|
||||
cwd=os.path.dirname(__file__)).strip().decode()
|
||||
except subprocess.CalledProcessError as e:
|
||||
print("Checking git version lead to non-null return code ", e.returncode)
|
||||
print("Checking git version lead to non-null return code ",
|
||||
e.returncode)
|
||||
|
||||
return v
|
||||
|
||||
|
@ -50,7 +52,8 @@ class HealthHandler(tornado.web.RequestHandler, metaclass=ABCMeta):
|
|||
health['git-version'] = self.git_version
|
||||
|
||||
health['timestamp'] = isodate.datetime_isoformat(datetime.now())
|
||||
health['uptime'] = isodate.duration_isoformat(datetime.now() - startup_timestamp)
|
||||
health['uptime'] = isodate.duration_isoformat(datetime.now()
|
||||
- startup_timestamp)
|
||||
|
||||
self.set_header("Content-Type", "application/json")
|
||||
self.write(json.dumps(health, indent=4))
|
||||
|
@ -61,7 +64,8 @@ class Oas3Handler(tornado.web.RequestHandler, metaclass=ABCMeta):
|
|||
def get(self):
|
||||
self.set_header("Content-Type", "text/plain")
|
||||
# This is the proposed content type,
|
||||
# but browsers like Firefox try to download instead of display the content
|
||||
# but browsers like Firefox try to download instead of
|
||||
# display the content
|
||||
# self.set_header("Content-Type", "text/vnd.yml")
|
||||
with open('OAS3.yml', 'r') as f:
|
||||
oas3 = f.read()
|
||||
|
|
90
test.py
90
test.py
|
@ -22,11 +22,16 @@ class TestBaseAPI(tornado.testing.AsyncHTTPTestCase):
|
|||
|
||||
health = json.loads(response.body.decode())
|
||||
|
||||
self.assertIn('api-version', health, msg="api-version is not provided by health endpoint")
|
||||
self.assertEqual("v0", health['api-version'], msg="API version should be v0")
|
||||
self.assertIn('git-version', health, msg="git-version is not provided by health endpoint")
|
||||
self.assertIn('timestamp', health, msg="timestamp is not provided by health endpoint")
|
||||
self.assertIn('uptime', health, msg="uptime is not provided by health endpoint")
|
||||
self.assertIn('api-version', health,
|
||||
msg="api-version is not provided by health endpoint")
|
||||
self.assertEqual("v0", health['api-version'],
|
||||
msg="API version should be v0")
|
||||
self.assertIn('git-version', health,
|
||||
msg="git-version is not provided by health endpoint")
|
||||
self.assertIn('timestamp', health,
|
||||
msg="timestamp is not provided by health endpoint")
|
||||
self.assertIn('uptime', health,
|
||||
msg="uptime is not provided by health endpoint")
|
||||
|
||||
def test_oas3(self):
|
||||
response = self.fetch('/v0/oas3',
|
||||
|
@ -35,7 +40,8 @@ class TestBaseAPI(tornado.testing.AsyncHTTPTestCase):
|
|||
|
||||
# check contents against local OAS3.yml
|
||||
with open('OAS3.yml') as oas3f:
|
||||
self.assertEqual(response.body.decode(), oas3f.read(), "OAS3 content differs from spec file!")
|
||||
self.assertEqual(response.body.decode(), oas3f.read(),
|
||||
"OAS3 content differs from spec file!")
|
||||
|
||||
|
||||
class TestValidation(tornado.testing.AsyncHTTPTestCase):
|
||||
|
@ -50,74 +56,90 @@ class TestValidation(tornado.testing.AsyncHTTPTestCase):
|
|||
method='POST',
|
||||
body=json.dumps(entity))
|
||||
|
||||
self.assertEqual(200, response.code, "Validation must always return 200")
|
||||
self.assertEqual(200, response.code,
|
||||
"Validation must always return 200")
|
||||
|
||||
validation_result = json.loads(response.body.decode())
|
||||
|
||||
self.assertIn('valid', validation_result, "Key 'valid' expected in validation result")
|
||||
self.assertFalse(validation_result['valid'], "Validation result is expected to be valid==false")
|
||||
self.assertIn('valid', validation_result,
|
||||
"Key 'valid' expected in validation result")
|
||||
self.assertFalse(validation_result['valid'],
|
||||
"Validation result is expected to be valid==false")
|
||||
|
||||
def test_valid_entity(self):
|
||||
with open('test_cases/valid/valid.json','r') af f:
|
||||
with open('test_cases/valid/valid.json', 'r') af f:
|
||||
entity_file = json.load(f)
|
||||
|
||||
response = self.fetch('/v0/validate',
|
||||
method='POST',
|
||||
body=json.dumps(entity_file))
|
||||
|
||||
self.assertEqual(200, response.code, "Validation must always return 200")
|
||||
|
||||
self.assertEqual(200, response.code,
|
||||
"Validation must always return 200")
|
||||
|
||||
validation_result = json.loads(response.body.decode())
|
||||
|
||||
self.assertIn('valid', validation_result, "Key 'valid' expected in validation result")
|
||||
self.assertTrue(validation_result['valid'], "Validation result is expected to be valid==true")
|
||||
self.assertIn('valid', validation_result,
|
||||
"Key 'valid' expected in validation result")
|
||||
self.assertTrue(validation_result['valid'],
|
||||
"Validation result is expected to be valid==true")
|
||||
|
||||
def test_invalid_iban(self):
|
||||
with open('test_cases/invalid/invalid_iban.json','r') af f:
|
||||
with open('test_cases/invalid/invalid_iban.json', 'r') af f:
|
||||
entity_file = json.load(f)
|
||||
|
||||
response = self.fetch('/v0/validate',
|
||||
method='POST',
|
||||
body=json.dumps(entity_file))
|
||||
|
||||
self.assertEqual(200, response.code, "Validation must always return 200")
|
||||
|
||||
self.assertEqual(200, response.code,
|
||||
"Validation must always return 200")
|
||||
|
||||
validation_result = json.loads(response.body.decode())
|
||||
|
||||
self.assertIn('valid', validation_result, "Key 'valid' expected in validation result")
|
||||
self.assertFalse(validation_result['valid'], "Validation result is expected to be valid==false")
|
||||
self.assertIn('valid', validation_result,
|
||||
"Key 'valid' expected in validation result")
|
||||
self.assertFalse(validation_result['valid'],
|
||||
"Validation result is expected to be valid==false")
|
||||
|
||||
def test_missing_id(self):
|
||||
with open('test_cases/invalid/missing_id.json','r') af f:
|
||||
with open('test_cases/invalid/missing_id.json', 'r') af f:
|
||||
entity_file = json.load(f)
|
||||
|
||||
response = self.fetch('/v0/validate',
|
||||
method='POST',
|
||||
body=json.dumps(entity_file))
|
||||
|
||||
self.assertEqual(200, response.code, "Validation must always return 200")
|
||||
method='POST',
|
||||
body=json.dumps(entity_file))
|
||||
|
||||
self.assertEqual(200, response.code,
|
||||
"Validation must always return 200")
|
||||
|
||||
validation_result = json.loads(response.body.decode())
|
||||
|
||||
self.assertIn('valid', validation_result, "Key 'valid' expected in validation result")
|
||||
self.assertFalse(validation_result['valid'], "Validation result is expected to be valid==false")
|
||||
self.assertIn('valid', validation_result,
|
||||
"Key 'valid' expected in validation result")
|
||||
self.assertFalse(validation_result['valid'],
|
||||
"Validation result is expected to be valid==false")
|
||||
self.assertIn('id', validation_result['errors'])
|
||||
|
||||
def test_invalid_id(self):
|
||||
with open('test_cases/invalid/invalid_id.json','r') af f:
|
||||
with open('test_cases/invalid/invalid_id.json', 'r') af f:
|
||||
entity_file = json.load(f)
|
||||
|
||||
|
||||
response = self.fetch('/v0/validate',
|
||||
method='POST',
|
||||
body=json.dumps(entity_file))
|
||||
|
||||
self.assertEqual(200, response.code, "Validation must always return 200")
|
||||
method='POST',
|
||||
body=json.dumps(entity_file))
|
||||
|
||||
self.assertEqual(200, response.code,
|
||||
"Validation must always return 200")
|
||||
|
||||
validation_result = json.loads(response.body.decode())
|
||||
|
||||
self.assertIn('valid', validation_result, "Key 'valid' expected in validation result")
|
||||
self.assertFalse(validation_result['valid'], "Validation result is expected to be valid==false")
|
||||
self.assertIn('valid', validation_result,
|
||||
"Key 'valid' expected in validation result")
|
||||
self.assertFalse(validation_result['valid'],
|
||||
"Validation result is expected to be valid==false")
|
||||
self.assertIn('id', validation_result['errors'])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -2,6 +2,7 @@ from schwifty import IBAN, BIC
|
|||
import datetime
|
||||
from validator_collection import validators, errors
|
||||
|
||||
|
||||
def valid_iban(field, value, error):
|
||||
try:
|
||||
IBAN(value)
|
||||
|
@ -9,6 +10,7 @@ def valid_iban(field, value, error):
|
|||
except ValueError:
|
||||
error(field, 'not a valid IBAN')
|
||||
|
||||
|
||||
def valid_bic(field, value, error):
|
||||
try:
|
||||
BIC(value)
|
||||
|
@ -16,6 +18,7 @@ def valid_bic(field, value, error):
|
|||
except ValueError:
|
||||
error(field, 'not a valid BIC')
|
||||
|
||||
|
||||
def iso_date(field, value, error):
|
||||
try:
|
||||
datetime.datetime.strptime(value, "%Y-%m-%d")
|
||||
|
@ -23,6 +26,7 @@ def iso_date(field, value, error):
|
|||
except ValueError:
|
||||
error(field, 'not a valid ISO 8601 date')
|
||||
|
||||
|
||||
def valid_money_amount(field, value, error):
|
||||
try:
|
||||
# value is string, check formatting by parsing as float
|
||||
|
@ -31,9 +35,10 @@ def valid_money_amount(field, value, error):
|
|||
except (ValueError, TypeError):
|
||||
error(field, 'not a valid money value')
|
||||
|
||||
|
||||
def valid_email(field, value, error):
|
||||
try:
|
||||
validators.email(value)
|
||||
return True
|
||||
except errors.InvalidEmailError:
|
||||
error(field, 'not a valid email')
|
||||
error(field, 'not a valid email')
|
||||
|
|
Loading…
Reference in a new issue