Skip to content

Commit 767b181

Browse files
committed
NPA-4474 Change Invalid Value to Invalid Parameter
1 parent b092475 commit 767b181

File tree

8 files changed

+148
-113
lines changed

8 files changed

+148
-113
lines changed

sandbox/api/app.py

Lines changed: 5 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,22 @@
55

66
from .constants import (
77
INTERNAL_SERVER_ERROR_EXAMPLE,
8+
QUESTIONNAIRE_RESPONSE__SUCCESS,
89
RELATED__LIST_RELATIONSHIP,
910
RELATED__LIST_RELATIONSHIP_WITH_INCLUDE,
10-
INVALIDATED_RESOURCE,
11-
QUESTIONNAIRE_RESPONSE__SUCCESS,
1211
RELATED__VERIFY_RELATIONSHIP_09,
13-
RELATED__VERIFY_RELATIONSHIP_25,
1412
RELATED__VERIFY_RELATIONSHIP_09_WITH_INCLUDE,
13+
RELATED__VERIFY_RELATIONSHIP_25,
1514
RELATED__VERIFY_RELATIONSHIP_25_WITH_INCLUDE,
16-
CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP,
17-
CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH,
18-
CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP,
19-
CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH,
20-
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH,
21-
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER,
22-
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT,
23-
CONSENT__MULTIPLE_RELATIONSHIPS,
24-
CONSENT__NO_RELATIONSHIPS,
25-
CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE,
26-
CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE,
27-
CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE,
2815
)
16+
from .get_consent import get_consent_response
2917
from .utils import (
3018
check_for_empty,
31-
check_for_consent_errors,
32-
check_for_related_person_errors,
3319
check_for_list,
20+
check_for_related_person_errors,
3421
check_for_validate,
3522
generate_response_from_example,
3623
remove_system,
37-
check_for_consent_include_params,
38-
check_for_consent_filtering,
3924
)
4025

4126
app = Flask(__name__)
@@ -134,53 +119,4 @@ def get_consent() -> Union[dict, tuple]:
134119
Returns:
135120
Union[dict, tuple]: Response for GET /Consent
136121
"""
137-
try:
138-
# Check Headers
139-
if errors := check_for_consent_errors(request):
140-
return errors
141-
142-
performer_identifier = remove_system(request.args.get("performer:identifier"))
143-
status = request.args.getlist("status")
144-
_include = request.args.getlist("_include")
145-
146-
# Single consenting adult relationship
147-
if performer_identifier == "9000000010":
148-
return check_for_consent_include_params(
149-
_include,
150-
CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP,
151-
CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH,
152-
)
153-
# Single mother child relationship
154-
elif performer_identifier == "9000000019":
155-
return check_for_consent_include_params(
156-
_include,
157-
CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP,
158-
CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH,
159-
)
160-
# Filtering
161-
elif performer_identifier == "9000000017":
162-
return check_for_consent_filtering(
163-
status,
164-
_include,
165-
CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE,
166-
CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE,
167-
CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE,
168-
)
169-
elif performer_identifier == "9000000022":
170-
return check_for_consent_include_params(
171-
_include,
172-
CONSENT__MULTIPLE_RELATIONSHIPS,
173-
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH,
174-
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT,
175-
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER,
176-
)
177-
# No relationships
178-
elif performer_identifier == "9000000025":
179-
return generate_response_from_example(CONSENT__NO_RELATIONSHIPS, 200)
180-
else:
181-
logger.error("Performer identifier does not match examples")
182-
return generate_response_from_example(INVALIDATED_RESOURCE, 404)
183-
184-
except Exception as e:
185-
logger.error(e)
186-
return generate_response_from_example(INTERNAL_SERVER_ERROR_EXAMPLE, 500)
122+
return get_consent_response()

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+
CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE,
8+
CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE,
9+
CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE,
10+
CONSENT__MULTIPLE_RELATIONSHIPS,
11+
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH,
12+
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT,
13+
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER,
14+
CONSENT__NO_RELATIONSHIPS,
15+
CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP,
16+
CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH,
17+
CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP,
18+
CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH,
19+
INTERNAL_SERVER_ERROR_EXAMPLE,
20+
INVALIDATED_RESOURCE,
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+
CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP,
54+
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+
CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP,
61+
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+
CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE,
69+
CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE,
70+
CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE,
71+
)
72+
elif performer_identifier == "9000000022":
73+
return check_for_consent_include_params(
74+
_include,
75+
CONSENT__MULTIPLE_RELATIONSHIPS,
76+
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH,
77+
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT,
78+
CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER,
79+
)
80+
# No relationships
81+
elif performer_identifier == "9000000025":
82+
return generate_response_from_example(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
)
@@ -207,7 +207,7 @@ def test_check_for_related_person_errors(
207207
(
208208
"performer:identifier=90000009990", # Invalid performer identifier
209209
"./api/examples/GET_Consent/errors/invalid-identifier.yaml",
210-
400,
210+
422,
211211
),
212212
(
213213
"", # missing performer identifier
@@ -217,11 +217,11 @@ def test_check_for_related_person_errors(
217217
(
218218
"performer:identifier=https://fhir.nhs.uk/Id/nhs-number|A730675929", # identifier system invalid
219219
"./api/examples/GET_Consent/errors/invalid-identifier-system.yaml",
220-
400,
220+
422,
221221
),
222222
],
223223
)
224-
@patch(f"{FILE_PATH}.generate_response_from_example")
224+
@patch(f"{GET_CONSENT_FILE_PATH}.generate_response_from_example")
225225
def test_check_for_consent_errors(
226226
mock_generate_response_from_example: MagicMock,
227227
request_args: str,

sandbox/api/utils.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
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

99
from .constants import (
10+
BAD_REQUEST_INCLUDE_PARAM_INVALID,
11+
CONSENT__STATUS_PARAM_INVALID,
12+
CONSENT_PATIENT,
13+
CONSENT_PERFORMER,
14+
INCLUDE_FLAG,
15+
INTERNAL_SERVER_ERROR_EXAMPLE,
16+
INVALIDATED_RESOURCE,
17+
PATIENT_IDENTIFIERS,
1018
RELATED__EMPTY_RESPONSE,
11-
RELATED__ERROR_IDENTIFIER_MISSING,
1219
RELATED__ERROR_IDENTIFIER,
20+
RELATED__ERROR_IDENTIFIER_MISSING,
1321
RELATED__ERROR_IDENTIFIER_SYSTEM,
14-
PATIENT_IDENTIFIERS,
15-
INVALIDATED_RESOURCE,
16-
INCLUDE_FLAG,
1722
RELATED_IDENTIFIERS,
18-
CONSENT_PERFORMER,
19-
CONSENT_PATIENT,
20-
INTERNAL_SERVER_ERROR_EXAMPLE,
21-
CONSENT__STATUS_PARAM_INVALID,
22-
BAD_REQUEST_INCLUDE_PARAM_INVALID,
2323
)
2424

2525
FHIR_MIMETYPE = "application/fhir+json"
@@ -92,6 +92,11 @@ def check_for_consent_errors(request: Request) -> Optional[tuple]:
9292
return generate_response_from_example(
9393
f"{GET_CONSENT_ERRORS}/invalid-identifier-system.yaml", 422
9494
)
95+
elif identifier_without_system == "9000000012":
96+
# invalid status
97+
return generate_response_from_example(
98+
f"{GET_CONSENT_ERRORS}/gp-practice-not-found.yaml", 404
99+
)
95100

96101

97102
def check_for_empty(identifier: str, patient_identifier: str) -> Response:
@@ -254,7 +259,7 @@ def check_for_consent_include_params(
254259
):
255260
return generate_response_from_example(include_both_response_yaml, 200)
256261
else:
257-
return generate_response_from_example(BAD_REQUEST_INCLUDE_PARAM_INVALID, 400)
262+
return generate_response_from_example(BAD_REQUEST_INCLUDE_PARAM_INVALID, 422)
258263

259264

260265
def check_for_consent_filtering(
@@ -296,4 +301,4 @@ def check_for_consent_filtering(
296301
status_proposed_and_active_response_yaml, 200
297302
)
298303
else:
299-
return generate_response_from_example(CONSENT__STATUS_PARAM_INVALID, 400)
304+
return generate_response_from_example(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)