Skip to content

Commit e88bebd

Browse files
Merge pull request #245 from NHSDigital/task/NPA-5357/questionnaireresponse-replace-referencecode-with-id
NPA-5357: Migrate GET /QuestionnaireResponse to accept an ID parameter
2 parents 1a41f9e + 906a5da commit e88bebd

17 files changed

+573
-380
lines changed

.github/pull_request_template.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ https://nhsd-jira.digital.nhs.uk/browse/NPA-XXXX
5151
- [ ] Commit messages follow the template: `NPA-XXXX: <short-description>`
5252
- [ ] All acceptance criteria from the Jira ticket are addressed
5353
- [ ] Automated tests (unit/integration/API/infrastructure etc. tests) are added or updated
54-
- [ ] The [traceability matrix](https://nhsd-confluence.digital.nhs.uk/display/NPA/Traceability+matrix) is updated
55-
with
56-
new tests or requirements
5754
- [ ] Assignees and appropriate labels (e.g. `terraform`, `documentation`) are added
5855

5956
---

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ env
2020
.dir-locals.el
2121
*.pyc
2222

23+
openapitools.json
24+
2325
sandbox/output.json
2426
sandbox/pytest_html_report.html
2527
sandbox/archive/

postman/Validate Relationship Service Sandbox.postman_collection.json renamed to postman/Validated Relationship Service Sandbox.postman_collection.json

Lines changed: 465 additions & 301 deletions
Large diffs are not rendered by default.

sandbox/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ Please note all commands are meant to be run from this directory `/sandbox`
6363

6464
To run the API with hot reloading use `make start-dev`
6565

66+
### Updating examples
67+
68+
The examples held in `./api/examples/` are copied at sandbox startup from `../specification/examples/`. See [Makefile](./Makefile) `start` & `start-dev`.
69+
6670
### Testing
6771

6872
#### Unit Tests

sandbox/api/constants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@
100100
# GET QuestionnaireResponse
101101
GET_QUESTIONNAIRE_RESPONSE_DIRECTORY = "./api/examples/GET_QuestionnaireResponse/"
102102
GET_QUESTIONNAIRE_RESPONSE__SUCCESS = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}success.yaml"
103-
GET_QUESTIONNAIRE_RESPONSE__INVALID = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/invalid_reference_code.yaml"
104-
GET_QUESTIONNAIRE_RESPONSE__MISSING = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/missing_reference_code.yaml"
103+
GET_QUESTIONNAIRE_RESPONSE__INVALID = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/invalid_access_request_id.yaml"
104+
GET_QUESTIONNAIRE_RESPONSE__MISSING = f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/missing_access_request_id.yaml"
105105
GET_QUESTIONNAIRE_RESPONSE__NOT_FOUND = (
106106
f"{GET_QUESTIONNAIRE_RESPONSE_DIRECTORY}errors/questionnaire_response_not_found.yaml"
107107
)

sandbox/api/get_questionnaire_response.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ def get_questionnaire_response_response() -> Union[dict, tuple]:
2323
Union[dict, tuple]: Response for GET /QuestionnaireResponse
2424
"""
2525
try:
26-
reference_code = request.args.get("referenceCode")
27-
if reference_code == "19318ZGLAB":
26+
access_request_id = request.args.get("ID")
27+
if access_request_id == "156e1560-e532-4e2a-85ad-5aeff03dc43e":
2828
return generate_response_from_example(GET_QUESTIONNAIRE_RESPONSE__SUCCESS, 200)
29-
elif reference_code == "INVALID":
29+
elif access_request_id == "INVALID":
3030
return generate_response_from_example(GET_QUESTIONNAIRE_RESPONSE__INVALID, 400)
31-
elif reference_code == "" or reference_code is None:
31+
elif access_request_id == "" or access_request_id is None:
3232
return generate_response_from_example(GET_QUESTIONNAIRE_RESPONSE__MISSING, 400)
33-
elif reference_code == "ABC123XY":
33+
elif access_request_id == "60d09b82-f4bb-41f9-b41e-767999b4ac9b":
3434
return generate_response_from_example(GET_QUESTIONNAIRE_RESPONSE__NOT_FOUND, 404)
3535
else:
36-
raise ValueError("Invalid reference code")
36+
raise ValueError("Invalid access request ID")
3737
except Exception:
3838
logger.exception("GET questionnaire response failed")
3939
return generate_response_from_example(INTERNAL_SERVER_ERROR_EXAMPLE, 500)

sandbox/api/post_questionnaire_response.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
)
1111
from .utils import generate_response_from_example
1212

13+
QUESTIONNAIRE_RESPONSE_APP_BASE_PATH = (
14+
"https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/QuestionnaireResponse"
15+
)
1316
basicConfig(level=INFO, format="%(asctime)s - %(message)s")
1417
logger = getLogger(__name__)
1518

@@ -29,7 +32,8 @@ def post_questionnaire_response_response() -> Union[dict, tuple]:
2932

3033
# Successful questionnaire response
3134
if source_identifier in ["9000000009", "9000000017"]:
32-
response = generate_response_from_example(POST_QUESTIONNAIRE_RESPONSE__SUCCESS, 200)
35+
header = {"location": f"{QUESTIONNAIRE_RESPONSE_APP_BASE_PATH}?ID=156e1560-e532-4e2a-85ad-5aeff03dc43e"}
36+
response = generate_response_from_example(POST_QUESTIONNAIRE_RESPONSE__SUCCESS, 200, headers=header)
3337
# Duplicate relationship
3438
elif source_identifier == "9000000049":
3539
response = generate_response_from_example(POST_QUESTIONNAIRE_RESPONSE__DUPLICATE_RELATIONSHIP_ERROR, 409)

sandbox/api/tests/test_get_questionnaire_response.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,34 @@
1010
("request_args", "response_file_name", "status_code"),
1111
[
1212
(
13-
"referenceCode=19318ZGLAB",
13+
"ID=156e1560-e532-4e2a-85ad-5aeff03dc43e",
1414
"./api/examples/GET_QuestionnaireResponse/success.yaml",
1515
200,
1616
),
1717
(
18-
"referenceCode=INVALID",
19-
"./api/examples/GET_QuestionnaireResponse/errors/invalid_reference_code.yaml",
18+
"ID=INVALID",
19+
"./api/examples/GET_QuestionnaireResponse/errors/invalid_access_request_id.yaml",
2020
400,
2121
),
2222
(
23-
"referenceCode=",
24-
"./api/examples/GET_QuestionnaireResponse/errors/missing_reference_code.yaml",
23+
"ID=",
24+
"./api/examples/GET_QuestionnaireResponse/errors/missing_access_request_id.yaml",
2525
400,
2626
),
2727
(
28-
"referenceCode=ABC123XY",
28+
"ID=60d09b82-f4bb-41f9-b41e-767999b4ac9b",
2929
"./api/examples/GET_QuestionnaireResponse/errors/questionnaire_response_not_found.yaml",
3030
404,
3131
),
3232
(
33-
"referenceCode=INVALID_CODE",
33+
"ID=INVALID_CODE",
3434
"./api/examples/errors/internal-server-error.yaml",
3535
500,
3636
),
3737
],
3838
)
3939
@patch("sandbox.api.get_questionnaire_response.generate_response_from_example")
40-
def test_get_consent_returns_expected_responses__mocked_utils(
40+
def test_get_questionnaire_response_returns_expected_responses__mocked_utils(
4141
mock_generate_response_from_example: MagicMock,
4242
request_args: str,
4343
response_file_name: str,

sandbox/api/tests/test_post_questionnaire_response.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,44 @@
1010
INTERNAL_SERVER_ERROR_EXAMPLE,
1111
)
1212

13+
SANDBOX_API_URL = "https://sandbox.api.service.nhs.uk/validated-relationships"
1314
QUESTIONNAIRE_RESPONSE_API_ENDPOINT = "/FHIR/R4/QuestionnaireResponse"
1415

1516

1617
@pytest.mark.parametrize(
17-
("nhs_num", "response_file_name", "status_code"),
18+
("nhs_num", "response_file_name", "status_code", "id"),
1819
[
1920
(
2021
"9000000009",
2122
POST_QUESTIONNAIRE_RESPONSE__SUCCESS,
2223
200,
24+
"156e1560-e532-4e2a-85ad-5aeff03dc43e",
2325
),
2426
(
2527
"9000000017",
2628
POST_QUESTIONNAIRE_RESPONSE__SUCCESS,
2729
200,
30+
"156e1560-e532-4e2a-85ad-5aeff03dc43e",
2831
),
2932
(
3033
"9000000049",
3134
POST_QUESTIONNAIRE_RESPONSE__DUPLICATE_RELATIONSHIP_ERROR,
3235
409,
36+
None,
3337
),
3438
(
3539
"INVALID_NHS_NUMBER",
3640
INTERNAL_SERVER_ERROR_EXAMPLE,
3741
500,
42+
None,
3843
),
3944
],
4045
)
4146
@patch("sandbox.api.post_questionnaire_response.generate_response_from_example")
4247
def test_post_questionnaire_response(
4348
mock_generate_response_from_example: MagicMock,
4449
nhs_num: str,
50+
id: str,
4551
response_file_name: str,
4652
status_code: int,
4753
client: object,
@@ -57,6 +63,13 @@ def test_post_questionnaire_response(
5763
# Act
5864
response = client.post(QUESTIONNAIRE_RESPONSE_API_ENDPOINT, json=json)
5965
# Assert
60-
mock_generate_response_from_example.assert_called_once_with(response_file_name, status_code)
66+
if id is not None:
67+
mock_generate_response_from_example.assert_called_once_with(
68+
response_file_name,
69+
status_code,
70+
headers={"location": f"{SANDBOX_API_URL}{QUESTIONNAIRE_RESPONSE_API_ENDPOINT}?ID={id}"},
71+
)
72+
else:
73+
mock_generate_response_from_example.assert_called_once_with(response_file_name, status_code)
6174
assert response.status_code == status_code
6275
assert response.json == loads(mocked_response.get_data(as_text=True))
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
InvalidAccessRequestID:
2+
summary: Invalid access request ID
3+
description: The provided access request ID is invalid in format.
4+
value:
5+
resourceType: "OperationOutcome"
6+
issue:
7+
- severity: "error"
8+
code: "invalid"
9+
details:
10+
coding:
11+
- system: "https://fhir.nhs.uk/STU3/CodeSystem/Spine-ErrorOrWarningCode-1"
12+
code: "INVALID_IDENTIFIER_VALUE"
13+
display: "Invalid identifier value"
14+
diagnostics: "The specified access request ID is invalid. Access request IDs must be a valid UUID."

0 commit comments

Comments
 (0)