Skip to content

Commit 5ad1474

Browse files
committed
NPA-4474 Change Invalid Value to Invalid Parameter
1 parent 414e8c1 commit 5ad1474

File tree

8 files changed

+140
-105
lines changed

8 files changed

+140
-105
lines changed

sandbox/api/app.py

Lines changed: 5 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,28 @@
44

55
from .constants import (
66
INTERNAL_SERVER_ERROR_EXAMPLE,
7+
QUESTIONNAIRE_RESPONSE__SUCCESS,
78
RELATED__LIST_RELATIONSHIP,
89
RELATED__LIST_RELATIONSHIP_WITH_INCLUDE,
9-
INVALIDATED_RESOURCE,
10-
QUESTIONNAIRE_RESPONSE__SUCCESS,
1110
RELATED__VERIFY_RELATIONSHIP_09,
12-
RELATED__VERIFY_RELATIONSHIP_25,
1311
RELATED__VERIFY_RELATIONSHIP_09_WITH_INCLUDE,
12+
RELATED__VERIFY_RELATIONSHIP_25,
1413
RELATED__VERIFY_RELATIONSHIP_25_WITH_INCLUDE,
15-
GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP,
16-
GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH,
17-
GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP,
18-
GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH,
19-
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH,
20-
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER,
21-
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT,
22-
GET_CONSENT__MULTIPLE_RELATIONSHIPS,
23-
GET_CONSENT__NO_RELATIONSHIPS,
24-
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE,
25-
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE,
26-
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE,
2714
POST_CONSENT__SUCCESS,
2815
POST_CONSENT__DUPLICATE_RELATIONSHIP_ERROR,
2916
POST_CONSENT__INVALID_ACCESS_LEVEL_ERROR,
3017
POST_CONSENT__INVALID_EVIDENCE_ERROR,
3118
POST_CONSENT__INVALID_PATIENT_AGE_ERROR,
3219
POST_CONSENT__PERFORMER_IDENTIFIER_ERROR,
3320
)
21+
from .get_consent import get_consent_response
3422
from .utils import (
3523
check_for_empty,
36-
check_for_consent_errors,
37-
check_for_related_person_errors,
3824
check_for_list,
25+
check_for_related_person_errors,
3926
check_for_validate,
4027
generate_response_from_example,
4128
remove_system,
42-
check_for_consent_include_params,
43-
check_for_consent_filtering,
4429
)
4530

4631
app = Flask(__name__)
@@ -140,57 +125,7 @@ def get_consent() -> Union[dict, tuple]:
140125
Returns:
141126
Union[dict, tuple]: Response for GET /Consent
142127
"""
143-
try:
144-
# Check Headers
145-
if errors := check_for_consent_errors(request):
146-
return errors
147-
148-
performer_identifier = remove_system(request.args.get("performer:identifier"))
149-
status = request.args.getlist("status")
150-
_include = request.args.getlist("_include")
151-
152-
# Single consenting adult relationship
153-
if performer_identifier == "9000000010":
154-
return check_for_consent_include_params(
155-
_include,
156-
GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP,
157-
GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH,
158-
)
159-
# Single mother child relationship
160-
elif performer_identifier == "9000000019":
161-
return check_for_consent_include_params(
162-
_include,
163-
GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP,
164-
GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH,
165-
)
166-
# Filtering
167-
elif performer_identifier == "9000000017":
168-
return check_for_consent_filtering(
169-
status,
170-
_include,
171-
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE,
172-
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE,
173-
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE,
174-
)
175-
elif performer_identifier == "9000000022":
176-
return check_for_consent_include_params(
177-
_include,
178-
GET_CONSENT__MULTIPLE_RELATIONSHIPS,
179-
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH,
180-
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT,
181-
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER,
182-
)
183-
# No relationships
184-
elif performer_identifier == "9000000025":
185-
return generate_response_from_example(GET_CONSENT__NO_RELATIONSHIPS, 200)
186-
else:
187-
logger.error("Performer identifier does not match examples")
188-
return generate_response_from_example(INVALIDATED_RESOURCE, 404)
189-
190-
except Exception:
191-
logger.exception("GET Consent failed")
192-
return generate_response_from_example(INTERNAL_SERVER_ERROR_EXAMPLE, 500)
193-
128+
get_consent_response()
194129

195130
@app.route(f"/{COMMON_PATH}/Consent", methods=["POST"])
196131
def post_consent() -> Union[dict, tuple]:

sandbox/api/get_consent.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from logging import INFO, basicConfig, getLogger
2+
from typing import Union
3+
4+
from flask import request
5+
6+
from .constants import (
7+
INTERNAL_SERVER_ERROR_EXAMPLE,
8+
INVALIDATED_RESOURCE,
9+
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE,
10+
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE,
11+
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE,
12+
GET_CONSENT__MULTIPLE_RELATIONSHIPS,
13+
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH,
14+
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT,
15+
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER,
16+
GET_CONSENT__NO_RELATIONSHIPS,
17+
GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP,
18+
GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH,
19+
GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP,
20+
GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH,
21+
)
22+
from .utils import (
23+
check_for_consent_errors,
24+
check_for_consent_filtering,
25+
check_for_consent_include_params,
26+
generate_response_from_example,
27+
remove_system,
28+
)
29+
30+
basicConfig(level=INFO, format="%(asctime)s - %(message)s")
31+
logger = getLogger(__name__)
32+
33+
34+
def get_consent_response() -> Union[dict, tuple]:
35+
"""Sandbox API for GET /Consent
36+
37+
Returns:
38+
Union[dict, tuple]: Response for GET /Consent
39+
"""
40+
try:
41+
# Check Headers
42+
if errors := check_for_consent_errors(request):
43+
return errors
44+
45+
performer_identifier = remove_system(request.args.get("performer:identifier"))
46+
status = request.args.getlist("status")
47+
_include = request.args.getlist("_include")
48+
49+
# Single consenting adult relationship
50+
if performer_identifier == "9000000010":
51+
return check_for_consent_include_params(
52+
_include,
53+
GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP,
54+
GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH,
55+
)
56+
# Single mother child relationship
57+
elif performer_identifier == "9000000019":
58+
return check_for_consent_include_params(
59+
_include,
60+
GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP,
61+
GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH,
62+
)
63+
# Filtering
64+
elif performer_identifier == "9000000017":
65+
return check_for_consent_filtering(
66+
status,
67+
_include,
68+
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE,
69+
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE,
70+
GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE,
71+
)
72+
elif performer_identifier == "9000000022":
73+
return check_for_consent_include_params(
74+
_include,
75+
GET_CONSENT__MULTIPLE_RELATIONSHIPS,
76+
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH,
77+
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT,
78+
GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER,
79+
)
80+
# No relationships
81+
elif performer_identifier == "9000000025":
82+
return generate_response_from_example(GET_CONSENT__NO_RELATIONSHIPS, 200)
83+
else:
84+
logger.error("Performer identifier does not match examples")
85+
return generate_response_from_example(INVALIDATED_RESOURCE, 404)
86+
87+
except Exception:
88+
logger.exception("An error occurred while processing the request")
89+
return generate_response_from_example(INTERNAL_SERVER_ERROR_EXAMPLE, 500)

sandbox/api/tests/test_utils.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
from flask import Response
66

77
from ..utils import load_json_file
8-
from .conftest import RELATED_PERSON_API_ENDPOINT, CONSENT_API_ENDPOINT
8+
from .conftest import CONSENT_API_ENDPOINT, RELATED_PERSON_API_ENDPOINT
99

1010
FILE_PATH = "sandbox.api.utils"
11-
11+
GET_CONSENT_FILE_PATH = "sandbox.api.get_consent"
1212

1313
@pytest.mark.parametrize(
1414
"request_args,response_file_name,status_code",
@@ -114,12 +114,12 @@ def test_related_person__not_found(
114114
(
115115
"performer:identifier=9000000017&status=test", # Invalid status parameter error
116116
"./api/examples/GET_Consent/errors/invalid-status-parameter.yaml",
117-
400,
117+
422,
118118
),
119119
(
120120
"performer:identifier=9000000019&_include=test", # Invalid include parameter error
121121
"./api/examples/errors/invalid-include-parameter.yaml",
122-
400,
122+
422,
123123
),
124124
],
125125
)
@@ -205,7 +205,7 @@ def test_check_for_related_person_errors(
205205
(
206206
"performer:identifier=90000009990", # Invalid performer identifier
207207
"./api/examples/GET_Consent/errors/invalid-identifier.yaml",
208-
400,
208+
422,
209209
),
210210
(
211211
"", # missing performer identifier
@@ -215,11 +215,11 @@ def test_check_for_related_person_errors(
215215
(
216216
"performer:identifier=https://fhir.nhs.uk/Id/nhs-number|A730675929", # identifier system invalid
217217
"./api/examples/GET_Consent/errors/invalid-identifier-system.yaml",
218-
400,
218+
422,
219219
),
220220
],
221221
)
222-
@patch(f"{FILE_PATH}.generate_response_from_example")
222+
@patch(f"{GET_CONSENT_FILE_PATH}.generate_response_from_example")
223223
def test_check_for_consent_errors(
224224
mock_generate_response_from_example: MagicMock,
225225
request_args: str,

sandbox/api/utils.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from logging import getLogger
21
from json import dumps, load
3-
from typing import Any, Optional, List
2+
from logging import getLogger
3+
from typing import Any, List, Optional
44

5-
from flask import Response, Request
5+
from flask import Request, Response
66
from yaml import CLoader as Loader
77
from yaml import load as yaml_load
88

@@ -20,6 +20,7 @@
2020
INTERNAL_SERVER_ERROR_EXAMPLE,
2121
GET_CONSENT__STATUS_PARAM_INVALID,
2222
BAD_REQUEST_INCLUDE_PARAM_INVALID,
23+
CONSENT__STATUS_PARAM_INVALID,
2324
)
2425

2526
FHIR_MIMETYPE = "application/fhir+json"
@@ -89,6 +90,11 @@ def check_for_consent_errors(request: Request) -> Optional[tuple]:
8990
"./api/examples/GET_Consent/errors/invalid-identifier-system.yaml",
9091
400,
9192
)
93+
elif identifier_without_system == "9000000012":
94+
# invalid status
95+
return generate_response_from_example(
96+
f"{GET_CONSENT_ERRORS}/gp-practice-not-found.yaml", 404
97+
)
9298

9399

94100
def check_for_empty(identifier: str, patient_identifier: str) -> Response:
@@ -250,7 +256,7 @@ def check_for_consent_include_params(
250256
elif len(_include) == 2 and CONSENT_PATIENT in _include and CONSENT_PERFORMER in _include:
251257
return generate_response_from_example(include_both_response_yaml, 200)
252258
else:
253-
return generate_response_from_example(BAD_REQUEST_INCLUDE_PARAM_INVALID, 400)
259+
return generate_response_from_example(BAD_REQUEST_INCLUDE_PARAM_INVALID, 422)
254260

255261

256262
def check_for_consent_filtering(
@@ -284,4 +290,4 @@ def check_for_consent_filtering(
284290
elif len(status) == 2 and "active" in status and "proposed" in status:
285291
return generate_response_from_example(status_proposed_and_active_response_yaml, 200)
286292
else:
287-
return generate_response_from_example(GET_CONSENT__STATUS_PARAM_INVALID, 400)
293+
return generate_response_from_example(GET_CONSENT__STATUS_PARAM_INVALID, 422)

specification/examples/responses/GET_Consent/errors/invalid-identifier-system.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
ConsentInvalidIdentifierSystemError:
2-
summary: Bad request identifier system invalid
2+
summary: Identifier system invalid
33
description: 422 error response bundle for an invalid system of the identifier
44
value:
55
issue:

specification/examples/responses/GET_Consent/errors/invalid-identifier.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
ConsentInvalidIdentifierError:
2-
summary: Bad request invalid identifier
2+
summary: Invalid identifier
33
description: Error raised due to an invalid identifier request parameter being specified.
44
value:
55
issue:

specification/examples/responses/GET_Consent/errors/invalid-status-parameter.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
ConsentInvalidStatusParameterError:
2-
summary: Bad request status param invalid
2+
summary: status parameter invalid
33
description: 422 error response bundle for an invalid status parameter
44
value:
55
issue:
66
- code: invalid
77
diagnostics: "Invalid request with error - status parameter is invalid."
88
details:
99
coding:
10-
- code: "INVALID_VALUE"
10+
- code: "INVALID_PARAMETER"
1111
display: "Required parameter(s) are invalid."
1212
system: "https://fhir.nhs.uk/R4/CodeSystem/ValidatedRelationships-ErrorOrWarningCode"
1313
version: "1"

0 commit comments

Comments
 (0)