TerekhovaKate commented on code in PR #7458:
URL: https://github.com/apache/trafficcontrol/pull/7458#discussion_r1175723017


##########
traffic_ops/testing/api_contract/v4/response_template.json:
##########
@@ -149,5 +149,80 @@
                 "type": "str"
             }
         }
+    },
+    "divisions": {
+        "type": "object",
+        "properties": {
+            "id": {
+                "type": "int"
+            },
+            "lastUpdated": {
+                "type": "str"
+            },
+            "name": {
+                "type": "str"
+            }
+        }
+    },
+    "regions": {
+        "type": "object",
+        "properties": {
+            "divisionName": {
+                "type": "str"
+            },
+            "division": {
+                "type": "int"
+            },
+            "id": {
+                "type": "int"
+            },
+            "lastUpdated": {
+                "type": "str"
+            },
+            "name": {
+                "type": "str"
+            }
+        }
+    },
+    "phys_locations": {
+        "type": "object",
+        "properties": {
+            "address": {
+                "type": "str"
+            },
+            "city": {
+                "type": "str"
+            },
+            "comments": {
+                "type": "str"
+            },
+            "email": {
+                "type": "str"
+            },
+            "name": {
+                "type": "str"
+            },
+            "phone": {
+                "type": "str"
+            },
+            "poc": {
+                "type": "str"
+            },
+            "regionId": {
+                "type": "int"
+            },
+            "region": {
+                "type": "str"
+            },
+            "shortName": {
+                "type": "str"
+            },
+            "state": {
+                "type": "str"
+            },
+            "zip": {
+                "type": "str"
+            }
+        }
     }
-}
+}

Review Comment:
   please run code over lint and flake ( pip8)
   no new line at end of file 



##########
traffic_ops/testing/api_contract/v4/test_divisions.py:
##########
@@ -0,0 +1,94 @@
+#
+# 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.
+#
+
+"""API Contract Test Case for divisions endpoint."""
+import logging
+import pytest
+import requests
+
+from trafficops.tosession import TOSession
+
+# Create and configure logger
+logger = logging.getLogger()
+
+primitive = bool | int | float | str | None
+
[email protected]('request_template_data', ["divisions"], indirect=True)
+def test_division_contract(
+       to_session: TOSession,
+       request_template_data: list[dict[str, object] | list[object] | 
primitive],
+       response_template_data: list[dict[str, object] | list[object] | 
primitive],
+       division_post_data: dict[str, object]
+) -> None:
+       """
+       Test step to validate keys, values and data types from divisions 
endpoint
+       response.
+       :param to_session: Fixture to get Traffic Ops session.
+       :param get_division_data: Fixture to get division data from a 
prerequisites file.
+       :param division_prereq: Fixture to get sample division data and actual 
division response.
+       """
+       # validate division keys from divisions get response
+       logger.info("Accessing /divisions endpoint through Traffic ops 
session.")
+
+       division = request_template_data[0]
+       if not isinstance(division, dict):
+               raise TypeError("malformed division in prerequisite data; not 
an object")
+
+       division_name = division.get("name")
+       if not isinstance(division_name, str):
+               raise TypeError("malformed division in prerequisite data; 
'name' not a string")
+
+       division_get_response: tuple[
+               dict[str, object] | list[dict[str, object] | list[object] | 
primitive] | primitive,
+               requests.Response
+       ] = to_session.get_divisions(query_params={"name": division_name})
+       try:
+               division_data = division_get_response[0]
+               if not isinstance(division_data, list):
+                       raise TypeError("malformed API response; 'response' 
property not an array")
+
+               first_division = division_data[0]
+               if not isinstance(first_division, dict):
+                       raise TypeError("malformed API response; first division 
in response is not an object")
+               division_keys = set(first_division.keys())
+
+               logger.info("division Keys from divisions endpoint response 
%s", division_keys)
+               response_template = 
response_template_data.get("divisions").get("properties")
+               # validate division values from prereq data in divisions get 
response.
+               prereq_values = [
+                       division_post_data["name"]]
+               get_values = [first_division["name"]]
+               get_types = {}
+               for key in first_division:
+                       get_types[key] = first_division[key].__class__.__name__
+               logger.info("types from division get response %s", get_types)
+               response_template_types= {}
+               for key in response_template:
+                       response_template_types[key] = 
response_template.get(key).get("type")
+               logger.info("types from division response template %s", 
response_template_types)
+
+               assert division_keys == set(response_template.keys())
+               assert dict(sorted(get_types.items())) == 
dict(sorted(response_template_types.items()))
+               assert get_values == prereq_values
+       except IndexError:
+               logger.error("Either prerequisite data or API response was 
malformed")
+               pytest.fail("Either prerequisite data or API response was 
malformed")

Review Comment:
   log message would be duplicated, change pytest or error log



##########
traffic_ops/testing/api_contract/v4/test_regions.py:
##########
@@ -0,0 +1,97 @@
+#
+# 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.
+#
+
+"""API Contract Test Case for regions endpoint."""
+import logging
+import pytest
+import requests
+
+from trafficops.tosession import TOSession
+
+# Create and configure logger
+logger = logging.getLogger()
+
+primitive = bool | int | float | str | None
+
[email protected]('request_template_data', ["regions"], indirect=True)
+def test_region_contract(
+       to_session: TOSession,
+       request_template_data: list[dict[str, object] | list[object] | 
primitive],
+       response_template_data: list[dict[str, object] | list[object] | 
primitive],
+       region_post_data: dict[str, object]
+) -> None:
+       """
+       Test step to validate keys, values and data types from regions endpoint
+       response.
+       :param to_session: Fixture to get Traffic Ops session.
+       :param get_region_data: Fixture to get region data from a prerequisites 
file.
+       :param region_prereq: Fixture to get sample region data and actual 
region response.
+       """
+       # validate region keys from regions get response
+       logger.info("Accessing /regions endpoint through Traffic ops session.")
+
+       region = request_template_data[0]
+       if not isinstance(region, dict):
+               raise TypeError("malformed region in prerequisite data; not an 
object")
+
+       region_name = region.get("name")
+       if not isinstance(region_name, str):
+               raise TypeError("malformed region in prerequisite data; 'name' 
not a string")
+
+       region_get_response: tuple[
+               dict[str, object] | list[dict[str, object] | list[object] | 
primitive] | primitive,
+               requests.Response
+       ] = to_session.get_regions(query_params={"name": region_name})
+       try:
+               region_data = region_get_response[0]
+               if not isinstance(region_data, list):
+                       raise TypeError("malformed API response; 'response' 
property not an array")
+
+               first_region = region_data[0]
+               if not isinstance(first_region, dict):
+                       raise TypeError("malformed API response; first region 
in response is not an object")
+               region_keys = set(first_region.keys())
+
+               logger.info("region Keys from regions endpoint response %s", 
region_keys)
+               response_template = 
response_template_data.get("region").get("properties")
+               # validate region values from prereq data in regions get 
response.
+               prereq_values = [
+                       region_post_data["name"],
+                       region_post_data["division"],
+            region_post_data["divisionName"]]
+            
+               get_values = [first_region["name"], first_region["division"], 
first_region["divisionName"]]
+               get_types = {}
+               for key in first_region:
+                       get_types[key] = first_region[key].__class__.__name__

Review Comment:
   type(value).__name__  -> see example in test_roles.py or over TC



##########
traffic_ops/testing/api_contract/v4/test_regions.py:
##########
@@ -0,0 +1,97 @@
+#
+# 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.
+#
+
+"""API Contract Test Case for regions endpoint."""
+import logging
+import pytest
+import requests
+
+from trafficops.tosession import TOSession
+
+# Create and configure logger
+logger = logging.getLogger()
+
+primitive = bool | int | float | str | None
+
[email protected]('request_template_data', ["regions"], indirect=True)
+def test_region_contract(
+       to_session: TOSession,
+       request_template_data: list[dict[str, object] | list[object] | 
primitive],
+       response_template_data: list[dict[str, object] | list[object] | 
primitive],
+       region_post_data: dict[str, object]
+) -> None:
+       """
+       Test step to validate keys, values and data types from regions endpoint
+       response.
+       :param to_session: Fixture to get Traffic Ops session.
+       :param get_region_data: Fixture to get region data from a prerequisites 
file.
+       :param region_prereq: Fixture to get sample region data and actual 
region response.
+       """
+       # validate region keys from regions get response
+       logger.info("Accessing /regions endpoint through Traffic ops session.")
+
+       region = request_template_data[0]
+       if not isinstance(region, dict):
+               raise TypeError("malformed region in prerequisite data; not an 
object")
+
+       region_name = region.get("name")
+       if not isinstance(region_name, str):
+               raise TypeError("malformed region in prerequisite data; 'name' 
not a string")
+
+       region_get_response: tuple[
+               dict[str, object] | list[dict[str, object] | list[object] | 
primitive] | primitive,
+               requests.Response
+       ] = to_session.get_regions(query_params={"name": region_name})
+       try:
+               region_data = region_get_response[0]
+               if not isinstance(region_data, list):
+                       raise TypeError("malformed API response; 'response' 
property not an array")
+
+               first_region = region_data[0]
+               if not isinstance(first_region, dict):
+                       raise TypeError("malformed API response; first region 
in response is not an object")
+               region_keys = set(first_region.keys())
+
+               logger.info("region Keys from regions endpoint response %s", 
region_keys)
+               response_template = 
response_template_data.get("region").get("properties")
+               # validate region values from prereq data in regions get 
response.
+               prereq_values = [
+                       region_post_data["name"],
+                       region_post_data["division"],
+            region_post_data["divisionName"]]
+            
+               get_values = [first_region["name"], first_region["division"], 
first_region["divisionName"]]
+               get_types = {}
+               for key in first_region:
+                       get_types[key] = first_region[key].__class__.__name__
+               logger.info("types from region get response %s", get_types)
+               response_template_types= {}
+               for key in response_template:
+                       response_template_types[key] = 
response_template.get(key).get("type")
+               logger.info("types from region response template %s", 
response_template_types)
+
+               assert region_keys == set(response_template.keys())
+               assert dict(sorted(get_types.items())) == 
dict(sorted(response_template_types.items()))
+               assert get_values == prereq_values
+       except IndexError:
+               logger.error("Either prerequisite data or API response was 
malformed")
+               pytest.fail("Either prerequisite data or API response was 
malformed")

Review Comment:
   edentical failue messages 



##########
traffic_ops/testing/api_contract/v4/conftest.py:
##########
@@ -628,3 +628,187 @@ def profile_post_data(to_session: TOSession, 
request_template_data: list[JSONDat
        except IndexError:
                logger.error("No Profile response data from cdns POST request.")
                sys.exit(1)
+
[email protected]()
+def division_post_data(to_session: TOSession, request_template_data: 
list[JSONData]
+                 ) -> dict[str, object]:
+       """
+       PyTest Fixture to create POST data for divisions endpoint.
+
+       :param to_session: Fixture to get Traffic Ops session.
+       :param request_template_data: Fixture to get divisions request template 
data from
+       request_template file.
+       :returns: Sample POST data and the actual API response.
+       """
+
+       try:
+               division = request_template_data[0]
+       except IndexError as e:
+               raise TypeError(
+                       "malformed prerequisite data; no division present in 
'division' array property") from e
+
+       if not isinstance(division, dict):
+               raise TypeError(
+                       f"malformed prerequisite data; divisions must be 
objects, not '{type(division)}'")
+
+       # Return new post data and post response from division POST request
+       randstr = str(randint(0, 1000))
+       try:
+               name = division["name"]
+               if not isinstance(name, str):
+                       raise TypeError(f"name must be str, not '{type(name)}'")
+               division["name"] = name[:4] + randstr
+       except KeyError as e:
+               raise TypeError(f"missing Parameter property '{e.args[0]}'") 
from e
+
+       logger.info("New division data to hit POST method %s", 
request_template_data)
+       # Hitting division POST methed
+       response: tuple[JSONData, requests.Response] = 
to_session.create_division(data=division)
+       try:
+               resp_obj = response[0]
+               if not isinstance(resp_obj, dict):
+                       raise TypeError("malformed API response; division is 
not an object")
+               return resp_obj
+       except IndexError:
+               logger.error("No division response data from division POST 
request.")
+               sys.exit(1)
+
[email protected]()
+def region_post_data(to_session: TOSession, request_template_data: 
list[JSONData]
+                 ) -> dict[str, object]:
+       """
+       PyTest Fixture to create POST data for regions endpoint.
+
+       :param to_session: Fixture to get Traffic Ops session.
+       :param request_template_data: Fixture to get regions request template 
data from
+       request_template file.
+       :returns: Sample POST data and the actual API response.
+       """
+
+       try:
+               region = request_template_data[0]
+       except IndexError as e:
+               raise TypeError(
+                       "malformed prerequisite data; no region present in 
'regions' array property") from e
+
+       if not isinstance(region, dict):
+               raise TypeError(
+                       f"malformed prerequisite data; regions must be objects, 
not '{type(region)}'")
+
+       # Return new post data and post response from region POST request
+       randstr = str(randint(0, 1000))
+       try:
+               name = region["name"]
+               if not isinstance(name, str):
+                       raise TypeError(f"name must be str, not '{type(name)}'")
+               region["name"] = name[:4] + randstr
+               division = region["division"]
+               if not isinstance(division, str):
+                       raise TypeError(f"division must be int, not 
'{type(division)}'")
+               region["division"] = division[:4] + randstr
+               divisionname = region["divisionname"]
+               if not isinstance(divisionname, str):
+                       raise TypeError(f"divisionname must be str, not 
'{type(divisionname)}'")
+               region["divisionname"] = divisionname[:4] + randstr
+       except KeyError as e:
+               raise TypeError(f"missing Parameter property '{e.args[0]}'") 
from e
+
+       logger.info("New region data to hit POST method %s", 
request_template_data)
+       # Hitting region POST methed
+       response: tuple[JSONData, requests.Response] = 
to_session.create_region(data=region)
+       try:
+               resp_obj = response[0]
+               if not isinstance(resp_obj, dict):
+                       raise TypeError("malformed API response; region is not 
an object")
+               return resp_obj
+       except IndexError:
+               logger.error("No region response data from region POST 
request.")
+               sys.exit(1)
+
[email protected]()
+def phys_locations__post_data(to_session: TOSession, request_template_data: 
list[JSONData]
+                 ) -> dict[str, object]:
+       """
+       PyTest Fixture to create POST data for phys_locations endpoint.
+
+       :param to_session: Fixture to get Traffic Ops session.
+       :param request_template_data: Fixture to get phys_locations request 
template data from
+       request_template file.
+       :returns: Sample POST data and the actual API response.
+       """
+
+       try:
+               phys_location = request_template_data[0]
+       except IndexError as e:
+               raise TypeError(
+                       "malformed prerequisite data; no phys_location in 
'phys_locations' array property") from e
+
+       if not isinstance(phys_location, dict):
+               raise TypeError(
+                       f"malformed prerequisite data; phys_locations must be 
objects, not '{type(phys_location)}'")
+
+       # Return new post data and post response from phys_locations POST 
request
+       randstr = str(randint(0, 1000))
+       try:

Review Comment:
   why you generating new data instead of using post api 



##########
traffic_ops/testing/api_contract/v4/to_data.json:
##########
@@ -1,6 +1,6 @@
 {
     "user": "admin",
-    "password": "twelve12",

Review Comment:
   what the reason to change password?
   



##########
traffic_ops/testing/api_contract/v4/request_template.json:
##########
@@ -43,5 +43,34 @@
                        "type": "UNK_PROFILE",
                        "routingDisabled": true
                }
-       ]
+
+       ],
+       "divisions":[
+               {
+                       "name":"test"
+               }
+       ],
+       "regions": [
+               {
+                       "divisionName": "Quebec",
+               "division": 1,
+               "name": "Montreal"
+               }
+       ],
+       "phys_locations":[
+               {
+                       "address": "Buckingham Palace",

Review Comment:
   check indents



##########
traffic_ops/testing/api_contract/v4/test_regions.py:
##########
@@ -0,0 +1,97 @@
+#
+# 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.
+#
+
+"""API Contract Test Case for regions endpoint."""
+import logging
+import pytest
+import requests
+
+from trafficops.tosession import TOSession
+
+# Create and configure logger
+logger = logging.getLogger()
+
+primitive = bool | int | float | str | None
+
[email protected]('request_template_data', ["regions"], indirect=True)
+def test_region_contract(
+       to_session: TOSession,
+       request_template_data: list[dict[str, object] | list[object] | 
primitive],
+       response_template_data: list[dict[str, object] | list[object] | 
primitive],
+       region_post_data: dict[str, object]
+) -> None:
+       """
+       Test step to validate keys, values and data types from regions endpoint
+       response.
+       :param to_session: Fixture to get Traffic Ops session.
+       :param get_region_data: Fixture to get region data from a prerequisites 
file.
+       :param region_prereq: Fixture to get sample region data and actual 
region response.
+       """
+       # validate region keys from regions get response
+       logger.info("Accessing /regions endpoint through Traffic ops session.")
+
+       region = request_template_data[0]
+       if not isinstance(region, dict):
+               raise TypeError("malformed region in prerequisite data; not an 
object")
+
+       region_name = region.get("name")
+       if not isinstance(region_name, str):
+               raise TypeError("malformed region in prerequisite data; 'name' 
not a string")
+
+       region_get_response: tuple[
+               dict[str, object] | list[dict[str, object] | list[object] | 
primitive] | primitive,
+               requests.Response
+       ] = to_session.get_regions(query_params={"name": region_name})
+       try:
+               region_data = region_get_response[0]
+               if not isinstance(region_data, list):
+                       raise TypeError("malformed API response; 'response' 
property not an array")
+
+               first_region = region_data[0]
+               if not isinstance(first_region, dict):
+                       raise TypeError("malformed API response; first region 
in response is not an object")
+               region_keys = set(first_region.keys())
+
+               logger.info("region Keys from regions endpoint response %s", 
region_keys)
+               response_template = 
response_template_data.get("region").get("properties")
+               # validate region values from prereq data in regions get 
response.
+               prereq_values = [
+                       region_post_data["name"],
+                       region_post_data["division"],
+            region_post_data["divisionName"]]

Review Comment:
   check indents 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to