Skip to content

Commit 085c470

Browse files
committed
Improving test branch coverage in client.py.
Testing un-traversed branches in - `OAuth2Credentials._expires_in()` - `OAuth2Credentials.get_access_token()` - `OAuth2Credentials._do_refresh_request()`
1 parent a4ca8cb commit 085c470

File tree

2 files changed

+149
-8
lines changed

2 files changed

+149
-8
lines changed

oauth2client/client.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@
5353
try:
5454
from oauth2client import crypt
5555
HAS_CRYPTO = True
56-
if crypt.OpenSSLVerifier is not None:
57-
HAS_OPENSSL = True
56+
HAS_OPENSSL = crypt.OpenSSLVerifier is not None
5857
except ImportError: # pragma: NO COVER
5958
pass
6059

@@ -917,15 +916,15 @@ def _do_refresh_request(self, http_request):
917916
# An {'error':...} response body means the token is expired or
918917
# revoked, so we flag the credentials as such.
919918
logger.info('Failed to retrieve access token: %s', content)
920-
error_msg = 'Invalid response %s.' % resp['status']
919+
error_msg = 'Invalid response %s.' % (resp['status'],)
921920
try:
922921
d = json.loads(content)
923922
if 'error' in d:
924923
error_msg = d['error']
925924
if 'error_description' in d:
926925
error_msg += ': ' + d['error_description']
927926
self.invalid = True
928-
if self.store:
927+
if self.store is not None:
929928
self.store.locked_put(self)
930929
except (TypeError, ValueError):
931930
pass

tests/test_client.py

Lines changed: 146 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import os
2626
import socket
2727
import sys
28+
import tempfile
2829

30+
import httplib2
2931
import mock
3032
import six
3133
from six.moves import http_client
@@ -296,7 +298,6 @@ class GoogleCredentialsTests(unittest2.TestCase):
296298

297299
def setUp(self):
298300
self.os_name = os.name
299-
from oauth2client import client
300301
client.SETTINGS.env_name = None
301302

302303
def tearDown(self):
@@ -607,7 +608,6 @@ def test_get_adc_from_environment_variable_service_account(self, *stubs):
607608
in_gae.assert_called_once_with()
608609

609610
def test_env_name(self):
610-
from oauth2client import client
611611
self.assertEqual(None, client.SETTINGS.env_name)
612612
self.test_get_adc_from_environment_variable_service_account()
613613
self.assertEqual(DEFAULT_ENV_NAME, client.SETTINGS.env_name)
@@ -990,6 +990,35 @@ def test_no_unicode_in_request_params(self):
990990
instance = OAuth2Credentials.from_json(self.credentials.to_json())
991991
self.assertEqual('foobar', instance.token_response)
992992

993+
def test__expires_in_no_expiry(self):
994+
credentials = OAuth2Credentials(None, None, None, None,
995+
None, None, None)
996+
self.assertIsNone(credentials.token_expiry)
997+
self.assertIsNone(credentials._expires_in())
998+
999+
@mock.patch('oauth2client.client._UTCNOW')
1000+
def test__expires_in_expired(self, utcnow):
1001+
credentials = OAuth2Credentials(None, None, None, None,
1002+
None, None, None)
1003+
credentials.token_expiry = datetime.datetime.utcnow()
1004+
now = credentials.token_expiry + datetime.timedelta(seconds=1)
1005+
self.assertLess(credentials.token_expiry, now)
1006+
utcnow.return_value = now
1007+
self.assertEqual(credentials._expires_in(), 0)
1008+
utcnow.assert_called_once_with()
1009+
1010+
@mock.patch('oauth2client.client._UTCNOW')
1011+
def test__expires_in_not_expired(self, utcnow):
1012+
credentials = OAuth2Credentials(None, None, None, None,
1013+
None, None, None)
1014+
credentials.token_expiry = datetime.datetime.utcnow()
1015+
seconds = 1234
1016+
now = credentials.token_expiry - datetime.timedelta(seconds=seconds)
1017+
self.assertLess(now, credentials.token_expiry)
1018+
utcnow.return_value = now
1019+
self.assertEqual(credentials._expires_in(), seconds)
1020+
utcnow.assert_called_once_with()
1021+
9931022
@mock.patch('oauth2client.client._UTCNOW')
9941023
def test_get_access_token(self, utcnow):
9951024
# Configure the patch.
@@ -1074,6 +1103,121 @@ def test_get_access_token(self, utcnow):
10741103
expected_utcnow_calls = [mock.call()] * (2 + 3 + 5)
10751104
self.assertEqual(expected_utcnow_calls, utcnow.mock_calls)
10761105

1106+
@mock.patch.object(OAuth2Credentials, 'refresh')
1107+
@mock.patch.object(OAuth2Credentials, '_expires_in',
1108+
return_value=1835)
1109+
def test_get_access_token_without_http(self, expires_in, refresh_mock):
1110+
credentials = OAuth2Credentials(None, None, None, None,
1111+
None, None, None)
1112+
# Make sure access_token_expired returns True
1113+
credentials.invalid = True
1114+
# Specify a token so we can use it in the response.
1115+
credentials.access_token = 'ya29-s3kr3t'
1116+
1117+
with mock.patch('httplib2.Http',
1118+
return_value=object) as http_kls:
1119+
token_info = credentials.get_access_token()
1120+
expires_in.assert_called_once_with()
1121+
refresh_mock.assert_called_once_with(http_kls.return_value)
1122+
1123+
self.assertIsInstance(token_info, client.AccessTokenInfo)
1124+
self.assertEqual(token_info.access_token,
1125+
credentials.access_token)
1126+
self.assertEqual(token_info.expires_in,
1127+
expires_in.return_value)
1128+
1129+
@mock.patch.object(OAuth2Credentials, 'refresh')
1130+
@mock.patch.object(OAuth2Credentials, '_expires_in',
1131+
return_value=1835)
1132+
def test_get_access_token_with_http(self, expires_in, refresh_mock):
1133+
credentials = OAuth2Credentials(None, None, None, None,
1134+
None, None, None)
1135+
# Make sure access_token_expired returns True
1136+
credentials.invalid = True
1137+
# Specify a token so we can use it in the response.
1138+
credentials.access_token = 'ya29-s3kr3t'
1139+
1140+
http_obj = object()
1141+
token_info = credentials.get_access_token(http_obj)
1142+
self.assertIsInstance(token_info, client.AccessTokenInfo)
1143+
self.assertEqual(token_info.access_token,
1144+
credentials.access_token)
1145+
self.assertEqual(token_info.expires_in,
1146+
expires_in.return_value)
1147+
1148+
expires_in.assert_called_once_with()
1149+
refresh_mock.assert_called_once_with(http_obj)
1150+
1151+
@mock.patch('oauth2client.client.logger')
1152+
def _do_refresh_request_test_helper(self, response, content,
1153+
error_msg, logger, store=None):
1154+
credentials = OAuth2Credentials(None, None, None, None,
1155+
None, None, None)
1156+
credentials.store = store
1157+
http_request = mock.Mock()
1158+
http_request.return_value = response, content
1159+
1160+
# HttpAccessTokenRefreshError(error_msg, status=resp.status)
1161+
with self.assertRaises(HttpAccessTokenRefreshError) as exc_manager:
1162+
credentials._do_refresh_request(http_request)
1163+
1164+
self.assertEqual(exc_manager.exception.args, (error_msg,))
1165+
self.assertEqual(exc_manager.exception.status, response.status)
1166+
1167+
call1 = mock.call('Refreshing access_token')
1168+
failure_template = 'Failed to retrieve access token: %s'
1169+
call2 = mock.call(failure_template, content)
1170+
self.assertEqual(logger.info.mock_calls, [call1, call2])
1171+
if store is not None:
1172+
store.locked_put.assert_called_once_with(credentials)
1173+
1174+
def test__do_refresh_request_non_json_failure(self):
1175+
response = httplib2.Response({
1176+
'status': http_client.BAD_REQUEST,
1177+
})
1178+
content = u'Bad request'
1179+
error_msg = 'Invalid response %s.' % (response.status,)
1180+
self._do_refresh_request_test_helper(response, content, error_msg)
1181+
1182+
def test__do_refresh_request_basic_failure(self):
1183+
response = httplib2.Response({
1184+
'status': http_client.INTERNAL_SERVER_ERROR,
1185+
})
1186+
content = u'{}'
1187+
error_msg = 'Invalid response %s.' % (response.status,)
1188+
self._do_refresh_request_test_helper(response, content, error_msg)
1189+
1190+
def test__do_refresh_request_failure_w_json_error(self):
1191+
response = httplib2.Response({
1192+
'status': http_client.BAD_GATEWAY,
1193+
})
1194+
error_msg = 'Hi I am an error not a bearer'
1195+
content = json.dumps({'error': error_msg})
1196+
self._do_refresh_request_test_helper(response, content, error_msg)
1197+
1198+
def test__do_refresh_request_failure_w_json_error_and_store(self):
1199+
response = httplib2.Response({
1200+
'status': http_client.BAD_GATEWAY,
1201+
})
1202+
error_msg = 'Where are we going wearer?'
1203+
content = json.dumps({'error': error_msg})
1204+
store = mock.MagicMock()
1205+
self._do_refresh_request_test_helper(response, content, error_msg,
1206+
store=store)
1207+
1208+
def test__do_refresh_request_failure_w_json_error_and_desc(self):
1209+
response = httplib2.Response({
1210+
'status': http_client.SERVICE_UNAVAILABLE,
1211+
})
1212+
base_error = 'Ruckus'
1213+
error_desc = 'Can you describe the ruckus'
1214+
content = json.dumps({
1215+
'error': base_error,
1216+
'error_description': error_desc,
1217+
})
1218+
error_msg = '%s: %s' % (base_error, error_desc)
1219+
self._do_refresh_request_test_helper(response, content, error_msg)
1220+
10771221
def test_has_scopes(self):
10781222
self.assertTrue(self.credentials.has_scopes('foo'))
10791223
self.assertTrue(self.credentials.has_scopes(['foo']))
@@ -1625,13 +1769,11 @@ def _save_helper(self, filename):
16251769
self.assertEqual(stat_mode, 0o600)
16261770

16271771
def test_new(self):
1628-
import tempfile
16291772
filename = tempfile.mktemp()
16301773
self.assertFalse(os.path.exists(filename))
16311774
self._save_helper(filename)
16321775

16331776
def test_existing(self):
1634-
import tempfile
16351777
filename = tempfile.mktemp()
16361778
with open(filename, 'w') as f:
16371779
f.write('a bunch of nonsense longer than []')

0 commit comments

Comments
 (0)