Skip to content

Commit 8afc7fc

Browse files
authored
[NDR-278] Refactor retrieve & search E2E tests (#830)
1 parent a84ed0f commit 8afc7fc

File tree

6 files changed

+128
-127
lines changed

6 files changed

+128
-127
lines changed

.github/workflows/base-e2e-fhir-backendtest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
- name: Checkout
3434
uses: actions/checkout@v5
3535
with:
36-
repository: "nhsconnect/national-document-repository"
36+
repository: "NHSDigital/national-document-repository"
3737
ref: ${{ inputs.build_branch }}
3838

3939
- name: AWS Role
Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import io
22
import uuid
33

4+
import pytest
5+
import requests
46
from tests.e2e.helpers.pdm_data_helper import PdmDataHelper
57

68
from lambdas.tests.e2e.api.fhir.conftest import (
@@ -13,90 +15,93 @@
1315
pdm_data_helper = PdmDataHelper()
1416

1517

16-
def test_small_file(test_data):
17-
pdm_record = {}
18-
test_data.append(pdm_record)
19-
20-
pdm_record["id"] = str(uuid.uuid4())
21-
pdm_record["nhs_number"] = "9912003071"
22-
pdm_record["data"] = io.BytesIO(b"Sample PDF Content")
18+
def build_pdm_record(nhs_number="9912003071", data=None, doc_status=None, size=None):
19+
"""Helper to create a PDM record dictionary."""
20+
record = {
21+
"id": str(uuid.uuid4()),
22+
"nhs_number": nhs_number,
23+
"data": data or io.BytesIO(b"Sample PDF Content"),
24+
}
25+
if doc_status:
26+
record["doc_status"] = doc_status
27+
if size:
28+
record["size"] = size
29+
return record
2330

24-
pdm_data_helper.create_metadata(pdm_record)
25-
pdm_data_helper.create_resource(pdm_record)
2631

27-
url = f"https://{MTLS_ENDPOINT}/DocumentReference/{PDM_SNOMED}~{pdm_record['id']}"
32+
def get_document_reference(record_id):
33+
"""Helper to perform GET request for DocumentReference."""
34+
url = f"https://{MTLS_ENDPOINT}/DocumentReference/{PDM_SNOMED}~{record_id}"
35+
print("url:", url)
2836
headers = {
2937
"Authorization": "Bearer 123",
3038
"X-Correlation-Id": "1234",
3139
}
32-
# Use mTLS
3340
session = create_mtls_session()
34-
response = session.get(url, headers=headers)
35-
assert response.status_code == 200
41+
return session.get(url, headers=headers)
3642

3743

38-
def test_large_file(test_data):
39-
pdm_record = {}
44+
@pytest.mark.parametrize("file_size", [None, 10 * 1024 * 1024])
45+
def test_file_retrieval(test_data, file_size):
46+
"""Test retrieval for small and large files."""
47+
pdm_record = build_pdm_record(
48+
data=io.BytesIO(b"A" * file_size) if file_size else None,
49+
size=file_size * 1024 if file_size else None,
50+
)
4051
test_data.append(pdm_record)
4152

42-
pdm_record["id"] = str(uuid.uuid4())
43-
pdm_record["nhs_number"] = "9912003071"
44-
pdm_record["data"] = io.BytesIO(b"A" * (10 * 1024 * 1024))
45-
pdm_record["size"] = 10 * 1024 * 1024 * 1024
46-
4753
pdm_data_helper.create_metadata(pdm_record)
4854
pdm_data_helper.create_resource(pdm_record)
4955

50-
url = f"https://{MTLS_ENDPOINT}/DocumentReference/{PDM_SNOMED}~{pdm_record['id']}"
51-
headers = {
52-
"Authorization": "Bearer 123",
53-
"X-Correlation-Id": "1234",
54-
}
55-
56-
# Use mTLS
57-
session = create_mtls_session()
58-
response = session.get(url, headers=headers)
56+
response = get_document_reference(pdm_record["id"])
5957
assert response.status_code == 200
6058

61-
json = response.json()
62-
expected_presign_uri = f"https://{PDM_S3_BUCKET}.s3.eu-west-2.amazonaws.com/{pdm_record['nhs_number']}/{pdm_record['id']}"
63-
assert expected_presign_uri in json["content"][0]["attachment"]["url"]
59+
if file_size:
60+
json = response.json()
61+
expected_presign_uri = (
62+
f"https://{PDM_S3_BUCKET}.s3.eu-west-2.amazonaws.com/"
63+
f"{pdm_record['nhs_number']}/{pdm_record['id']}"
64+
)
65+
assert expected_presign_uri in json["content"][0]["attachment"]["url"]
6466

6567

6668
def test_no_file_found():
67-
pdm_record = {}
68-
pdm_record["id"] = str(uuid.uuid4())
69-
70-
url = f"https://{MTLS_ENDPOINT}/DocumentReference/{PDM_SNOMED}~{pdm_record['id']}"
71-
headers = {
72-
"Authorization": "Bearer 123",
73-
"X-Correlation-Id": "1234",
74-
}
75-
# Use mTLS
76-
session = create_mtls_session()
77-
response = session.get(url, headers=headers)
69+
"""Test retrieval when file does not exist."""
70+
pdm_record = build_pdm_record()
71+
response = get_document_reference(pdm_record["id"])
7872
assert response.status_code == 404
7973

8074

8175
def test_preliminary_file(test_data):
82-
pdm_record = {}
76+
"""Test retrieval for preliminary document status."""
77+
pdm_record = build_pdm_record(doc_status="preliminary")
8378
test_data.append(pdm_record)
8479

85-
pdm_record["id"] = str(uuid.uuid4())
86-
pdm_record["nhs_number"] = "9912003071"
87-
pdm_record["data"] = io.BytesIO(b"Sample PDF Content")
88-
pdm_record["doc_status"] = "preliminary"
80+
pdm_data_helper.create_metadata(pdm_record)
81+
pdm_data_helper.create_resource(pdm_record)
82+
83+
response = get_document_reference(pdm_record["id"])
84+
assert response.status_code == 200
85+
86+
87+
# the error is about the auth token not mtls?
88+
def test_forbidden_without_mtls(test_data):
89+
pdm_record = build_pdm_record()
90+
test_data.append(pdm_record)
8991

9092
pdm_data_helper.create_metadata(pdm_record)
9193
pdm_data_helper.create_resource(pdm_record)
9294

93-
url = f"https://{MTLS_ENDPOINT}/DocumentReference/{PDM_SNOMED}~{pdm_record['id']}"
95+
url = (
96+
f"https://{MTLS_ENDPOINT}/FhirDocumentReference/{PDM_SNOMED}~{pdm_record['id']}"
97+
)
9498
headers = {
9599
"Authorization": "Bearer 123",
96100
"X-Correlation-Id": "1234",
97101
}
102+
response = requests.request("GET", url, headers=headers)
103+
print("inital response:", response)
104+
json = response.json()
105+
print("response:", json)
98106

99-
# Use mTLS
100-
session = create_mtls_session()
101-
response = session.get(url, headers=headers)
102-
assert response.status_code == 200
107+
assert response.status_code == 403

lambdas/tests/e2e/api/fhir/test_search_patient_fhir_api.py

Lines changed: 54 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,94 +2,77 @@
22
import logging
33
import uuid
44

5+
import pytest
6+
57
from lambdas.tests.e2e.api.fhir.conftest import MTLS_ENDPOINT, create_mtls_session
68
from lambdas.tests.e2e.helpers.pdm_data_helper import PdmDataHelper
79

810
pdm_data_helper = PdmDataHelper()
911

1012

11-
def test_search_patient_details(test_data):
12-
pdm_record = {}
13-
test_data.append(pdm_record)
14-
15-
pdm_record["id"] = str(uuid.uuid4())
16-
pdm_record["nhs_number"] = "9912003071"
17-
pdm_record["data"] = io.BytesIO(b"Sample PDF Content")
18-
19-
pdm_data_helper.create_metadata(pdm_record)
20-
pdm_data_helper.create_resource(pdm_record)
21-
22-
url = f"https://{MTLS_ENDPOINT}/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|{pdm_record['nhs_number']}"
23-
headers = {
24-
"Authorization": "Bearer 123",
25-
"X-Correlation-Id": "1234",
13+
def build_pdm_record(nhs_number="9912003071", data=None, doc_status=None):
14+
"""Helper to create a PDM record dictionary."""
15+
record = {
16+
"id": str(uuid.uuid4()),
17+
"nhs_number": nhs_number,
18+
"data": data or io.BytesIO(b"Sample PDF Content"),
2619
}
27-
# Use mTLS
28-
session = create_mtls_session()
29-
response = session.get(url, headers=headers)
30-
bundle = response.json()
31-
logging.info(bundle)
32-
33-
34-
def test_multiple_cancelled_search_patient_details(test_data):
35-
pdm_record = {}
36-
test_data.append(pdm_record)
37-
38-
pdm_record["id"] = str(uuid.uuid4())
39-
pdm_record["nhs_number"] = "9912003071"
40-
pdm_record["data"] = io.BytesIO(b"Sample PDF Content")
41-
pdm_record["doc_status"] = "cancelled"
42-
43-
pdm_data_helper.create_metadata(pdm_record)
44-
pdm_data_helper.create_resource(pdm_record)
45-
46-
second_pdm_record = {}
47-
test_data.append(second_pdm_record)
48-
49-
second_pdm_record["id"] = str(uuid.uuid4())
50-
second_pdm_record["nhs_number"] = "9912003071"
51-
second_pdm_record["data"] = io.BytesIO(b"Sample PDF Content")
52-
second_pdm_record["doc_status"] = "cancelled"
20+
if doc_status:
21+
record["doc_status"] = doc_status
22+
return record
5323

54-
pdm_data_helper.create_metadata(second_pdm_record)
55-
pdm_data_helper.create_resource(second_pdm_record)
5624

57-
url = f"https://{MTLS_ENDPOINT}/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|{pdm_record['nhs_number']}"
25+
def search_document_reference(nhs_number):
26+
"""Helper to perform search by NHS number."""
27+
url = (
28+
f"https://{MTLS_ENDPOINT}/DocumentReference?"
29+
f"subject:identifier=https://fhir.nhs.uk/Id/nhs-number|{nhs_number}"
30+
)
5831
headers = {
5932
"Authorization": "Bearer 123",
6033
"X-Correlation-Id": "1234",
6134
}
62-
# Use mTLS
6335
session = create_mtls_session()
64-
response = session.get(url, headers=headers)
65-
assert response.status_code == 200
36+
return session.get(url, headers=headers)
6637

6738

68-
def test_no_records():
69-
pdm_record = {}
70-
pdm_record["nhs_number"] = "9912003071"
39+
def create_and_store_record(test_data, nhs_number="9912003071", doc_status=None):
40+
"""Helper to create metadata and resource for a record."""
41+
record = build_pdm_record(nhs_number=nhs_number, doc_status=doc_status)
42+
test_data.append(record)
43+
pdm_data_helper.create_metadata(record)
44+
pdm_data_helper.create_resource(record)
45+
return record
7146

72-
url = f"https://{MTLS_ENDPOINT}/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|{pdm_record['nhs_number']}"
73-
headers = {
74-
"Authorization": "Bearer 123",
75-
"X-Correlation-Id": "1234",
76-
}
77-
# Use mTLS
78-
session = create_mtls_session()
79-
response = session.get(url, headers=headers)
80-
assert response.status_code == 404
8147

48+
def test_search_patient_details(test_data):
49+
"""Search for a patient with one record."""
50+
create_and_store_record(test_data)
51+
response = search_document_reference("9912003071")
52+
assert response.status_code == 200
53+
bundle = response.json()
54+
logging.info(bundle)
55+
assert "entry" in bundle # Basic validation
8256

83-
def test_invalid_patient():
84-
pdm_record = {}
85-
pdm_record["nhs_number"] = "9999999993"
8657

87-
url = f"https://{MTLS_ENDPOINT}/DocumentReference?subject:identifier=https://fhir.nhs.uk/Id/nhs-number|{pdm_record['nhs_number']}"
88-
headers = {
89-
"Authorization": "Bearer 123",
90-
"X-Correlation-Id": "1234",
91-
}
92-
# Use mTLS
93-
session = create_mtls_session()
94-
response = session.get(url, headers=headers)
95-
assert response.status_code == 400
58+
def test_multiple_cancelled_search_patient_details(test_data):
59+
"""Search for a patient with multiple cancelled records."""
60+
create_and_store_record(test_data, doc_status="cancelled")
61+
create_and_store_record(test_data, doc_status="cancelled")
62+
response = search_document_reference("9912003071")
63+
assert response.status_code == 200
64+
bundle = response.json()
65+
assert len(bundle.get("entry", [])) >= 2
66+
67+
68+
@pytest.mark.parametrize(
69+
"nhs_number,expected_status",
70+
[
71+
("9912003071", 404), # No records
72+
("9999999993", 400), # Invalid patient
73+
],
74+
)
75+
def test_search_edge_cases(nhs_number, expected_status):
76+
"""Test search for no records and invalid patient."""
77+
response = search_document_reference(nhs_number)
78+
assert response.status_code == expected_status

lambdas/tests/e2e/helpers/pdm_data_helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ def create_metadata(self, pdm_document_details):
2121
"Custodian": "H81109",
2222
"DocStatus": pdm_document_details.get("doc_status", "final"),
2323
"DocumentScanCreation": "2023-01-01",
24+
"DocumentSnomedCodeType": "717391000000106",
2425
"FileLocation": f"s3://{self.s3_bucket}/{pdm_document_details['nhs_number']}/{pdm_document_details['id']}",
2526
"FileName": f"1of1_pdm_record_[Holly Lorna MAGAN]_[{pdm_document_details['nhs_number']}]_[29-05-2006].pdf",
2627
"FileSize": pdm_document_details.get("size", "12345"),
2728
"LastUpdated": 1743177202,
2829
"NhsNumber": pdm_document_details["nhs_number"],
2930
"Status": "current",
30-
"DocumentSnomedCode": "717391000000106",
3131
"Uploaded": True,
3232
"Uploading": False,
3333
"Version": "1",

scripts/test/run-e2e-fhir-api-tests.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ while [[ "$#" -gt 0 ]]; do
1414
done
1515

1616
echo "Selected workspace: $WORKSPACE"
17+
18+
if [ "$WORKSPACE" = "prod" ]; then
19+
echo "Error: Cannot run E2E tests in production workspace."
20+
exit 1
21+
fi
22+
1723
# Set environment variables
1824
source ./scripts/test/set-e2e-env-vars.sh $WORKSPACE
1925

scripts/test/set-e2e-env-vars.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,17 @@ fi
99

1010
WORKSPACE="$1"
1111

12+
# Set domain
13+
if [[ "$WORKSPACE" = "ndr-test" || "$WORKSPACE" = "pre-prod" ]]; then
14+
DOMAIN="national-document-repository.nhs.uk"
15+
else
16+
DOMAIN="access-request-fulfilment.patient-deductions.nhs.uk"
17+
fi
18+
1219
# Set environment variables
1320
export PDM_METADATA_TABLE="${WORKSPACE}_PDMDocumentMetadata"
1421
export PDM_S3_BUCKET="${WORKSPACE}-pdm-document-store"
15-
export MTLS_ENDPOINT="mtls.${WORKSPACE}.access-request-fulfilment.patient-deductions.nhs.uk"
22+
export MTLS_ENDPOINT="mtls.${WORKSPACE}.${DOMAIN}"
1623

1724
# Ensure Client certificates in place
1825
if ! make download-api-certs WORKSPACE="${WORKSPACE}"

0 commit comments

Comments
 (0)