@@ -73,6 +73,78 @@ async def test_headers_on_echo_target(
7373 expected_amr ,
7474 )
7575
76+ @pytest .mark .asyncio
77+ @pytest .mark .parametrize (
78+ "business_function,endpoint_url,is_r4" ,
79+ [
80+ ("PROVIDER_AUTHORISED_APPLICATION" , "" , False ),
81+ ("REFERRER_AUTHORISED_APPLICATION" , "" , False ),
82+ ("AUTHORISED_APPLICATION" , "" , False ),
83+ ("PROVIDER_AUTHORISED_APPLICATION" , "/FHIR/STU3/" , False ),
84+ ("REFERRER_AUTHORISED_APPLICATION" , "/FHIR/STU3/" , False ),
85+ ("AUTHORISED_APPLICATION" , "/FHIR/STU3/" , False ),
86+ ("PROVIDER_AUTHORISED_APPLICATION" , "/FHIR/R4/" , True ),
87+ ("REFERRER_AUTHORISED_APPLICATION" , "/FHIR/R4/" , True ),
88+ ("AUTHORISED_APPLICATION" , "/FHIR/R4/" , True ),
89+ ],
90+ )
91+ async def test_headers_on_echo_target_with_app_restricted_business_function (
92+ self , business_function , endpoint_url , is_r4 , authenticate_user , service_url
93+ ):
94+ user = Actor .RC
95+ access_code = await authenticate_user (user )
96+ client_request_headers = {
97+ _HEADER_ECHO : "" , # enable echo target
98+ _HEADER_AUTHORIZATION : "Bearer " + access_code ,
99+ _HEADER_REQUEST_ID : "DUMMY-VALUE" ,
100+ RenamedHeader .REFERRAL_ID .original : _EXPECTED_REFERRAL_ID ,
101+ RenamedHeader .CORRELATION_ID .original : _EXPECTED_CORRELATION_ID ,
102+ RenamedHeader .BUSINESS_FUNCTION .original : business_function ,
103+ RenamedHeader .ODS_CODE .original : user .org_code ,
104+ RenamedHeader .FILENAME .original : _EXPECTED_FILENAME ,
105+ RenamedHeader .COMM_RULE_ORG .original : _EXPECTED_COMM_RULE_ORG ,
106+ RenamedHeader .OBO_USER_ID .original : _EXPECTED_OBO_USER_ID ,
107+ }
108+
109+ # Make the API call
110+ response = requests .get (
111+ service_url + endpoint_url , headers = client_request_headers
112+ )
113+
114+ assert response .status_code == 403 , (
115+ "Expected a 403 response when attempting to call the endpoint, but instead received a "
116+ + str (response .status_code )
117+ )
118+
119+ assert response .reason == "Forbidden"
120+
121+ # Verify the OperationOutcome payload
122+ response_data = response .json ()
123+ assert response_data ["resourceType" ] == "OperationOutcome"
124+ assert response_data ["meta" ]["lastUpdated" ] is not None
125+ assert len (response_data ["meta" ]["profile" ]) == 1
126+ assert response_data ["meta" ]["profile" ][0 ] == (
127+ "https://www.hl7.org/fhir/R4/operationoutcome.html"
128+ if is_r4
129+ else "https://fhir.nhs.uk/STU3/StructureDefinition/eRS-OperationOutcome-1"
130+ )
131+ assert len (response_data ["issue" ]) == 1
132+ issue = response_data ["issue" ][0 ]
133+ assert issue ["severity" ] == "error"
134+ assert issue ["code" ] == "forbidden"
135+ assert issue ["diagnostics" ] == (
136+ "User does not have the required Business Function at the specified Organisation."
137+ )
138+ assert len (issue ["details" ]["coding" ]) == 1
139+ issue_details = issue ["details" ]["coding" ][0 ]
140+ assert (
141+ issue_details ["system" ]
142+ == "https://fhir.nhs.uk/CodeSystem/NHSD-API-ErrorOrWarningCode"
143+ if is_r4
144+ else "https://fhir.nhs.uk/STU3/CodeSystem/eRS-APIErrorCode-1"
145+ )
146+ assert issue_details ["code" ] == "ACCESS_DENIED" if is_r4 else "NO_ACCESS"
147+
76148 @pytest .mark .asyncio
77149 @pytest .mark .parametrize (
78150 "endpoint_url,is_r4" ,
@@ -438,6 +510,8 @@ def test_unknown_access_code(
438510 response .status_code
439511 )
440512
513+ assert response .reason == "Unauthorized"
514+
441515 if not is_operation_outcome :
442516 assert len (response .content ) == 0
443517 else :
@@ -475,7 +549,7 @@ def test_unknown_access_code(
475549 assert renamed_header .renamed not in client_response_headers
476550
477551 @pytest .mark .asyncio
478- @pytest .mark .parametrize ("service_name" , [( None ) ])
552+ @pytest .mark .parametrize ("service_name" , [None ])
479553 async def test_access_code_not_supported (
480554 self , referring_clinician , authenticate_user , service_url
481555 ):
0 commit comments