1- from json import dumps , loads
2- from unittest .mock import MagicMock , patch
3-
41import pytest
5- from flask import Response
6-
7- from sandbox .api .constants import (
8- PATCH_CONSENT__INVALID_PATCH_FORMAT ,
9- PATCH_CONSENT__INVALID_PATH ,
10- PATCH_CONSENT__INVALID_STATE_TRANSITION ,
11- PATCH_CONSENT__INVALID_STATUS_CODE ,
12- PATCH_CONSENT__RESOURCE_NOT_FOUND ,
13- PATCH_CONSENT__SUCCESS ,
14- POST_CONSENT__DUPLICATE_RELATIONSHIP_ERROR ,
15- POST_CONSENT__PERFORMER_IDENTIFIER_ERROR ,
16- POST_CONSENT__SUCCESS ,
17- )
18-
19- from .conftest import (
20- CONSENT_API_ENDPOINT ,
21- QUESTIONNAIRE_RESPONSE_API_ENDPOINT ,
22- RELATED_PERSON_API_ENDPOINT ,
23- )
24-
25- UTILS_FILE_PATH = "sandbox.api.utils"
26- APP_FILE_PATH = "sandbox.api.app"
27- GET_CONSENT_FILE_PATH = "sandbox.api.get_consent"
282
293
304@pytest .mark .parametrize ("endpoint" , ["/_status" , "/_ping" , "/health" ])
@@ -38,276 +12,3 @@ def test_health_check(client: object, endpoint: str) -> None:
3812 "status" : "online" ,
3913 "message" : "Validated Relationships Service Sandbox is running" ,
4014 }
41-
42-
43- @pytest .mark .parametrize (
44- "request_args,response_file_name,status_code" ,
45- [
46- (
47- "identifier=9000000033" ,
48- "./api/examples/GET_RelatedPerson/empty_response_9000000033.yaml" ,
49- 200 ,
50- ),
51- (
52- "identifier=9000000017" ,
53- "./api/examples/GET_RelatedPerson/list_relationship_9000000017.yaml" ,
54- 200 ,
55- ),
56- (
57- "identifier=9000000017&_include=RelatedPerson:patient" ,
58- "./api/examples/GET_RelatedPerson/list_relationship_9000000017_include.yaml" ,
59- 200 ,
60- ),
61- (
62- "identifier=9000000017&_include=any" ,
63- "./api/examples/GET_RelatedPerson/list_relationship_9000000017.yaml" ,
64- 200 ,
65- ),
66- (
67- "identifier=9000000017&patient:identifier=9000000009" ,
68- "./api/examples/GET_RelatedPerson/verify_relationship_9000000009.yaml" ,
69- 200 ,
70- ),
71- (
72- "identifier=9000000017&patient:identifier=9000000009&_include=RelatedPerson:patient" ,
73- "./api/examples/GET_RelatedPerson/verify_relationship_9000000009_include.yaml" ,
74- 200 ,
75- ),
76- (
77- "identifier=9000000017&patient:identifier=9000000009&_include=any" ,
78- "./api/examples/GET_RelatedPerson/verify_relationship_9000000009.yaml" ,
79- 200 ,
80- ),
81- (
82- "identifier=9000000017&patient:identifier=9000000025" ,
83- "./api/examples/GET_RelatedPerson/verify_relationship_9000000025.yaml" ,
84- 200 ,
85- ),
86- (
87- "identifier=9000000017&patient:identifier=9000000025&_include=RelatedPerson:patient" ,
88- "./api/examples/GET_RelatedPerson/verify_relationship_9000000025_include.yaml" ,
89- 200 ,
90- ),
91- (
92- "identifier=9000000017&patient:identifier=9000000025&_include=any" ,
93- "./api/examples/GET_RelatedPerson/verify_relationship_9000000025.yaml" ,
94- 200 ,
95- ),
96- ],
97- )
98- @patch ("sandbox.api.utils.generate_response_from_example" )
99- def test_related_person (
100- mock_generate_response_from_example : MagicMock ,
101- request_args : str ,
102- response_file_name : str ,
103- status_code : int ,
104- client : object ,
105- ) -> None :
106- """Test related_persons endpoint."""
107-
108- # Arrange
109- mock_generate_response_from_example .return_value = mocked_response = Response (
110- dumps ({"data" : "mocked" }),
111- status = status_code ,
112- content_type = "application/json" ,
113- )
114- # Act
115- response = client .get (f"{ RELATED_PERSON_API_ENDPOINT } ?{ request_args } " )
116- # Assert
117- mock_generate_response_from_example .assert_called_once_with (
118- response_file_name , status_code
119- )
120- assert response .status_code == status_code
121- assert response .json == loads (mocked_response .get_data (as_text = True ))
122-
123-
124- @pytest .mark .parametrize (
125- "url_path,response_file_name,status_code" ,
126- [
127- (
128- QUESTIONNAIRE_RESPONSE_API_ENDPOINT ,
129- "./api/examples/POST_QuestionnaireResponse/success.yaml" ,
130- 200 ,
131- ),
132- ],
133- )
134- @patch (f"{ APP_FILE_PATH } .generate_response_from_example" )
135- def test_questionnaire_response (
136- mock_generate_response_from_example : MagicMock ,
137- url_path : str ,
138- response_file_name : str ,
139- client : object ,
140- status_code : int ,
141- ) -> None :
142- """Test related_persons endpoint with identifier only."""
143- # Arrange
144- mock_generate_response_from_example .return_value = mocked_response = Response (
145- dumps ({"data" : "mocked" }),
146- status = status_code ,
147- content_type = "application/json" ,
148- )
149- # Act
150- response = client .post (url_path , json = {"data" : "mocked" })
151- # Assert
152- mock_generate_response_from_example .assert_called_once_with (
153- response_file_name , status_code
154- )
155- assert response .status_code == status_code
156- assert response .json == loads (mocked_response .get_data (as_text = True ))
157-
158-
159- @pytest .mark .parametrize (
160- ("request_args,response_file_name,status_code" ),
161- [
162- (
163- "performer:identifier=9000000025" , # No performer record found error
164- "./api/examples/GET_Consent/no-relationships.yaml" ,
165- 200 ,
166- ),
167- (
168- "performer:identifier=9000000999" , # No performer record found error
169- "./api/examples/errors/invalidated-resource.yaml" ,
170- 404 ,
171- ),
172- ],
173- )
174- @patch (f"{ GET_CONSENT_FILE_PATH } .generate_response_from_example" )
175- def test_get_consent (
176- mock_generate_response_from_example : MagicMock ,
177- request_args : str ,
178- response_file_name : str ,
179- status_code : int ,
180- client : object ,
181- ) -> None :
182- """Test Consent endpoint."""
183- mock_generate_response_from_example .return_value = mocked_response = Response (
184- dumps ({"data" : "mocked" }),
185- status = status_code ,
186- content_type = "application/json" ,
187- )
188- # Act
189- response = client .get (f"{ CONSENT_API_ENDPOINT } ?{ request_args } " )
190- # Assert
191- mock_generate_response_from_example .assert_called_once_with (
192- response_file_name , status_code
193- )
194- assert response .status_code == status_code
195- assert response .json == loads (mocked_response .get_data (as_text = True ))
196-
197-
198- @pytest .mark .parametrize (
199- "nhs_num,response_file_name,status_code,location" ,
200- [
201- (
202- "9000000009" ,
203- POST_CONSENT__SUCCESS ,
204- 201 ,
205- "https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/Consent/9000000009" ,
206- ),
207- (
208- "9000000017" ,
209- POST_CONSENT__SUCCESS ,
210- 201 ,
211- "https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/Consent/9000000017" ,
212- ),
213- ("9000000000" , POST_CONSENT__PERFORMER_IDENTIFIER_ERROR , 422 , None ),
214- ("9000000049" , POST_CONSENT__DUPLICATE_RELATIONSHIP_ERROR , 409 , None ),
215- ],
216- )
217- @patch (f"{ APP_FILE_PATH } .generate_response_from_example" )
218- def test_post_consent_when_valid_returns_success (
219- mock_generate_response_from_example : MagicMock ,
220- response_file_name : str ,
221- nhs_num : str ,
222- location : str ,
223- client : object ,
224- status_code : int ,
225- ) -> None :
226- """
227- Function: app.post_consent
228- Scenario: Valid consent is POSTed to /consent
229- Expected Behavior: Request is accepted and 201 response returned
230- """
231- # Arrange
232- mock_generate_response_from_example .return_value = mocked_response = Response (
233- dumps ({"data" : "mocked" }),
234- status = status_code ,
235- content_type = "application/json" ,
236- )
237- # Act
238- json = {"performer" : [{"identifier" : {"value" : nhs_num }}]}
239- response = client .post (CONSENT_API_ENDPOINT , json = json )
240- # Assert
241- if location is not None :
242- mock_generate_response_from_example .assert_called_once_with (
243- response_file_name , status_code , headers = {"location" : location }
244- )
245- else :
246- mock_generate_response_from_example .assert_called_once_with (
247- response_file_name , status_code
248- )
249- assert response .status_code == status_code
250- assert response .json == loads (mocked_response .get_data (as_text = True ))
251-
252-
253- @pytest .mark .parametrize (
254- "nhs_num,response_file_name,status_code" ,
255- [
256- ("c6f48e4d" , PATCH_CONSENT__SUCCESS , 200 ),
257- ("0c56a594" , PATCH_CONSENT__SUCCESS , 200 ),
258- ("b02ea26c" , PATCH_CONSENT__SUCCESS , 200 ),
259- ("3a2679eb" , PATCH_CONSENT__INVALID_PATCH_FORMAT , 400 ),
260- ("94df7c8f" , PATCH_CONSENT__INVALID_PATH , 400 ),
261- ("2a7b736d" , PATCH_CONSENT__INVALID_STATUS_CODE , 422 ),
262- ("6fb4361b" , PATCH_CONSENT__INVALID_STATE_TRANSITION , 422 ),
263- ("xxxxxxxx" , PATCH_CONSENT__RESOURCE_NOT_FOUND , 404 ),
264- ("12345678" , PATCH_CONSENT__RESOURCE_NOT_FOUND , 404 ),
265- ],
266- )
267- @patch (f"{ APP_FILE_PATH } .generate_response_from_example" )
268- def test_patch_consent_on_request_returns_expected_response (
269- mock_generate_response_from_example : MagicMock ,
270- response_file_name : str ,
271- nhs_num : str ,
272- client : object ,
273- status_code : int ,
274- ) -> None :
275- """
276- Function: app.patch_consent
277- Scenario: Valid consent is PATCHed to /consent
278- Expected Behavior: Request is handled and appropriate response is returned
279- """
280- # Arrange
281- mock_generate_response_from_example .return_value = mocked_response = Response (
282- dumps ({"data" : "mocked" }),
283- status = status_code ,
284- content_type = "application/json" ,
285- )
286- # Act
287- json = [{"op" : "replace" , "path" : "/status" , "value" : "inactive" }]
288- response = client .patch (CONSENT_API_ENDPOINT + f"/{ nhs_num } " , json = json )
289- # Assert
290- mock_generate_response_from_example .assert_called_once_with (
291- response_file_name , status_code
292- )
293- assert response .status_code == status_code
294- assert response .json == loads (mocked_response .get_data (as_text = True ))
295-
296-
297- @patch (f"{ GET_CONSENT_FILE_PATH } .remove_system" )
298- @patch (f"{ GET_CONSENT_FILE_PATH } .generate_response_from_example" )
299- def test_consent__500_internal_server_error (
300- mock_generate_response_from_example : MagicMock ,
301- mock_remove_system : MagicMock ,
302- client : object ,
303- ) -> None :
304- """Test Consent endpoint."""
305- mock_remove_system .side_effect = Exception ("Test exception" )
306- # Act
307- client .get (
308- f"{ CONSENT_API_ENDPOINT } ?performer:identifier=9000000015&status=active&_include=Consent:performer"
309- )
310- # Assert
311- mock_generate_response_from_example .assert_called_once_with (
312- "./api/examples/errors/internal-server-error.yaml" , 500
313- )
0 commit comments