Skip to content

Commit 8f0aa90

Browse files
committed
AMB-1741 move create_response out and test it separately
1 parent d35915f commit 8f0aa90

File tree

6 files changed

+93
-86
lines changed

6 files changed

+93
-86
lines changed

lambda_code/src/get_imms_handler.py

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import json
2+
import re
13
import uuid
24

35
from dynamodb import EventTable
4-
import json
5-
import re
6+
from immunisation_api import create_response
67

78

8-
def create_response(event_id, message, code):
9+
def create_operation_outcome(event_id, message, code):
910
return {
1011
"resourceType": "OperationOutcome",
1112
"id": event_id,
@@ -46,32 +47,16 @@ def is_valid_id(_event_id):
4647
return re.match(pattern, _event_id) is not None
4748

4849
if not is_valid_id(event_id) or not event_id:
49-
return {
50-
"statusCode": 400,
51-
"headers": {
52-
"Content-Type": "application/fhir+json",
53-
},
54-
"body": json.dumps(
55-
create_response(str(uuid.uuid4()),
56-
"he provided event ID is either missing or not in the expected format.",
57-
"invalid"))
58-
}
59-
60-
message = dynamo_service.get_event_by_id(event_id)
61-
if message is None:
62-
63-
return {
64-
"statusCode": 404,
65-
"headers": {
66-
"Content-Type": "application/fhir+json",
67-
},
68-
"body": json.dumps(create_response(str(uuid.uuid4()), "The requested resource was not found.", "not-found"))
69-
}
70-
71-
return {
72-
'statusCode': 200,
73-
"headers": {
74-
"Content-Type": "application/fhir+json",
75-
},
76-
'body': json.dumps(message)
77-
}
50+
body = json.dumps(
51+
create_operation_outcome(str(uuid.uuid4()),
52+
"he provided event ID is either missing or not in the expected format.",
53+
"invalid"))
54+
return create_response(400, body)
55+
56+
query_result = dynamo_service.get_event_by_id(event_id)
57+
if query_result is None:
58+
body = json.dumps(
59+
create_operation_outcome(str(uuid.uuid4()), "The requested resource was not found.", "not-found"))
60+
return create_response(404, body)
61+
62+
return create_response(200, json.dumps(query_result))

lambda_code/src/immunisation_api.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import requests
22

33

4+
def create_response(status_code, body):
5+
return {
6+
"statusCode": status_code,
7+
"headers": {
8+
"Content-Type": "application/fhir+json",
9+
},
10+
"body": body
11+
}
12+
13+
414
class ImmunisationApi:
515
def __init__(self, url):
616
self.url = url

lambda_code/src/models/errors.py

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,51 +9,38 @@ class Severity(str, Enum):
99

1010

1111
class Code(str, Enum):
12-
not_found = "NOT_FOUND"
12+
not_found = "not_found"
1313

1414

15-
# @dataclass
16-
class ApiError(BaseModel):
15+
class ApiError(BaseModel, use_enum_values=True):
1716
id: str
1817
severity: Severity
1918
code: Code
2019
diagnostics: str
2120

22-
23-
base_model = {
24-
"resourceType": "OperationOutcome",
25-
"id": None,
26-
"meta": {
27-
"profile": [
28-
"https://simplifier.net/guide/UKCoreDevelopment2/ProfileUKCore-OperationOutcome"
29-
]
30-
},
31-
"issue": [
32-
{
33-
"severity": None,
34-
"code": None,
35-
"details": {
36-
"coding": [
37-
{
38-
"system": "https://fhir.nhs.uk/Codesystem/http-error-codes",
39-
"code": None
40-
}
21+
def to_uk_core(self) -> OperationOutcome:
22+
model = {
23+
"resourceType": "OperationOutcome",
24+
"id": self.id,
25+
"meta": {
26+
"profile": [
27+
"https://simplifier.net/guide/UKCoreDevelopment2/ProfileUKCore-OperationOutcome"
4128
]
4229
},
43-
"diagnostics": None
30+
"issue": [
31+
{
32+
"severity": self.severity,
33+
"code": self.code,
34+
"details": {
35+
"coding": [
36+
{
37+
"system": "https://fhir.nhs.uk/Codesystem/http-error-codes",
38+
"code": self.code.upper()
39+
}
40+
]
41+
},
42+
"diagnostics": self.diagnostics
43+
}
44+
]
4445
}
45-
]
46-
}
47-
48-
49-
class ApiErrors:
50-
@staticmethod
51-
def event_not_found(error: ApiError) -> OperationOutcome:
52-
op = OperationOutcome.parse_obj(base_model, "fd")
53-
# op = OperationOutcome.construct()
54-
# op.id = error_id
55-
# issue = OperationOutcomeIssue.construct()
56-
# issue.severity = "error"
57-
# issue.code = "not_found"
58-
# op.issue = issue
59-
return op
46+
return OperationOutcome.parse_obj(model)

lambda_code/tests/test_api_errors.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,24 @@
44

55
sys.path.append(f"{os.path.dirname(os.path.abspath(__file__))}/../src")
66

7-
from models.errors import ApiError, Severity, Code
7+
from models.errors import ApiError, Severity, Code
88

99

1010
class TestApiErrors(unittest.TestCase):
11-
def test_event_not_found(self):
12-
a = ApiError(id="foo", severity=Severity.error, code=Code.not_found, diagnostics="bad thing happened")
13-
print(a.dict())
14-
# print(ApiErrors.event_not_found("foo").json())
11+
def test_error_to_uk_core(self):
12+
code = Code.not_found
13+
severity = Severity.error
14+
diag = "a-diagnostic"
15+
error_id = "a-id"
16+
17+
api_error = ApiError(id=error_id, severity=severity, code=code, diagnostics=diag)
18+
error = api_error.to_uk_core().dict()
19+
20+
issue = error["issue"][0]
21+
self.assertEqual(error["id"], error_id)
22+
self.assertEqual(issue["code"], "not_found")
23+
self.assertEqual(issue["severity"], "error")
24+
self.assertEqual(issue["diagnostics"], diag)
25+
self.assertEqual(issue["details"]["coding"][0]["code"], "NOT_FOUND")
26+
27+

lambda_code/tests/test_get_imms.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
sys.path.append(f"{os.path.dirname(os.path.abspath(__file__))}/../src")
99

1010
from dynamodb import EventTable
11-
from get_imms_handler import get_imms, create_response
11+
from get_imms_handler import get_imms, create_operation_outcome
1212

1313

1414
class TestGetImms(unittest.TestCase):
@@ -18,16 +18,16 @@ def setUp(self):
1818
def test_get_imms_happy_path(self):
1919
# Arrange
2020
self.dynamodb_service.get_event_by_id = MagicMock(return_value={"message": "Mocked event data"})
21-
formatted_event = {"pathParameters": {"id": "sampleid"}}
21+
lambda_event = {"pathParameters": {"id": "sample-id"}}
2222

2323
# Act
24-
result = get_imms(formatted_event, self.dynamodb_service)
24+
result = get_imms(lambda_event, self.dynamodb_service)
2525

2626
# Assert
27-
self.dynamodb_service.get_event_by_id.assert_called_once_with(formatted_event["pathParameters"]["id"])
28-
assert result['statusCode'] == 200
27+
self.dynamodb_service.get_event_by_id.assert_called_once_with(lambda_event["pathParameters"]["id"])
28+
self.assertEqual(result['statusCode'], 200)
2929
self.assertEqual(result['headers']['Content-Type'], "application/fhir+json")
30-
assert json.loads(result['body']) == {"message": "Mocked event data"}
30+
self.assertDictEqual(json.loads(result['body']), {"message": "Mocked event data"})
3131

3232
def test_get_imms_handler_sad_path_400(self):
3333
unformatted_event = {"pathParameters": {"id": "unexpected_id"}}
@@ -39,9 +39,9 @@ def test_get_imms_handler_sad_path_400(self):
3939
assert result['statusCode'] == 400
4040
self.assertEqual(result['headers']['Content-Type'], "application/fhir+json")
4141
act_body = json.loads(result['body'])
42-
exp_body = create_response(str(uuid.uuid4()),
43-
"he provided event ID is either missing or not in the expected format.",
44-
"invalid")
42+
exp_body = create_operation_outcome(str(uuid.uuid4()),
43+
"he provided event ID is either missing or not in the expected format.",
44+
"invalid")
4545
act_body["id"] = None
4646
exp_body["id"] = None
4747
self.assertDictEqual(act_body, exp_body)
@@ -58,7 +58,7 @@ def test_get_imms_handler_sad_path_404(self):
5858
assert result['statusCode'] == 404
5959
self.assertEqual(result['headers']['Content-Type'], "application/fhir+json")
6060
act_body = json.loads(result['body'])
61-
exp_body = create_response(str(uuid.uuid4()), "The requested resource was not found.", "not-found")
61+
exp_body = create_operation_outcome(str(uuid.uuid4()), "The requested resource was not found.", "not-found")
6262
act_body["id"] = None
6363
exp_body["id"] = None
6464
self.assertDictEqual(act_body, exp_body)

lambda_code/tests/test_imms_api_service.py renamed to lambda_code/tests/test_immunisation_api.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,19 @@
77

88
sys.path.append(f"{os.path.dirname(os.path.abspath(__file__))}/../src")
99

10-
from immunisation_api import ImmunisationApi
10+
from immunisation_api import ImmunisationApi, create_response
11+
12+
13+
class TestRequestResponseHelpers(unittest.TestCase):
14+
def test_create_response(self):
15+
res = create_response(42, "a body")
16+
headers = res["headers"]
17+
self.assertEqual(res["statusCode"], 42)
18+
19+
self.assertDictEqual(headers, {
20+
"Content-Type": "application/fhir+json",
21+
})
22+
self.assertEqual(res["body"], "a body")
1123

1224

1325
class TestImmsApiService(unittest.TestCase):

0 commit comments

Comments
 (0)