Skip to content

Commit 256d48d

Browse files
committed
Removes usage of httplib2 in unit tests.
The only remaining unit test module utilizing httplib2 is test_transport since it utilizes httplib2 directly at the moment.
1 parent cd825cc commit 256d48d

File tree

7 files changed

+218
-234
lines changed

7 files changed

+218
-234
lines changed

tests/contrib/test_appengine.py

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
from google.appengine.ext import db
3232
from google.appengine.ext import ndb
3333
from google.appengine.ext import testbed
34-
import httplib2
3534
import mock
3635
from six.moves import urllib
3736
import unittest2
@@ -42,11 +41,19 @@
4241
from oauth2client import client
4342
from oauth2client import clientsecrets
4443
from oauth2client.contrib import appengine
45-
from ..http_mock import CacheMock
44+
from .. import http_mock
4645

4746
__author__ = '[email protected] (Joe Gregorio)'
4847

4948
DATA_DIR = os.path.join(os.path.dirname(__file__), '..', 'data')
49+
DEFAULT_RESP = """\
50+
{
51+
"access_token": "foo_access_token",
52+
"expires_in": 3600,
53+
"extra": "value",
54+
"refresh_token": "foo_refresh_token"
55+
}
56+
"""
5057

5158

5259
def datafile(filename):
@@ -75,22 +82,6 @@ def __call__(self):
7582
return None
7683

7784

78-
class Http2Mock(object):
79-
"""Mock httplib2.Http"""
80-
status = 200
81-
content = {
82-
'access_token': 'foo_access_token',
83-
'refresh_token': 'foo_refresh_token',
84-
'expires_in': 3600,
85-
'extra': 'value',
86-
}
87-
88-
def request(self, token_uri, method, body, headers, *args, **kwargs):
89-
self.body = body
90-
self.headers = headers
91-
return self, json.dumps(self.content)
92-
93-
9485
class TestAppAssertionCredentials(unittest2.TestCase):
9586
account_name = "[email protected]"
9687
signature = "signature"
@@ -139,7 +130,7 @@ def test_raise_correct_type_of_exception(self):
139130

140131
scope = 'http://www.googleapis.com/scope'
141132
credentials = appengine.AppAssertionCredentials(scope)
142-
http = httplib2.Http()
133+
http = http_mock.HttpMock(data=DEFAULT_RESP)
143134
with self.assertRaises(client.AccessTokenRefreshError):
144135
credentials.refresh(http)
145136

@@ -155,7 +146,7 @@ def test_get_access_token_on_refresh(self):
155146
"http://www.googleapis.com/scope",
156147
"http://www.googleapis.com/scope2"]
157148
credentials = appengine.AppAssertionCredentials(scope)
158-
http = httplib2.Http()
149+
http = http_mock.HttpMock(data=DEFAULT_RESP)
159150
credentials.refresh(http)
160151
self.assertEqual('a_token_123', credentials.access_token)
161152

@@ -168,7 +159,7 @@ def test_get_access_token_on_refresh(self):
168159
scope = ('http://www.googleapis.com/scope '
169160
'http://www.googleapis.com/scope2')
170161
credentials = appengine.AppAssertionCredentials(scope)
171-
http = httplib2.Http()
162+
http = http_mock.HttpMock(data=DEFAULT_RESP)
172163
credentials.refresh(http)
173164
self.assertEqual('a_token_123', credentials.access_token)
174165
self.assertEqual(
@@ -184,7 +175,7 @@ def test_custom_service_account(self):
184175
autospec=True) as get_access_token:
185176
credentials = appengine.AppAssertionCredentials(
186177
scope, service_account_id=account_id)
187-
http = httplib2.Http()
178+
http = http_mock.HttpMock(data=DEFAULT_RESP)
188179
credentials.refresh(http)
189180

190181
self.assertEqual('a_token_456', credentials.access_token)
@@ -370,7 +361,7 @@ def test_validate(self):
370361

371362

372363
def _http_request(*args, **kwargs):
373-
resp = httplib2.Response({'status': '200'})
364+
resp = http_mock.ResponseMock()
374365
content = json.dumps({'access_token': 'bar'})
375366

376367
return resp, content
@@ -630,12 +621,9 @@ def get(self, *args, **kwargs):
630621
})
631622
self.current_user = user_mock()
632623
users.get_current_user = self.current_user
633-
self.httplib2_orig = httplib2.Http
634-
httplib2.Http = Http2Mock
635624

636625
def tearDown(self):
637626
self.testbed.deactivate()
638-
httplib2.Http = self.httplib2_orig
639627

640628
def test_in_error(self):
641629
# NOTE: This branch is never reached. _in_error is not set by any code
@@ -655,7 +643,9 @@ def test_callback_application(self):
655643
app.router.match_routes[0].handler.__name__,
656644
'OAuth2Handler')
657645

658-
def test_required(self):
646+
@mock.patch('oauth2client.transport.get_http_object')
647+
def test_required(self, new_http):
648+
new_http.return_value = http_mock.HttpMock(data=DEFAULT_RESP)
659649
# An initial request to an oauth_required decorated path should be a
660650
# redirect to start the OAuth dance.
661651
self.assertEqual(self.decorator.flow, None)
@@ -688,7 +678,7 @@ def test_required(self):
688678
response_query = urllib.parse.parse_qs(parts[1])
689679
response = response_query[
690680
self.decorator._token_response_param][0]
691-
self.assertEqual(Http2Mock.content,
681+
self.assertEqual(json.loads(DEFAULT_RESP),
692682
json.loads(urllib.parse.unquote(response)))
693683
self.assertEqual(self.decorator.flow, self.decorator._tls.flow)
694684
self.assertEqual(self.decorator.credentials,
@@ -736,7 +726,12 @@ def test_required(self):
736726
self.assertEqual('http://localhost/oauth2callback',
737727
query_params['redirect_uri'][0])
738728

739-
def test_storage_delete(self):
729+
# Check the mocks were called.
730+
new_http.assert_called_once_with()
731+
732+
@mock.patch('oauth2client.transport.get_http_object')
733+
def test_storage_delete(self, new_http):
734+
new_http.return_value = http_mock.HttpMock(data=DEFAULT_RESP)
740735
# An initial request to an oauth_required decorated path should be a
741736
# redirect to start the OAuth dance.
742737
response = self.app.get('/foo_path')
@@ -772,7 +767,12 @@ def test_storage_delete(self):
772767
parse_state_value.assert_called_once_with(
773768
'foo_path:xsrfkey123', self.current_user)
774769

775-
def test_aware(self):
770+
# Check the mocks were called.
771+
new_http.assert_called_once_with()
772+
773+
@mock.patch('oauth2client.transport.get_http_object')
774+
def test_aware(self, new_http):
775+
new_http.return_value = http_mock.HttpMock(data=DEFAULT_RESP)
776776
# An initial request to an oauth_aware decorated path should
777777
# not redirect.
778778
response = self.app.get('http://localhost/bar_path/2012/01')
@@ -825,6 +825,9 @@ def test_aware(self):
825825
self.should_raise = False
826826
self.assertEqual(None, self.decorator.credentials)
827827

828+
# Check the mocks were called.
829+
new_http.assert_called_once_with()
830+
828831
def test_error_in_step2(self):
829832
# An initial request to an oauth_aware decorated path should
830833
# not redirect.
@@ -855,10 +858,14 @@ def test_kwargs_are_passed_to_underlying_flow(self):
855858
self.assertEqual(decorator.flow, decorator._tls.flow)
856859

857860
def test_token_response_param(self):
861+
# No need to set-up a mock since test_required() does.
858862
self.decorator._token_response_param = 'foobar'
859863
self.test_required()
860864

861-
def test_decorator_from_client_secrets(self):
865+
@mock.patch('oauth2client.transport.get_http_object')
866+
def test_decorator_from_client_secrets(self, new_http):
867+
new_http.return_value = http_mock.HttpMock(data=DEFAULT_RESP)
868+
# Execute test after setting up mock.
862869
decorator = appengine.OAuth2DecoratorFromClientSecrets(
863870
datafile('client_secrets.json'),
864871
scope=['foo_scope', 'bar_scope'])
@@ -877,6 +884,9 @@ def test_decorator_from_client_secrets(self):
877884
self.assertEqual(self.decorator._revoke_uri,
878885
self.decorator.credentials.revoke_uri)
879886

887+
# Check the mocks were called.
888+
new_http.assert_called_once_with()
889+
880890
def test_decorator_from_client_secrets_toplevel(self):
881891
decorator_patch = mock.patch(
882892
'oauth2client.contrib.appengine.OAuth2DecoratorFromClientSecrets')
@@ -915,7 +925,7 @@ def test_decorator_from_client_secrets_kwargs(self):
915925
self.assertIn('prompt', decorator._kwargs)
916926

917927
def test_decorator_from_cached_client_secrets(self):
918-
cache_mock = CacheMock()
928+
cache_mock = http_mock.CacheMock()
919929
load_and_cache('client_secrets.json', 'secret', cache_mock)
920930
decorator = appengine.OAuth2DecoratorFromClientSecrets(
921931
# filename, scope, message=None, cache=None
@@ -991,7 +1001,10 @@ def test_decorator_from_client_secrets_with_optional_settings(self):
9911001
# This is never set, but it's consistent with other tests.
9921002
self.assertFalse(decorator._in_error)
9931003

994-
def test_invalid_state(self):
1004+
@mock.patch('oauth2client.transport.get_http_object')
1005+
def test_invalid_state(self, new_http):
1006+
new_http.return_value = http_mock.HttpMock(data=DEFAULT_RESP)
1007+
# Execute test after setting up mock.
9951008
with mock.patch.object(appengine, '_parse_state_value',
9961009
return_value=None, autospec=True):
9971010
# Now simulate the callback to /oauth2callback.
@@ -1002,6 +1015,9 @@ def test_invalid_state(self):
10021015
self.assertEqual('200 OK', response.status)
10031016
self.assertEqual('The authorization request failed', response.body)
10041017

1018+
# Check the mocks were called.
1019+
new_http.assert_called_once_with()
1020+
10051021

10061022
class DecoratorXsrfSecretTests(unittest2.TestCase):
10071023
"""Test xsrf_secret_key."""

tests/contrib/test_flask_util.py

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import logging
2020

2121
import flask
22-
import httplib2
2322
import mock
2423
import six.moves.http_client as httplib
2524
import six.moves.urllib.parse as urlparse
@@ -29,39 +28,20 @@
2928
from oauth2client import client
3029
from oauth2client import clientsecrets
3130
from oauth2client.contrib import flask_util
31+
from .. import http_mock
3232

3333

3434
__author__ = '[email protected] (Jon Wayne Parrott)'
3535

3636

37-
class Http2Mock(object):
38-
"""Mock httplib2.Http for code exchange / refresh"""
39-
40-
def __init__(self, status=httplib.OK, **kwargs):
41-
self.status = status
42-
self.content = {
43-
'access_token': 'foo_access_token',
44-
'refresh_token': 'foo_refresh_token',
45-
'expires_in': 3600,
46-
'extra': 'value',
47-
}
48-
self.content.update(kwargs)
49-
50-
def request(self, token_uri, method, body, headers, *args, **kwargs):
51-
self.body = body
52-
self.headers = headers
53-
return (self, json.dumps(self.content).encode('utf-8'))
54-
55-
def __enter__(self):
56-
self.httplib2_orig = httplib2.Http
57-
httplib2.Http = self
58-
return self
59-
60-
def __exit__(self, exc_type, exc_value, traceback):
61-
httplib2.Http = self.httplib2_orig
62-
63-
def __call__(self, *args, **kwargs):
64-
return self
37+
DEFAULT_RESP = """\
38+
{
39+
"access_token": "foo_access_token",
40+
"expires_in": 3600,
41+
"extra": "value",
42+
"refresh_token": "foo_refresh_token"
43+
}
44+
"""
6545

6646

6747
class FlaskOAuth2Tests(unittest2.TestCase):
@@ -246,7 +226,12 @@ def _setup_callback_state(self, client, **kwargs):
246226
def test_callback_view(self):
247227
self.oauth2.storage = mock.Mock()
248228
with self.app.test_client() as client:
249-
with Http2Mock() as http:
229+
with mock.patch(
230+
'oauth2client.transport.get_http_object') as new_http:
231+
# Set-up mock.
232+
new_http.return_value = http = http_mock.HttpMock(
233+
data=DEFAULT_RESP)
234+
# Run tests.
250235
state = self._setup_callback_state(client)
251236

252237
response = client.get(
@@ -258,6 +243,9 @@ def test_callback_view(self):
258243
self.assertIn('codez', http.body)
259244
self.assertTrue(self.oauth2.storage.put.called)
260245

246+
# Check the mocks were called.
247+
new_http.assert_called_once_with()
248+
261249
def test_authorize_callback(self):
262250
self.oauth2.authorize_callback = mock.Mock()
263251
self.test_callback_view()
@@ -296,11 +284,20 @@ def test_callback_view_errors(self):
296284
with self.app.test_client() as client:
297285
state = self._setup_callback_state(client)
298286

299-
with Http2Mock(status=httplib.INTERNAL_SERVER_ERROR):
287+
with mock.patch(
288+
'oauth2client.transport.get_http_object') as new_http:
289+
# Set-up mock.
290+
new_http.return_value = http_mock.HttpMock(
291+
headers={'status': httplib.INTERNAL_SERVER_ERROR},
292+
data=DEFAULT_RESP)
293+
# Run tests.
300294
response = client.get(
301295
'/oauth2callback?state={0}&code=codez'.format(state))
302296
self.assertEqual(response.status_code, httplib.BAD_REQUEST)
303297

298+
# Check the mocks were called.
299+
new_http.assert_called_once_with()
300+
304301
# Invalid state json
305302
with self.app.test_client() as client:
306303
with client.session_transaction() as session:
@@ -495,7 +492,10 @@ def test_incremental_auth(self):
495492
def test_incremental_auth_exchange(self):
496493
self._create_incremental_auth_app()
497494

498-
with Http2Mock():
495+
with mock.patch('oauth2client.transport.get_http_object') as new_http:
496+
# Set-up mock.
497+
new_http.return_value = http_mock.HttpMock(data=DEFAULT_RESP)
498+
# Run tests.
499499
with self.app.test_client() as client:
500500
state = self._setup_callback_state(
501501
client,
@@ -511,16 +511,21 @@ def test_incremental_auth_exchange(self):
511511
self.assertTrue(
512512
credentials.has_scopes(['email', 'one', 'two']))
513513

514+
# Check the mocks were called.
515+
new_http.assert_called_once_with()
516+
514517
def test_refresh(self):
518+
token_val = 'new_token'
519+
json_resp = '{"access_token": "%s"}' % (token_val,)
520+
http = http_mock.HttpMock(data=json_resp)
515521
with self.app.test_request_context():
516522
with mock.patch('flask.session'):
517523
self.oauth2.storage.put(self._generate_credentials())
518524

519-
self.oauth2.credentials.refresh(
520-
Http2Mock(access_token='new_token'))
525+
self.oauth2.credentials.refresh(http)
521526

522527
self.assertEqual(
523-
self.oauth2.storage.get().access_token, 'new_token')
528+
self.oauth2.storage.get().access_token, token_val)
524529

525530
def test_delete(self):
526531
with self.app.test_request_context():

tests/contrib/test_gce.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import datetime
1818
import json
1919

20-
import httplib2
2120
import mock
2221
from six.moves import http_client
2322
from tests.contrib.test_metadata import request_mock
@@ -129,12 +128,12 @@ def test_retrieve_scopes(self, metadata):
129128
service_account='default')
130129

131130
@mock.patch('oauth2client.contrib._metadata.get_service_account_info',
132-
side_effect=httplib2.HttpLib2Error('No Such Email'))
131+
side_effect=http_client.HTTPException('No Such Email'))
133132
def test_retrieve_scopes_bad_email(self, metadata):
134133
http_request = mock.MagicMock()
135134
http_mock = mock.MagicMock(request=http_request)
136135
credentials = gce.AppAssertionCredentials(email='[email protected]')
137-
with self.assertRaises(httplib2.HttpLib2Error):
136+
with self.assertRaises(http_client.HTTPException):
138137
credentials.retrieve_scopes(http_mock)
139138

140139
metadata.assert_called_once_with(http_request,

0 commit comments

Comments
 (0)