Skip to content

Commit 75f4577

Browse files
author
JAMES FUQIAN
committed
added tests to cover on demand token refresh enabled/disable
1 parent 0c044c9 commit 75f4577

2 files changed

Lines changed: 96 additions & 1 deletion

File tree

cms_bluebutton/fhir_request.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
def fhir_request(bb, config):
88
auth_token = config["auth_token"]
9-
109
if bb.token_refresh_on_expire:
1110
auth_token = handle_expired(bb, auth_token)
1211

cms_bluebutton/tests/test_fhir_request.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ def json(self):
2626
return self.json_data
2727

2828

29+
class MockResponseWithRaiseForStatus:
30+
def __init__(self, json_data, status_code):
31+
self.json_data = json_data
32+
self.status_code = status_code
33+
34+
def json(self):
35+
return self.json_data
36+
37+
def raise_for_status(self):
38+
pass
39+
40+
2941
class MockSession:
3042
def __init__(self, json_data, status_code):
3143
self.response = MockResponse(json_data, status_code)
@@ -58,10 +70,45 @@ def get(self, *args, **kwargs):
5870
return MockResponse(json.load(f), 200)
5971

6072

73+
class MockSessionTokenRefresh:
74+
def __init__(self, json_data, status_code):
75+
self.response = MockResponse(json_data, status_code)
76+
77+
def mount(self, *args, **kwargs):
78+
return
79+
80+
def get(self, *args, **kwargs):
81+
endpoint_url = kwargs['url']
82+
parsed_url = urlparse(endpoint_url)
83+
if parsed_url.path.endswith('Patient/'):
84+
# patient
85+
return self.response
86+
else:
87+
raise ValueError("Unexpected GET path={}".format(parsed_url.path))
88+
89+
6190
def success_fhir_patient_request_mock(*args, **kwargs):
6291
return MockSession({"resourceType": "Patient", "id": "-20140000010000"}, 200)
6392

6493

94+
def mocked_token_refresh_post(*args, **kwargs):
95+
endpoint_url = kwargs['url']
96+
parsed_url = urlparse(endpoint_url)
97+
if parsed_url.path.endswith('token/'):
98+
# auth token - refreshed
99+
expires_at_str = str(datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(seconds=36000))
100+
return MockResponseWithRaiseForStatus({"access_token": "fake_access_token",
101+
"refresh_token": "fake_refresh_token",
102+
"expires_at": expires_at_str,
103+
"patient": "-20140000010000"}, 200)
104+
else:
105+
raise ValueError("Unexpected POST path={}".format(parsed_url.path))
106+
107+
108+
def success_fhir_patient_request_refresh_token_mock(*args, **kwargs):
109+
return MockSessionTokenRefresh({"resourceType": "Patient", "id": "-20140000010000"}, 200)
110+
111+
65112
def success_fhir_coverage_request_mock(*args, **kwargs):
66113
return MockSession({"resourceType": "Bundle", "id": "aaa-111-111-111-aaaa"}, 200)
67114

@@ -101,6 +148,21 @@ def generate_mock_config():
101148
}
102149

103150

151+
def generate_mock_config_w_expired_access_token():
152+
return {
153+
"params": {},
154+
"auth_token": AuthorizationToken(
155+
{
156+
"access_token": "fake_access_token",
157+
"refresh_token": "fake_refresh_token",
158+
"expires_at": datetime.datetime.now(datetime.timezone.utc)
159+
- datetime.timedelta(seconds=36000),
160+
"patient": "-20140000010000",
161+
}
162+
),
163+
}
164+
165+
104166
class TestAPI(unittest.TestCase):
105167
@mock.patch("requests.Session", side_effect=success_fhir_patient_request_mock)
106168
def test_successful_fhir_patient_request(self, get_request_mock):
@@ -151,6 +213,40 @@ def test_successful_fhir_eob_pages_request(self, get_request_mock):
151213
self.assertEqual(len(pages["pages"]), 6)
152214
self.assertEqual(get_request_mock.call_count, 6)
153215

216+
@mock.patch("requests.post", side_effect=mocked_token_refresh_post)
217+
@mock.patch("requests.Session", side_effect=success_fhir_patient_request_refresh_token_mock)
218+
def test_successful_fhir_request_token_refreshed(self, post_mock, get_mock):
219+
bb = BlueButton(config=MOCK_BB_CONFIG)
220+
config = generate_mock_config_w_expired_access_token()
221+
response = bb.get_patient_data(config)
222+
self.assertTrue(config['auth_token'].access_token_expired())
223+
self.assertIsNotNone(response["auth_token"])
224+
self.assertFalse(response['auth_token'].access_token_expired())
225+
self.assertEqual(response["response"].status_code, 200)
226+
self.assertEqual(response["response"].json()["id"], "-20140000010000")
227+
self.assertEqual(response["response"].json()["resourceType"], "Patient")
228+
# mock post called once for token refresh
229+
self.assertEqual(post_mock.call_count, 1)
230+
# mock get called once for fhir resource
231+
self.assertEqual(get_mock.call_count, 1)
232+
233+
@mock.patch("requests.post", side_effect=mocked_token_refresh_post)
234+
@mock.patch("requests.Session", side_effect=success_fhir_patient_request_refresh_token_mock)
235+
def test_successful_fhir_request_token_refresh_disabled(self, get_mock, post_mock):
236+
bb = BlueButton(config="./tests/test_configs/json/bluebutton-sample-config-disable-token-refresh-on-expire.json")
237+
config = generate_mock_config_w_expired_access_token()
238+
response = bb.get_patient_data(config)
239+
self.assertTrue(config['auth_token'].access_token_expired())
240+
self.assertIsNotNone(response["auth_token"])
241+
self.assertTrue(response['auth_token'].access_token_expired())
242+
self.assertEqual(response["response"].status_code, 200)
243+
self.assertEqual(response["response"].json()["id"], "-20140000010000")
244+
self.assertEqual(response["response"].json()["resourceType"], "Patient")
245+
# mock post for toekn not called
246+
self.assertEqual(post_mock.call_count, 0)
247+
# mock get called once for fhir resource
248+
self.assertEqual(get_mock.call_count, 1)
249+
154250
@mock.patch("requests.Session", side_effect=success_fhir_profile_request_mock)
155251
def test_successful_fhir_profile_request(self, get_request_mock):
156252
bb = BlueButton(config=MOCK_BB_CONFIG)

0 commit comments

Comments
 (0)