Add JSON Should Contain Sub JSON Keyword 57/99557/1
authorPawel Wieczorek <p.wieczorek2@samsung.com>
Thu, 12 Dec 2019 10:07:10 +0000 (11:07 +0100)
committerPawel Wieczorek <p.wieczorek2@samsung.com>
Thu, 12 Dec 2019 10:37:41 +0000 (11:37 +0100)
This patch provides functionality of "Dictionary Should Contain Sub
Dictionary" Keyword (from Robot Framework "Collections" library) for
JSON. It supports both objects and strings containing JSON.

Added tests were intended to verify no regressions were introduced as
well as corner cases are handled properly.

Issue-ID: SECCOM-261
Change-Id: Id7581d79b93ce0403e97e1bbf47c10e0e166f2ec
Signed-off-by: Pawel Wieczorek <p.wieczorek2@samsung.com>
robotframework-onap/ONAPLibrary/JSONKeywords.py
robotframework-onap/tests/ONAPLibrary/JSONKeywordsTest.py [new file with mode: 0644]
robotframework-onap/tests/runner.py

index 5b9e24e..70fa2c0 100644 (file)
@@ -25,10 +25,8 @@ class JSONKeywords(object):
     def __init__(self):
         super(JSONKeywords, self).__init__()
 
-    @keyword
-    def json_equals(self, left, right):
-        """JSON Equals takes in two strings or json objects, converts them into json if needed and then compares them,
-        returning if they are equal or not."""
+    def _json_compare(self, left, right, cmp):
+        """_json_compare takes two strings or JSON objects and checks their DeepDiff using cmp function."""
         if isinstance(left, string_types):
             left_json = json.loads(left)
         else:
@@ -39,11 +37,28 @@ class JSONKeywords(object):
             right_json = right
 
         ddiff = DeepDiff(left_json, right_json, ignore_order=True)
-        if ddiff == {}:
-            return True
-        else:
+        return cmp(ddiff)
+
+    @keyword
+    def json_equals(self, left, right):
+        """JSON Equals takes in two strings or json objects, converts them into json if needed and then compares them,
+        returning if they are equal or not."""
+        return self._json_compare(left, right, lambda ddiff: ddiff == {})
+
+    @keyword
+    def json_should_contain_sub_json(self, left, right):
+        """JSON Should Contain Sub JSON fails unless all items in right are found in left."""
+
+        # following could have been really long lambda but readability counts
+        def _is_subset(ddiff):
+            if ddiff == {}:
+                return True
+            if len(ddiff.keys()) == 1 and 'dictionary_item_removed' in ddiff.keys():
+                return True
             return False
 
+        return self._json_compare(left, right, _is_subset)
+
     @keyword
     def make_list_into_dict(self, dict_list, key):
         """ Converts a list of dicts that contains a field that has a unique key into a dict of dicts """
diff --git a/robotframework-onap/tests/ONAPLibrary/JSONKeywordsTest.py b/robotframework-onap/tests/ONAPLibrary/JSONKeywordsTest.py
new file mode 100644 (file)
index 0000000..3fef40f
--- /dev/null
@@ -0,0 +1,204 @@
+# Copyright 2019 Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+
+from unittest import TestCase
+
+from ONAPLibrary.JSONKeywords import JSONKeywords
+
+
+class JSONKeywordsTest(TestCase):
+    content_empty_string = '{}'
+    content_empty_dict = {}
+    content1_string = '{"foo": "bar"}'
+    content1_dict = {"foo": u"bar"}
+    content1b_string = '{"foo": "quuz"}'
+    content1b_dict = {"foo": u"quuz"}
+    content2_string = '{"baz": "quuz"}'
+    content2_dict = {"baz": u"quuz"}
+    content_big_string = '{"foo": "bar", "baz": "quuz"}'
+    content_big_dict = {"foo": u"bar", "baz": u"quuz"}
+
+    def setUp(self):
+        self.jk = JSONKeywords()
+
+    # equality - corner cases
+    def test_json_empty_strings_equality(self):
+        left_json_string = JSONKeywordsTest.content_empty_string
+        right_json_string = JSONKeywordsTest.content_empty_string
+        self.assertTrue(self.jk.json_equals(left_json_string, right_json_string))
+
+    def test_json_empty_objects_equality(self):
+        left_json_object = JSONKeywordsTest.content_empty_dict
+        right_json_object = JSONKeywordsTest.content_empty_dict
+        self.assertTrue(self.jk.json_equals(left_json_object, right_json_object))
+
+    # equality - type conversions
+    def test_json_strings_equality(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_string = JSONKeywordsTest.content1_string
+        self.assertTrue(self.jk.json_equals(left_json_string, right_json_string))
+
+    def test_json_objects_equality(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_object = JSONKeywordsTest.content1_dict
+        self.assertTrue(self.jk.json_equals(left_json_object, right_json_object))
+
+    def test_json_string_object_equality(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_object = JSONKeywordsTest.content1_dict
+        self.assertTrue(self.jk.json_equals(left_json_string, right_json_object))
+
+    def test_json_object_string_equality(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_string = JSONKeywordsTest.content1_string
+        self.assertTrue(self.jk.json_equals(left_json_object, right_json_string))
+
+    # equality - difference detection
+    def test_json_strings_inequality(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_string = JSONKeywordsTest.content2_string
+        self.assertFalse(self.jk.json_equals(left_json_string, right_json_string))
+
+    def test_json_objects_inequality(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_object = JSONKeywordsTest.content2_dict
+        self.assertFalse(self.jk.json_equals(left_json_object, right_json_object))
+
+    def test_json_string_object_inequality(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_object = JSONKeywordsTest.content2_dict
+        self.assertFalse(self.jk.json_equals(left_json_string, right_json_object))
+
+    def test_json_object_string_inequality(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_string = JSONKeywordsTest.content2_string
+        self.assertFalse(self.jk.json_equals(left_json_object, right_json_string))
+
+    # subsets - corner cases
+    def test_json_empty_strings_subset(self):
+        left_json_string = JSONKeywordsTest.content_empty_string
+        right_json_string = JSONKeywordsTest.content_empty_string
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_string, right_json_string))
+
+    def test_json_empty_objects_subset(self):
+        left_json_object = JSONKeywordsTest.content_empty_dict
+        right_json_object = JSONKeywordsTest.content_empty_dict
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_object, right_json_object))
+
+    # subsets - type conversions
+    def test_json_strings_subset(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_string = JSONKeywordsTest.content1_string
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_string, right_json_string))
+
+    def test_json_objects_subset(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_object = JSONKeywordsTest.content1_dict
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_object, right_json_object))
+
+    def test_json_string_object_subset(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_object = JSONKeywordsTest.content1_dict
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_string, right_json_object))
+
+    def test_json_object_string_subset(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_string = JSONKeywordsTest.content1_string
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_object, right_json_string))
+
+    # subsets - inclusion
+    def test_json_strings_proper_subset(self):
+        left_json_string = JSONKeywordsTest.content_big_string
+        right_json_string = JSONKeywordsTest.content1_string
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_string, right_json_string))
+
+    def test_json_objects_proper_subset(self):
+        left_json_object = JSONKeywordsTest.content_big_dict
+        right_json_object = JSONKeywordsTest.content1_dict
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_object, right_json_object))
+
+    def test_json_string_object_proper_subset(self):
+        left_json_string = JSONKeywordsTest.content_big_string
+        right_json_object = JSONKeywordsTest.content1_dict
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_string, right_json_object))
+
+    def test_json_object_string_proper_subset(self):
+        left_json_object = JSONKeywordsTest.content_big_dict
+        right_json_string = JSONKeywordsTest.content1_string
+        self.assertTrue(self.jk.json_should_contain_sub_json(left_json_object, right_json_string))
+
+    # subsets - intersection
+    def test_json_strings_intersection(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_string = JSONKeywordsTest.content_big_string
+        self.assertFalse(self.jk.json_should_contain_sub_json(left_json_string, right_json_string))
+
+    def test_json_objects_intersection(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_object = JSONKeywordsTest.content_big_dict
+        self.assertFalse(self.jk.json_should_contain_sub_json(left_json_object, right_json_object))
+
+    def test_json_string_object_intersection(self):
+        left_json_string = JSONKeywordsTest.content1_dict
+        right_json_object = JSONKeywordsTest.content_big_string
+        self.assertFalse(self.jk.json_should_contain_sub_json(left_json_string, right_json_object))
+
+    def test_json_object_string_intersection(self):
+        left_json_object = JSONKeywordsTest.content1_string
+        right_json_string = JSONKeywordsTest.content_big_dict
+        self.assertFalse(self.jk.json_should_contain_sub_json(left_json_object, right_json_string))
+
+    # subsets - exclusion
+    def test_json_strings_exclusion(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_string = JSONKeywordsTest.content2_string
+        self.assertFalse(self.jk.json_equals(left_json_string, right_json_string))
+
+    def test_json_objects_exclusion(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_object = JSONKeywordsTest.content2_dict
+        self.assertFalse(self.jk.json_equals(left_json_object, right_json_object))
+
+    def test_json_string_object_exclusion(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_object = JSONKeywordsTest.content2_dict
+        self.assertFalse(self.jk.json_equals(left_json_string, right_json_object))
+
+    def test_json_object_string_exclusion(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_string = JSONKeywordsTest.content2_string
+        self.assertFalse(self.jk.json_equals(left_json_object, right_json_string))
+
+    # subsets - value change detection
+    def test_json_strings_changed_value(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_string = JSONKeywordsTest.content1b_string
+        self.assertFalse(self.jk.json_equals(left_json_string, right_json_string))
+
+    def test_json_objects_changed_value(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_object = JSONKeywordsTest.content1b_dict
+        self.assertFalse(self.jk.json_equals(left_json_object, right_json_object))
+
+    def test_json_string_object_changed_value(self):
+        left_json_string = JSONKeywordsTest.content1_string
+        right_json_object = JSONKeywordsTest.content1b_dict
+        self.assertFalse(self.jk.json_equals(left_json_string, right_json_object))
+
+    def test_json_object_string_changed_value(self):
+        left_json_object = JSONKeywordsTest.content1_dict
+        right_json_string = JSONKeywordsTest.content1b_string
+        self.assertFalse(self.jk.json_equals(left_json_object, right_json_string))
index ae132d1..a8c1afc 100644 (file)
@@ -11,6 +11,7 @@ from tests.ONAPLibrary.Base64KeywordsTests import Base64KeywordsTests
 from tests.ONAPLibrary.RequestsHelperTests import RequestsHelperTests
 from tests.ONAPLibrary.AAITests import AAITests
 from tests.ONAPLibrary.SOTests import SOTests
+from tests.ONAPLibrary.JSONKeywordsTest import JSONKeywordsTest
 
 # initialize the test suite
 loader = TestLoader()
@@ -25,6 +26,7 @@ suite.addTests(loader.loadTestsFromTestCase(UUIDKeywordsTest))
 suite.addTests(loader.loadTestsFromTestCase(ServiceMappingKeywordsTests))
 suite.addTests(loader.loadTestsFromTestCase(Base64KeywordsTests))
 suite.addTests(loader.loadTestsFromTestCase(RequestsHelperTests))
+suite.addTests(loader.loadTestsFromTestCase(JSONKeywordsTest))
 
 # initialize a runner, pass it your suite and run it
 runner = TextTestRunner(verbosity=3)