From 39c6cd0675c18331f9464922acb6d37c7d6e21e2 Mon Sep 17 00:00:00 2001 From: Lana Date: Fri, 20 Sep 2024 11:34:53 -0400 Subject: [PATCH] fix fhirsearch_perform_iter_test --- fhirclient/models/fhirsearch.py | 22 +--- tests/data/examples/bundle-example-page2.json | 65 +++++++++++ tests/models/fhirsearch_perform_iter_test.py | 103 ++++++++++-------- 3 files changed, 124 insertions(+), 66 deletions(-) create mode 100644 tests/data/examples/bundle-example-page2.json diff --git a/fhirclient/models/fhirsearch.py b/fhirclient/models/fhirsearch.py index 140146ae7..d1819d462 100644 --- a/fhirclient/models/fhirsearch.py +++ b/fhirclient/models/fhirsearch.py @@ -178,29 +178,9 @@ def perform_resources_iter(self, server) -> Iterator['Resource']: if not first_bundle or not first_bundle.entry: return iter([]) - ###### FOR DEBUGING ONLY - # for bundle in iter_pages(first_bundle): - # print(f"Processing bundle with {len(bundle.entry)} entries") - # for entry in bundle.entry: - # print(f"Entry resource being processed: {entry.resource}") - # yield entry.resource - for bundle in iter_pages(first_bundle): - print(f"Processing bundle with {len(bundle.entry)} entries") if bundle.entry: - for entry in bundle.entry: - resource = getattr(entry, 'resource', None) - if resource: - print(f"Entry resource being processed: {resource}") - yield resource - else: - print("Entry does not contain a resource!") - - ########################## - - # for bundle in iter_pages(first_bundle): - # if bundle.entry: - # yield from (entry.resource for entry in bundle.entry) + yield from (entry.resource for entry in bundle.entry) class FHIRSearchParam(object): diff --git a/tests/data/examples/bundle-example-page2.json b/tests/data/examples/bundle-example-page2.json new file mode 100644 index 000000000..206624acb --- /dev/null +++ b/tests/data/examples/bundle-example-page2.json @@ -0,0 +1,65 @@ +{ + "resourceType": "Bundle", + "id": "bundle-example", + "meta": { + "lastUpdated": "2014-08-18T01:43:30Z", + "tag": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason", + "code": "HTEST", + "display": "test health data" + } + ] + }, + "type": "searchset", + "total": 3, + "link": [ + { + "relation": "self", + "url": "https://example.com/base/MedicationRequest?patient\u003d347\u0026_include\u003dMedicationRequest.medication\u0026_count\u003d2" + }, + { + "relation": "next", + "url": "https://example.com/base/MedicationRequest?patient\u003d347\u0026searchId\u003dff15fd40-ff71-4b48-b366-09c706bed9d0\u0026page\u003d2" + } + ], + "entry": [ + { + "fullUrl": "https://example.com/base/MedicationRequest/3123", + "resource": { + "resourceType": "MedicationRequest", + "id": "9999", + "text": { + "status": "generated", + "div": "\u003cdiv xmlns\u003d\"http://www.w3.org/1999/xhtml\"\u003e\u003cp\u003e\u003cb\u003eGenerated Narrative with Details\u003c/b\u003e\u003c/p\u003e\u003cp\u003e\u003cb\u003eid\u003c/b\u003e: 3123\u003c/p\u003e\u003cp\u003e\u003cb\u003estatus\u003c/b\u003e: unknown\u003c/p\u003e\u003cp\u003e\u003cb\u003eintent\u003c/b\u003e: order\u003c/p\u003e\u003cp\u003e\u003cb\u003emedication\u003c/b\u003e: \u003ca\u003eMedication/example\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003cb\u003esubject\u003c/b\u003e: \u003ca\u003ePatient/347\u003c/a\u003e\u003c/p\u003e\u003c/div\u003e" + }, + "status": "unknown", + "intent": "order", + "medicationReference": { + "reference": "Medication/example" + }, + "subject": { + "reference": "Patient/347" + } + }, + "search": { + "mode": "match", + "score": 1 + } + }, + { + "fullUrl": "https://example.com/base/Medication/example", + "resource": { + "resourceType": "Medication", + "id": "example2", + "text": { + "status": "generated", + "div": "\u003cdiv xmlns\u003d\"http://www.w3.org/1999/xhtml\"\u003e\u003cp\u003e\u003cb\u003eGenerated Narrative with Details\u003c/b\u003e\u003c/p\u003e\u003cp\u003e\u003cb\u003eid\u003c/b\u003e: example\u003c/p\u003e\u003c/div\u003e" + } + }, + "search": { + "mode": "include" + } + } + ] +} \ No newline at end of file diff --git a/tests/models/fhirsearch_perform_iter_test.py b/tests/models/fhirsearch_perform_iter_test.py index fbc9580f8..a63f2626b 100644 --- a/tests/models/fhirsearch_perform_iter_test.py +++ b/tests/models/fhirsearch_perform_iter_test.py @@ -4,6 +4,8 @@ import unittest from unittest.mock import MagicMock, patch +import fhirclient + from fhirclient import server from fhirclient.models import bundle @@ -90,72 +92,83 @@ def test_perform_resources_iter_single_page(self, mock_iter_pages, mock_get): self.assertEqual(len(resources), len(mock_bundle.entry)) self.assertTrue(all(isinstance(entry, BundleEntry) for entry in mock_bundle.entry)) - - # TODO: need to fix this test or method itself. @patch('fhirclient._utils.iter_pages') - @patch('requests.get') - def test_perform_resources_iter_multiple_pages(self, mock_iter_pages, mock_get): - - # Manually create valid FHIR resources - medication_request_resource = { - 'resourceType': 'MedicationRequest', - 'id': '3123', - 'subject': { - 'reference': 'Patient/347' - }, - 'intent': 'order', - 'status': 'unknown', - 'medicationReference': { - 'reference': 'Medication/example' - } - } - - # Create a valid Bundle with first page of entries + def test_perform_resources_iter_multiple_pages(self, mock_iter_pages): + # Create first bundle with one entry and a next link mock_bundle_page1 = Bundle({ 'resourceType': 'Bundle', - 'type': 'searchset', # Required field + 'type': 'searchset', 'entry': [ {'fullUrl': 'https://example.com/base/MedicationRequest/3123', - 'resource': medication_request_resource} + 'resource': { + 'resourceType': 'MedicationRequest', + 'id': '3123', + 'subject': { + 'reference': 'Patient/347' + }, + 'intent': 'order', + 'status': 'unknown', + 'medicationReference': { + 'reference': 'Medication/example' + } + }} + ], + 'link': [ + { + 'relation': 'next', + 'url': 'https://example.com/base/MedicationRequest?page=2' # Simulating the next page link + } ] }) - # Create a second valid Bundle for the second page of entries + # Create second bundle with another entry mock_bundle_page2 = Bundle({ 'resourceType': 'Bundle', - 'type': 'searchset', # Required field + 'type': 'searchset', 'entry': [ {'fullUrl': 'https://example.com/base/MedicationRequest/3124', - 'resource': medication_request_resource} + 'resource': { + 'resourceType': 'MedicationRequest', + 'id': '3124', + 'subject': { + 'reference': 'Patient/348' + }, + 'intent': 'order', + 'status': 'unknown', + 'medicationReference': { + 'reference': 'Medication/example2' + } + }} ] }) - # Mock the behavior of `perform` to return the first page bundle - self.search.perform = MagicMock(return_value=mock_bundle_page1) - - mock_iter_pages.return_value = iter([mock_bundle_page1, mock_bundle_page2]) + # Directly mock requests.get to return a proper response + mock_response = MagicMock() + mock_response.raise_for_status = MagicMock() # Simulate that there is no HTTP error + mock_response.json.return_value = mock_bundle_page2.as_json() # Return the second bundle's JSON - # Ensure `requests.get` does not actually run for pagination - mock_get.return_value.status_code = 200 - mock_get.return_value.json.return_value = {'resourceType': 'Bundle'} + # Now override the requests.get behavior + with patch('requests.get', return_value=mock_response): + # Mock perform to return the first page bundle + self.search.perform = MagicMock(return_value=mock_bundle_page1) - resource_iter = self.search.perform_resources_iter(self.mock_server) - resources = list(resource_iter) + # Mock iter_pages to return both bundles + mock_iter_pages.return_value = iter([mock_bundle_page1, mock_bundle_page2]) - # Debug print statements to see what's happening - print(f"Number of resources collected: {len(resources)}") - print(f"Resources: {resources}") - print(f"Bundle 1 entries: {mock_bundle_page1.entry}") - print(f"Bundle 2 entries: {mock_bundle_page2.entry}") + # Execute the method to get resources + resource_iter = self.search.perform_resources_iter(self.mock_server) + resources = list(resource_iter) - self.assertEqual(len(resources), 2) # Expect 2 resources (one per page) + # Ensure that both resources from both pages are included + self.assertEqual(len(resources), 2) # Expect 2 resources, one per page - # Check that resources from both pages are included - # self.assertEqual(len(resources), len(mock_bundle_page1.entry) + len(mock_bundle_page2.entry)) + # Ensure that the entries are from the correct pages + self.assertEqual(resources[0].id, '3123') + self.assertEqual(resources[1].id, '3124') - # Ensure that the entries in both pages are of the correct type - self.assertTrue(all(isinstance(entry, BundleEntry) for entry in mock_bundle_page1.entry)) - self.assertTrue(all(isinstance(entry, BundleEntry) for entry in mock_bundle_page2.entry)) + # Ensure that all resources are correctly typed + self.assertTrue(all( + isinstance(resource, fhirclient.models.medicationrequest.MedicationRequest) for resource in resources)) class MockServer(server.FHIRServer):