Skip to content

Commit

Permalink
add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
leoschwarz committed May 17, 2024
1 parent 27b459d commit e5deb2b
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 24 deletions.
7 changes: 4 additions & 3 deletions bfabric/engine/engine_suds.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

from bfabric.engine.response_format_suds import suds_asdict_recursive
from bfabric.errors import BfabricRequestError, get_response_errors
from bfabric.results.result_container import _clean_result, ResultContainer
from bfabric.results.result_container import ResultContainer
from bfabric.results.response_format_dict import clean_result

if TYPE_CHECKING:
from suds.serviceproxy import ServiceProxy
Expand Down Expand Up @@ -98,10 +99,10 @@ def _convert_results(self, response: Any, endpoint: str) -> ResultContainer:
results = []
for result in response[endpoint]:
result_parsed = suds_asdict_recursive(result, convert_types=True)
result_parsed = _clean_result(
result_parsed = clean_result(
result_parsed,
drop_underscores_suds=self._drop_underscores,
sort_responses=True,
sort_keys=True,
)
results += [result_parsed]
return ResultContainer(results=results, total_pages_api=n_available_pages, errors=errors)
7 changes: 4 additions & 3 deletions bfabric/engine/engine_zeep.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from zeep.helpers import serialize_object

from bfabric.errors import BfabricRequestError, get_response_errors
from bfabric.results.result_container import ResultContainer, _clean_result
from bfabric.results.result_container import ResultContainer
from bfabric.results.response_format_dict import clean_result

if TYPE_CHECKING:
from bfabric.bfabric_config import BfabricAuth
Expand Down Expand Up @@ -122,10 +123,10 @@ def _convert_results(self, response: Any, endpoint: str) -> ResultContainer:
results = []
for result in response[endpoint]:
results_parsed = dict(serialize_object(result, target_cls=dict))
results_parsed = _clean_result(
results_parsed = clean_result(
results_parsed,
drop_underscores_suds=False, # NOTE: Underscore problem specific to SUDS
sort_responses=True,
sort_keys=True,
)
results += [results_parsed]
return ResultContainer(results=results, total_pages_api=n_available_pages, errors=errors)
Expand Down
17 changes: 17 additions & 0 deletions bfabric/results/response_format_dict.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from __future__ import annotations

from copy import deepcopy


Expand Down Expand Up @@ -115,3 +116,19 @@ def sort_dicts_by_key(response: list | dict, inplace: bool = True) -> list | dic
response_filtered = deepcopy(response) if not inplace else response
_recursive_sort_dicts_by_key(response_filtered)
return response_filtered


def clean_result(result: dict, drop_underscores_suds: bool = True, sort_keys: bool = False) -> dict:
"""
:param result: the response dictionary to clean
:param drop_underscores_suds: if True, the keys of the dictionaries in the response will have leading
underscores removed in some cases (relevant for SUDS)
:param sort_keys: the keys of the dictionaries in the response will be sorted (recursively)
"""
result = deepcopy(result)
if drop_underscores_suds:
map_element_keys(result, {"_id": "id", "_classname": "classname", "_projectid": "projectid"}, inplace=True)
if sort_keys:
sort_dicts_by_key(result, inplace=True)

return result
16 changes: 0 additions & 16 deletions bfabric/results/result_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,3 @@ def to_polars(self, drop_empty: bool = False) -> polars.DataFrame:
import polars

return polars.DataFrame(self.to_list_dict(drop_empty=drop_empty))


def _clean_result(result: dict, drop_underscores_suds: bool = True, sort_responses: bool = False) -> dict:
"""
:param drop_underscores_suds: if True, the keys of the dictionaries in the response will have leading
underscores removed in some cases (relevant for SUDS)
:param sort_responses: the keys of the dictionaries in the response will be sorted (recursively)
"""
if drop_underscores_suds:
formatter.map_element_keys(
result, {"_id": "id", "_classname": "classname", "_projectid": "projectid"}, inplace=True
)
if sort_responses:
formatter.sort_dicts_by_key(result, inplace=True)

return result
32 changes: 32 additions & 0 deletions bfabric/tests/unit/test_bfabric.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,38 @@ def test_delete_when_auth_and_check_true(self):
method_assert_success.assert_called_once_with()
mock_engine.delete.assert_called_once_with(endpoint=endpoint, id=10, auth=self.mock_auth)

@patch.object(Bfabric, "read")
def test_exists_when_true(self, method_read):
method_read.return_value.__len__.return_value = 1
self.assertTrue(self.mock_bfabric.exists(endpoint="test_endpoint", key="key", value="value"))
method_read.assert_called_once_with(
endpoint="test_endpoint", obj={"key": "value"}, max_results=1, check=True, return_id_only=True
)

@patch.object(Bfabric, "read")
def test_exists_when_true_and_extra_args(self, method_read):
method_read.return_value.__len__.return_value = 1
self.assertTrue(
self.mock_bfabric.exists(
endpoint="test_endpoint", key="key", value="value", query={"extra": "arg"}, check=False
)
)
method_read.assert_called_once_with(
endpoint="test_endpoint",
obj={"key": "value", "extra": "arg"},
max_results=1,
check=False,
return_id_only=True,
)

@patch.object(Bfabric, "read")
def test_exists_when_false(self, method_read):
method_read.return_value.__len__.return_value = 0
self.assertFalse(self.mock_bfabric.exists(endpoint="test_endpoint", key="key", value="value"))
method_read.assert_called_once_with(
endpoint="test_endpoint", obj={"key": "value"}, max_results=1, check=True, return_id_only=True
)

@patch.object(Bfabric, "save")
def test_upload_resource(self, method_save):
resource_name = "hello_world.txt"
Expand Down
10 changes: 10 additions & 0 deletions bfabric/tests/unit/test_response_format_dict.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import unittest

import bfabric.results.response_format_dict as response_format_dict


Expand Down Expand Up @@ -27,6 +28,15 @@ def test_sort_dicts_by_key(self):
output_list_dict = response_format_dict.sort_dicts_by_key(input_list_dict, inplace=False)
self.assertEqual(str(output_list_dict), str(target_list_dict))

def test_clean_result(self):
result_input = [{"b": 1, "a": 2, "_id": 3}, {"b": 4, "_id": 5, "a": 6}]
cleaned = response_format_dict.clean_result(result_input, drop_underscores_suds=True, sort_keys=True)
self.assertEqual(repr([{"a": 2, "b": 1, "id": 3}, {"a": 6, "b": 4, "id": 5}]), repr(cleaned))
self.assertEqual(
repr([{"b": 1, "a": 2, "_id": 3}, {"b": 4, "_id": 5, "a": 6}]),
repr(result_input),
)


if __name__ == "__main__":
unittest.main(verbosity=2)
11 changes: 9 additions & 2 deletions bfabric/tests/unit/test_result_container.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging
import unittest

import polars.testing

from bfabric.results.result_container import ResultContainer


Expand All @@ -15,8 +17,8 @@ def test_str(self):
self.assertEqual("[4, 5]", str(self.res2))

def test_repr(self):
self.assertEqual("[1, 2, 3]", str(self.res1))
self.assertEqual("[4, 5]", str(self.res2))
self.assertEqual("[1, 2, 3]", repr(self.res1))
self.assertEqual("[4, 5]", repr(self.res2))

def test_len(self):
self.assertEqual(3, len(self.res1))
Expand Down Expand Up @@ -82,6 +84,11 @@ def test_to_list_dict_when_drop_empty(self):
expected = [{"b": 1}, {"a": 2, "b": 3}]
self.assertListEqual(expected, self.res_with_empty.to_list_dict(drop_empty=True))

def test_to_polars(self):
res = ResultContainer([{"a": 1, "b": 2}, {"a": 3, "b": 4}])
df = res.to_polars()
polars.testing.assert_frame_equal(polars.DataFrame({"a": [1, 3], "b": [2, 4]}), df)


if __name__ == "__main__":
unittest.main(verbosity=2)

0 comments on commit e5deb2b

Please sign in to comment.