Skip to content

Commit

Permalink
fix fhirsearch_perform_iter_test
Browse files Browse the repository at this point in the history
  • Loading branch information
LanaNYC committed Sep 20, 2024
1 parent 1d9800b commit 39c6cd0
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 66 deletions.
22 changes: 1 addition & 21 deletions fhirclient/models/fhirsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
65 changes: 65 additions & 0 deletions tests/data/examples/bundle-example-page2.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
]
}
103 changes: 58 additions & 45 deletions tests/models/fhirsearch_perform_iter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import unittest
from unittest.mock import MagicMock, patch

import fhirclient

from fhirclient import server

from fhirclient.models import bundle
Expand Down Expand Up @@ -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):
Expand Down

0 comments on commit 39c6cd0

Please sign in to comment.