Skip to content

Commit ea39091

Browse files
committed
Use entities instead of passing dicts around
1 parent 19dff69 commit ea39091

File tree

4 files changed

+34
-24
lines changed

4 files changed

+34
-24
lines changed

backend/src/repository/fhir_repository.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import simplejson as json
99
from boto3.dynamodb.conditions import Attr, Key
1010
from botocore.config import Config
11+
from fhir.resources.R4B.fhirtypes import Id
12+
from fhir.resources.R4B.immunization import Immunization
1113
from mypy_boto3_dynamodb.service_resource import DynamoDBServiceResource, Table
1214
from responses import logger
1315

@@ -163,17 +165,19 @@ def check_immunization_identifier_exists(self, system: str, unique_id: str) -> b
163165

164166
return False
165167

166-
def create_immunization(self, immunization: dict, supplier_system: str) -> str:
168+
def create_immunization(self, immunization: Immunization, supplier_system: str) -> Id:
167169
"""Creates a new immunization record returning the unique id if successful."""
168-
patient = get_contained_patient(immunization)
169-
attr = RecordAttributes(immunization, patient)
170+
immunization_as_dict = immunization.dict()
171+
172+
patient = get_contained_patient(immunization_as_dict)
173+
attr = RecordAttributes(immunization_as_dict, patient)
170174

171175
response = self.table.put_item(
172176
Item={
173177
"PK": attr.pk,
174178
"PatientPK": attr.patient_pk,
175179
"PatientSK": attr.patient_sk,
176-
"Resource": json.dumps(attr.resource, use_decimal=True),
180+
"Resource": immunization.json(use_decimal=True),
177181
"IdentifierPK": attr.identifier,
178182
"Operation": "CREATE",
179183
"Version": 1,
@@ -184,7 +188,7 @@ def create_immunization(self, immunization: dict, supplier_system: str) -> str:
184188
if response["ResponseMetadata"]["HTTPStatusCode"] != 200:
185189
raise UnhandledResponseError(message="Non-200 response from dynamodb", response=dict(response))
186190

187-
return immunization.get("id")
191+
return immunization.id
188192

189193
def update_immunization(
190194
self,

backend/src/service/fhir_service.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
import uuid
55
from enum import Enum
6-
from typing import Optional, Union
6+
from typing import Optional, Union, cast
77
from uuid import uuid4
88

99
from fhir.resources.R4B.bundle import (
@@ -14,6 +14,8 @@
1414
BundleEntrySearch,
1515
BundleLink,
1616
)
17+
from fhir.resources.R4B.fhirtypes import Id
18+
from fhir.resources.R4B.identifier import Identifier
1719
from fhir.resources.R4B.immunization import Immunization
1820
from pydantic import ValidationError
1921

@@ -134,7 +136,7 @@ def get_immunization_by_id_all(self, imms_id: str, imms: dict) -> Optional[dict]
134136
imms_resp = self.immunization_repo.get_immunization_by_id_all(imms_id, imms)
135137
return imms_resp
136138

137-
def create_immunization(self, immunization: dict, supplier_system: str) -> str:
139+
def create_immunization(self, immunization: dict, supplier_system: str) -> Id:
138140
if immunization.get("id") is not None:
139141
raise CustomValidationError("id field must not be present for CREATE operation")
140142

@@ -148,15 +150,16 @@ def create_immunization(self, immunization: dict, supplier_system: str) -> str:
148150
if not self.authoriser.authorise(supplier_system, ApiOperationCode.CREATE, {vaccination_type}):
149151
raise UnauthorizedVaxError()
150152

151-
identifier_system = immunization["identifier"][0]["system"]
152-
identifier_value = immunization["identifier"][0]["value"]
153-
154-
if self.immunization_repo.check_immunization_identifier_exists(identifier_system, identifier_value):
155-
raise IdentifierDuplicationError(identifier=f"{identifier_system}#{identifier_value}")
156-
157153
# Set ID for the requested new record
158154
immunization["id"] = str(uuid.uuid4())
159-
return self.immunization_repo.create_immunization(immunization, supplier_system)
155+
156+
immunization_fhir_entity = Immunization.parse_obj(immunization)
157+
identifier = cast(Identifier, immunization_fhir_entity.identifier[0])
158+
159+
if self.immunization_repo.check_immunization_identifier_exists(identifier.system, identifier.value):
160+
raise IdentifierDuplicationError(identifier=f"{identifier.system}#{identifier.value}")
161+
162+
return self.immunization_repo.create_immunization(immunization_fhir_entity, supplier_system)
160163

161164
def update_immunization(
162165
self,

backend/tests/repository/test_fhir_repository.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import botocore.exceptions
77
import simplejson as json
88
from boto3.dynamodb.conditions import Attr, Key
9+
from fhir.resources.R4B.immunization import Immunization
910

1011
from models.errors import (
1112
IdentifierDuplicationError,
@@ -195,7 +196,7 @@ def setUp(self):
195196

196197
def test_create_immunization(self):
197198
"""it should create Immunization, and return created object unique ID"""
198-
imms = create_covid_19_immunization_dict(imms_id=self._MOCK_CREATED_UUID)
199+
imms = Immunization.parse_obj(create_covid_19_immunization_dict(imms_id=self._MOCK_CREATED_UUID))
199200

200201
self.table.put_item = MagicMock(return_value={"ResponseMetadata": {"HTTPStatusCode": 200}})
201202
self.mock_redis_client.hget.return_value = "COVID19"
@@ -208,7 +209,7 @@ def test_create_immunization(self):
208209
"PK": f"Immunization#{self._MOCK_CREATED_UUID}",
209210
"PatientPK": "Patient#9990548609",
210211
"PatientSK": f"COVID19#{self._MOCK_CREATED_UUID}",
211-
"Resource": json.dumps(imms),
212+
"Resource": imms.json(),
212213
"IdentifierPK": "https://supplierABC/identifiers/vacc#ACME-vacc123456",
213214
"Operation": "CREATE",
214215
"Version": 1,
@@ -225,7 +226,9 @@ def test_create_should_catch_dynamo_error(self):
225226

226227
with self.assertRaises(UnhandledResponseError) as e:
227228
# When
228-
self.repository.create_immunization(create_covid_19_immunization_dict("an-id"), "Test")
229+
self.repository.create_immunization(
230+
Immunization.parse_obj(create_covid_19_immunization_dict("an-id")), "Test"
231+
)
229232

230233
# Then
231234
self.assertDictEqual(e.exception.response, response)
@@ -251,7 +254,7 @@ def test_create_patient_gsi(self):
251254
self.table.query = MagicMock(return_value={})
252255

253256
# When
254-
_ = self.repository.create_immunization(imms, "Test")
257+
_ = self.repository.create_immunization(Immunization.parse_obj(imms), "Test")
255258

256259
# Then
257260
item = self.table.put_item.call_args.kwargs["Item"]
@@ -268,7 +271,7 @@ def test_create_patient_with_vaccine_type(self):
268271
self.table.put_item = MagicMock(return_value={"ResponseMetadata": {"HTTPStatusCode": 200}})
269272

270273
# When
271-
_ = self.repository.create_immunization(imms, "Test")
274+
_ = self.repository.create_immunization(Immunization.parse_obj(imms), "Test")
272275

273276
# Then
274277
item = self.table.put_item.call_args.kwargs["Item"]
@@ -584,12 +587,12 @@ def setUp(self):
584587
def test_decimal_on_create(self):
585588
"""it should create Immunization, and preserve decimal value"""
586589
imms = create_covid_19_immunization_dict(imms_id="an-id")
587-
imms["doseQuantity"] = 0.7477
590+
imms["doseQuantity"]["value"] = 0.7477
588591

589592
self.table.put_item = MagicMock(return_value={"ResponseMetadata": {"HTTPStatusCode": 200}})
590593
self.table.query = MagicMock(return_value={})
591594

592-
res_imms = self.repository.create_immunization(imms, "Test")
595+
res_imms = self.repository.create_immunization(Immunization.parse_obj(imms), "Test")
593596

594597
self.assertEqual(res_imms, "an-id")
595598

@@ -599,7 +602,7 @@ def test_decimal_on_create(self):
599602
"PK": ANY,
600603
"PatientPK": ANY,
601604
"PatientSK": ANY,
602-
"Resource": json.dumps(imms, use_decimal=True),
605+
"Resource": Immunization.parse_obj(imms).json(use_decimal=True),
603606
"IdentifierPK": ANY,
604607
"Operation": "CREATE",
605608
"Version": 1,
@@ -612,7 +615,7 @@ def test_decimal_on_create(self):
612615

613616
resource_from_item = json.loads(item_passed_to_put_item["Resource"])
614617
self.assertEqual(
615-
resource_from_item["doseQuantity"],
618+
resource_from_item["doseQuantity"]["value"],
616619
0.7477,
617620
)
618621

backend/tests/service/test_fhir_service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ def test_create_immunization(self):
481481
self.imms_repo.check_immunization_identifier_exists.assert_called_once_with(
482482
"https://supplierABC/identifiers/vacc", "ACME-vacc123456"
483483
)
484-
self.imms_repo.create_immunization.assert_called_once_with(req_imms, "Test")
484+
self.imms_repo.create_immunization.assert_called_once_with(Immunization.parse_obj(req_imms), "Test")
485485

486486
self.validator.validate.assert_called_once_with(req_imms)
487487
self.assertEqual(self._MOCK_NEW_UUID, created_id)

0 commit comments

Comments
 (0)