]> ToastFreeware Gitweb - philipp/winterrodeln/wrpylib.git/commitdiff
Type of arrays are not tested.
authorPhilipp Spitzer <philipp@spitzer.priv.at>
Thu, 28 Oct 2021 20:32:19 +0000 (22:32 +0200)
committerPhilipp Spitzer <philipp@spitzer.priv.at>
Thu, 28 Oct 2021 20:32:19 +0000 (22:32 +0200)
tests/test_json_validate.py
wrpylib/json_tools.py

index d8888abcac0442f8524ce0c014f4d81d8904158f..a98af6d70203243ca595520134dad9c7ccd4ee24 100644 (file)
@@ -1,22 +1,20 @@
 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",
@@ -24,18 +22,15 @@ schema_object = {
             }
         },
         "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",
@@ -44,13 +39,21 @@ schema_object = {
             ],
         },
         "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"})
@@ -145,8 +148,102 @@ class TestJsonValidate(unittest.TestCase):
         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]:
index e48730223fbe6542516a870af71116ed7da2af6b..d9443c7fa2bda59e7f569c46b4ff4b1d04de7d5b 100644 (file)
@@ -24,7 +24,7 @@ def _order_json_keys_object(sub_value: JsonTypes, sub_schema: JsonTypes, path: L
     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:
@@ -44,7 +44,8 @@ def _order_json_keys_object(sub_value: JsonTypes, sub_schema: JsonTypes, path: L
 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:
@@ -60,6 +61,10 @@ def _order_json_keys_null(sub_value: JsonTypes, sub_schema: JsonTypes, path: Lis
 
 
 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,