Add "additionalProperties" support to remove_extra_items in utils 97/7597/1
authorAnderson Bravalheri <a.bravalheri@bristol.ac.uk>
Thu, 30 May 2019 14:55:55 +0000 (15:55 +0100)
committerAnderson Bravalheri <a.bravalheri@bristol.ac.uk>
Mon, 3 Jun 2019 17:28:34 +0000 (18:28 +0100)
Change-Id: Ia3d48796f0d6b9b5dfd7d5838df0863846778944
Signed-off-by: Anderson Bravalheri <a.bravalheri@bristol.ac.uk>
osm_ro/tests/test_utils.py
osm_ro/utils.py
osm_ro/wim/schemas.py

index c3a4e7a..9fd71cf 100644 (file)
@@ -3,12 +3,16 @@
 
 import unittest
 
-from ..utils import get_arg, inject_args
+from ..utils import (
+    get_arg,
+    inject_args,
+    remove_extra_items,
+)
 
 
 class TestUtils(unittest.TestCase):
     def test_inject_args_curries_arguments(self):
-        fn = inject_args(lambda a=None, b=None: a+b, a=3, b=5)
+        fn = inject_args(lambda a=None, b=None: a + b, a=3, b=5)
         self.assertEqual(fn(), 8)
 
     def test_inject_args_doesnt_add_arg_if_not_needed(self):
@@ -31,20 +35,43 @@ class TestUtils(unittest.TestCase):
         def _fn(x, y, z):
             return x + y + z
 
-        x = get_arg('x', _fn, (1, 3, 4), {})
+        x = get_arg("x", _fn, (1, 3, 4), {})
         self.assertEqual(x, 1)
-        y = get_arg('y', _fn, (1, 3, 4), {})
+        y = get_arg("y", _fn, (1, 3, 4), {})
         self.assertEqual(y, 3)
-        z = get_arg('z', _fn, (1, 3, 4), {})
+        z = get_arg("z", _fn, (1, 3, 4), {})
         self.assertEqual(z, 4)
 
     def test_get_arg__keyword(self):
         def _fn(x, y, z=5):
             return x + y + z
 
-        z = get_arg('z', _fn, (1, 2), {'z': 3})
+        z = get_arg("z", _fn, (1, 2), {"z": 3})
         self.assertEqual(z, 3)
 
 
-if __name__ == '__main__':
+
+    def test_remove_extra_items__keep_aditional_properties(self):
+        schema = {
+            "type": "object",
+            "properties": {
+                "a": {
+                    "type": "object",
+                    "properties": {
+                        "type": "object",
+                        "properties": {"b": "string"},
+                    },
+                    "additionalProperties": True,
+                }
+            },
+        }
+
+        example = {"a": {"b": 1, "c": 2}, "d": 3}
+        deleted = remove_extra_items(example, schema)
+        self.assertIn("d", deleted)
+        self.assertIs(example.get("d"), None)
+        self.assertEqual(example["a"]["c"], 2)
+
+
+if __name__ == "__main__":
     unittest.main()
index 05c9801..625ff6d 100644 (file)
@@ -81,25 +81,30 @@ def format_in(http_response, schema):
         return False, ("validate_in error, jsonschema exception ", exc.message, "at", exc.path)
 
 def remove_extra_items(data, schema):
-    deleted=[]
+    deleted = []
     if type(data) is tuple or type(data) is list:
         for d in data:
-            a= remove_extra_items(d, schema['items'])
-            if a is not None: deleted.append(a)
+            a = remove_extra_items(d, schema['items'])
+            if a is not None:
+                deleted.append(a)
     elif type(data) is dict:
-        #TODO deal with patternProperties
+        # TODO deal with patternProperties
         if 'properties' not in schema:
             return None
         for k in data.keys():
-            if k not in schema['properties'].keys():
+            if k in schema['properties'].keys():
+                a = remove_extra_items(data[k], schema['properties'][k])
+                if a is not None:
+                    deleted.append({k: a})
+            elif not schema.get('additionalProperties'):
                 del data[k]
                 deleted.append(k)
-            else:
-                a = remove_extra_items(data[k], schema['properties'][k])
-                if a is not None:  deleted.append({k:a})
-    if len(deleted) == 0: return None
-    elif len(deleted) == 1: return deleted[0]
-    else: return deleted
+    if len(deleted) == 0:
+        return None
+    elif len(deleted) == 1:
+        return deleted[0]
+
+    return deleted
 
 #def format_html2text(http_content):
 #    soup=BeautifulSoup(http_content)
index a88cb5e..101bcb1 100644 (file)
@@ -131,11 +131,9 @@ wim_schema = {
             "type": "object",
             "properties": wim_schema_properties,
             "required": ["name", "type", "wim_url"],
-            "additionalProperties": True
         }
     },
     "required": ["wim"],
-    "additionalProperties": False
 }
 
 wim_edit_schema = {
@@ -146,11 +144,9 @@ wim_edit_schema = {
         "wim": {
             "type": "object",
             "properties": wim_schema_properties,
-            "additionalProperties": False
         }
     },
     "required": ["wim"],
-    "additionalProperties": False
 }
 
 wim_account_schema = {
@@ -166,11 +162,9 @@ wim_account_schema = {
                 "password": nameshort_schema,
                 "config": {"type": "object"}
             },
-            "additionalProperties": True
         }
     },
     "required": ["wim_account"],
-    "additionalProperties": False
 }
 
 wim_port_mapping_schema = {