Skip to content

Commit b39824c

Browse files
authored
Merge pull request #46 from NHSDigital/AMB-1744-complete-read-endpoint
Amb 1744 complete read endpoint
2 parents cdbec47 + 3410924 commit b39824c

File tree

10 files changed

+219
-61
lines changed

10 files changed

+219
-61
lines changed

lambda_code/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ package: build
66
docker run --rm -v $(shell pwd)/build:/build imms-lambda-build
77

88
test:
9-
python -m unittest
9+
DYNAMODB_TABLE_NAME=example-table python -m unittest
1010

1111
.PHONY: build package test

lambda_code/entrypoint.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ cd /lambda_test || exit 2
55
echo "Installing dependencies for test..."
66
pip install -q -r requirements.txt
77
echo "Running unit tests"
8+
export DYNAMODB_TABLE_NAME=example_table
89
python -m unittest
910

1011
cd /lambda_package || exit 2

lambda_code/src/dynamodb.py

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

88
class EventTable:
99
def __init__(self, table_name=os.environ["DYNAMODB_TABLE_NAME"], endpoint_url=None):
10-
db = boto3.resource("dynamodb", endpoint_url=endpoint_url)
10+
db = boto3.resource("dynamodb", endpoint_url=endpoint_url, region_name='eu-west-2')
1111
self.table = db.Table(table_name)
1212

1313
def get_event_by_id(self, event_id):

lambda_code/src/get_imms_handler.py

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,77 @@
1+
import uuid
2+
13
from dynamodb import EventTable
24
import json
5+
import re
6+
7+
8+
def create_response(event_id, message, code):
9+
return {
10+
"resourceType": "OperationOutcome",
11+
"id": event_id,
12+
"meta": {
13+
"profile": [
14+
"https://simplifier.net/guide/UKCoreDevelopment2/ProfileUKCore-OperationOutcome"
15+
]
16+
},
17+
"issue": [
18+
{
19+
"severity": "error",
20+
"code": code,
21+
"details": {
22+
"coding": [
23+
{
24+
"system": "https://fhir.nhs.uk/Codesystem/http-error-codes",
25+
"code": code.upper()
26+
}
27+
]
28+
},
29+
"diagnostics": message
30+
}
31+
]
32+
}
333

434

535
def get_imms_handler(event, context):
6-
event_body = json.dumps(event)
7-
print(event_body)
8-
event_id = event["pathParameters"]["id"]
936
dynamo_service = EventTable()
37+
return get_imms(event, dynamo_service)
38+
39+
40+
# create function which receives event and instance of dynamodb
41+
def get_imms(event, dynamo_service):
42+
event_id = event["pathParameters"]["id"]
43+
44+
def is_valid_id(_event_id):
45+
pattern = r'^[A-Za-z0-9\-.]{1,64}$'
46+
return re.match(pattern, _event_id) is not None
47+
48+
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+
1060
message = dynamo_service.get_event_by_id(event_id)
11-
response = {
12-
"statusCode": 200, # HTTP status code
13-
"body": json.dumps({
14-
"message": message
15-
})
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)
1677
}
17-
return response

lambda_code/tests/test_get_imms.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import uuid
2+
from unittest.mock import MagicMock
3+
import unittest
4+
import json
5+
import sys
6+
import os
7+
8+
sys.path.append(f"{os.path.dirname(os.path.abspath(__file__))}/../src")
9+
10+
from dynamodb import EventTable
11+
from get_imms_handler import get_imms, create_response
12+
13+
14+
class TestGetImms(unittest.TestCase):
15+
def setUp(self):
16+
self.dynamodb_service = EventTable()
17+
18+
def test_get_imms_happy_path(self):
19+
# Arrange
20+
self.dynamodb_service.get_event_by_id = MagicMock(return_value={"message": "Mocked event data"})
21+
formatted_event = {"pathParameters": {"id": "sampleid"}}
22+
23+
# Act
24+
result = get_imms(formatted_event, self.dynamodb_service)
25+
26+
# Assert
27+
self.dynamodb_service.get_event_by_id.assert_called_once_with(formatted_event["pathParameters"]["id"])
28+
assert result['statusCode'] == 200
29+
self.assertEquals(result['headers']['Content-Type'], "application/fhir+json")
30+
assert json.loads(result['body']) == {"message": "Mocked event data"}
31+
32+
def test_get_imms_handler_sad_path_400(self):
33+
unformatted_event = {"pathParameters": {"id": "unexpected_id"}}
34+
35+
# Act
36+
result = get_imms(unformatted_event, None)
37+
38+
# Assert
39+
assert result['statusCode'] == 400
40+
self.assertEquals(result['headers']['Content-Type'], "application/fhir+json")
41+
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")
45+
act_body["id"] = None
46+
exp_body["id"] = None
47+
self.assertDictEqual(act_body, exp_body)
48+
49+
def test_get_imms_handler_sad_path_404(self):
50+
# Arrange
51+
self.dynamodb_service.get_event_by_id = MagicMock(return_value=None)
52+
incorrect_event = {"pathParameters": {"id": "incorrectid"}}
53+
54+
# Act
55+
result = get_imms(incorrect_event, self.dynamodb_service)
56+
57+
# Assert
58+
assert result['statusCode'] == 404
59+
self.assertEquals(result['headers']['Content-Type'], "application/fhir+json")
60+
act_body = json.loads(result['body'])
61+
exp_body = create_response(str(uuid.uuid4()), "The requested resource was not found.", "not-found")
62+
act_body["id"] = None
63+
exp_body["id"] = None
64+
self.assertDictEqual(act_body, exp_body)

openapi.json

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

terraform/.terraform.lock.hcl

Lines changed: 18 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

terraform/oas.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ paths:
1818
'201':
1919
description: Get status
2020
content:
21-
application/json:
21+
application/fhir+json:
2222
schema:
2323
type: object
2424

@@ -35,7 +35,7 @@ paths:
3535
'200':
3636
description: An Immunisation get event
3737
content:
38-
application/json:
38+
application/fhir+json:
3939
schema:
4040
type: object
4141
delete:
@@ -50,7 +50,7 @@ paths:
5050
'200':
5151
description: An Immunisation delete event
5252
content:
53-
application/json:
53+
application/fhir+json:
5454
schema:
5555
type: object
5656

@@ -77,7 +77,7 @@ paths:
7777
'201':
7878
description: An Immunisation search event
7979
content:
80-
application/json:
80+
application/fhir+json:
8181
schema:
8282
type: object
8383
post:
@@ -92,7 +92,7 @@ paths:
9292
'201':
9393
description: An Immunisation post event
9494
content:
95-
application/json:
95+
application/fhir+json:
9696
schema:
9797
type: object
9898
/{proxy+}:
@@ -114,6 +114,6 @@ paths:
114114
'404':
115115
description: Not Found
116116
content:
117-
application/json:
117+
application/fhir+json:
118118
schema:
119119
type: object

tests/test_auth.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ def test_invalid_access_token():
2424

2525

2626
@pytest.mark.auth
27-
@pytest.mark.debug
2827
@pytest.mark.nhsd_apim_authorization(
2928
{
3029
"access": "healthcare_worker",

0 commit comments

Comments
 (0)