Skip to content

Commit 92719e2

Browse files
committed
feature/PI-603-update_spine_mhs_questionnaire refactor spine_mhs questionnaire
1 parent bce830f commit 92719e2

File tree

17 files changed

+596
-542
lines changed

17 files changed

+596
-542
lines changed

src/api/createDeviceMessageHandlingSystem/src/v1/steps.py

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from domain.core.error import ConfigurationError
2121
from domain.core.product_team import ProductTeam
2222
from domain.core.questionnaire import Questionnaire, QuestionnaireResponse
23+
from domain.core.timestamp import now
2324
from domain.repository.device_reference_data_repository import (
2425
DeviceReferenceDataRepository,
2526
)
@@ -39,6 +40,30 @@ def parse_mhs_device_payload(data, cache) -> CreateMhsDeviceIncomingParams:
3940
return CreateMhsDeviceIncomingParams(**payload)
4041

4142

43+
def read_spine_mhs_questionnaire(data, cache) -> Questionnaire:
44+
return QuestionnaireRepository().read(QuestionnaireInstance.SPINE_MHS)
45+
46+
47+
def check_expected_questionnaire_response_fields(data, cache):
48+
spine_mhs_questionnaire: Questionnaire = data[read_spine_mhs_questionnaire]
49+
expected_fields = sorted(spine_mhs_questionnaire.user_provided_fields)
50+
payload: CreateMhsDeviceIncomingParams = data[parse_mhs_device_payload]
51+
spine_mhs_questionnaire_response = payload.questionnaire_responses[
52+
QuestionnaireInstance.SPINE_MHS
53+
]
54+
payload_fields = set(spine_mhs_questionnaire_response.__root__[0].keys())
55+
56+
# Find unexpected fields
57+
unexpected_fields = payload_fields - set(expected_fields)
58+
if unexpected_fields:
59+
raise ConfigurationError(
60+
f"Payload contains unexpected fields: {unexpected_fields}. "
61+
f"Expected fields are: {expected_fields}."
62+
)
63+
# Return questionnaire responses
64+
return spine_mhs_questionnaire_response.__root__[0]
65+
66+
4267
def check_for_existing_mhs(data, cache):
4368
product_team: ProductTeam = data[read_product_team]
4469
product: CpmProduct = data[read_product]
@@ -82,21 +107,41 @@ def read_device_reference_data(data, cache) -> DeviceReferenceData:
82107
return device_reference_data
83108

84109

85-
def read_spine_mhs_questionnaire(data, cache) -> Questionnaire:
86-
return QuestionnaireRepository().read(QuestionnaireInstance.SPINE_MHS)
87-
88-
89-
def validate_spine_mhs_questionnaire_response(data, cache) -> QuestionnaireResponse:
90-
spine_mhs_questionnaire: Questionnaire = data[read_spine_mhs_questionnaire]
91-
payload: CreateMhsDeviceIncomingParams = data[parse_mhs_device_payload]
110+
def generate_spine_mhs_responses(data, cache) -> list:
111+
spine_mhs_questionnaire_responses = data[
112+
check_expected_questionnaire_response_fields
113+
]
92114

93-
spine_mhs_questionnaire_response = payload.questionnaire_responses[
94-
QuestionnaireInstance.SPINE_MHS
115+
missing_fields_used_for_system_generated_fields = [
116+
field
117+
for field in ["Binding", "MHS FQDN"]
118+
if not spine_mhs_questionnaire_responses.get(field)
95119
]
96120

97-
return spine_mhs_questionnaire.validate(
98-
data=spine_mhs_questionnaire_response.__root__[0]
121+
if missing_fields_used_for_system_generated_fields:
122+
raise ConfigurationError(
123+
f"The following required fields are missing in the response to spine_mhs: {', '.join(missing_fields_used_for_system_generated_fields)}"
124+
)
125+
126+
# System generated fields:
127+
spine_mhs_questionnaire_responses["Address"] = (
128+
f"{spine_mhs_questionnaire_responses.get("Binding")}{spine_mhs_questionnaire_responses.get("MHS FQDN")}"
99129
)
130+
spine_mhs_questionnaire_responses["MHS Party key"] = data[get_party_key]
131+
spine_mhs_questionnaire_responses["Managing Organization"] = (
132+
spine_mhs_questionnaire_responses["MHS Party key"].split("-")[0]
133+
)
134+
spine_mhs_questionnaire_responses["Date Approved"] = str(now())
135+
spine_mhs_questionnaire_responses["Date Requested"] = str(now())
136+
spine_mhs_questionnaire_responses["Date DNS Approved"] = str(None)
137+
138+
return spine_mhs_questionnaire_responses
139+
140+
141+
def validate_spine_mhs_questionnaire_response(data, cache) -> QuestionnaireResponse:
142+
spine_mhs_questionnaire: Questionnaire = data[read_spine_mhs_questionnaire]
143+
spine_mhs_response = data[generate_spine_mhs_responses]
144+
return spine_mhs_questionnaire.validate(spine_mhs_response)
100145

101146

102147
def create_mhs_device(data, cache) -> Device:
@@ -173,12 +218,14 @@ def set_http_status(data, cache) -> tuple[HTTPStatus, dict]:
173218
parse_event_body,
174219
parse_path_params,
175220
parse_mhs_device_payload,
221+
read_spine_mhs_questionnaire,
222+
check_expected_questionnaire_response_fields,
176223
read_product_team,
177224
read_product,
178225
get_party_key,
179226
check_for_existing_mhs,
180227
read_device_reference_data,
181-
read_spine_mhs_questionnaire,
228+
generate_spine_mhs_responses,
182229
validate_spine_mhs_questionnaire_response,
183230
create_mhs_device,
184231
create_party_key_tag,

src/api/createDeviceMessageHandlingSystem/tests/test_index.py

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,26 @@
3535
PRODUCT_TEAM_NAME = "My Product Team"
3636
PRODUCT_NAME = "My Product"
3737
VERSION = 1
38+
PARTY_KEY = "ABC1234-987654"
3839

3940
QUESTIONNAIRE_DATA = {
40-
"Address": "http://example.com",
41-
"Unique Identifier": "123456",
42-
"Managing Organization": "Example Org",
43-
"MHS Party key": "party-key-001",
44-
"MHS CPA ID": "cpa-id-001",
45-
"Approver URP": "approver-123",
46-
"Contract Property Template Key": "contract-key-001",
47-
"Date Approved": "2024-01-01",
48-
"Date DNS Approved": "2024-01-02",
49-
"Date Requested": "2024-01-03",
50-
"DNS Approver": "dns-approver-456",
51-
"Interaction Type": "FHIR",
41+
"Binding": "https://",
5242
"MHS FQDN": "mhs.example.com",
53-
"MHS Is Authenticated": "PERSISTENT",
54-
"Product Key": "product-key-001",
55-
"Requestor URP": "requestor-789",
56-
"MHS Manufacturer Organisation": "AAA",
43+
"MHS Service Description": "Example Description",
44+
"MHS Manufacturer Organisation": "F5H1R",
45+
"Product Name": "Product Name",
46+
"Product Version": 1,
47+
"Approver URP": "UI provided",
48+
"DNS Approver": "UI provided",
49+
"Requestor URP": "UI provided",
50+
}
51+
QUESTIONNAIRE_DATA_SYSTEM_GENERATED_FIELDS = {
52+
"Address": "https://mhs.example.com",
53+
"MHS Party key": PARTY_KEY,
54+
"Date Approved": "datetime",
55+
"Date DNS Approved": "None",
56+
"Date Requested": "datetime",
57+
"Managing Organization": "ABC1234",
5758
}
5859

5960

@@ -77,7 +78,7 @@ def mock_epr_product_with_message_set_drd() -> (
7778
product = product_team.create_cpm_product(
7879
name=PRODUCT_NAME, product_id=PRODUCT_ID
7980
)
80-
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value="ABC1234-987654")
81+
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value=PARTY_KEY)
8182
product_repo = CpmProductRepository(
8283
table_name=TABLE_NAME, dynamodb_client=client
8384
)
@@ -215,7 +216,9 @@ def test_index() -> None:
215216
questionnaire_responses = device.questionnaire_responses["spine_mhs/1"]
216217
assert len(questionnaire_responses) == 1
217218
questionnaire_response = questionnaire_responses[0]
218-
assert questionnaire_response.data == QUESTIONNAIRE_DATA
219+
assert len(questionnaire_response.data) == len(QUESTIONNAIRE_DATA) + len(
220+
QUESTIONNAIRE_DATA_SYSTEM_GENERATED_FIELDS
221+
)
219222

220223
# Retrieve the created resource
221224
repo = DeviceRepository(
@@ -299,13 +302,25 @@ def test_incoming_errors(body, path_parameters, error_code, status_code):
299302
(
300303
{
301304
"questionnaire_responses": {
302-
"spine_mhs": [{"Address": "http://example.com"}]
305+
"spine_mhs": [
306+
{"Binding": "https://", "MHS FQDN": "mhs.example.com"}
307+
]
303308
}
304309
},
305310
"MISSING_VALUE",
306311
"Failed to validate data against 'spine_mhs/1': 'MHS Manufacturer Organisation' is a required property",
307312
400,
308313
),
314+
(
315+
{
316+
"questionnaire_responses": {
317+
"spine_mhs": [{"MHS Manufacturer Organisation": "F5H1R"}]
318+
}
319+
},
320+
"VALIDATION_ERROR",
321+
"The following required fields are missing in the response to spine_mhs: Binding, MHS FQDN",
322+
400,
323+
),
309324
],
310325
)
311326
def test_questionnaire_response_validation_errors(

src/api/readDevice/tests/test_index.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,21 +190,16 @@ def test_index_mhs_device(version):
190190
)
191191
spine_mhs_questionnaire_response = mhs_message_set_questionnaire.validate(
192192
data={
193-
"Address": "http://example.com",
194-
"Unique Identifier": "123456",
193+
"Binding": "https://",
194+
"Address": "https://example.com",
195195
"Managing Organization": "Example Org",
196196
"MHS Party key": "party-key-001",
197-
"MHS CPA ID": "cpa-id-001",
198197
"Approver URP": "approver-123",
199-
"Contract Property Template Key": "contract-key-001",
200198
"Date Approved": "2024-01-01",
201199
"Date DNS Approved": "2024-01-02",
202200
"Date Requested": "2024-01-03",
203201
"DNS Approver": "dns-approver-456",
204-
"Interaction Type": "FHIR",
205202
"MHS FQDN": "mhs.example.com",
206-
"MHS Is Authenticated": "PERSISTENT",
207-
"Product Key": "product-key-001",
208203
"Requestor URP": "requestor-789",
209204
"MHS Manufacturer Organisation": "AAA",
210205
}

src/api/readQuestionnaire/tests/test_index.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def test_index():
2626
"name": "spine_mhs",
2727
"version": "1",
2828
}
29-
assert len(json_schema["properties"]) == 25
29+
assert len(json_schema["properties"]) == 16
3030

3131

3232
def test_index_no_such_questionnaire():

0 commit comments

Comments
 (0)