Skip to content

Commit 32f233e

Browse files
committed
Merge branch 'feature/PI-582-modify_readdevice_endpoint_for_mhs' into release/2024-11-27
2 parents d9c7144 + d1f955e commit 32f233e

File tree

7 files changed

+366
-25
lines changed

7 files changed

+366
-25
lines changed

src/api/createDeviceMessageHandlingSystem/tests/test_index.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def mock_epr_product_with_message_set_drd() -> (
8181
)
8282
product_repo.write(entity=product)
8383

84-
# set up questionnaire response
84+
# set up questionnaire responses
8585
mhs_message_set_questionnaire = QuestionnaireRepository().read(
8686
QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS
8787
)
@@ -92,7 +92,6 @@ def mock_epr_product_with_message_set_drd() -> (
9292
"MHS IN": "baz",
9393
}
9494
)
95-
9695
questionnaire_response_2 = mhs_message_set_questionnaire.validate(
9796
data={
9897
"Interaction ID": "urn:foo2",
@@ -375,4 +374,42 @@ def test_no_existing_message_set_drd():
375374
assert expected_message_code in response["body"]
376375

377376

378-
# add test for already existing mhs device?
377+
def test_mhs_already_exists() -> None:
378+
with mock_epr_product_with_message_set_drd() as (index, product):
379+
# Execute the lambda
380+
response = index.handler(
381+
event={
382+
"headers": {"version": VERSION},
383+
"body": json.dumps(
384+
{"questionnaire_responses": {"spine_mhs": [QUESTIONNAIRE_DATA]}}
385+
),
386+
"pathParameters": {
387+
"product_team_id": str(product.product_team_id),
388+
"product_id": str(product.id),
389+
},
390+
}
391+
)
392+
393+
assert response["statusCode"] == 201
394+
395+
# Execute the lambda again
396+
response = index.handler(
397+
event={
398+
"headers": {"version": VERSION},
399+
"body": json.dumps(
400+
{"questionnaire_responses": {"spine_mhs": [QUESTIONNAIRE_DATA]}}
401+
),
402+
"pathParameters": {
403+
"product_team_id": str(product.product_team_id),
404+
"product_id": str(product.id),
405+
},
406+
}
407+
)
408+
409+
assert response["statusCode"] == 400
410+
expected_error_code = "VALIDATION_ERROR"
411+
expected_message_code = (
412+
"There is already an existing MHS Device for this Product"
413+
)
414+
assert expected_error_code in response["body"]
415+
assert expected_message_code in response["body"]

src/api/readDevice/src/v1/steps.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent
44
from domain.core.cpm_product import CpmProduct
55
from domain.core.device import Device
6+
from domain.core.device_reference_data import DeviceReferenceData
67
from domain.core.product_team import ProductTeam
78
from domain.repository.cpm_product_repository import CpmProductRepository
9+
from domain.repository.device_reference_data_repository import (
10+
DeviceReferenceDataRepository,
11+
)
812
from domain.repository.device_repository import DeviceRepository
913
from domain.repository.product_team_repository import ProductTeamRepository
1014
from domain.request_models import DevicePathParams
@@ -54,6 +58,39 @@ def read_device(data, cache) -> Device:
5458
)
5559

5660

61+
def read_device_reference_data(data, cache) -> list[DeviceReferenceData]:
62+
product_team: ProductTeam = data[read_product_team]
63+
product: CpmProduct = data[read_product]
64+
device: Device = data[read_device]
65+
66+
device_reference_datas = []
67+
device_reference_data_repo = DeviceReferenceDataRepository(
68+
table_name=cache["DYNAMODB_TABLE"], dynamodb_client=cache["DYNAMODB_CLIENT"]
69+
)
70+
for id in device.device_reference_data:
71+
drd = device_reference_data_repo.read(
72+
product_team_id=product_team.id,
73+
product_id=product.id,
74+
id=id,
75+
)
76+
device_reference_datas.append(drd)
77+
78+
return device_reference_datas
79+
80+
81+
def update_device_with_device_reference_data(data, cache) -> Device:
82+
device: Device = data[read_device]
83+
device_reference_datas = data[read_device_reference_data]
84+
85+
[
86+
device.questionnaire_responses.setdefault(key, []).extend(responses)
87+
for drd in device_reference_datas
88+
for key, responses in drd.questionnaire_responses.items()
89+
]
90+
91+
return device
92+
93+
5794
def device_to_dict(data, cache) -> tuple[str, dict]:
5895
device: Device = data[read_device]
5996
return HTTPStatus.OK, device.state()
@@ -64,5 +101,7 @@ def device_to_dict(data, cache) -> tuple[str, dict]:
64101
read_product_team,
65102
read_product,
66103
read_device,
104+
read_device_reference_data,
105+
update_device_with_device_reference_data,
67106
device_to_dict,
68107
]

src/api/readDevice/tests/test_index.py

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,20 @@
33
from unittest import mock
44

55
import pytest
6+
from domain.core.device import Device
7+
from domain.core.enum import Status
8+
from domain.core.product_key import ProductKeyType
69
from domain.core.root import Root
710
from domain.repository.cpm_product_repository import CpmProductRepository
11+
from domain.repository.device_reference_data_repository import (
12+
DeviceReferenceDataRepository,
13+
)
814
from domain.repository.device_repository import DeviceRepository
915
from domain.repository.product_team_repository import ProductTeamRepository
16+
from domain.repository.questionnaire_repository import (
17+
QuestionnaireInstance,
18+
QuestionnaireRepository,
19+
)
1020
from event.json import json_loads
1121

1222
from test_helpers.dynamodb import mock_table
@@ -102,6 +112,157 @@ def test_index(version):
102112
assert result["headers"][key] == value
103113

104114

115+
@pytest.mark.parametrize(
116+
"version",
117+
[
118+
"1",
119+
],
120+
)
121+
def test_index_mhs_device(version):
122+
org = Root.create_ods_organisation(ods_code=ODS_CODE)
123+
product_team = org.create_product_team(
124+
name=PRODUCT_TEAM_NAME, keys=PRODUCT_TEAM_KEYS
125+
)
126+
127+
with mock_table(TABLE_NAME) as client, mock.patch.dict(
128+
os.environ,
129+
{
130+
"DYNAMODB_TABLE": TABLE_NAME,
131+
"AWS_DEFAULT_REGION": "eu-west-2",
132+
},
133+
clear=True,
134+
):
135+
# Set up ProductTeam in DB
136+
product_team_repo = ProductTeamRepository(
137+
table_name=TABLE_NAME, dynamodb_client=client
138+
)
139+
product_team_repo.write(entity=product_team)
140+
141+
# Set up EPR Product in DB
142+
cpm_product = product_team.create_cpm_product(
143+
name=PRODUCT_NAME, product_id=PRODUCT_ID
144+
)
145+
cpm_product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value="F5H1R-850000")
146+
product_repo = CpmProductRepository(
147+
table_name=TABLE_NAME, dynamodb_client=client
148+
)
149+
product_repo.write(cpm_product)
150+
151+
# set up mhs message set questionnaire responses
152+
mhs_message_set_questionnaire = QuestionnaireRepository().read(
153+
QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS
154+
)
155+
questionnaire_response = mhs_message_set_questionnaire.validate(
156+
data={
157+
"Interaction ID": "urn:foo",
158+
"MHS SN": "bar",
159+
"MHS IN": "baz",
160+
}
161+
)
162+
questionnaire_response_2 = mhs_message_set_questionnaire.validate(
163+
data={
164+
"Interaction ID": "urn:foo2",
165+
"MHS SN": "bar2",
166+
"MHS IN": "baz2",
167+
},
168+
)
169+
170+
# Set up DeviceReferenceData in DB
171+
device_reference_data = cpm_product.create_device_reference_data(
172+
name="ABC1234-987654 - MHS Message Set"
173+
)
174+
device_reference_data.add_questionnaire_response(questionnaire_response)
175+
device_reference_data.add_questionnaire_response(questionnaire_response_2)
176+
device_reference_data_repo = DeviceReferenceDataRepository(
177+
table_name=TABLE_NAME, dynamodb_client=client
178+
)
179+
device_reference_data_repo.write(device_reference_data)
180+
181+
# Set up Device in DB
182+
device: Device = cpm_product.create_device(name="Product-MHS")
183+
device.add_key(key_type="interaction_id", key_value="F5H1R-850000:urn:foo")
184+
device.add_key(key_type="interaction_id", key_value="F5H1R-850000:urn:foo2")
185+
device.add_tag(party_key="f5h1r-850000")
186+
187+
# set up spine mhs questionnaire response
188+
mhs_message_set_questionnaire = QuestionnaireRepository().read(
189+
QuestionnaireInstance.SPINE_MHS
190+
)
191+
spine_mhs_questionnaire_response = mhs_message_set_questionnaire.validate(
192+
data={
193+
"Address": "http://example.com",
194+
"Unique Identifier": "123456",
195+
"Managing Organization": "Example Org",
196+
"MHS Party key": "party-key-001",
197+
"MHS CPA ID": "cpa-id-001",
198+
"Approver URP": "approver-123",
199+
"Contract Property Template Key": "contract-key-001",
200+
"Date Approved": "2024-01-01",
201+
"Date DNS Approved": "2024-01-02",
202+
"Date Requested": "2024-01-03",
203+
"DNS Approver": "dns-approver-456",
204+
"Interaction Type": "FHIR",
205+
"MHS FQDN": "mhs.example.com",
206+
"MHS Is Authenticated": "PERSISTENT",
207+
"Product Key": "product-key-001",
208+
"Requestor URP": "requestor-789",
209+
}
210+
)
211+
device.add_questionnaire_response(spine_mhs_questionnaire_response)
212+
213+
device.add_device_reference_data_id(
214+
device_reference_data_id=str(device_reference_data.id), path_to_data=["*"]
215+
)
216+
217+
device_repo = DeviceRepository(table_name=TABLE_NAME, dynamodb_client=client)
218+
device_repo.write(device)
219+
220+
from api.readDevice.index import handler
221+
222+
result = handler(
223+
event={
224+
"headers": {"version": version},
225+
"pathParameters": {
226+
"product_team_id": str(product_team.id),
227+
"product_id": str(cpm_product.id.id),
228+
"device_id": str(device.id),
229+
},
230+
}
231+
)
232+
233+
response_body = json_loads(result["body"])
234+
235+
# Assertions for fields that must exactly match
236+
assert response_body["id"] == str(device.id)
237+
assert response_body["product_id"] == str(cpm_product.id)
238+
assert response_body["product_team_id"] == str(product_team.id)
239+
assert response_body["name"] == device.name
240+
assert response_body["ods_code"] == device.ods_code
241+
assert response_body["status"] == Status.ACTIVE
242+
assert response_body["deleted_on"] is None
243+
assert response_body["keys"] is not None
244+
assert response_body["tags"] is not None
245+
assert response_body["device_reference_data"] is not None
246+
247+
# Assertions for fields that only need to be included
248+
assert "created_on" in response_body
249+
assert "spine_mhs/1" in response_body["questionnaire_responses"]
250+
251+
# Assert drd questionnaire responses have been added
252+
assert "spine_mhs_message_sets/1" in response_body["questionnaire_responses"]
253+
254+
expected_headers = {
255+
"Content-Type": "application/json",
256+
"Version": version,
257+
}
258+
259+
# Check response headers
260+
assert result["statusCode"] == 200
261+
assert result["headers"]["Content-Length"] == str(len(result["body"]))
262+
for key, value in expected_headers.items():
263+
assert result["headers"][key] == value
264+
265+
105266
@pytest.mark.parametrize(
106267
"version",
107268
[

src/api/tests/feature_tests/features/createDeviceMessageHandlingSystem.failure.feature

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,17 @@ Feature: Create MHS Device - failure scenarios
255255
| path | value |
256256
| name | My Great Product |
257257
And I note the response field "$.id" as "product_id"
258-
And I note the response field "$.keys.0.key_type" as "party_key_tag"
259-
And I note the response field "$.keys.0.key_value" as "party_key_value"
260-
And I have already made a "POST" request with "default" headers to "ProductTeam/${ note(product_team_id) }/Product/${ note(product_id) }/DeviceReferenceData/MhsMessageSet"
258+
And I have already made a "POST" request with "default" headers to "ProductTeam/${ note(product_team_id) }/Product/${ note(product_id) }/DeviceReferenceData/MhsMessageSet" with body:
259+
| path | value |
260+
| questionnaire_responses.spine_mhs_message_sets.0.Interaction ID | urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001 |
261+
| questionnaire_responses.spine_mhs_message_sets.0.MHS SN | urn:nhs:names:services:ers |
262+
| questionnaire_responses.spine_mhs_message_sets.0.MHS IN | READ_PRACTITIONER_ROLE_R4_V001 |
263+
| questionnaire_responses.spine_mhs_message_sets.1.Interaction ID | urn:nhs:names:services:ebs:PRSC_IN080000UK07 |
264+
| questionnaire_responses.spine_mhs_message_sets.1.MHS SN | urn:nhs:names:services:ebs |
265+
| questionnaire_responses.spine_mhs_message_sets.1.MHS IN | PRSC_IN080000UK07 |
266+
| questionnaire_responses.spine_mhs_message_sets.1.Reliability Configuration Retry Interval | PT1M |
267+
| questionnaire_responses.spine_mhs_message_sets.1.Reliability Configuration Retries | ${ integer(2) } |
268+
| questionnaire_responses.spine_mhs_message_sets.1.Reliability Configuration Persist Duration | PT10M |
261269
And I note the response field "$.id" as "message_set_drd_id"
262270
And I have already made a "POST" request with "default" headers to "ProductTeam/${ note(product_team_id) }/Product/${ note(product_id) }/Device/MessageHandlingSystem" with body:
263271
| path | value |

0 commit comments

Comments
 (0)