Skip to content

Commit ed16794

Browse files
authored
Fixing _build_..., adding tests. (#1420)
Fixes a URL formation bug, and adds test.
1 parent 4f8737a commit ed16794

File tree

3 files changed

+70
-40
lines changed

3 files changed

+70
-40
lines changed

apps/testclient/tests.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from apps.constants import Versions, VersionNotMatched
99
from apps.testclient.utils import (_ormap, _deepfind)
1010
from apps.testclient.constants import EndpointUrl
11+
from apps.testclient.views import FhirDataParams, _build_pagination_uri
12+
from django.http import HttpRequest
1113

1214

1315
class TestclientHelpers(TestCase):
@@ -54,6 +56,40 @@ def test_httpification(self):
5456
self.assertEqual(_start_url_with_http_or_https("httpsx://localhost:8000"), "https://httpsx://localhost:8000")
5557

5658

59+
class TestPaginationURIs(TestCase):
60+
def test_build_pagination_no_id(self):
61+
uri_base = "https://notaurl.gov"
62+
params = FhirDataParams("explanation-of-benefit", "some-resource-uri", 2, None)
63+
req = HttpRequest()
64+
# Set up no GET properties.
65+
setattr(req, "GET", {})
66+
try:
67+
_build_pagination_uri(uri_base, params, req)
68+
except ValueError:
69+
# Because no 'patient' or 'beneficiary' was found in the GET params,
70+
# _build_pagination_uri will fail.
71+
pass
72+
73+
def test_build_pagination_with_id(self):
74+
uri_base = "https://notaurl.gov"
75+
params = FhirDataParams("explanation-of-benefit", "some-resource-uri", 2, None)
76+
req = HttpRequest()
77+
for id_type in ['patient', 'beneficiary']:
78+
with self.subTest(id_type=id_type):
79+
# Set up pagination GET properties
80+
setattr(req, "GET", {
81+
"_count": 42,
82+
f"{id_type}": "-123456",
83+
})
84+
85+
result = _build_pagination_uri(uri_base, params, req)
86+
self.assertIn(uri_base, result)
87+
self.assertIn(f"{id_type}=-123456", result)
88+
# We should have no navi elements
89+
self.assertIn("_count", result)
90+
self.assertIn("startIndex", result)
91+
92+
5793
class BlueButtonClientApiUserInfoTest(TestCase):
5894
"""
5995
Test the BlueButton API UserInfo Endpoint
@@ -76,7 +112,7 @@ def versionedSetUp(self, version=Versions.NOT_AN_API_VERSION):
76112
self.patient = settings.DEFAULT_SAMPLE_FHIR_ID_V3
77113
self.username = settings.DEFAULT_SAMPLE_FHIR_ID_V3
78114
case _:
79-
raise VersionNotMatched(f"Failed to set up tests with a valid version number; given {version}")
115+
raise VersionNotMatched(f"Failed to set up tests with a valid version number; given {version}") # noqa: E702
80116

81117
# TODO V3: This may need to be parameterized based on the version number.
82118
self.another_patient = "20140000000001"
@@ -125,7 +161,7 @@ def versionedSetUp(self, version=Versions.NOT_AN_API_VERSION):
125161
case Versions.V3:
126162
self.patient = settings.DEFAULT_SAMPLE_FHIR_ID_V3
127163
case _:
128-
raise VersionNotMatched(f"Failed to set a patient id for version; given {version}")
164+
raise VersionNotMatched(f"Failed to set a patient id for version; given {version}") # noqa: E702
129165

130166
self.another_patient = "20140000000001"
131167

apps/testclient/utils.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ def _start_url_with_http_or_https(host: str) -> str:
2929
# This is also fine
3030
pass
3131
else:
32-
host = f'https://{host}'
32+
host = f'https://{host}' # noqa: E231
3333

3434
return host
3535

3636

37-
def testclient_http_response_setup(include_client_secret: bool = True, version: str = Versions.NOT_AN_API_VERSION) -> OrderedDict:
37+
def testclient_http_response_setup(include_client_secret: bool = True, version: int = Versions.NOT_AN_API_VERSION) -> OrderedDict:
3838
"""Prepare testclient response environment
3939
4040
When navigating through the testclient, we need to update the Django session
@@ -52,7 +52,6 @@ def testclient_http_response_setup(include_client_secret: bool = True, version:
5252
response = OrderedDict()
5353

5454
response['api_ver'] = version
55-
version_as_string = Versions.as_str(version)
5655

5756
oa2client = Application.objects.get(name="TestApp")
5857
response['client_id'] = oa2client.client_id
@@ -65,20 +64,20 @@ def testclient_http_response_setup(include_client_secret: bool = True, version:
6564

6665
response['resource_uri'] = host
6766
response['redirect_uri'] = '{}{}'.format(host, settings.TESTCLIENT_REDIRECT_URI)
68-
response['coverage_uri'] = '{}/{}/fhir/Coverage/'.format(host, version_as_string)
67+
response['coverage_uri'] = '{}/v{}/fhir/Coverage/'.format(host, version)
6968

7069
auth_data = __generate_auth_data()
7170
response['code_challenge_method'] = "S256"
7271
response['code_verifier'] = auth_data['code_verifier']
7372
response['code_challenge'] = auth_data['code_challenge']
7473
response['state'] = auth_data['state']
7574

76-
response['authorization_uri'] = f'{host}/{version_as_string}/o/authorize/'
77-
response['token_uri'] = f'{host}/{version_as_string}/o/token/'
78-
response['userinfo_uri'] = f'{host}/{version_as_string}/connect/userinfo'
79-
response['patient_uri'] = f'{host}/{version_as_string}/fhir/Patient/'
80-
response['eob_uri'] = f'{host}/{version_as_string}/fhir/ExplanationOfBenefit/'
81-
response['coverage_uri'] = f'{host}/{version_as_string}/fhir/Coverage/'
75+
response['authorization_uri'] = f'{host}/v{version}/o/authorize/'
76+
response['token_uri'] = f'{host}/v{version}/o/token/'
77+
response['userinfo_uri'] = f'{host}/v{version}/connect/userinfo'
78+
response['patient_uri'] = f'{host}/v{version}/fhir/Patient/'
79+
response['eob_uri'] = f'{host}/v{version}/fhir/ExplanationOfBenefit/'
80+
response['coverage_uri'] = f'{host}/v{version}/fhir/Coverage/'
8281

8382
return response
8483

apps/testclient/views.py

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -54,43 +54,38 @@ def _get_oauth2_session_with_token(request: HttpRequest) -> OAuth2Session:
5454
FhirDataParams = namedtuple("FhirDataParams", "name,uri,version,patient")
5555

5656

57-
def _build_pagination_uri(params, request):
58-
uri = None
57+
def _build_pagination_uri(uri: str, params: FhirDataParams, request: HttpRequest) -> str:
5958
# This sets up the navigation URI (pagination) based on whether we are handling
6059
# a patient or a beneficiary. All of this logic is essentially to add one parameter,
6160
# name correctly, to the nav URI. It is version dependent (there is no pagination in V3).
62-
nav_link = request.GET.get('nav_link', None)
63-
if nav_link is not None:
64-
# for now it's either EOB or Coverage, make this more generic later
65-
patient = request.GET.get('patient')
66-
beneficiary = request.GET.get('beneficiary')
67-
if patient is not None:
68-
id_type = 'patient'
69-
id = patient
70-
elif beneficiary is not None:
71-
id_type = 'beneficiary'
72-
id = beneficiary
73-
else:
74-
# We should not be able to get here.
75-
raise VersionNotMatched(f"Failed to set a patient id for version; given {params.version}")
76-
77-
# Extend the base URI with pagination information.
78-
uri = EndpointUrl.nav_uri(uri,
79-
count=request.GET.get('_count', 10),
80-
start_index=request.GET.get('startIndex', 0),
81-
id_type=id_type,
82-
id=id)
61+
# for now it's either EOB or Coverage, make this more generic later
62+
patient = request.GET.get('patient')
63+
beneficiary = request.GET.get('beneficiary')
64+
if patient is not None:
65+
id_type = 'patient'
66+
id = patient
67+
elif beneficiary is not None:
68+
id_type = 'beneficiary'
69+
id = beneficiary
70+
else:
71+
# We should not be able to get here.
72+
raise ValueError("Failed to set a patient id or beneficiary id on the pagination URI") # noqa: E702
73+
74+
# Extend the base URI with pagination information.
75+
uri = EndpointUrl.nav_uri(uri,
76+
count=request.GET.get('_count', 10),
77+
start_index=request.GET.get('startIndex', 0),
78+
id_type=id_type,
79+
id=id)
8380
return uri
8481

8582

8683
def _get_fhir_data_as_json(request: HttpRequest, params: FhirDataParams) -> Dict[str, object]:
8784
"""Make a call to the FHIR backend and return the JSON data from the call"""
8885
uri = EndpointUrl.fmt(params.name, params.uri, params.version, params.patient)
8986

90-
if params.version in [Versions.V1, Versions.V2]:
91-
pagination_uri = _build_pagination_uri(params, request)
92-
if pagination_uri is not None:
93-
uri = pagination_uri
87+
if params.version in [Versions.V1, Versions.V2] and request.GET.get('nav_link', None):
88+
uri = _build_pagination_uri(uri, params, request)
9489

9590
oas = _get_oauth2_session_with_token(request)
9691
r = oas.get(uri)
@@ -109,7 +104,7 @@ def _convert_response_string_to_json(json_response: str) -> Dict[str, object]:
109104
try:
110105
return json.loads(json_response.content)
111106
except JSONDecodeError:
112-
return {'error': f'Could not decode JSON; status code {json_response.status_code}'}
107+
return {'error': f'Could not decode JSON; status code {json_response.status_code}'} # noqa: E702
113108
else:
114109
# Same as above.
115110
return {'error': json_response.status_code}

0 commit comments

Comments
 (0)