import unittest
+from copy import deepcopy
from wrpylib.json_tools import order_json_keys
schema_object = {
"$schema": "http://json-schema.org/draft-07/schema#",
- "title": "Rodelbahn",
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
- "title": "Rodelbahn Name",
"type": "string",
},
"aliases": {
- "title": "Alternative Namen",
"type": "array",
"items": {
"type": "string",
}
},
"entry_under_construction": {
- "title": "Eintrag in Arbeit",
"type": "boolean",
"default": True,
},
"length": {
- "title": "Länge",
"type": "number",
"minimum": 1,
"optional": True
},
"difficulty": {
- "title": "Schwierigkeit",
"type": "string",
"enum": [
"leicht",
],
},
"walkup_time": {
- "title": "Gehzeit",
"type": "number",
},
}
}
+schema_array = {
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "array",
+ "items": {
+ "type": "string",
+ }
+}
+
+
class TestJsonValidate(unittest.TestCase):
def test_string_empty(self):
actual = order_json_keys('', {"type": "string"})
with self.assertRaises(ValueError):
order_json_keys(value, schema)
- def test_array(self):
- raise NotImplementedError()
+ def test_object_nested(self):
+ schema = deepcopy(schema_object)
+ schema['properties']['nested'] = schema_object
+ value = {
+ 'nested': {
+ 'length': 3,
+ 'name': 'Mustermann',
+ },
+ 'name': 'parent',
+ }
+ expected = {
+ 'name': 'parent',
+ 'nested': {
+ 'name': 'Mustermann',
+ 'length': 3,
+ }
+ }
+ actual = order_json_keys(value, schema)
+ self.assertEqual(expected, actual)
+
+ def test_object_nested_wrong_type(self):
+ schema = deepcopy(schema_object)
+ schema['properties']['nested'] = schema_object
+ with self.assertRaises(ValueError):
+ order_json_keys({'name': 'name', 'nested': {'name': True}}, schema)
+
+ def test_array_empty(self):
+ schema = schema_array
+ actual = order_json_keys([], schema)
+ self.assertEqual([], actual)
+
+ def test_array_string(self):
+ schema = schema_array
+ actual = order_json_keys(['', 'a', 'ßöÄ'], schema)
+ self.assertEqual(['', 'a', 'ßöÄ'], actual)
+
+ def test_array_number(self):
+ schema = deepcopy(schema_array)
+ schema['items']['type'] = "number"
+ value = [0, 6.3, -3]
+ actual = order_json_keys(value, schema)
+ self.assertEqual(value, actual)
+
+ def test_array_object(self):
+ schema = deepcopy(schema_array)
+ schema['items']['type'] = "object"
+ value = [{}, {'a': 'b'}]
+ actual = order_json_keys(value, schema)
+ self.assertEqual(value, actual)
+
+ def test_array_array(self):
+ schema = deepcopy(schema_array)
+ schema['items']['type'] = "array"
+ value = [[], [3], [6, 8, 3.3]]
+ actual = order_json_keys(value, schema)
+ self.assertEqual(value, actual)
+
+ def test_array_boolean(self):
+ schema = deepcopy(schema_array)
+ schema['items']['type'] = "boolean"
+ value = [False, True, False]
+ actual = order_json_keys(value, schema)
+ self.assertEqual(value, actual)
+
+ def test_array_null(self):
+ schema = deepcopy(schema_array)
+ schema['items']['type'] = "null"
+ value = [None, None]
+ actual = order_json_keys(value, schema)
+ self.assertEqual(value, actual)
+
+ def test_array_wrong_string_types(self):
+ schema = {
+ "type": "array",
+ "items": {
+ "type": "string",
+ }
+ }
+ for v in [7, 0.4, {}, {'a': 'b'}, [], [1, 2, 3], True, False, None]:
+ value = [v]
+ with self.subTest(f'Try invalid value {value}.', value=value):
+ with self.assertRaises(ValueError):
+ order_json_keys(value, schema)
+
+ def test_array_mixed_types(self):
+ schema = {
+ "type": "array",
+ "items": {
+ "type": "string",
+ }
+ }
+ for v in [7, 0.4, {}, {'a': 'b'}, [], [1, 2, 3], True, False, None]:
+ value = ['a', v]
+ with self.subTest(f'Try invalid value {value}.', value=value):
+ with self.assertRaises(ValueError):
+ order_json_keys(value, schema)
def test_boolean_valid(self):
for value in [False, True]:
if not isinstance(sub_value, dict):
raise ValidationError(f'Type of {"".join(path)} needs to be object (Python dict).')
v = sub_value.copy()
- p = sub_schema['properties']
+ p = sub_schema.get('properties', {})
result = {}
for key in p:
if key in v:
def _order_json_keys_array(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> List:
if not isinstance(sub_value, list):
raise ValidationError(f'Type of {"".join(path)} needs to be array (Python list).')
- return sub_value
+ s = sub_schema.get('items', True)
+ return [_order_json_keys(v, s, path + [f'[{i}]']) for i, v in enumerate(sub_value)]
def _order_json_keys_boolean(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> bool:
def _order_json_keys(sub_value: JsonTypes, sub_schema: JsonTypes, path: List[str]) -> JsonTypes:
+ if isinstance(sub_schema, bool):
+ if sub_schema:
+ return sub_value
+ raise ValidationError(f'Value {sub_value} not allowed in {"".join(path)}.')
return {
'string': _order_json_keys_string,
'number': _order_json_keys_number,