diff --git a/seerpy/seerpy.py b/seerpy/seerpy.py index 322ace2..0811389 100644 --- a/seerpy/seerpy.py +++ b/seerpy/seerpy.py @@ -217,6 +217,7 @@ def get_paginated_response(self, query_string, variable_values, limit, object_pa result = [] total_items_returned = 0 + is_first_iteration = True while True: # Update the number of items remaining # And set the limit for the final batch if needed @@ -234,6 +235,10 @@ def get_paginated_response(self, query_string, variable_values, limit, object_pa # select the part of the response we are interested in response = utils.get_nested_dict_item(response, object_path) + # If first iteration, then assign the entire top level response to results + if is_first_iteration: + result = response + # select the part of the response which can vary. if iteration_path is None this will be # the same as the part of the response we are interested in response_increment = response @@ -244,11 +249,10 @@ def get_paginated_response(self, query_string, variable_values, limit, object_pa break # Update the number of items received - total_items_returned += len(response) + total_items_returned += len(response_increment) - if not result: - # if this is the first response, save it - result = response + if is_first_iteration: + is_first_iteration = False else: # otherwise add the response increment to the existing result at the correct level values_container = result diff --git a/setup.py b/setup.py index 77197d6..ee7177e 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='seerpy', - version='0.6.3', + version='0.6.4', description='Seer Platform SDK for Python', long_description=open('README.md').read(), url='https://github.com/seermedical/seer-py', diff --git a/tests/test_data/no_label_groups_for_studies.py b/tests/test_data/no_label_groups_for_studies.py new file mode 100644 index 0000000..1563bb0 --- /dev/null +++ b/tests/test_data/no_label_groups_for_studies.py @@ -0,0 +1,41 @@ +""" +Data for mocking intermediate function calls, as well as expected return values +when testing the following functions: +- client.get_label_groups_for_studies() +- client.get_label_groups_for_studies_dataframe() + +For condition in which the studies do not contain any label groups. +""" +import io +import pandas as pd + +# Individual responses it gets from calling client.get_label_groups_for_study() +individual_study_responses = [ + { + "id": "study1_id", + "name": "study1_name", + "labelGroups": [] + }, + { + "id": "study2_id", + "name": "study2_name", + "labelGroups": [] + } +] + +# The expected result from client.get_label_groups_for_studies() +expected_seerpy_response = [ + { + "id": "study1_id", + "name": "study1_name", + "labelGroups": [] + }, + { + "id": "study2_id", + "name": "study2_name", + "labelGroups": [] + }, +] + +# The expected result from client.get_label_groups_for_studies_dataframe() +expected_seerpy_df = pd.DataFrame([]) diff --git a/tests/test_data/no_label_groups_for_study.py b/tests/test_data/no_label_groups_for_study.py new file mode 100644 index 0000000..a620186 --- /dev/null +++ b/tests/test_data/no_label_groups_for_study.py @@ -0,0 +1,27 @@ +""" +Data for mocking intermediate function calls, as well as expected return values +when testing the following function: +- client.get_label_groups_for_study() + +For condition in which the study does not contain any label groups. +""" + +# Mocked paginated responses on each subsequent call of client.execute_query() +# within the client.get_paginated_response() function that gets called by +# client.get_label_groups_for_study() +raw_paginated_responses = [ + { + "study": { + "id": "study1_id", + "name": "study1_name", + "labelGroups": [] + } + }, +] + +# Expected return value when calling client.get_label_groups_for_study() +expected_seerpy_response = { + "id": "study1_id", + "name": "study1_name", + "labelGroups": [] +} diff --git a/tests/test_seerpy.py b/tests/test_seerpy.py index 54ed861..b168ca2 100644 --- a/tests/test_seerpy.py +++ b/tests/test_seerpy.py @@ -11,7 +11,13 @@ from seerpy.seerpy import SeerConnect import seerpy.graphql as graphql -from tests.test_data import label_groups_for_study, label_groups_for_studies +from tests.test_data import ( + label_groups_for_study, + label_groups_for_studies, + no_label_groups_for_study, + no_label_groups_for_studies, + ) + # having a class is useful to allow patches to be shared across mutliple test functions, but then # pylint complains that the methods could be a function. this disables that warning. @@ -852,21 +858,43 @@ def test_empty(self, gql_client, unused_sleep, seer_connect): @mock.patch('seerpy.seerpy.GQLClient', autospec=True) class TestLabelGroups: def test_get_label_groups_for_study(self, gql_client, unused_sleep, seer_connect): + # TEST WHEN STUDY CONTAINS TWO PAGES OF LABELGROUPS raw_paginated_responses = label_groups_for_study.raw_paginated_responses expected_seerpy_response = label_groups_for_study.expected_seerpy_response + gql_client.return_value.execute.side_effect = raw_paginated_responses + response = seer_connect.get_label_groups_for_study("study1") + assert response == expected_seerpy_response + # TEST WHEN STUDY CONTAINS NO LABELGROUPS + raw_paginated_responses = no_label_groups_for_study.raw_paginated_responses + expected_seerpy_response = no_label_groups_for_study.expected_seerpy_response gql_client.return_value.execute.side_effect = raw_paginated_responses response = seer_connect.get_label_groups_for_study("study1") assert response == expected_seerpy_response def test_get_label_groups_for_studies(self, gql_client, unused_sleep, seer_connect): with mock.patch.object(seer_connect, "get_label_groups_for_study") as mock_stdy_labelgroups: + # TEST WHEN STUDIES CONTAIN LABELGROUPS mock_stdy_labelgroups.side_effect = label_groups_for_studies.individual_study_responses response = seer_connect.get_label_groups_for_studies(["study1","study2"]) - assert label_groups_for_studies.expected_seerpy_response == response + assert label_groups_for_studies.expected_seerpy_response == response + + # TEST WHEN STUDIES CONTAIN NO LABELGROUPS + side_effects = no_label_groups_for_studies.individual_study_responses + mock_stdy_labelgroups.side_effect = side_effects + response = seer_connect.get_label_groups_for_studies(["study1","study2"]) + assert no_label_groups_for_studies.expected_seerpy_response == response + def test_get_label_groups_for_studies_dataframe(self, gql_client, unused_sleep, seer_connect): with mock.patch.object(seer_connect, "get_label_groups_for_study") as mock_stdy_labelgroups: + # TEST WHEN STUDIES CONTAIN LABELGROUPS mock_stdy_labelgroups.side_effect = label_groups_for_studies.individual_study_responses response = seer_connect.get_label_groups_for_studies_dataframe(["study1","study2"]) - assert label_groups_for_studies.expected_seerpy_df.equals(response) + assert label_groups_for_studies.expected_seerpy_df.equals(response) + + # TEST WHEN STUDIES CONTAIN NO LABELGROUPS + side_effects = no_label_groups_for_studies.individual_study_responses + mock_stdy_labelgroups.side_effect = side_effects + response = seer_connect.get_label_groups_for_studies_dataframe(["study1","study2"]) + assert no_label_groups_for_studies.expected_seerpy_df.equals(response)