compressedfhir 0.0.1__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.
Potentially problematic release.
This version of compressedfhir might be problematic. Click here for more details.
- compressedfhir/__init__.py +0 -0
- compressedfhir/fhir/__init__.py +0 -0
- compressedfhir/fhir/base_resource_list.py +165 -0
- compressedfhir/fhir/fhir_bundle.py +291 -0
- compressedfhir/fhir/fhir_bundle_entry.py +234 -0
- compressedfhir/fhir/fhir_bundle_entry_list.py +82 -0
- compressedfhir/fhir/fhir_bundle_entry_request.py +71 -0
- compressedfhir/fhir/fhir_bundle_entry_response.py +64 -0
- compressedfhir/fhir/fhir_bundle_entry_search.py +75 -0
- compressedfhir/fhir/fhir_identifier.py +84 -0
- compressedfhir/fhir/fhir_link.py +63 -0
- compressedfhir/fhir/fhir_meta.py +47 -0
- compressedfhir/fhir/fhir_resource.py +163 -0
- compressedfhir/fhir/fhir_resource_list.py +143 -0
- compressedfhir/fhir/fhir_resource_map.py +193 -0
- compressedfhir/fhir/test/__init__.py +0 -0
- compressedfhir/fhir/test/test_bundle_entry.py +129 -0
- compressedfhir/fhir/test/test_bundle_entry_list.py +187 -0
- compressedfhir/fhir/test/test_bundle_entry_request.py +74 -0
- compressedfhir/fhir/test/test_bundle_entry_response.py +65 -0
- compressedfhir/fhir/test/test_fhir_bundle.py +245 -0
- compressedfhir/fhir/test/test_fhir_resource.py +225 -0
- compressedfhir/fhir/test/test_fhir_resource_list.py +160 -0
- compressedfhir/fhir/test/test_fhir_resource_map.py +293 -0
- compressedfhir/py.typed +0 -0
- compressedfhir/utilities/__init__.py +0 -0
- compressedfhir/utilities/compressed_dict/__init__.py +0 -0
- compressedfhir/utilities/compressed_dict/v1/__init__.py +0 -0
- compressedfhir/utilities/compressed_dict/v1/compressed_dict.py +635 -0
- compressedfhir/utilities/compressed_dict/v1/compressed_dict_access_error.py +2 -0
- compressedfhir/utilities/compressed_dict/v1/compressed_dict_storage_mode.py +50 -0
- compressedfhir/utilities/compressed_dict/v1/test/__init__.py +0 -0
- compressedfhir/utilities/compressed_dict/v1/test/test_compressed_dict.py +360 -0
- compressedfhir/utilities/fhir_json_encoder.py +30 -0
- compressedfhir/utilities/json_helpers.py +181 -0
- compressedfhir-0.0.1.dist-info/METADATA +28 -0
- compressedfhir-0.0.1.dist-info/RECORD +41 -0
- compressedfhir-0.0.1.dist-info/WHEEL +5 -0
- compressedfhir-0.0.1.dist-info/licenses/LICENSE +201 -0
- compressedfhir-0.0.1.dist-info/top_level.txt +2 -0
- 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,225 @@
|
|
|
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
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class TestFhirResourceRemoveNulls:
|
|
108
|
+
def test_remove_nulls_simple_dict(self) -> None:
|
|
109
|
+
"""
|
|
110
|
+
Test removing None values from a simple dictionary
|
|
111
|
+
"""
|
|
112
|
+
initial_dict: Dict[str, Any] = {
|
|
113
|
+
"name": "John Doe",
|
|
114
|
+
"age": None,
|
|
115
|
+
"active": True,
|
|
116
|
+
"email": None,
|
|
117
|
+
}
|
|
118
|
+
resource = FhirResource(initial_dict=initial_dict)
|
|
119
|
+
resource.remove_nulls()
|
|
120
|
+
|
|
121
|
+
with resource.transaction():
|
|
122
|
+
# Check that None values are removed
|
|
123
|
+
assert "age" not in resource
|
|
124
|
+
assert "email" not in resource
|
|
125
|
+
assert resource.get("name") == "John Doe"
|
|
126
|
+
assert resource.get("active") is True
|
|
127
|
+
|
|
128
|
+
def test_remove_nulls_nested_dict(self) -> None:
|
|
129
|
+
"""
|
|
130
|
+
Test removing None values from a nested dictionary
|
|
131
|
+
"""
|
|
132
|
+
initial_dict: Dict[str, Any] = {
|
|
133
|
+
"patient": {
|
|
134
|
+
"name": "Jane Smith",
|
|
135
|
+
"contact": None,
|
|
136
|
+
"address": {"street": None, "city": "New York"},
|
|
137
|
+
},
|
|
138
|
+
"status": None,
|
|
139
|
+
}
|
|
140
|
+
resource = FhirResource(initial_dict=initial_dict)
|
|
141
|
+
resource.remove_nulls()
|
|
142
|
+
|
|
143
|
+
with resource.transaction():
|
|
144
|
+
assert "status" not in resource
|
|
145
|
+
assert "contact" not in resource.get("patient", {})
|
|
146
|
+
assert resource.get("patient", {}).get("address", {}).get("street") is None
|
|
147
|
+
assert (
|
|
148
|
+
resource.get("patient", {}).get("address", {}).get("city") == "New York"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
def test_remove_nulls_list_of_dicts(self) -> None:
|
|
152
|
+
"""
|
|
153
|
+
Test removing None values from a list of dictionaries
|
|
154
|
+
"""
|
|
155
|
+
initial_dict: Dict[str, Any] = {
|
|
156
|
+
"patients": [
|
|
157
|
+
{"name": "Alice", "age": None},
|
|
158
|
+
{"name": "Bob", "age": 30},
|
|
159
|
+
{"name": None, "active": False},
|
|
160
|
+
]
|
|
161
|
+
}
|
|
162
|
+
resource = FhirResource(initial_dict=initial_dict)
|
|
163
|
+
resource.remove_nulls()
|
|
164
|
+
|
|
165
|
+
with resource.transaction():
|
|
166
|
+
assert len(resource.get("patients", [])) == 3
|
|
167
|
+
assert resource.get("patients", [])[0].get("name") == "Alice"
|
|
168
|
+
assert resource.get("patients", [])[1].get("name") == "Bob"
|
|
169
|
+
assert resource.get("patients", [])[1].get("age") == 30
|
|
170
|
+
|
|
171
|
+
def test_remove_nulls_empty_dict(self) -> None:
|
|
172
|
+
"""
|
|
173
|
+
Test removing None values from an empty dictionary
|
|
174
|
+
"""
|
|
175
|
+
resource = FhirResource(initial_dict={})
|
|
176
|
+
resource.remove_nulls()
|
|
177
|
+
|
|
178
|
+
assert len(resource) == 0
|
|
179
|
+
|
|
180
|
+
def test_remove_nulls_no_changes(self) -> None:
|
|
181
|
+
"""
|
|
182
|
+
Test removing None values when no None values exist
|
|
183
|
+
"""
|
|
184
|
+
initial_dict: Dict[str, Any] = {
|
|
185
|
+
"name": "Test User",
|
|
186
|
+
"active": True,
|
|
187
|
+
"score": 100,
|
|
188
|
+
}
|
|
189
|
+
resource = FhirResource(initial_dict=initial_dict)
|
|
190
|
+
original_dict = resource.copy()
|
|
191
|
+
resource.remove_nulls()
|
|
192
|
+
|
|
193
|
+
assert resource == original_dict
|
|
194
|
+
|
|
195
|
+
def test_remove_nulls_with_custom_storage_mode(self) -> None:
|
|
196
|
+
"""
|
|
197
|
+
Test removing None values with a custom storage mode
|
|
198
|
+
"""
|
|
199
|
+
initial_dict: Dict[str, Any] = {
|
|
200
|
+
"name": "Custom Mode User",
|
|
201
|
+
"email": None,
|
|
202
|
+
"active": True,
|
|
203
|
+
}
|
|
204
|
+
resource = FhirResource(
|
|
205
|
+
initial_dict=initial_dict, storage_mode=CompressedDictStorageMode.default()
|
|
206
|
+
)
|
|
207
|
+
resource.remove_nulls()
|
|
208
|
+
|
|
209
|
+
with resource.transaction():
|
|
210
|
+
assert "email" not in resource
|
|
211
|
+
assert resource.get("name") == "Custom Mode User"
|
|
212
|
+
assert resource.get("active") is True
|
|
213
|
+
|
|
214
|
+
def test_remove_nulls_preserves_false_and_zero_values(self) -> None:
|
|
215
|
+
"""
|
|
216
|
+
Test that False and 0 values are not removed
|
|
217
|
+
"""
|
|
218
|
+
initial_dict: Dict[str, Any] = {"active": False, "score": 0, "name": None}
|
|
219
|
+
resource = FhirResource(initial_dict=initial_dict)
|
|
220
|
+
resource.remove_nulls()
|
|
221
|
+
|
|
222
|
+
with resource.transaction():
|
|
223
|
+
assert resource.get("active") is False
|
|
224
|
+
assert resource.get("score") == 0
|
|
225
|
+
assert "name" not in resource
|