Skip to content

Commit 75175ad

Browse files
committed
NPA-3887 Handle System and fix error messages
1 parent f1cbcea commit 75175ad

File tree

6 files changed

+74
-18
lines changed

6 files changed

+74
-18
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ smoketest-report.xml
1919
env
2020
.dir-locals.el
2121
*.pyc
22+
23+
sandbox/output.json
24+
sandbox/pytest_html_report.html
25+
sandbox/archive/
26+
sandbox/.hypothesis/

sandbox/api/app.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
check_for_validate,
1919
generate_response,
2020
load_json_file,
21+
remove_system,
2122
)
2223

2324
app = Flask(__name__)
@@ -50,8 +51,8 @@ def get_related_persons() -> Union[dict, tuple]:
5051
if errors := check_for_errors(request):
5152
return errors
5253

53-
identifier = request.args.get("identifier")
54-
patient_identifier = request.args.get("patient:identifier")
54+
identifier = remove_system(request.args.get("identifier"))
55+
patient_identifier = remove_system(request.args.get("patient:identifier"))
5556
include = request.args.get("_include")
5657

5758
if empty := check_for_empty(identifier, patient_identifier):
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"issue": [
3+
{
4+
"code": "invalid",
5+
"details": {
6+
"coding": [
7+
{
8+
"code": "INVALID_IDENTIFIER_VALUE",
9+
"display": "Provided value is invalid",
10+
"system": "https://fhir.nhs.uk/R4/CodeSystem/ValidatedRelationships-ErrorOrWarningCode",
11+
"version": "1"
12+
}
13+
]
14+
},
15+
"diagnostics": "Not a valid NHS Number provided for the 'identifier' parameter",
16+
"severity": "error"
17+
}
18+
],
19+
"resourceType": "OperationOutcome"
20+
}

sandbox/api/responses/GET_RelatedPerson/bad_request_identifier_not_as_expected.json renamed to sandbox/api/responses/GET_RelatedPerson/bad_request_identifier_invalid_system.json

File renamed without changes.

sandbox/api/tests/test_utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ def test_get_response(mock_open: MagicMock) -> None:
3232
),
3333
(
3434
"identifier=123456789", # identifier length is less than 10
35-
"./api/responses/GET_RelatedPerson/bad_request_identifier_not_as_expected.json",
35+
"./api/responses/GET_RelatedPerson/bad_request_identifier_invalid.json",
36+
400,
37+
),
38+
(
39+
"identifier=https://fhir.nhs.uk/ID/nhs-number|1234567890", # identifier system invalid
40+
"./api/responses/GET_RelatedPerson/bad_request_identifier_invalid_system.json",
3641
400,
3742
),
3843
],

sandbox/api/utils.py

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from json import load, dumps
2-
from typing import Optional
2+
from typing import Optional, Any
33

44
from flask import request, Response
55

@@ -49,17 +49,33 @@ def check_for_errors(request: request) -> Optional[tuple]:
4949
Returns:
5050
Optional[tuple]: Tuple with response and status code if error is found
5151
"""
52-
if not request.args.get("identifier"):
52+
identifier = request.args.get("identifier")
53+
identifier_without_system = remove_system(request.args.get("identifier"))
54+
55+
if not identifier:
5356
return (
5457
load_json_file(
5558
"./api/responses/GET_RelatedPerson/bad_request_identifier_missing.json"
5659
),
5760
400,
5861
)
59-
elif request.args.get("identifier") and len(request.args.get("identifier")) != 10:
62+
elif identifier and len(identifier_without_system) != 10:
63+
# invalid identifier
64+
return (
65+
load_json_file(
66+
"./api/responses/GET_RelatedPerson/bad_request_identifier_invalid.json"
67+
),
68+
400,
69+
)
70+
elif (
71+
isinstance(identifier, str)
72+
and "|" in identifier
73+
and "https://fhir.nhs.uk/Id/nhs-number" != identifier.split("|", maxsplit=2)[0]
74+
):
75+
# invalid identifier system
6076
return (
6177
load_json_file(
62-
"./api/responses/GET_RelatedPerson/bad_request_identifier_not_as_expected.json"
78+
"./api/responses/GET_RelatedPerson/bad_request_identifier_invalid_system.json"
6379
),
6480
400,
6581
)
@@ -91,8 +107,8 @@ def check_for_validate(
91107
identifier: str,
92108
patient_identifier: str,
93109
include: str,
94-
basefile: str,
95-
incfile: str,
110+
base_file: str,
111+
inc_file: str,
96112
) -> Response:
97113
"""Checks for validate request responses for a given relationship record
98114
@@ -101,41 +117,41 @@ def check_for_validate(
101117
identifier (str): The identifier supplied to the request
102118
patient_identifier (str): The patient:identifier supplied to the request
103119
include (str): The include parameter supplied to the request
104-
basefile (str): The file to return when record matches but does not request includeded data
105-
incfile (str): The file to return when record matches and does request included data
120+
base_file (str): The file to return when record matches but does not request included data
121+
inc_file (str): The file to return when record matches and does request included data
106122
107123
Returns:
108124
Response: Resultant response or None
109125
"""
110126
if identifier and patient_identifier == value and include == INCLUDE_FLAG:
111127
# Request with identifier, patient and _include=patient
112-
return generate_response(load_json_file(incfile))
128+
return generate_response(load_json_file(inc_file))
113129
elif identifier and patient_identifier == value:
114130
# Request with identifier and patient
115-
return generate_response(load_json_file(basefile))
131+
return generate_response(load_json_file(base_file))
116132

117133

118134
def check_for_list(
119-
value: str, identifier: str, include: str, basefile: str, incfile: str
135+
value: str, identifier: str, include: str, base_file: str, inc_file: str
120136
) -> Response:
121137
"""Check for a list relationship response for a given NHS number
122138
123139
Args:
124140
value (str): NHS number of the relationship to look for
125141
identifier (str): The identifier supplied to the request
126142
include (str): The include parameter supplied to the request
127-
basefile (str): The file to return when record matches but does not request includeded data
128-
incfile (str): The file to return when record matches and does request included data
143+
base_file (str): The file to return when record matches but does not request included data
144+
inc_file (str): The file to return when record matches and does request included data
129145
130146
Returns:
131147
Response: Resultant response or None
132148
"""
133149
if identifier == value and include == INCLUDE_FLAG:
134150
# Request with identifier and _include=patient
135-
return generate_response(load_json_file(incfile))
151+
return generate_response(load_json_file(inc_file))
136152
elif identifier:
137153
# Request with identifier
138-
return generate_response(load_json_file(basefile))
154+
return generate_response(load_json_file(base_file))
139155

140156

141157
def generate_response(content: str, status: int = 200):
@@ -149,3 +165,12 @@ def generate_response(content: str, status: int = 200):
149165
Response: Resultant Response object based on input.
150166
"""
151167
return Response(dumps(content), status=status, mimetype="application/fhir+json")
168+
169+
170+
def remove_system(identifier: Any) -> str:
171+
if isinstance(identifier, str):
172+
if "|" in identifier:
173+
# Identifier includes system
174+
return identifier.split("|", maxsplit=1)[1]
175+
return identifier
176+
return ""

0 commit comments

Comments
 (0)