Skip to content

Commit d7a116c

Browse files
committed
adds test cases for the utilities and fixes the utilities in the APIHelper class as well
1 parent 4c781f1 commit d7a116c

2 files changed

Lines changed: 87 additions & 6 deletions

File tree

apimatic_core/utilities/api_helper.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -753,8 +753,8 @@ def resolve_response_pointer(pointer, json_body, json_headers):
753753
if pointer is None or pointer == '':
754754
return None
755755

756-
prefix = pointer.split("#")[0]
757-
path = pointer.rsplit('#')[1].rstrip('}')
756+
prefix, path = ApiHelper.split_into_parts(pointer)
757+
path = path.rstrip('}')
758758

759759
try:
760760
if prefix == "$response.body":
@@ -778,7 +778,7 @@ def split_into_parts(json_pointer):
778778
Returns:
779779
tuple: A tuple containing the path prefix and the field path. Returns None if input is None.
780780
"""
781-
if json_pointer is None:
781+
if json_pointer is None or json_pointer == '':
782782
return None
783783

784784
pointer_parts = json_pointer.split("#")
@@ -801,7 +801,18 @@ def update_entry_by_json_pointer(dictionary, pointer, value, inplace=True):
801801
Returns:
802802
dict: The updated dictionary.
803803
"""
804-
return set_pointer(dictionary, pointer, value, inplace=inplace)
804+
if not inplace:
805+
import copy
806+
dictionary = copy.deepcopy(dictionary)
807+
808+
parts = pointer.strip("/").split("/")
809+
current = dictionary
810+
for part in parts[:-1]:
811+
if part not in current or not isinstance(current[part], dict):
812+
current[part] = {}
813+
current = current[part]
814+
current[parts[-1]] = value
815+
return dictionary
805816

806817
@staticmethod
807818
def get_value_by_json_pointer(dictionary, pointer):
@@ -820,7 +831,7 @@ def get_value_by_json_pointer(dictionary, pointer):
820831
"""
821832
try:
822833
return resolve_pointer(dictionary, pointer)
823-
except JsonPointerException as jpe:
834+
except JsonPointerException:
824835
return None
825836

826837
class CustomDate(object):

tests/apimatic_core/utility_tests/test_api_helper.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import copy
12
from datetime import datetime, date
23

34
import jsonpickle
@@ -1099,4 +1100,73 @@ def test_apply_unboxing_function(self, value, unboxing_function, is_array, is_di
10991100
is_array_of_map,
11001101
is_map_of_array,
11011102
dimension_count)
1102-
assert result == expected
1103+
assert result == expected
1104+
1105+
@pytest.mark.parametrize(
1106+
"dictionary, pointer, expected",
1107+
[
1108+
({"foo": "bar"}, "/foo", "bar"), # basic access
1109+
({"a": {"b": {"c": 1}}}, "/a/b/c", 1), # nested path
1110+
({"list": [10, 20, 30]}, "/list/1", 20), # list index
1111+
({}, "/missing", None), # missing key
1112+
({"x": {"y": 5}}, "/x/z", None), # partial match but invalid final key
1113+
({"": "empty_key"}, "/", "empty_key"), # root-level empty string key
1114+
]
1115+
)
1116+
def test_get_value_by_json_pointer_valid_and_invalid(self, dictionary, pointer, expected):
1117+
result = ApiHelper.get_value_by_json_pointer(dictionary, pointer)
1118+
assert result == expected
1119+
1120+
def test_get_value_by_json_pointer_raises_invalid_pointer(self):
1121+
# Pointer with invalid format (should raise and be caught internally)
1122+
result = ApiHelper.get_value_by_json_pointer({"foo": "bar"}, "invalid_pointer")
1123+
assert result is None
1124+
1125+
@pytest.mark.parametrize(
1126+
"pointer, json_body, json_headers, expected",
1127+
[
1128+
("$response.body#/name", '{"name": "Alice"}', {}, "Alice"),
1129+
("$response.body#/details/age", '{"details": {"age": 30}}', {}, 30),
1130+
("$response.headers#/X-Request-ID", "", {"X-Request-ID": "abc-123"}, "abc-123"),
1131+
("$response.body#/missing", '{"name": "Alice"}', {}, None),
1132+
("$response.headers#/missing", "", {"X-Request-ID": "abc-123"}, None),
1133+
("$response.unknown#/path", '{"some": "data"}', {}, None),
1134+
("", '{"some": "data"}', {}, None),
1135+
(None, '{"some": "data"}', {}, None),
1136+
]
1137+
)
1138+
def test_resolve_response_pointer(self, pointer, json_body, json_headers, expected):
1139+
result = ApiHelper.resolve_response_pointer(pointer, json_body, json_headers)
1140+
assert result == expected
1141+
1142+
@pytest.mark.parametrize(
1143+
"json_pointer, expected",
1144+
[
1145+
("$response.body#/name", ("$response.body", "/name")),
1146+
("$response.headers#/X-Header", ("$response.headers", "/X-Header")),
1147+
("$response.body#", ("$response.body", "")),
1148+
("$response.body", ("$response.body", "")),
1149+
("", None),
1150+
(None, None),
1151+
]
1152+
)
1153+
def test_split_into_parts(self, json_pointer, expected):
1154+
result = ApiHelper.split_into_parts(json_pointer)
1155+
assert result == expected
1156+
1157+
@pytest.mark.parametrize(
1158+
"initial_dict, pointer, new_value, inplace, expected_dict",
1159+
[
1160+
({"name": "Alice"}, "/name", "Bob", True, {"name": "Bob"}),
1161+
({"a": {"b": 1}}, "/a/b", 2, True, {"a": {"b": 2}}),
1162+
({}, "/new/key", "value", True, {"new": {"key": "value"}}),
1163+
({"x": 1}, "/x", {"nested": "yes"}, False, {"x": {"nested": "yes"}}),
1164+
]
1165+
)
1166+
def test_update_entry_by_json_pointer(self, initial_dict, pointer, new_value, inplace, expected_dict):
1167+
original_copy = copy.deepcopy(initial_dict)
1168+
result = ApiHelper.update_entry_by_json_pointer(initial_dict, pointer, new_value, inplace=inplace)
1169+
1170+
assert result == expected_dict
1171+
if not inplace:
1172+
assert initial_dict == original_copy

0 commit comments

Comments
 (0)