compressedfhir 3.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. compressedfhir/__init__.py +0 -0
  2. compressedfhir/fhir/__init__.py +0 -0
  3. compressedfhir/fhir/base_resource_list.py +165 -0
  4. compressedfhir/fhir/fhir_bundle.py +295 -0
  5. compressedfhir/fhir/fhir_bundle_entry.py +240 -0
  6. compressedfhir/fhir/fhir_bundle_entry_list.py +97 -0
  7. compressedfhir/fhir/fhir_bundle_entry_request.py +73 -0
  8. compressedfhir/fhir/fhir_bundle_entry_response.py +67 -0
  9. compressedfhir/fhir/fhir_bundle_entry_search.py +75 -0
  10. compressedfhir/fhir/fhir_identifier.py +84 -0
  11. compressedfhir/fhir/fhir_link.py +63 -0
  12. compressedfhir/fhir/fhir_meta.py +47 -0
  13. compressedfhir/fhir/fhir_resource.py +170 -0
  14. compressedfhir/fhir/fhir_resource_list.py +149 -0
  15. compressedfhir/fhir/fhir_resource_map.py +193 -0
  16. compressedfhir/fhir/test/__init__.py +0 -0
  17. compressedfhir/fhir/test/test_bundle_entry.py +129 -0
  18. compressedfhir/fhir/test/test_bundle_entry_list.py +187 -0
  19. compressedfhir/fhir/test/test_bundle_entry_request.py +74 -0
  20. compressedfhir/fhir/test/test_bundle_entry_response.py +65 -0
  21. compressedfhir/fhir/test/test_fhir_bundle.py +245 -0
  22. compressedfhir/fhir/test/test_fhir_resource.py +104 -0
  23. compressedfhir/fhir/test/test_fhir_resource_list.py +160 -0
  24. compressedfhir/fhir/test/test_fhir_resource_map.py +293 -0
  25. compressedfhir/py.typed +0 -0
  26. compressedfhir/utilities/__init__.py +0 -0
  27. compressedfhir/utilities/compressed_dict/__init__.py +0 -0
  28. compressedfhir/utilities/compressed_dict/v1/__init__.py +0 -0
  29. compressedfhir/utilities/compressed_dict/v1/compressed_dict.py +701 -0
  30. compressedfhir/utilities/compressed_dict/v1/compressed_dict_access_error.py +2 -0
  31. compressedfhir/utilities/compressed_dict/v1/compressed_dict_storage_mode.py +50 -0
  32. compressedfhir/utilities/compressed_dict/v1/test/__init__.py +0 -0
  33. compressedfhir/utilities/compressed_dict/v1/test/test_compressed_dict.py +467 -0
  34. compressedfhir/utilities/fhir_json_encoder.py +71 -0
  35. compressedfhir/utilities/json_helpers.py +181 -0
  36. compressedfhir/utilities/json_serializers/__init__.py +0 -0
  37. compressedfhir/utilities/json_serializers/test/__init__.py +0 -0
  38. compressedfhir/utilities/json_serializers/test/test_type_preservation_decoder.py +165 -0
  39. compressedfhir/utilities/json_serializers/test/test_type_preservation_encoder.py +71 -0
  40. compressedfhir/utilities/json_serializers/test/test_type_preservation_serializer.py +197 -0
  41. compressedfhir/utilities/json_serializers/type_preservation_decoder.py +135 -0
  42. compressedfhir/utilities/json_serializers/type_preservation_encoder.py +55 -0
  43. compressedfhir/utilities/json_serializers/type_preservation_serializer.py +57 -0
  44. compressedfhir/utilities/ordered_dict_to_dict_converter/__init__.py +0 -0
  45. compressedfhir/utilities/ordered_dict_to_dict_converter/ordered_dict_to_dict_converter.py +24 -0
  46. compressedfhir/utilities/string_compressor/__init__.py +0 -0
  47. compressedfhir/utilities/string_compressor/v1/__init__.py +0 -0
  48. compressedfhir/utilities/string_compressor/v1/string_compressor.py +99 -0
  49. compressedfhir/utilities/string_compressor/v1/test/__init__.py +0 -0
  50. compressedfhir/utilities/string_compressor/v1/test/test_string_compressor.py +189 -0
  51. compressedfhir/utilities/test/__init__.py +0 -0
  52. compressedfhir/utilities/test/test_fhir_json_encoder.py +177 -0
  53. compressedfhir/utilities/test/test_json_helpers.py +99 -0
  54. compressedfhir-3.0.2.dist-info/METADATA +139 -0
  55. compressedfhir-3.0.2.dist-info/RECORD +59 -0
  56. compressedfhir-3.0.2.dist-info/WHEEL +5 -0
  57. compressedfhir-3.0.2.dist-info/licenses/LICENSE +201 -0
  58. compressedfhir-3.0.2.dist-info/top_level.txt +2 -0
  59. tests/__init__.py +0 -0
@@ -0,0 +1,74 @@
1
+ from datetime import datetime, timezone
2
+
3
+ from compressedfhir.fhir.fhir_bundle_entry_request import FhirBundleEntryRequest
4
+
5
+
6
+ class TestBundleEntryRequest:
7
+ def test_init_default(self) -> None:
8
+ """Test initialization with default parameters."""
9
+ request = FhirBundleEntryRequest(url="https://example.com")
10
+ assert request.url == "https://example.com"
11
+ assert request.method == "GET"
12
+ assert request.ifModifiedSince is None
13
+ assert request.ifNoneMatch is None
14
+
15
+ def test_init_full(self) -> None:
16
+ """Test initialization with all parameters."""
17
+ now = datetime.now(timezone.utc)
18
+ request = FhirBundleEntryRequest(
19
+ url="https://example.com",
20
+ method="POST",
21
+ ifModifiedSince=now,
22
+ ifNoneMatch='W/"abc"',
23
+ )
24
+ assert request.url == "https://example.com"
25
+ assert request.method == "POST"
26
+ assert request.ifModifiedSince == now
27
+ assert request.ifNoneMatch == 'W/"abc"'
28
+
29
+ def test_to_dict_minimal(self) -> None:
30
+ """Test converting to dictionary with minimal parameters."""
31
+ request = FhirBundleEntryRequest(url="https://example.com")
32
+ result = request.dict()
33
+ assert result == {"url": "https://example.com", "method": "GET"}
34
+
35
+ def test_to_dict_full(self) -> None:
36
+ """Test converting to dictionary with all parameters."""
37
+ now = datetime.now(timezone.utc)
38
+ request = FhirBundleEntryRequest(
39
+ url="https://example.com",
40
+ method="POST",
41
+ ifModifiedSince=now,
42
+ ifNoneMatch='W/"abc"',
43
+ )
44
+ result = request.dict()
45
+ assert result == {
46
+ "url": "https://example.com",
47
+ "method": "POST",
48
+ "ifModifiedSince": now.isoformat(),
49
+ "ifNoneMatch": 'W/"abc"',
50
+ }
51
+
52
+ def test_from_dict_minimal(self) -> None:
53
+ """Test creating from dictionary with minimal parameters."""
54
+ data = {"url": "https://example.com", "method": "GET"}
55
+ request = FhirBundleEntryRequest.from_dict(data)
56
+ assert request.url == "https://example.com"
57
+ assert request.method == "GET"
58
+ assert request.ifModifiedSince is None
59
+ assert request.ifNoneMatch is None
60
+
61
+ def test_from_dict_full(self) -> None:
62
+ """Test creating from dictionary with all parameters."""
63
+ now = datetime.now(timezone.utc)
64
+ data = {
65
+ "url": "https://example.com",
66
+ "method": "POST",
67
+ "ifModifiedSince": now.isoformat(),
68
+ "ifNoneMatch": 'W/"abc"',
69
+ }
70
+ request = FhirBundleEntryRequest.from_dict(data)
71
+ assert request.url == "https://example.com"
72
+ assert request.method == "POST"
73
+ assert request.ifModifiedSince == now
74
+ assert request.ifNoneMatch == 'W/"abc"'
@@ -0,0 +1,65 @@
1
+ from datetime import datetime, timezone
2
+
3
+ from compressedfhir.fhir.fhir_bundle_entry_response import (
4
+ FhirBundleEntryResponse,
5
+ )
6
+
7
+
8
+ class TestBundleEntryResponse:
9
+ def test_init_default(self) -> None:
10
+ """Test initialization with default parameters."""
11
+ response = FhirBundleEntryResponse(status="200", etag=None, lastModified=None)
12
+ assert response.status == "200"
13
+ assert response.etag is None
14
+ assert response.lastModified is None
15
+
16
+ def test_init_full(self) -> None:
17
+ """Test initialization with all parameters."""
18
+ now = datetime.now(timezone.utc)
19
+ response = FhirBundleEntryResponse(
20
+ status="201", etag='W/"def"', lastModified=now
21
+ )
22
+ assert response.status == "201"
23
+ assert response.etag == 'W/"def"'
24
+ assert response.lastModified == now
25
+
26
+ def test_init_int_status(self) -> None:
27
+ """Test initialization with integer status."""
28
+ response = FhirBundleEntryResponse(status="200", etag=None, lastModified=None)
29
+ assert response.status == "200"
30
+
31
+ def test_to_dict_minimal(self) -> None:
32
+ """Test converting to dictionary with minimal parameters."""
33
+ response = FhirBundleEntryResponse(status="200", etag=None, lastModified=None)
34
+ result = response.dict()
35
+ assert result == {"status": "200"}
36
+
37
+ def test_to_dict_full(self) -> None:
38
+ """Test converting to dictionary with all parameters."""
39
+ now = datetime.now(timezone.utc)
40
+ response = FhirBundleEntryResponse(
41
+ status="201", etag='W/"def"', lastModified=now
42
+ )
43
+ result = response.dict()
44
+ assert result == {
45
+ "status": "201",
46
+ "lastModified": now.isoformat(),
47
+ "etag": 'W/"def"',
48
+ }
49
+
50
+ def test_from_dict_minimal(self) -> None:
51
+ """Test creating from dictionary with minimal parameters."""
52
+ data = {"status": "200"}
53
+ response = FhirBundleEntryResponse.from_dict(data)
54
+ assert response.status == "200"
55
+ assert response.etag is None
56
+ assert response.lastModified is None
57
+
58
+ def test_from_dict_full(self) -> None:
59
+ """Test creating from dictionary with all parameters."""
60
+ now = datetime.now(timezone.utc)
61
+ data = {"status": "201", "lastModified": now.isoformat(), "etag": 'W/"def"'}
62
+ response = FhirBundleEntryResponse.from_dict(data)
63
+ assert response.status == "201"
64
+ assert response.lastModified == now
65
+ assert response.etag == 'W/"def"'
@@ -0,0 +1,245 @@
1
+ import json
2
+
3
+ from compressedfhir.fhir.fhir_bundle import FhirBundle
4
+ from compressedfhir.fhir.fhir_bundle_entry import FhirBundleEntry
5
+ from compressedfhir.fhir.fhir_bundle_entry_list import FhirBundleEntryList
6
+ from compressedfhir.fhir.fhir_resource import FhirResource
7
+ from compressedfhir.utilities.compressed_dict.v1.compressed_dict_storage_mode import (
8
+ CompressedDictStorageMode,
9
+ )
10
+
11
+
12
+ class TestBundle:
13
+ def test_init_minimal(self) -> None:
14
+ """Test initialization with minimal parameters."""
15
+ bundle = FhirBundle(type_="searchset")
16
+ assert bundle.type_ == "searchset"
17
+ assert len(bundle.entry) == 0
18
+ assert bundle.total is None
19
+ assert bundle.id_ is None
20
+ assert bundle.timestamp is None
21
+
22
+ def test_init_full(self) -> None:
23
+ """Test initialization with all parameters."""
24
+ entries = FhirBundleEntryList(
25
+ [
26
+ FhirBundleEntry(
27
+ resource={"resourceType": "Patient"},
28
+ request=None,
29
+ response=None,
30
+ storage_mode=CompressedDictStorageMode(),
31
+ ),
32
+ FhirBundleEntry(
33
+ resource={"resourceType": "Observation"},
34
+ request=None,
35
+ response=None,
36
+ storage_mode=CompressedDictStorageMode(),
37
+ ),
38
+ ]
39
+ )
40
+ bundle = FhirBundle(
41
+ type_="searchset",
42
+ entry=entries,
43
+ total=2,
44
+ id_="test-bundle",
45
+ timestamp="2023-12-01T12:00:00Z",
46
+ )
47
+ assert bundle.type_ == "searchset"
48
+ assert bundle.entry is not None
49
+ assert len(bundle.entry) == 2
50
+ assert bundle.total == 2
51
+ assert bundle.id_ == "test-bundle"
52
+ assert bundle.timestamp == "2023-12-01T12:00:00Z"
53
+
54
+ def test_to_dict_minimal(self) -> None:
55
+ """Test converting to dictionary with minimal parameters."""
56
+ bundle = FhirBundle(type_="searchset")
57
+ result = bundle.dict()
58
+ assert result == {"type": "searchset", "resourceType": "Bundle"}
59
+
60
+ def test_to_dict_full(self) -> None:
61
+ """Test converting to dictionary with all parameters."""
62
+ entries = FhirBundleEntryList(
63
+ [
64
+ FhirBundleEntry(
65
+ resource={"resourceType": "Patient"},
66
+ request=None,
67
+ response=None,
68
+ storage_mode=CompressedDictStorageMode(),
69
+ ),
70
+ FhirBundleEntry(
71
+ resource={"resourceType": "Observation"},
72
+ request=None,
73
+ response=None,
74
+ storage_mode=CompressedDictStorageMode(),
75
+ ),
76
+ ]
77
+ )
78
+ bundle = FhirBundle(
79
+ type_="searchset",
80
+ entry=entries,
81
+ total=2,
82
+ id_="test-bundle",
83
+ timestamp="2023-12-01T12:00:00Z",
84
+ )
85
+ result = bundle.dict()
86
+ assert result == {
87
+ "type": "searchset",
88
+ "resourceType": "Bundle",
89
+ "id": "test-bundle",
90
+ "timestamp": "2023-12-01T12:00:00Z",
91
+ "total": 2,
92
+ "entry": [
93
+ {"resource": {"resourceType": "Patient"}},
94
+ {"resource": {"resourceType": "Observation"}},
95
+ ],
96
+ }
97
+
98
+ def test_to_json(self) -> None:
99
+ """Test converting Bundle to JSON."""
100
+ entries = FhirBundleEntryList(
101
+ [
102
+ FhirBundleEntry(
103
+ resource={"resourceType": "Patient"},
104
+ request=None,
105
+ response=None,
106
+ storage_mode=CompressedDictStorageMode(),
107
+ ),
108
+ FhirBundleEntry(
109
+ resource={"resourceType": "Observation"},
110
+ request=None,
111
+ response=None,
112
+ storage_mode=CompressedDictStorageMode(),
113
+ ),
114
+ ]
115
+ )
116
+ bundle = FhirBundle(
117
+ type_="searchset",
118
+ entry=entries,
119
+ total=2,
120
+ id_="test-bundle",
121
+ timestamp="2023-12-01T12:00:00Z",
122
+ )
123
+ json_str = bundle.json()
124
+ parsed_json = json.loads(json_str)
125
+ assert parsed_json["type"] == "searchset"
126
+ assert parsed_json["resourceType"] == "Bundle"
127
+
128
+ def test_add_diagnostics_to_operation_outcomes(self) -> None:
129
+ """Test adding diagnostics to OperationOutcome resources."""
130
+ resource = FhirResource(
131
+ initial_dict={
132
+ "resourceType": "OperationOutcome",
133
+ "issue": [{"severity": "error", "details": {}}],
134
+ },
135
+ storage_mode=CompressedDictStorageMode(),
136
+ )
137
+ diagnostics_coding = [{"code": "test-code"}]
138
+
139
+ updated_resource = FhirBundle.add_diagnostics_to_operation_outcomes(
140
+ resource=resource, diagnostics_coding=diagnostics_coding
141
+ )
142
+
143
+ with updated_resource.transaction():
144
+ assert (
145
+ updated_resource["issue"][0]["details"]["coding"] == diagnostics_coding
146
+ )
147
+
148
+
149
+ class TestFhirBundleCopy:
150
+ def test_copy_full_bundle(self) -> None:
151
+ """
152
+ Test copying a fully populated FhirBundle
153
+ """
154
+ # Create a mock FhirBundleEntryList
155
+ mock_entry_list = FhirBundleEntryList()
156
+ mock_resource = FhirBundleEntry(
157
+ resource=FhirResource({"resourceType": "Patient", "id": "123"})
158
+ )
159
+ mock_entry_list.append(mock_resource)
160
+
161
+ # Create original bundle
162
+ original_bundle = FhirBundle(
163
+ id_="test-bundle-id",
164
+ timestamp="2023-01-01T00:00:00Z",
165
+ type_="transaction",
166
+ entry=mock_entry_list,
167
+ total=1,
168
+ )
169
+
170
+ # Create a copy
171
+ copied_bundle = original_bundle.copy()
172
+
173
+ # Assert that the copied bundle has the same attributes
174
+ assert copied_bundle.id_ == original_bundle.id_
175
+ assert copied_bundle.timestamp == original_bundle.timestamp
176
+ assert copied_bundle.type_ == original_bundle.type_
177
+ assert copied_bundle.total == original_bundle.total
178
+
179
+ # Ensure the entry list is a copy, not the same object
180
+ assert copied_bundle.entry is not original_bundle.entry
181
+ assert copied_bundle.entry is not None
182
+ assert original_bundle.entry is not None
183
+ assert len(copied_bundle.entry) == len(original_bundle.entry)
184
+ assert copied_bundle.entry[0].dict() == original_bundle.entry[0].dict()
185
+
186
+ def test_copy_empty_bundle(self) -> None:
187
+ """
188
+ Test copying a bundle with no entries
189
+ """
190
+ # Create an empty bundle
191
+ original_bundle = FhirBundle(type_="batch", entry=None, total=None)
192
+
193
+ # Create a copy
194
+ copied_bundle = original_bundle.copy()
195
+
196
+ # Assert that the copied bundle has the same attributes
197
+ assert copied_bundle.id_ is None
198
+ assert copied_bundle.timestamp is None
199
+ assert copied_bundle.type_ == "batch"
200
+ assert copied_bundle.total is None
201
+ assert len(copied_bundle.entry) == 0
202
+
203
+ def test_copy_modifying_original_does_not_affect_copy(self) -> None:
204
+ """
205
+ Test that modifying the original bundle does not affect the copy
206
+ """
207
+ # Create a mock FhirBundleEntryList
208
+ mock_entry_list = FhirBundleEntryList()
209
+ mock_resource = FhirResource({"resourceType": "Patient", "id": "123"})
210
+ mock_entry_list.append(FhirBundleEntry(resource=mock_resource))
211
+
212
+ # Create original bundle
213
+ original_bundle = FhirBundle(
214
+ id_="test-bundle-id",
215
+ timestamp="2023-01-01T00:00:00Z",
216
+ type_="transaction",
217
+ entry=mock_entry_list,
218
+ total=1,
219
+ )
220
+
221
+ # Create a copy
222
+ copied_bundle = original_bundle.copy()
223
+
224
+ # Modify the original bundle
225
+ original_bundle.id_ = "modified-id"
226
+ original_bundle.timestamp = "2023-02-01T00:00:00Z"
227
+ original_bundle.total = 2
228
+
229
+ # Assert that the copied bundle remains unchanged
230
+ assert copied_bundle.id_ == "test-bundle-id"
231
+ assert copied_bundle.timestamp == "2023-01-01T00:00:00Z"
232
+ assert copied_bundle.total == 1
233
+
234
+ def test_copy_returns_new_instance(self) -> None:
235
+ """
236
+ Test that copy() returns a new FhirBundle instance
237
+ """
238
+ # Create a bundle
239
+ original_bundle = FhirBundle(type_="batch")
240
+
241
+ # Create a copy
242
+ copied_bundle = original_bundle.copy()
243
+
244
+ # Assert that it's a different object
245
+ assert copied_bundle is not original_bundle
@@ -0,0 +1,104 @@
1
+ import json
2
+ from typing import Dict, Any
3
+
4
+ from compressedfhir.fhir.fhir_resource import FhirResource
5
+ from compressedfhir.utilities.compressed_dict.v1.compressed_dict_storage_mode import (
6
+ CompressedDictStorageMode,
7
+ )
8
+
9
+
10
+ class TestFhirResource:
11
+ def test_init_empty(self) -> None:
12
+ """Test initializing FhirResource with no initial dictionary."""
13
+ resource = FhirResource(storage_mode=CompressedDictStorageMode())
14
+ assert len(resource) == 0
15
+ assert resource.resource_type is None
16
+ assert resource.id is None
17
+ assert resource.resource_type_and_id is None
18
+
19
+ def test_init_with_data(self) -> None:
20
+ """Test initializing FhirResource with a dictionary."""
21
+ initial_data: Dict[str, Any] = {
22
+ "resourceType": "Patient",
23
+ "id": "123",
24
+ "name": [{"given": ["John"]}],
25
+ }
26
+ resource = FhirResource(
27
+ initial_dict=initial_data, storage_mode=CompressedDictStorageMode()
28
+ )
29
+
30
+ with resource.transaction():
31
+ assert resource.resource_type == "Patient"
32
+ assert resource.id == "123"
33
+ assert resource.resource_type_and_id == "Patient/123"
34
+ assert resource["name"][0]["given"][0] == "John"
35
+
36
+ def test_resource_type_and_id_property(self) -> None:
37
+ """Test resource_type_and_id property with various scenarios."""
38
+ # Scenario 1: Both resource type and id present
39
+ resource1 = FhirResource(
40
+ initial_dict={"resourceType": "Observation", "id": "456"},
41
+ storage_mode=CompressedDictStorageMode(),
42
+ )
43
+ assert resource1.resource_type_and_id == "Observation/456"
44
+
45
+ # Scenario 2: Missing resource type
46
+ resource2 = FhirResource(
47
+ initial_dict={"id": "789"}, storage_mode=CompressedDictStorageMode()
48
+ )
49
+ assert resource2.resource_type_and_id is None
50
+
51
+ # Scenario 3: Missing id
52
+ resource3 = FhirResource(
53
+ initial_dict={"resourceType": "Patient"},
54
+ storage_mode=CompressedDictStorageMode(),
55
+ )
56
+ assert resource3.resource_type_and_id is None
57
+
58
+ def test_equality(self) -> None:
59
+ """Test equality comparison between FhirResource instances."""
60
+ # Scenario 1: Equal resources
61
+ resource1 = FhirResource(
62
+ initial_dict={"resourceType": "Patient", "id": "123"},
63
+ storage_mode=CompressedDictStorageMode(),
64
+ )
65
+ resource2 = FhirResource(
66
+ initial_dict={"resourceType": "Patient", "id": "123"},
67
+ storage_mode=CompressedDictStorageMode(),
68
+ )
69
+ assert resource1 == resource2
70
+
71
+ # Scenario 2: Different resource types
72
+ resource3 = FhirResource(
73
+ initial_dict={"resourceType": "Observation", "id": "123"},
74
+ storage_mode=CompressedDictStorageMode(),
75
+ )
76
+ assert resource1 != resource3
77
+
78
+ # Scenario 3: Different ids
79
+ resource4 = FhirResource(
80
+ initial_dict={"resourceType": "Patient", "id": "456"},
81
+ storage_mode=CompressedDictStorageMode(),
82
+ )
83
+ assert resource1 != resource4
84
+
85
+ # Scenario 4: Comparing with non-FhirResource
86
+ assert resource1 != "Not a FhirResource"
87
+
88
+ def test_to_json(self) -> None:
89
+ """Test JSON serialization of FhirResource."""
90
+ initial_data: Dict[str, Any] = {
91
+ "resourceType": "Patient",
92
+ "id": "123",
93
+ "name": [{"given": ["John"]}],
94
+ }
95
+ resource = FhirResource(
96
+ initial_dict=initial_data, storage_mode=CompressedDictStorageMode()
97
+ )
98
+
99
+ json_str = resource.json()
100
+ parsed_json = json.loads(json_str)
101
+
102
+ assert parsed_json == initial_data
103
+ assert "resourceType" in parsed_json
104
+ assert "id" in parsed_json
@@ -0,0 +1,160 @@
1
+ import json
2
+ from unittest.mock import Mock
3
+
4
+ import pytest
5
+
6
+ from compressedfhir.fhir.fhir_resource_list import FhirResourceList
7
+
8
+
9
+ class TestFhirResourceList:
10
+ def test_get_resource_type_and_ids(self) -> None:
11
+ # Create mock FhirResource objects
12
+ mock_resources = [
13
+ Mock(resource_type="Patient", id="123"),
14
+ Mock(resource_type="Observation", id="456"),
15
+ ]
16
+
17
+ resource_list = FhirResourceList(mock_resources)
18
+
19
+ # Check the returned resource type and ids
20
+ expected_result = ["Patient/123", "Observation/456"]
21
+ assert resource_list.get_resource_type_and_ids() == expected_result
22
+
23
+ def test_get_operation_outcomes(self) -> None:
24
+ # Create mock FhirResource objects with different resource types
25
+ mock_resources = [
26
+ Mock(resource_type="OperationOutcome", id="err1"),
27
+ Mock(resource_type="Patient", id="123"),
28
+ Mock(resource_type="OperationOutcome", id="err2"),
29
+ ]
30
+
31
+ resource_list = FhirResourceList(mock_resources)
32
+
33
+ # Get operation outcomes
34
+ operation_outcomes = resource_list.get_operation_outcomes()
35
+
36
+ # Check the result
37
+ assert len(operation_outcomes) == 2
38
+ assert all(r.resource_type == "OperationOutcome" for r in operation_outcomes)
39
+
40
+ def test_get_resources_except_operation_outcomes(self) -> None:
41
+ # Create mock FhirResource objects with different resource types
42
+ mock_resources = [
43
+ Mock(resource_type="OperationOutcome", id="err1"),
44
+ Mock(resource_type="Patient", id="123"),
45
+ Mock(resource_type="Observation", id="456"),
46
+ Mock(resource_type="OperationOutcome", id="err2"),
47
+ ]
48
+
49
+ resource_list = FhirResourceList(mock_resources)
50
+
51
+ # Get resources except operation outcomes
52
+ valid_resources = resource_list.get_resources_except_operation_outcomes()
53
+
54
+ # Check the result
55
+ assert len(valid_resources) == 2
56
+ assert all(r.resource_type != "OperationOutcome" for r in valid_resources)
57
+
58
+ def test_remove_duplicates(self) -> None:
59
+ # Create mock FhirResource objects with duplicates
60
+ mock_resources = [
61
+ Mock(resource_type="Patient", id="123", resource_type_and_id="Patient/123"),
62
+ Mock(resource_type="Patient", id="123", resource_type_and_id="Patient/123"),
63
+ Mock(
64
+ resource_type="Observation",
65
+ id="456",
66
+ resource_type_and_id="Observation/456",
67
+ ),
68
+ Mock(resource_type="Patient", id="789", resource_type_and_id="Patient/789"),
69
+ ]
70
+
71
+ resource_list = FhirResourceList(mock_resources)
72
+
73
+ # Remove duplicates
74
+ resource_list.remove_duplicates()
75
+
76
+ # Check the result
77
+ assert len(resource_list) == 3
78
+ assert len(set(r.resource_type_and_id for r in resource_list)) == 3
79
+
80
+ def test_to_json(self) -> None:
81
+ # Create mock FhirResource objects
82
+ mock_resources = [
83
+ Mock(
84
+ resource_type="Patient",
85
+ id="123",
86
+ dict=lambda: {"id": "123", "resourceType": "Patient"},
87
+ ),
88
+ Mock(
89
+ resource_type="Observation",
90
+ id="456",
91
+ dict=lambda: {"id": "456", "resourceType": "Observation"},
92
+ ),
93
+ ]
94
+
95
+ resource_list = FhirResourceList(mock_resources)
96
+
97
+ # Convert to JSON
98
+ json_str = resource_list.json()
99
+
100
+ # Parse and check the JSON
101
+ parsed_json = json.loads(json_str)
102
+ assert len(parsed_json) == 2
103
+ assert parsed_json[0]["resourceType"] == "Patient"
104
+ assert parsed_json[1]["resourceType"] == "Observation"
105
+
106
+ @pytest.mark.asyncio
107
+ async def test_consume_resource_async_default(self) -> None:
108
+ # Create mock FhirResource objects
109
+ mock_resources = [
110
+ Mock(resource_type="Patient", id="123"),
111
+ Mock(resource_type="Observation", id="456"),
112
+ ]
113
+
114
+ resource_list = FhirResourceList(mock_resources)
115
+
116
+ # Consume resources asynchronously with default (None) batch size
117
+ async for batch in resource_list.consume_resource_batch_async(batch_size=None):
118
+ assert len(batch) == 2
119
+
120
+ # Ensure all resources are consumed
121
+ assert len(resource_list) == 0
122
+
123
+ @pytest.mark.asyncio
124
+ async def test_consume_resource_async_with_batch_size(self) -> None:
125
+ # Create mock FhirResource objects
126
+ mock_resources = [
127
+ Mock(resource_type="Patient", id="123"),
128
+ Mock(resource_type="Observation", id="456"),
129
+ Mock(resource_type="Condition", id="789"),
130
+ ]
131
+
132
+ resource_list = FhirResourceList(mock_resources)
133
+
134
+ # Consume resources asynchronously with batch size of 2
135
+ batches = []
136
+ async for batch in resource_list.consume_resource_batch_async(batch_size=2):
137
+ batches.append(batch)
138
+
139
+ # Check batches
140
+ assert len(batches) == 2
141
+ assert len(batches[0]) == 2
142
+ assert len(batches[1]) == 1
143
+
144
+ # Ensure all resources are consumed
145
+ assert len(resource_list) == 0
146
+
147
+ def test_consume_resource_async_invalid_batch_size(self) -> None:
148
+ resource_list = FhirResourceList()
149
+
150
+ # Test invalid batch sizes
151
+ with pytest.raises(ValueError, match="Batch size must be greater than 0."):
152
+
153
+ async def test() -> None:
154
+ async for _ in resource_list.consume_resource_batch_async(batch_size=0):
155
+ pass
156
+
157
+ # Run the async function
158
+ import asyncio
159
+
160
+ asyncio.run(test())