Skip to content

Commit 1a0c4db

Browse files
committed
Use transport.request in tests.
In the process - "spring clean" the modules that were touched - use HttpMock when HttpMockSequence not needed - add some verifications on new HttpMock's
1 parent b7f3eca commit 1a0c4db

File tree

6 files changed

+237
-119
lines changed

6 files changed

+237
-119
lines changed

tests/contrib/test_multiprocess_file_storage.py

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@
2424

2525
import fasteners
2626
import mock
27-
from six import StringIO
27+
import six
28+
from six.moves import urllib_parse
2829

2930
from oauth2client import client
3031
from oauth2client.contrib import multiprocess_file_storage
3132

32-
from ..http_mock import HttpMockSequence
33+
from .. import http_mock
3334

3435

3536
@contextlib.contextmanager
@@ -68,11 +69,7 @@ def _generate_token_response_http(new_token='new_token'):
6869
'access_token': new_token,
6970
'expires_in': '3600',
7071
})
71-
http = HttpMockSequence([
72-
({'status': '200'}, token_response),
73-
])
74-
75-
return http
72+
return http_mock.HttpMock(data=token_response)
7673

7774

7875
class MultiprocessStorageBehaviorTests(unittest.TestCase):
@@ -115,6 +112,23 @@ def test_basic_operations(self):
115112

116113
self.assertIsNone(credentials)
117114

115+
def _verify_refresh_payload(self, http, credentials):
116+
self.assertEqual(http.requests, 1)
117+
self.assertEqual(http.uri, credentials.token_uri)
118+
self.assertEqual(http.method, 'POST')
119+
expected_body = {
120+
'grant_type': ['refresh_token'],
121+
'client_id': [credentials.client_id],
122+
'client_secret': [credentials.client_secret],
123+
'refresh_token': [credentials.refresh_token],
124+
}
125+
self.assertEqual(urllib_parse.parse_qs(http.body), expected_body)
126+
expected_headers = {
127+
'content-type': 'application/x-www-form-urlencoded',
128+
'user-agent': credentials.user_agent,
129+
}
130+
self.assertEqual(http.headers, expected_headers)
131+
118132
def test_single_process_refresh(self):
119133
store = multiprocess_file_storage.MultiprocessFileStorage(
120134
self.filename, 'single-process')
@@ -128,6 +142,9 @@ def test_single_process_refresh(self):
128142
retrieved = store.get()
129143
self.assertEqual(retrieved.access_token, 'new_token')
130144

145+
# Verify mocks.
146+
self._verify_refresh_payload(http, credentials)
147+
131148
def test_multi_process_refresh(self):
132149
# This will test that two processes attempting to refresh credentials
133150
# will only refresh once.
@@ -136,6 +153,7 @@ def test_multi_process_refresh(self):
136153
credentials = _create_test_credentials()
137154
credentials.set_store(store)
138155
store.put(credentials)
156+
actual_token = 'b'
139157

140158
def child_process_func(
141159
die_event, ready_event, check_event): # pragma: NO COVER
@@ -156,10 +174,12 @@ def replacement_acquire_lock(*args, **kwargs):
156174

157175
credentials.store.acquire_lock = replacement_acquire_lock
158176

159-
http = _generate_token_response_http('b')
177+
http = _generate_token_response_http(actual_token)
160178
credentials.refresh(http)
179+
self.assertEqual(credentials.access_token, actual_token)
161180

162-
self.assertEqual(credentials.access_token, 'b')
181+
# Verify mock http.
182+
self._verify_refresh_payload(http, credentials)
163183

164184
check_event = multiprocessing.Event()
165185
with scoped_child_process(child_process_func, check_event=check_event):
@@ -168,15 +188,17 @@ def replacement_acquire_lock(*args, **kwargs):
168188
store._backend._process_lock.acquire(blocking=False))
169189
check_event.set()
170190

171-
# The child process will refresh first, so we should end up
172-
# with 'b' as the token.
173-
http = mock.Mock()
191+
http = _generate_token_response_http('not ' + actual_token)
174192
credentials.refresh(http=http)
175-
self.assertEqual(credentials.access_token, 'b')
176-
self.assertFalse(http.request.called)
193+
# The child process will refresh first, so we should end up
194+
# with `actual_token`' as the token.
195+
self.assertEqual(credentials.access_token, actual_token)
196+
197+
# Make sure the refresh did not make a request.
198+
self.assertEqual(http.requests, 0)
177199

178200
retrieved = store.get()
179-
self.assertEqual(retrieved.access_token, 'b')
201+
self.assertEqual(retrieved.access_token, actual_token)
180202

181203
def test_read_only_file_fail_lock(self):
182204
credentials = _create_test_credentials()
@@ -233,7 +255,7 @@ def test__get_backend(self):
233255

234256
def test__read_write_credentials_file(self):
235257
credentials = _create_test_credentials()
236-
contents = StringIO()
258+
contents = six.StringIO()
237259

238260
multiprocess_file_storage._write_credentials_file(
239261
contents, {'key': credentials})
@@ -253,23 +275,23 @@ def test__read_write_credentials_file(self):
253275
# the invalid one but still load the valid one.
254276
data['credentials']['invalid'] = '123'
255277
results = multiprocess_file_storage._load_credentials_file(
256-
StringIO(json.dumps(data)))
278+
six.StringIO(json.dumps(data)))
257279
self.assertNotIn('invalid', results)
258280
self.assertEqual(
259281
results['key'].access_token, credentials.access_token)
260282

261283
def test__load_credentials_file_invalid_json(self):
262-
contents = StringIO('{[')
284+
contents = six.StringIO('{[')
263285
self.assertEqual(
264286
multiprocess_file_storage._load_credentials_file(contents), {})
265287

266288
def test__load_credentials_file_no_file_version(self):
267-
contents = StringIO('{}')
289+
contents = six.StringIO('{}')
268290
self.assertEqual(
269291
multiprocess_file_storage._load_credentials_file(contents), {})
270292

271293
def test__load_credentials_file_bad_file_version(self):
272-
contents = StringIO(json.dumps({'file_version': 1}))
294+
contents = six.StringIO(json.dumps({'file_version': 1}))
273295
self.assertEqual(
274296
multiprocess_file_storage._load_credentials_file(contents), {})
275297

tests/http_mock.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class HttpMockSequence(object):
7575
({'status': '200'}, b'{"access_token":"1/3w","expires_in":3600}'),
7676
({'status': '200'}, 'echo_request_headers'),
7777
])
78-
resp, content = http.request("http://examples.com")
78+
resp, content = http.request('http://examples.com')
7979
8080
There are special values you can pass in for content to trigger
8181
behavours that are helpful in testing.

tests/test_client.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from oauth2client import client
3636
from oauth2client import clientsecrets
3737
from oauth2client import service_account
38+
from oauth2client import transport
3839
from . import http_mock
3940

4041
__author__ = '[email protected] (Joe Gregorio)'
@@ -899,7 +900,7 @@ def test_token_refresh_success(self):
899900
({'status': http_client.OK}, 'echo_request_headers'),
900901
])
901902
http = self.credentials.authorize(http)
902-
resp, content = http.request('http://example.com')
903+
resp, content = transport.request(http, 'http://example.com')
903904
self.assertEqual(b'Bearer 1/3w', content[b'Authorization'])
904905
self.assertFalse(self.credentials.access_token_expired)
905906
self.assertEqual(token_response, self.credentials.token_response)
@@ -918,7 +919,7 @@ def test_recursive_authorize(self):
918919
http = http_mock.HttpMock(data=encoded_response)
919920
http = self.credentials.authorize(http)
920921
http = self.credentials.authorize(http)
921-
http.request('http://example.com')
922+
transport.request(http, 'http://example.com')
922923

923924
def test_token_refresh_failure(self):
924925
for status_code in client.REFRESH_STATUS_CODES:
@@ -930,7 +931,7 @@ def test_token_refresh_failure(self):
930931
http = self.credentials.authorize(http)
931932
with self.assertRaises(
932933
client.HttpAccessTokenRefreshError) as exc_manager:
933-
http.request('http://example.com')
934+
transport.request(http, 'http://example.com')
934935
self.assertEqual(http_client.BAD_REQUEST,
935936
exc_manager.exception.status)
936937
self.assertTrue(self.credentials.access_token_expired)
@@ -957,7 +958,7 @@ def test_token_revoke_fallback(self):
957958
def test_non_401_error_response(self):
958959
http = http_mock.HttpMock(headers={'status': http_client.BAD_REQUEST})
959960
http = self.credentials.authorize(http)
960-
resp, content = http.request('http://example.com')
961+
resp, content = transport.request(http, 'http://example.com')
961962
self.assertEqual(http_client.BAD_REQUEST, resp.status)
962963
self.assertEqual(None, self.credentials.token_response)
963964

@@ -1001,16 +1002,18 @@ def test_unicode_header_checks(self):
10011002
http = credentials.authorize(http_mock.HttpMock())
10021003
headers = {u'foo': 3, b'bar': True, 'baz': b'abc'}
10031004
cleaned_headers = {b'foo': b'3', b'bar': b'True', b'baz': b'abc'}
1004-
http.request(u'http://example.com', method=u'GET', headers=headers)
1005+
transport.request(
1006+
http, u'http://example.com', method=u'GET', headers=headers)
10051007
for k, v in cleaned_headers.items():
10061008
self.assertTrue(k in http.headers)
10071009
self.assertEqual(v, http.headers[k])
10081010

10091011
# Next, test that we do fail on unicode.
10101012
unicode_str = six.unichr(40960) + 'abcd'
10111013
with self.assertRaises(client.NonAsciiHeaderError):
1012-
http.request(u'http://example.com', method=u'GET',
1013-
headers={u'foo': unicode_str})
1014+
transport.request(
1015+
http, u'http://example.com', method=u'GET',
1016+
headers={u'foo': unicode_str})
10141017

10151018
def test_no_unicode_in_request_params(self):
10161019
access_token = u'foo'
@@ -1027,17 +1030,18 @@ def test_no_unicode_in_request_params(self):
10271030

10281031
http = http_mock.HttpMock()
10291032
http = credentials.authorize(http)
1030-
http.request(u'http://example.com', method=u'GET',
1031-
headers={u'foo': u'bar'})
1033+
transport.request(
1034+
http, u'http://example.com', method=u'GET',
1035+
headers={u'foo': u'bar'})
10321036
for k, v in six.iteritems(http.headers):
10331037
self.assertIsInstance(k, six.binary_type)
10341038
self.assertIsInstance(v, six.binary_type)
10351039

10361040
# Test again with unicode strings that can't simply be converted
10371041
# to ASCII.
10381042
with self.assertRaises(client.NonAsciiHeaderError):
1039-
http.request(
1040-
u'http://example.com', method=u'GET',
1043+
transport.request(
1044+
http, u'http://example.com', method=u'GET',
10411045
headers={u'foo': u'\N{COMET}'})
10421046

10431047
self.credentials.token_response = 'foobar'
@@ -1473,7 +1477,7 @@ def test_refresh_updates_id_token(self):
14731477
({'status': '200'}, 'echo_request_headers'),
14741478
])
14751479
http = self.credentials.authorize(http)
1476-
resp, content = http.request('http://example.com')
1480+
resp, content = transport.request(http, 'http://example.com')
14771481
self.assertEqual(self.credentials.id_token, body)
14781482

14791483

@@ -1492,7 +1496,7 @@ def test_token_refresh_success(self):
14921496
headers={'status': status_code}, data=b'')
14931497
http = self.credentials.authorize(http)
14941498
with self.assertRaises(client.AccessTokenCredentialsError):
1495-
resp, content = http.request('http://example.com')
1499+
resp, content = transport.request(http, 'http://example.com')
14961500

14971501
def test_token_revoke_success(self):
14981502
_token_revoke_test_helper(
@@ -1507,15 +1511,15 @@ def test_token_revoke_failure(self):
15071511
def test_non_401_error_response(self):
15081512
http = http_mock.HttpMock(headers={'status': http_client.BAD_REQUEST})
15091513
http = self.credentials.authorize(http)
1510-
resp, content = http.request('http://example.com')
1514+
resp, content = transport.request(http, 'http://example.com')
15111515
self.assertEqual(http_client.BAD_REQUEST, resp.status)
15121516

15131517
def test_auth_header_sent(self):
15141518
http = http_mock.HttpMockSequence([
15151519
({'status': '200'}, 'echo_request_headers'),
15161520
])
15171521
http = self.credentials.authorize(http)
1518-
resp, content = http.request('http://example.com')
1522+
resp, content = transport.request(http, 'http://example.com')
15191523
self.assertEqual(b'Bearer foo', content[b'Authorization'])
15201524

15211525

@@ -1551,7 +1555,7 @@ def test_assertion_refresh(self):
15511555
({'status': '200'}, 'echo_request_headers'),
15521556
])
15531557
http = self.credentials.authorize(http)
1554-
resp, content = http.request('http://example.com')
1558+
resp, content = transport.request(http, 'http://example.com')
15551559
self.assertEqual(b'Bearer 1/3w', content[b'Authorization'])
15561560

15571561
def test_token_revoke_success(self):
@@ -1742,16 +1746,17 @@ def _step1_get_device_and_user_codes_helper(
17421746
device_code, user_code, None, ver_url, None)
17431747
self.assertEqual(result, expected)
17441748
self.assertEqual(len(http.requests), 1)
1745-
self.assertEqual(
1746-
http.requests[0]['uri'], oauth2client.GOOGLE_DEVICE_URI)
1747-
body = http.requests[0]['body']
1748-
self.assertEqual(urllib.parse.parse_qs(body),
1749-
{'client_id': [flow.client_id],
1750-
'scope': [flow.scope]})
1749+
info = http.requests[0]
1750+
self.assertEqual(info['uri'], oauth2client.GOOGLE_DEVICE_URI)
1751+
expected_body = {
1752+
'client_id': [flow.client_id],
1753+
'scope': [flow.scope],
1754+
}
1755+
self.assertEqual(urllib.parse.parse_qs(info['body']), expected_body)
17511756
headers = {'content-type': 'application/x-www-form-urlencoded'}
17521757
if extra_headers is not None:
17531758
headers.update(extra_headers)
1754-
self.assertEqual(http.requests[0]['headers'], headers)
1759+
self.assertEqual(info['headers'], headers)
17551760

17561761
def test_step1_get_device_and_user_codes(self):
17571762
self._step1_get_device_and_user_codes_helper()

0 commit comments

Comments
 (0)