Skip to content

Commit 0517252

Browse files
committed
feature/PI-645-update_spine_mhs_message_sets_questionnaire Create generic questionnaire response validation, including system generated fields generator and refactor spine_mhs and spine_mhs_message_sets questionnaires
1 parent c019d11 commit 0517252

38 files changed

+4134
-1755
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,21 +247,21 @@ Executing feature tests in integration mode will then give you confidence that t
247247
To execute the feature tests entirely locally (executing lambdas directly, and otherwise mocking databases and responses to a high standard) you can do:
248248

249249
```shell
250-
make test--feature-local
250+
make test--feature--local
251251
```
252252

253253
If you would like to pass `behave` flags, e.g. to \[stop after the first failure\]:
254254

255255
```shell
256-
make test--feature-local BEHAVE_FLAGS="--stop"
256+
make test--feature--local BEHAVE_FLAGS="--stop"
257257
```
258258

259259
#### Integration
260260

261261
To execute the feature tests across the entire stack (including Apigee and AWS) you can do
262262

263263
```shell
264-
make test--feature-integration
264+
make test--feature--integration
265265
```
266266

267267
### Generate the Feature Test Postman collection

src/api/createDeviceAccreditedSystem/tests/test_index.py

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

3940
QUESTIONNAIRE_DATA = {
4041
"ODS Code": "FH15R",
@@ -69,7 +70,7 @@ def mock_epr_product_with_one_message_set_drd() -> (
6970
product = product_team.create_cpm_product(
7071
name=PRODUCT_NAME, product_id=PRODUCT_ID
7172
)
72-
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value="ABC1234-987654")
73+
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value=PARTY_KEY)
7374
product_repo = CpmProductRepository(
7475
table_name=TABLE_NAME, dynamodb_client=client
7576
)
@@ -79,10 +80,22 @@ def mock_epr_product_with_one_message_set_drd() -> (
7980
QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS
8081
)
8182
questionnaire_response_1 = mhs_message_set_questionnaire.validate(
82-
data={"Interaction ID": "urn:foo1", "MHS SN": "bar", "MHS IN": "baz"}
83+
data={
84+
"Interaction ID": "bar:baz",
85+
"MHS SN": "bar",
86+
"MHS IN": "baz",
87+
"MHS CPA ID": f"{PARTY_KEY}:bar:baz",
88+
"Unique Identifier": f"{PARTY_KEY}:bar:baz",
89+
}
8390
)
8491
questionnaire_response_2 = mhs_message_set_questionnaire.validate(
85-
data={"Interaction ID": "urn:foo2", "MHS SN": "bar2", "MHS IN": "baz2"}
92+
data={
93+
"Interaction ID": "bar2:baz2",
94+
"MHS SN": "bar2",
95+
"MHS IN": "baz2",
96+
"MHS CPA ID": f"{PARTY_KEY}:bar2:baz2",
97+
"Unique Identifier": f"{PARTY_KEY}:bar2:baz2",
98+
}
8699
)
87100

88101
# Set up DeviceReferenceData in DB
@@ -124,7 +137,7 @@ def mock_epr_product_with_message_sets_drd() -> (
124137
product = product_team.create_cpm_product(
125138
name=PRODUCT_NAME, product_id=PRODUCT_ID
126139
)
127-
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value="ABC1234-987654")
140+
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value=PARTY_KEY)
128141
product_repo = CpmProductRepository(
129142
table_name=TABLE_NAME, dynamodb_client=client
130143
)
@@ -135,10 +148,22 @@ def mock_epr_product_with_message_sets_drd() -> (
135148
)
136149

137150
questionnaire_response_1 = mhs_message_set_questionnaire.validate(
138-
data={"Interaction ID": "urn:foo1", "MHS SN": "bar", "MHS IN": "baz"}
151+
data={
152+
"Interaction ID": "bar:baz",
153+
"MHS SN": "bar",
154+
"MHS IN": "baz",
155+
"MHS CPA ID": f"{PARTY_KEY}:bar:baz",
156+
"Unique Identifier": f"{PARTY_KEY}:bar:baz",
157+
}
139158
)
140159
questionnaire_response_2 = mhs_message_set_questionnaire.validate(
141-
data={"Interaction ID": "urn:foo2", "MHS SN": "bar2", "MHS IN": "baz2"}
160+
data={
161+
"Interaction ID": "bar2:baz2",
162+
"MHS SN": "bar2",
163+
"MHS IN": "baz2",
164+
"MHS CPA ID": f"{PARTY_KEY}:bar2:baz2",
165+
"Unique Identifier": f"{PARTY_KEY}:bar2:baz2",
166+
}
142167
)
143168
# Set up DeviceReferenceData in DB
144169
device_reference_data_mhs = product.create_device_reference_data(
@@ -197,7 +222,7 @@ def mock_epr_product_with_more_than_two_message_sets_drd() -> (
197222
product = product_team.create_cpm_product(
198223
name=PRODUCT_NAME, product_id=PRODUCT_ID
199224
)
200-
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value="ABC1234-987654")
225+
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value=PARTY_KEY)
201226
product_repo = CpmProductRepository(
202227
table_name=TABLE_NAME, dynamodb_client=client
203228
)
@@ -207,10 +232,22 @@ def mock_epr_product_with_more_than_two_message_sets_drd() -> (
207232
QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS
208233
)
209234
questionnaire_response_1 = mhs_message_set_questionnaire_1.validate(
210-
data={"Interaction ID": "urn:foo1", "MHS SN": "bar", "MHS IN": "baz"}
235+
data={
236+
"Interaction ID": "bar:baz",
237+
"MHS SN": "bar",
238+
"MHS IN": "baz",
239+
"MHS CPA ID": f"{PARTY_KEY}:bar:baz",
240+
"Unique Identifier": f"{PARTY_KEY}:bar:baz",
241+
}
211242
)
212243
questionnaire_response_2 = mhs_message_set_questionnaire_1.validate(
213-
data={"Interaction ID": "urn:foo2", "MHS SN": "bar2", "MHS IN": "baz2"}
244+
data={
245+
"Interaction ID": "bar2:baz2",
246+
"MHS SN": "bar2",
247+
"MHS IN": "baz2",
248+
"MHS CPA ID": f"{PARTY_KEY}:bar2:baz2",
249+
"Unique Identifier": f"{PARTY_KEY}:bar2:baz2",
250+
}
214251
)
215252

216253
# Set up DeviceReferenceData in DB
@@ -224,10 +261,22 @@ def mock_epr_product_with_more_than_two_message_sets_drd() -> (
224261
QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS
225262
)
226263
questionnaire_response_3 = mhs_message_set_questionnaire_2.validate(
227-
data={"Interaction ID": "urn:foo3", "MHS SN": "bar3", "MHS IN": "baz3"}
264+
data={
265+
"Interaction ID": "bar3:baz3",
266+
"MHS SN": "bar3",
267+
"MHS IN": "baz3",
268+
"MHS CPA ID": f"{PARTY_KEY}:bar3:baz3",
269+
"Unique Identifier": f"{PARTY_KEY}:bar3:baz3",
270+
}
228271
)
229272
questionnaire_response_4 = mhs_message_set_questionnaire_2.validate(
230-
data={"Interaction ID": "urn:foo4", "MHS SN": "bar4", "MHS IN": "baz4"}
273+
data={
274+
"Interaction ID": "bar4:baz4",
275+
"MHS SN": "bar4",
276+
"MHS IN": "baz4",
277+
"MHS CPA ID": f"{PARTY_KEY}:bar4:baz4",
278+
"Unique Identifier": f"{PARTY_KEY}:bar4:baz4",
279+
}
231280
)
232281

233282
# Set up DeviceReferenceData in DB
@@ -287,7 +336,7 @@ def mock_epr_product_with_two_message_sets_the_same_drd() -> (
287336
product = product_team.create_cpm_product(
288337
name=PRODUCT_NAME, product_id=PRODUCT_ID
289338
)
290-
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value="ABC1234-987654")
339+
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value=PARTY_KEY)
291340
product_repo = CpmProductRepository(
292341
table_name=TABLE_NAME, dynamodb_client=client
293342
)
@@ -297,10 +346,22 @@ def mock_epr_product_with_two_message_sets_the_same_drd() -> (
297346
QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS
298347
)
299348
questionnaire_response_1 = mhs_message_set_questionnaire_1.validate(
300-
data={"Interaction ID": "urn:foo1", "MHS SN": "bar", "MHS IN": "baz"}
349+
data={
350+
"Interaction ID": "bar:baz",
351+
"MHS SN": "bar",
352+
"MHS IN": "baz",
353+
"MHS CPA ID": f"{PARTY_KEY}:bar:baz",
354+
"Unique Identifier": f"{PARTY_KEY}:bar:baz",
355+
}
301356
)
302357
questionnaire_response_2 = mhs_message_set_questionnaire_1.validate(
303-
data={"Interaction ID": "urn:foo2", "MHS SN": "bar2", "MHS IN": "baz2"}
358+
data={
359+
"Interaction ID": "bar2:baz2",
360+
"MHS SN": "ba2r",
361+
"MHS IN": "baz2",
362+
"MHS CPA ID": f"{PARTY_KEY}:bar2:baz2",
363+
"Unique Identifier": f"{PARTY_KEY}:bar2:baz2",
364+
}
304365
)
305366

306367
# Set up DeviceReferenceData in DB
@@ -314,10 +375,22 @@ def mock_epr_product_with_two_message_sets_the_same_drd() -> (
314375
QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS
315376
)
316377
questionnaire_response_3 = mhs_message_set_questionnaire_2.validate(
317-
data={"Interaction ID": "urn:foo3", "MHS SN": "bar3", "MHS IN": "baz3"}
378+
data={
379+
"Interaction ID": "bar3:baz3",
380+
"MHS SN": "bar3",
381+
"MHS IN": "baz3",
382+
"MHS CPA ID": f"{PARTY_KEY}:bar3:baz3",
383+
"Unique Identifier": f"{PARTY_KEY}:bar3:baz3",
384+
}
318385
)
319386
questionnaire_response_4 = mhs_message_set_questionnaire_2.validate(
320-
data={"Interaction ID": "urn:foo4", "MHS SN": "bar4", "MHS IN": "baz4"}
387+
data={
388+
"Interaction ID": "bar4:baz4",
389+
"MHS SN": "bar4",
390+
"MHS IN": "baz4",
391+
"MHS CPA ID": f"{PARTY_KEY}:bar4:baz4",
392+
"Unique Identifier": f"{PARTY_KEY}:bar4:baz4",
393+
}
321394
)
322395

323396
# Set up DeviceReferenceData in DB
@@ -390,7 +463,7 @@ def mock_epr_product_without_message_set_drd() -> (
390463
product = product_team.create_cpm_product(
391464
name=PRODUCT_NAME, product_id=PRODUCT_ID
392465
)
393-
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value="ABC1234-987654")
466+
product.add_key(key_type=ProductKeyType.PARTY_KEY, key_value=PARTY_KEY)
394467
product_repo = CpmProductRepository(
395468
table_name=TABLE_NAME, dynamodb_client=client
396469
)
@@ -449,7 +522,7 @@ def test_index() -> None:
449522
)
450523

451524
# Check party_key is added to tags in the created device
452-
expected_party_key = (str(ProductKeyType.PARTY_KEY), "abc1234-987654")
525+
expected_party_key = (str(ProductKeyType.PARTY_KEY), PARTY_KEY.lower())
453526
assert any(expected_party_key in tag.__root__ for tag in created_device.tags)
454527

455528
# Check an ASID is generated and added to the keys.

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

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
from http import HTTPStatus
22

33
from domain.api.common_steps.general import parse_event_body
4+
from domain.api.common_steps.questionnaire_response_validation import (
5+
process_and_validate_questionnaire_response,
6+
)
47
from domain.api.common_steps.read_product import (
58
get_party_key,
69
parse_path_params,
@@ -77,7 +80,7 @@ def read_device_reference_data(data, cache) -> DeviceReferenceData:
7780
)
7881
except ValueError:
7982
raise ConfigurationError(
80-
"You must configure exactly one MessageSet Device Reference Data before creating an MHS Device"
83+
"You must configure exactly one MessageSet Device Reference Data before creating an MHS Device."
8184
)
8285
return device_reference_data
8386

@@ -87,16 +90,26 @@ def read_spine_mhs_questionnaire(data, cache) -> Questionnaire:
8790

8891

8992
def validate_spine_mhs_questionnaire_response(data, cache) -> QuestionnaireResponse:
90-
spine_mhs_questionnaire: Questionnaire = data[read_spine_mhs_questionnaire]
93+
questionnaire: Questionnaire = data[read_spine_mhs_questionnaire]
9194
payload: CreateMhsDeviceIncomingParams = data[parse_mhs_device_payload]
92-
93-
spine_mhs_questionnaire_response = payload.questionnaire_responses[
95+
raw_questionnaire_responses = payload.questionnaire_responses[
9496
QuestionnaireInstance.SPINE_MHS
9597
]
9698

97-
return spine_mhs_questionnaire.validate(
98-
data=spine_mhs_questionnaire_response.__root__[0]
99-
)
99+
if len(raw_questionnaire_responses) != 1:
100+
raise ConfigurationError(
101+
"You must provide exactly one spine_mhs questionnaire response to create an MHS Device."
102+
)
103+
party_key = data[get_party_key]
104+
105+
validated_responses = [
106+
process_and_validate_questionnaire_response(
107+
questionnaire, qr, party_key, instance=QuestionnaireInstance.SPINE_MHS
108+
)
109+
for qr in raw_questionnaire_responses
110+
]
111+
112+
return validated_responses
100113

101114

102115
def create_mhs_device(data, cache) -> Device:
@@ -118,20 +131,18 @@ def create_party_key_tag(data, cache) -> DeviceTagAddedEvent:
118131

119132
def create_cpa_id_keys(data, cache) -> DeviceKeyAddedEvent:
120133
mhs_device: Device = data[create_mhs_device]
121-
party_key = data[get_party_key]
122134
drd: DeviceReferenceData = data[read_device_reference_data]
123135

124136
questionnaire_responses = drd.questionnaire_responses.get(
125137
f"{QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS}/1", []
126138
)
127139

128-
interaction_ids = [
129-
response.data.get(SdsFieldName.INTERACTION_ID)
130-
for response in questionnaire_responses
140+
cpa_ids = [
141+
response.data.get(SdsFieldName.CPA_ID) for response in questionnaire_responses
131142
]
132143

133-
for id in interaction_ids:
134-
mhs_device.add_key(key_type=DeviceKeyType.CPA_ID, key_value=f"{party_key}:{id}")
144+
for id in cpa_ids:
145+
mhs_device.add_key(key_type=DeviceKeyType.CPA_ID, key_value=id)
135146

136147
return mhs_device
137148

@@ -148,12 +159,13 @@ def add_device_reference_data_id(data, cache) -> DeviceReferenceDataIdAddedEvent
148159
def add_spine_mhs_questionnaire_response(
149160
data, cache
150161
) -> QuestionnaireResponseUpdatedEvent:
151-
spine_mhs_questionnaire_response: QuestionnaireResponse = data[
162+
spine_mhs_questionnaire_response: list[QuestionnaireResponse] = data[
152163
validate_spine_mhs_questionnaire_response
153164
]
154165
mhs_device: Device = data[create_mhs_device]
155166

156-
return mhs_device.add_questionnaire_response(spine_mhs_questionnaire_response)
167+
for qr in spine_mhs_questionnaire_response:
168+
mhs_device.add_questionnaire_response(qr)
157169

158170

159171
def write_device(data: dict[str, Device], cache) -> Device:
@@ -177,8 +189,8 @@ def set_http_status(data, cache) -> tuple[HTTPStatus, dict]:
177189
read_product,
178190
get_party_key,
179191
check_for_existing_mhs,
180-
read_device_reference_data,
181192
read_spine_mhs_questionnaire,
193+
read_device_reference_data,
182194
validate_spine_mhs_questionnaire_response,
183195
create_mhs_device,
184196
create_party_key_tag,

0 commit comments

Comments
 (0)