diff --git a/converter/converter/utils.py b/converter/converter/utils.py index 6bc20a3ad..b43a242bd 100644 --- a/converter/converter/utils.py +++ b/converter/converter/utils.py @@ -50,7 +50,9 @@ def delete_paths(data: Dict[str, Any], paths: List[str]) -> None: paths: List of dot-separated paths (e.g., "a.b.c") """ - def delete_recursively(d: Dict[str, Any], keys: List[str]) -> None: + def delete_recursively( + d: Dict[str, Any], keys: List[str], current_path: str + ) -> None: if not keys or not isinstance(d, (dict, list)): return @@ -58,25 +60,28 @@ def delete_recursively(d: Dict[str, Any], keys: List[str]) -> None: if key.endswith("[]"): # Handle array notation key = key[:-2] # Remove the array notation if key in d and isinstance(d[key], list): - for item in d[key]: + for index, item in enumerate(d[key]): if isinstance(item, dict): - delete_recursively(item, keys[1:]) + new_current_path = f"{current_path}.{key}[{index}]" + delete_recursively(item, keys[1:], new_current_path) elif len(keys) == 1: # Delete target key if it exists if isinstance(d, dict): - logger.info("Deleting key: %s", key) + new_current_path = f"{current_path}.{key}" + logger.info("Removing path: %s", new_current_path) d.pop(key, None) else: # Recurse if intermediate key exists if key in d: - delete_recursively(d[key], keys[1:]) + new_current_path = f"{current_path}.{key}" + delete_recursively(d[key], keys[1:], new_current_path) # Clean up empty dictionaries or lists if isinstance(d[key], (dict, list)) and not d[key]: - logger.info("Deleting key: %s", key) + logger.info("Removing path: %s", new_current_path) d.pop(key) for path in paths: - delete_recursively(data, path.strip("$.").split(".")) + delete_recursively(data, path.strip("$.").split("."), "$") def add_space_before_uppercase(text): @@ -199,7 +204,7 @@ def update_json_value(data, jsonpath_query, new_value): for match in matches: old_value = get_field_value(data, str(match.full_path)) logger.info( - "Updating value from %s to %s at path %s", + "Updating value from %s to %s at path $.%s", old_value, new_value, match.full_path, diff --git a/converter/tests/test_utils.py b/converter/tests/test_utils.py index ed2fbe33e..d0f8f78f4 100644 --- a/converter/tests/test_utils.py +++ b/converter/tests/test_utils.py @@ -163,11 +163,73 @@ def test_delete_paths_logs_info(self, mock_logger): first_call_args, _ = mock_logger.info.call_args_list[0] second_call_args, _ = mock_logger.info.call_args_list[1] - assert first_call_args[0] == "Deleting key: %s" - assert first_call_args[1] == "a" + assert first_call_args[0] == "Removing path: %s" + assert first_call_args[1] == "$.a" - assert second_call_args[0] == "Deleting key: %s" - assert second_call_args[1] == "c" + assert second_call_args[0] == "Removing path: %s" + assert second_call_args[1] == "$.b.c" + + @patch("converter.utils.logger") + def test_delete_array_logs_info(self, mock_logger): + # Arrange + data = { + "a": [ + { + "b": 1, + }, + { + "b": 2, + "c": 3, + }, + ], + } + + # Act + delete_paths(data, ["a[].b"]) + + # Assert logger has been called twice + assert mock_logger.info.call_count == 2 + + # Check the log message content + first_call_args, _ = mock_logger.info.call_args_list[0] + second_call_args, _ = mock_logger.info.call_args_list[1] + + assert first_call_args[0] == "Removing path: %s" + assert first_call_args[1] == "$.a[0].b" + + assert second_call_args[0] == "Removing path: %s" + assert second_call_args[1] == "$.a[1].b" + + @patch("converter.utils.logger") + def test_delete_empty_dict_logs_info(self, mock_logger): + # Arrange + data = { + "a": { + "b": { + "c": 1, + }, + } + } + + # Act + delete_paths(data, ["a.b.c"]) + + # Assert logger has been called three times + assert mock_logger.info.call_count == 3 + + # Check the log message content + first_call_args, _ = mock_logger.info.call_args_list[0] + second_call_args, _ = mock_logger.info.call_args_list[1] + third_call_args, _ = mock_logger.info.call_args_list[2] + + assert first_call_args[0] == "Removing path: %s" + assert first_call_args[1] == "$.a.b.c" + + assert second_call_args[0] == "Removing path: %s" + assert second_call_args[1] == "$.a.b" + + assert third_call_args[0] == "Removing path: %s" + assert third_call_args[1] == "$.a" def test_translate_keys(): @@ -356,7 +418,7 @@ def test_update_json_value_logs_info(self, mock_logger): # Check the log message content args, kwargs = mock_logger.info.call_args - assert args[0] == "Updating value from %s to %s at path %s" + assert args[0] == "Updating value from %s to %s at path $.%s" assert args[1] == "P1" assert args[2] == "P2" assert str(args[3]) == "qualification.details.priority"