Clean up usage of HTTP mocks in tests.
This commit is contained in:
@@ -29,6 +29,7 @@ from google.appengine.ext import ndb
|
||||
from google.appengine.ext import testbed
|
||||
import mock
|
||||
from six.moves import urllib
|
||||
from six.moves import urllib_parse
|
||||
import unittest2
|
||||
import webapp2
|
||||
from webtest import TestApp
|
||||
@@ -50,6 +51,8 @@ DEFAULT_RESP = """\
|
||||
"refresh_token": "foo_refresh_token"
|
||||
}
|
||||
"""
|
||||
BASIC_TOKEN = 'bar'
|
||||
BASIC_RESP = json.dumps({'access_token': BASIC_TOKEN})
|
||||
|
||||
|
||||
def datafile(filename):
|
||||
@@ -356,13 +359,6 @@ class CredentialsPropertyTest(unittest2.TestCase):
|
||||
appengine.CredentialsProperty().validate(42)
|
||||
|
||||
|
||||
def _http_request(*args, **kwargs):
|
||||
resp = http_mock.ResponseMock()
|
||||
content = json.dumps({'access_token': 'bar'})
|
||||
|
||||
return resp, content
|
||||
|
||||
|
||||
class StorageByKeyNameTest(unittest2.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
@@ -407,6 +403,23 @@ class StorageByKeyNameTest(unittest2.TestCase):
|
||||
storage._model = appengine.CredentialsNDBModel
|
||||
self.assertTrue(storage._is_ndb())
|
||||
|
||||
def _verify_basic_refresh(self, http):
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, oauth2client.GOOGLE_TOKEN_URI)
|
||||
self.assertEqual(http.method, 'POST')
|
||||
expected_body = {
|
||||
'grant_type': ['refresh_token'],
|
||||
'client_id': [self.credentials.client_id],
|
||||
'client_secret': [self.credentials.client_secret],
|
||||
'refresh_token': [self.credentials.refresh_token],
|
||||
}
|
||||
self.assertEqual(urllib_parse.parse_qs(http.body), expected_body)
|
||||
expected_headers = {
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
'user-agent': self.credentials.user_agent,
|
||||
}
|
||||
self.assertEqual(http.headers, expected_headers)
|
||||
|
||||
def test_get_and_put_simple(self):
|
||||
storage = appengine.StorageByKeyName(
|
||||
appengine.CredentialsModel, 'foo', 'credentials')
|
||||
@@ -414,9 +427,12 @@ class StorageByKeyNameTest(unittest2.TestCase):
|
||||
self.assertEqual(None, storage.get())
|
||||
self.credentials.set_store(storage)
|
||||
|
||||
self.credentials._refresh(_http_request)
|
||||
http = http_mock.HttpMock(data=BASIC_RESP)
|
||||
self.credentials._refresh(http)
|
||||
credmodel = appengine.CredentialsModel.get_by_key_name('foo')
|
||||
self.assertEqual('bar', credmodel.credentials.access_token)
|
||||
self.assertEqual(BASIC_TOKEN, credmodel.credentials.access_token)
|
||||
# Verify mock.
|
||||
self._verify_basic_refresh(http)
|
||||
|
||||
def test_get_and_put_cached(self):
|
||||
storage = appengine.StorageByKeyName(
|
||||
@@ -425,16 +441,17 @@ class StorageByKeyNameTest(unittest2.TestCase):
|
||||
self.assertEqual(None, storage.get())
|
||||
self.credentials.set_store(storage)
|
||||
|
||||
self.credentials._refresh(_http_request)
|
||||
http = http_mock.HttpMock(data=BASIC_RESP)
|
||||
self.credentials._refresh(http)
|
||||
credmodel = appengine.CredentialsModel.get_by_key_name('foo')
|
||||
self.assertEqual('bar', credmodel.credentials.access_token)
|
||||
self.assertEqual(BASIC_TOKEN, credmodel.credentials.access_token)
|
||||
|
||||
# Now remove the item from the cache.
|
||||
memcache.delete('foo')
|
||||
|
||||
# Check that getting refreshes the cache.
|
||||
credentials = storage.get()
|
||||
self.assertEqual('bar', credentials.access_token)
|
||||
self.assertEqual(BASIC_TOKEN, credentials.access_token)
|
||||
self.assertNotEqual(None, memcache.get('foo'))
|
||||
|
||||
# Deleting should clear the cache.
|
||||
@@ -443,6 +460,9 @@ class StorageByKeyNameTest(unittest2.TestCase):
|
||||
self.assertEqual(None, credentials)
|
||||
self.assertEqual(None, memcache.get('foo'))
|
||||
|
||||
# Verify mock.
|
||||
self._verify_basic_refresh(http)
|
||||
|
||||
def test_get_and_put_set_store_on_cache_retrieval(self):
|
||||
storage = appengine.StorageByKeyName(
|
||||
appengine.CredentialsModel, 'foo', 'credentials', cache=memcache)
|
||||
@@ -455,9 +475,13 @@ class StorageByKeyNameTest(unittest2.TestCase):
|
||||
old_creds = storage.get()
|
||||
self.assertEqual(old_creds.access_token, 'foo')
|
||||
old_creds.invalid = True
|
||||
old_creds._refresh(_http_request)
|
||||
http = http_mock.HttpMock(data=BASIC_RESP)
|
||||
old_creds._refresh(http)
|
||||
new_creds = storage.get()
|
||||
self.assertEqual(new_creds.access_token, 'bar')
|
||||
self.assertEqual(new_creds.access_token, BASIC_TOKEN)
|
||||
|
||||
# Verify mock.
|
||||
self._verify_basic_refresh(http)
|
||||
|
||||
def test_get_and_put_ndb(self):
|
||||
# Start empty
|
||||
@@ -467,12 +491,16 @@ class StorageByKeyNameTest(unittest2.TestCase):
|
||||
|
||||
# Refresh storage and retrieve without using storage
|
||||
self.credentials.set_store(storage)
|
||||
self.credentials._refresh(_http_request)
|
||||
http = http_mock.HttpMock(data=BASIC_RESP)
|
||||
self.credentials._refresh(http)
|
||||
credmodel = appengine.CredentialsNDBModel.get_by_id('foo')
|
||||
self.assertEqual('bar', credmodel.credentials.access_token)
|
||||
self.assertEqual(BASIC_TOKEN, credmodel.credentials.access_token)
|
||||
self.assertEqual(credmodel.credentials.to_json(),
|
||||
self.credentials.to_json())
|
||||
|
||||
# Verify mock.
|
||||
self._verify_basic_refresh(http)
|
||||
|
||||
def test_delete_ndb(self):
|
||||
# Start empty
|
||||
storage = appengine.StorageByKeyName(
|
||||
@@ -498,14 +526,18 @@ class StorageByKeyNameTest(unittest2.TestCase):
|
||||
|
||||
# Set NDB store and refresh to add to storage
|
||||
self.credentials.set_store(storage)
|
||||
self.credentials._refresh(_http_request)
|
||||
http = http_mock.HttpMock(data=BASIC_RESP)
|
||||
self.credentials._refresh(http)
|
||||
|
||||
# Retrieve same key from DB model to confirm mixing works
|
||||
credmodel = appengine.CredentialsModel.get_by_key_name('foo')
|
||||
self.assertEqual('bar', credmodel.credentials.access_token)
|
||||
self.assertEqual(BASIC_TOKEN, credmodel.credentials.access_token)
|
||||
self.assertEqual(self.credentials.to_json(),
|
||||
credmodel.credentials.to_json())
|
||||
|
||||
# Verify mock.
|
||||
self._verify_basic_refresh(http)
|
||||
|
||||
def test_get_and_put_mixed_db_storage_ndb_get(self):
|
||||
# Start empty
|
||||
storage = appengine.StorageByKeyName(
|
||||
@@ -514,14 +546,18 @@ class StorageByKeyNameTest(unittest2.TestCase):
|
||||
|
||||
# Set DB store and refresh to add to storage
|
||||
self.credentials.set_store(storage)
|
||||
self.credentials._refresh(_http_request)
|
||||
http = http_mock.HttpMock(data=BASIC_RESP)
|
||||
self.credentials._refresh(http)
|
||||
|
||||
# Retrieve same key from NDB model to confirm mixing works
|
||||
credmodel = appengine.CredentialsNDBModel.get_by_id('foo')
|
||||
self.assertEqual('bar', credmodel.credentials.access_token)
|
||||
self.assertEqual(BASIC_TOKEN, credmodel.credentials.access_token)
|
||||
self.assertEqual(self.credentials.to_json(),
|
||||
credmodel.credentials.to_json())
|
||||
|
||||
# Verify mock.
|
||||
self._verify_basic_refresh(http)
|
||||
|
||||
def test_delete_db_ndb_mixed(self):
|
||||
# Start empty
|
||||
storage_ndb = appengine.StorageByKeyName(
|
||||
@@ -981,11 +1017,11 @@ class DecoratorTests(unittest2.TestCase):
|
||||
'oauth2client.contrib.appengine.clientsecrets.loadfile')
|
||||
with loadfile_patch as loadfile_mock:
|
||||
loadfile_mock.return_value = (clientsecrets.TYPE_WEB, {
|
||||
"client_id": "foo_client_id",
|
||||
"client_secret": "foo_client_secret",
|
||||
"redirect_uris": [],
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
"token_uri": "https://www.googleapis.com/oauth2/v4/token",
|
||||
'client_id': 'foo_client_id',
|
||||
'client_secret': 'foo_client_secret',
|
||||
'redirect_uris': [],
|
||||
'auth_uri': oauth2client.GOOGLE_AUTH_URI,
|
||||
'token_uri': oauth2client.GOOGLE_TOKEN_URI,
|
||||
# No revoke URI
|
||||
})
|
||||
|
||||
|
||||
@@ -19,19 +19,20 @@ import json
|
||||
|
||||
import mock
|
||||
from six.moves import http_client
|
||||
from tests.contrib.test_metadata import request_mock
|
||||
import unittest2
|
||||
|
||||
from oauth2client import client
|
||||
from oauth2client.contrib import _metadata
|
||||
from oauth2client.contrib import gce
|
||||
from .. import http_mock
|
||||
|
||||
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
|
||||
SERVICE_ACCOUNT_INFO = {
|
||||
'scopes': ['a', 'b'],
|
||||
'email': 'a@example.com',
|
||||
'aliases': ['default']
|
||||
}
|
||||
METADATA_PATH = 'instance/service-accounts/a@example.com/token'
|
||||
|
||||
|
||||
class AppAssertionCredentialsTests(unittest2.TestCase):
|
||||
@@ -85,16 +86,24 @@ class AppAssertionCredentialsTests(unittest2.TestCase):
|
||||
get_info.assert_not_called()
|
||||
|
||||
def test_refresh_token_failed_fetch(self):
|
||||
http_request = request_mock(
|
||||
http_client.NOT_FOUND,
|
||||
'application/json',
|
||||
json.dumps({'access_token': 'a', 'expires_in': 100})
|
||||
)
|
||||
headers = {
|
||||
'status': http_client.NOT_FOUND,
|
||||
'content-type': 'application/json',
|
||||
}
|
||||
response = json.dumps({'access_token': 'a', 'expires_in': 100})
|
||||
http = http_mock.HttpMock(headers=headers, data=response)
|
||||
credentials = gce.AppAssertionCredentials()
|
||||
credentials.invalid = False
|
||||
credentials.service_account_email = 'a@example.com'
|
||||
with self.assertRaises(client.HttpAccessTokenRefreshError):
|
||||
credentials._refresh(http_request)
|
||||
credentials._refresh(http)
|
||||
# Verify mock.
|
||||
self.assertEqual(http.requests, 1)
|
||||
expected_uri = _metadata.METADATA_ROOT + METADATA_PATH
|
||||
self.assertEqual(http.uri, expected_uri)
|
||||
self.assertEqual(http.method, 'GET')
|
||||
self.assertIsNone(http.body)
|
||||
self.assertEqual(http.headers, _metadata.METADATA_HEADERS)
|
||||
|
||||
def test_serialization_data(self):
|
||||
credentials = gce.AppAssertionCredentials()
|
||||
|
||||
@@ -28,52 +28,59 @@ DATA = {'foo': 'bar'}
|
||||
EXPECTED_URL = (
|
||||
'http://metadata.google.internal/computeMetadata/v1/instance'
|
||||
'/service-accounts/default')
|
||||
EXPECTED_KWARGS = {
|
||||
'headers': _metadata.METADATA_HEADERS,
|
||||
'body': None,
|
||||
'connection_type': None,
|
||||
'method': 'GET',
|
||||
'redirections': 5,
|
||||
}
|
||||
|
||||
|
||||
def request_mock(status, content_type, content):
|
||||
response = http_mock.ResponseMock(
|
||||
{'status': status, 'content-type': content_type})
|
||||
request_method = mock.Mock(
|
||||
return_value=(response, content.encode('utf-8')))
|
||||
# Make sure the mock doesn't have a request attr.
|
||||
del request_method.request
|
||||
return request_method
|
||||
headers = {'status': status, 'content-type': content_type}
|
||||
http = http_mock.HttpMock(headers=headers,
|
||||
data=content.encode('utf-8'))
|
||||
return http
|
||||
|
||||
|
||||
class TestMetadata(unittest2.TestCase):
|
||||
|
||||
def test_get_success_json(self):
|
||||
http_request = request_mock(
|
||||
http = request_mock(
|
||||
http_client.OK, 'application/json', json.dumps(DATA))
|
||||
self.assertEqual(
|
||||
_metadata.get(http_request, PATH),
|
||||
_metadata.get(http, PATH),
|
||||
DATA
|
||||
)
|
||||
http_request.assert_called_once_with(EXPECTED_URL, **EXPECTED_KWARGS)
|
||||
|
||||
# Verify mocks.
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, EXPECTED_URL)
|
||||
self.assertEqual(http.method, 'GET')
|
||||
self.assertIsNone(http.body)
|
||||
self.assertEqual(http.headers, _metadata.METADATA_HEADERS)
|
||||
|
||||
def test_get_success_string(self):
|
||||
http_request = request_mock(
|
||||
http = request_mock(
|
||||
http_client.OK, 'text/html', '<p>Hello World!</p>')
|
||||
self.assertEqual(
|
||||
_metadata.get(http_request, PATH),
|
||||
_metadata.get(http, PATH),
|
||||
'<p>Hello World!</p>'
|
||||
)
|
||||
http_request.assert_called_once_with(EXPECTED_URL, **EXPECTED_KWARGS)
|
||||
|
||||
# Verify mocks.
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, EXPECTED_URL)
|
||||
self.assertEqual(http.method, 'GET')
|
||||
self.assertIsNone(http.body)
|
||||
self.assertEqual(http.headers, _metadata.METADATA_HEADERS)
|
||||
|
||||
def test_get_failure(self):
|
||||
http_request = request_mock(
|
||||
http = request_mock(
|
||||
http_client.NOT_FOUND, 'text/html', '<p>Error</p>')
|
||||
with self.assertRaises(http_client.HTTPException):
|
||||
_metadata.get(http_request, PATH)
|
||||
_metadata.get(http, PATH)
|
||||
|
||||
http_request.assert_called_once_with(EXPECTED_URL, **EXPECTED_KWARGS)
|
||||
# Verify mocks.
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, EXPECTED_URL)
|
||||
self.assertEqual(http.method, 'GET')
|
||||
self.assertIsNone(http.body)
|
||||
self.assertEqual(http.headers, _metadata.METADATA_HEADERS)
|
||||
|
||||
@mock.patch(
|
||||
'oauth2client.client._UTCNOW',
|
||||
@@ -88,18 +95,22 @@ class TestMetadata(unittest2.TestCase):
|
||||
self.assertEqual(token, 'a')
|
||||
self.assertEqual(
|
||||
expiry, datetime.datetime.min + datetime.timedelta(seconds=100))
|
||||
http.assert_called_once_with(
|
||||
EXPECTED_URL + '/token',
|
||||
**EXPECTED_KWARGS
|
||||
)
|
||||
# Verify mocks.
|
||||
now.assert_called_once_with()
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, EXPECTED_URL + '/token')
|
||||
self.assertEqual(http.method, 'GET')
|
||||
self.assertIsNone(http.body)
|
||||
self.assertEqual(http.headers, _metadata.METADATA_HEADERS)
|
||||
|
||||
def test_service_account_info(self):
|
||||
http_request = request_mock(
|
||||
http = request_mock(
|
||||
http_client.OK, 'application/json', json.dumps(DATA))
|
||||
info = _metadata.get_service_account_info(http_request)
|
||||
info = _metadata.get_service_account_info(http)
|
||||
self.assertEqual(info, DATA)
|
||||
http_request.assert_called_once_with(
|
||||
EXPECTED_URL + '/?recursive=True',
|
||||
**EXPECTED_KWARGS
|
||||
)
|
||||
# Verify mock.
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, EXPECTED_URL + '/?recursive=True')
|
||||
self.assertEqual(http.method, 'GET')
|
||||
self.assertIsNone(http.body)
|
||||
self.assertEqual(http.headers, _metadata.METADATA_HEADERS)
|
||||
|
||||
@@ -46,6 +46,7 @@ class HttpMock(object):
|
||||
self.method = None
|
||||
self.body = None
|
||||
self.headers = None
|
||||
self.requests = 0
|
||||
|
||||
def request(self, uri,
|
||||
method='GET',
|
||||
@@ -57,6 +58,8 @@ class HttpMock(object):
|
||||
self.method = method
|
||||
self.body = body
|
||||
self.headers = headers
|
||||
self.redirections = redirections
|
||||
self.requests += 1
|
||||
return ResponseMock(self.response_headers), self.data
|
||||
|
||||
|
||||
@@ -89,7 +92,6 @@ class HttpMockSequence(object):
|
||||
iterable: iterable, a sequence of pairs of (headers, body)
|
||||
"""
|
||||
self._iterable = iterable
|
||||
self.follow_redirects = True
|
||||
self.requests = []
|
||||
|
||||
def request(self, uri,
|
||||
@@ -99,7 +101,12 @@ class HttpMockSequence(object):
|
||||
redirections=1,
|
||||
connection_type=None):
|
||||
resp, content = self._iterable.pop(0)
|
||||
self.requests.append({'uri': uri, 'body': body, 'headers': headers})
|
||||
self.requests.append({
|
||||
'method': method,
|
||||
'uri': uri,
|
||||
'body': body,
|
||||
'headers': headers,
|
||||
})
|
||||
# Read any underlying stream before sending the request.
|
||||
body_stream_content = (body.read()
|
||||
if getattr(body, 'read', None) else None)
|
||||
|
||||
@@ -12,10 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Oauth2client tests
|
||||
|
||||
Unit tests for oauth2client.
|
||||
"""
|
||||
"""Unit tests for oauth2client.client."""
|
||||
|
||||
import base64
|
||||
import contextlib
|
||||
@@ -705,8 +702,9 @@ class GoogleCredentialsTests(unittest2.TestCase):
|
||||
# Make sure the well-known file actually doesn't exist.
|
||||
self.assertTrue(os.path.exists(get_well_known.return_value))
|
||||
|
||||
method_name = \
|
||||
'oauth2client.client._get_application_default_credential_from_file'
|
||||
method_name = (
|
||||
'oauth2client.client.'
|
||||
'_get_application_default_credential_from_file')
|
||||
result_creds = object()
|
||||
with mock.patch(method_name,
|
||||
return_value=result_creds) as get_from_file:
|
||||
@@ -846,9 +844,9 @@ def _token_revoke_test_helper(testcase, status, revoke_raise,
|
||||
actual_do_revoke = testcase.credentials._do_revoke
|
||||
testcase.token_from_revoke = None
|
||||
|
||||
def do_revoke_stub(http_request, token):
|
||||
def do_revoke_stub(http, token):
|
||||
testcase.token_from_revoke = token
|
||||
return actual_do_revoke(http_request, token)
|
||||
return actual_do_revoke(http, token)
|
||||
testcase.credentials._do_revoke = do_revoke_stub
|
||||
|
||||
http = http_mock.HttpMock(headers={'status': status})
|
||||
@@ -1216,24 +1214,25 @@ class BasicCredentialsTests(unittest2.TestCase):
|
||||
def _do_refresh_request_test_helper(self, response, content,
|
||||
error_msg, logger, gen_body,
|
||||
gen_headers, store=None):
|
||||
token_uri = 'http://token_uri'
|
||||
credentials = client.OAuth2Credentials(None, None, None, None,
|
||||
None, None, None)
|
||||
None, token_uri, None)
|
||||
credentials.store = store
|
||||
http_request = mock.Mock()
|
||||
# Make sure the mock doesn't have a request attr.
|
||||
del http_request.request
|
||||
http_request.return_value = response, content
|
||||
http = http_mock.HttpMock(headers=response, data=content)
|
||||
|
||||
with self.assertRaises(
|
||||
client.HttpAccessTokenRefreshError) as exc_manager:
|
||||
credentials._do_refresh_request(http_request)
|
||||
credentials._do_refresh_request(http)
|
||||
|
||||
self.assertEqual(exc_manager.exception.args, (error_msg,))
|
||||
self.assertEqual(exc_manager.exception.status, response.status)
|
||||
http_request.assert_called_once_with(
|
||||
None, method='POST', body=gen_body.return_value,
|
||||
headers=gen_headers.return_value, redirections=5,
|
||||
connection_type=None)
|
||||
|
||||
# Verify mocks.
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, token_uri)
|
||||
self.assertEqual(http.method, 'POST')
|
||||
self.assertEqual(http.body, gen_body.return_value)
|
||||
self.assertEqual(http.headers, gen_headers.return_value)
|
||||
|
||||
call1 = mock.call('Refreshing access_token')
|
||||
failure_template = 'Failed to retrieve access token: %s'
|
||||
@@ -1288,22 +1287,20 @@ class BasicCredentialsTests(unittest2.TestCase):
|
||||
None, None, None, None, None, None, None,
|
||||
revoke_uri=oauth2client.GOOGLE_REVOKE_URI)
|
||||
credentials.store = store
|
||||
http_request = mock.Mock()
|
||||
# Make sure the mock doesn't have a request attr.
|
||||
del http_request.request
|
||||
http_request.return_value = response, content
|
||||
|
||||
http = http_mock.HttpMock(headers=response, data=content)
|
||||
token = u's3kr3tz'
|
||||
|
||||
if response.status == http_client.OK:
|
||||
self.assertFalse(credentials.invalid)
|
||||
self.assertIsNone(credentials._do_revoke(http_request, token))
|
||||
self.assertIsNone(credentials._do_revoke(http, token))
|
||||
self.assertTrue(credentials.invalid)
|
||||
if store is not None:
|
||||
store.delete.assert_called_once_with()
|
||||
else:
|
||||
self.assertFalse(credentials.invalid)
|
||||
with self.assertRaises(client.TokenRevokeError) as exc_manager:
|
||||
credentials._do_revoke(http_request, token)
|
||||
credentials._do_revoke(http, token)
|
||||
# Make sure invalid was not flipped on.
|
||||
self.assertFalse(credentials.invalid)
|
||||
self.assertEqual(exc_manager.exception.args, (error_msg,))
|
||||
@@ -1311,9 +1308,13 @@ class BasicCredentialsTests(unittest2.TestCase):
|
||||
store.delete.assert_not_called()
|
||||
|
||||
revoke_uri = oauth2client.GOOGLE_REVOKE_URI + '?token=' + token
|
||||
http_request.assert_called_once_with(
|
||||
revoke_uri, method='GET', body=None, headers=None,
|
||||
redirections=5, connection_type=None)
|
||||
|
||||
# Verify mocks.
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, revoke_uri)
|
||||
self.assertEqual(http.method, 'GET')
|
||||
self.assertIsNone(http.body)
|
||||
self.assertIsNone(http.headers)
|
||||
|
||||
logger.info.assert_called_once_with('Revoking token')
|
||||
|
||||
@@ -1359,21 +1360,18 @@ class BasicCredentialsTests(unittest2.TestCase):
|
||||
credentials = client.OAuth2Credentials(
|
||||
None, None, None, None, None, None, None,
|
||||
token_info_uri=oauth2client.GOOGLE_TOKEN_INFO_URI)
|
||||
http_request = mock.Mock()
|
||||
# Make sure the mock doesn't have a request attr.
|
||||
del http_request.request
|
||||
http_request.return_value = response, content
|
||||
http = http_mock.HttpMock(headers=response, data=content)
|
||||
token = u's3kr3tz'
|
||||
|
||||
if response.status == http_client.OK:
|
||||
self.assertEqual(credentials.scopes, set())
|
||||
self.assertIsNone(
|
||||
credentials._do_retrieve_scopes(http_request, token))
|
||||
credentials._do_retrieve_scopes(http, token))
|
||||
self.assertEqual(credentials.scopes, scopes)
|
||||
else:
|
||||
self.assertEqual(credentials.scopes, set())
|
||||
with self.assertRaises(client.Error) as exc_manager:
|
||||
credentials._do_retrieve_scopes(http_request, token)
|
||||
credentials._do_retrieve_scopes(http, token)
|
||||
# Make sure scopes were not changed.
|
||||
self.assertEqual(credentials.scopes, set())
|
||||
self.assertEqual(exc_manager.exception.args, (error_msg,))
|
||||
@@ -1381,12 +1379,13 @@ class BasicCredentialsTests(unittest2.TestCase):
|
||||
token_uri = client._update_query_params(
|
||||
oauth2client.GOOGLE_TOKEN_INFO_URI,
|
||||
{'fields': 'scope', 'access_token': token})
|
||||
self.assertEqual(len(http_request.mock_calls), 1)
|
||||
scopes_call = http_request.mock_calls[0]
|
||||
call_args = scopes_call[1]
|
||||
self.assertEqual(len(call_args), 1)
|
||||
called_uri = call_args[0]
|
||||
assertUrisEqual(self, token_uri, called_uri)
|
||||
|
||||
# Verify mocks.
|
||||
self.assertEqual(http.requests, 1)
|
||||
assertUrisEqual(self, token_uri, http.uri)
|
||||
self.assertEqual(http.method, 'GET')
|
||||
self.assertIsNone(http.body)
|
||||
self.assertIsNone(http.headers)
|
||||
logger.info.assert_called_once_with('Refreshing scopes')
|
||||
|
||||
def test__do_retrieve_scopes_success_bad_json(self):
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Oauth2client tests.
|
||||
"""oauth2client tests.
|
||||
|
||||
Unit tests for service account credentials implemented using RSA.
|
||||
"""
|
||||
@@ -24,13 +24,15 @@ import tempfile
|
||||
|
||||
import mock
|
||||
import rsa
|
||||
from six import BytesIO
|
||||
import six
|
||||
from six.moves import http_client
|
||||
import unittest2
|
||||
|
||||
from oauth2client import client
|
||||
from oauth2client import crypt
|
||||
from oauth2client import service_account
|
||||
from .http_mock import HttpMockSequence
|
||||
from oauth2client import transport
|
||||
from . import http_mock
|
||||
|
||||
|
||||
def data_filename(filename):
|
||||
@@ -180,7 +182,7 @@ class ServiceAccountCredentialsTests(unittest2.TestCase):
|
||||
scopes=scopes, token_uri=token_uri, revoke_uri=revoke_uri))
|
||||
creds_from_file_contents = (
|
||||
service_account.ServiceAccountCredentials.from_p12_keyfile_buffer(
|
||||
service_account_email, BytesIO(key_contents),
|
||||
service_account_email, six.BytesIO(key_contents),
|
||||
private_key_password=private_key_password,
|
||||
scopes=scopes, token_uri=token_uri, revoke_uri=revoke_uri))
|
||||
for creds in (creds_from_filename, creds_from_file_contents):
|
||||
@@ -301,10 +303,10 @@ class ServiceAccountCredentialsTests(unittest2.TestCase):
|
||||
'access_token': token2,
|
||||
'expires_in': lifetime,
|
||||
}
|
||||
http = HttpMockSequence([
|
||||
({'status': '200'},
|
||||
http = http_mock.HttpMockSequence([
|
||||
({'status': http_client.OK},
|
||||
json.dumps(token_response_first).encode('utf-8')),
|
||||
({'status': '200'},
|
||||
({'status': http_client.OK},
|
||||
json.dumps(token_response_second).encode('utf-8')),
|
||||
])
|
||||
|
||||
@@ -479,31 +481,34 @@ class JWTAccessCredentialsTests(unittest2.TestCase):
|
||||
utcnow.return_value = T1_DATE
|
||||
time.return_value = T1
|
||||
|
||||
def mock_request(uri, method='GET', body=None, headers=None,
|
||||
redirections=0, connection_type=None):
|
||||
self.assertEqual(uri, self.url)
|
||||
bearer, token = headers[b'Authorization'].split()
|
||||
http = http_mock.HttpMockSequence([
|
||||
({'status': http_client.OK}, b''),
|
||||
({'status': http_client.OK}, b''),
|
||||
])
|
||||
|
||||
self.jwt.authorize(http)
|
||||
transport.request(http, self.url)
|
||||
|
||||
# Ensure we use the cached token
|
||||
utcnow.return_value = T2_DATE
|
||||
transport.request(http, self.url)
|
||||
|
||||
# Verify mocks.
|
||||
certs = {'key': datafile('public_cert.pem')}
|
||||
self.assertEqual(len(http.requests), 2)
|
||||
for info in http.requests:
|
||||
self.assertEqual(info['method'], 'GET')
|
||||
self.assertEqual(info['uri'], self.url)
|
||||
self.assertIsNone(info['body'])
|
||||
self.assertEqual(len(info['headers']), 1)
|
||||
bearer, token = info['headers'][b'Authorization'].split()
|
||||
payload = crypt.verify_signed_jwt_with_certs(
|
||||
token,
|
||||
{'key': datafile('public_cert.pem')},
|
||||
audience=self.url)
|
||||
token, certs, audience=self.url)
|
||||
self.assertEqual(payload['iss'], self.service_account_email)
|
||||
self.assertEqual(payload['sub'], self.service_account_email)
|
||||
self.assertEqual(payload['iat'], T1)
|
||||
self.assertEqual(payload['exp'], T1_EXPIRY)
|
||||
self.assertEqual(uri, self.url)
|
||||
self.assertEqual(bearer, b'Bearer')
|
||||
response = mock.Mock(status=200)
|
||||
return response, b''
|
||||
|
||||
h = mock.Mock()
|
||||
h.request = mock_request
|
||||
self.jwt.authorize(h)
|
||||
h.request(self.url)
|
||||
|
||||
# Ensure we use the cached token
|
||||
utcnow.return_value = T2_DATE
|
||||
h.request(self.url)
|
||||
|
||||
@mock.patch('oauth2client.client._UTCNOW')
|
||||
@mock.patch('time.time')
|
||||
@@ -515,37 +520,41 @@ class JWTAccessCredentialsTests(unittest2.TestCase):
|
||||
self.service_account_email, self.signer,
|
||||
private_key_id=self.private_key_id, client_id=self.client_id)
|
||||
|
||||
def mock_request(uri, method='GET', body=None, headers=None,
|
||||
redirections=0, connection_type=None):
|
||||
self.assertEqual(uri, self.url)
|
||||
bearer, token = headers[b'Authorization'].split()
|
||||
http = http_mock.HttpMockSequence([
|
||||
({'status': http_client.OK}, b''),
|
||||
])
|
||||
|
||||
jwt.authorize(http)
|
||||
transport.request(http, self.url)
|
||||
|
||||
# Ensure we do not cache the token
|
||||
self.assertIsNone(jwt.access_token)
|
||||
|
||||
# Verify mocks.
|
||||
self.assertEqual(len(http.requests), 1)
|
||||
info = http.requests[0]
|
||||
self.assertEqual(info['method'], 'GET')
|
||||
self.assertEqual(info['uri'], self.url)
|
||||
self.assertIsNone(info['body'])
|
||||
self.assertEqual(len(info['headers']), 1)
|
||||
bearer, token = info['headers'][b'Authorization'].split()
|
||||
certs = {'key': datafile('public_cert.pem')}
|
||||
payload = crypt.verify_signed_jwt_with_certs(
|
||||
token,
|
||||
{'key': datafile('public_cert.pem')},
|
||||
audience=self.url)
|
||||
token, certs, audience=self.url)
|
||||
self.assertEqual(payload['iss'], self.service_account_email)
|
||||
self.assertEqual(payload['sub'], self.service_account_email)
|
||||
self.assertEqual(payload['iat'], T1)
|
||||
self.assertEqual(payload['exp'], T1_EXPIRY)
|
||||
self.assertEqual(uri, self.url)
|
||||
self.assertEqual(bearer, b'Bearer')
|
||||
response = mock.Mock(status=200)
|
||||
return response, b''
|
||||
|
||||
h = mock.Mock()
|
||||
h.request = mock_request
|
||||
jwt.authorize(h)
|
||||
h.request(self.url)
|
||||
|
||||
# Ensure we do not cache the token
|
||||
self.assertIsNone(jwt.access_token)
|
||||
|
||||
@mock.patch('oauth2client.client._UTCNOW')
|
||||
def test_authorize_stale_token(self, utcnow):
|
||||
utcnow.return_value = T1_DATE
|
||||
# Create an initial token
|
||||
h = HttpMockSequence([({'status': '200'}, b''),
|
||||
({'status': '200'}, b'')])
|
||||
h = http_mock.HttpMockSequence([
|
||||
({'status': http_client.OK}, b''),
|
||||
({'status': http_client.OK}, b''),
|
||||
])
|
||||
self.jwt.authorize(h)
|
||||
h.request(self.url)
|
||||
token_1 = self.jwt.access_token
|
||||
@@ -561,10 +570,11 @@ class JWTAccessCredentialsTests(unittest2.TestCase):
|
||||
def test_authorize_401(self, utcnow):
|
||||
utcnow.return_value = T1_DATE
|
||||
|
||||
h = HttpMockSequence([
|
||||
({'status': '200'}, b''),
|
||||
({'status': '401'}, b''),
|
||||
({'status': '200'}, b'')])
|
||||
h = http_mock.HttpMockSequence([
|
||||
({'status': http_client.OK}, b''),
|
||||
({'status': http_client.UNAUTHORIZED}, b''),
|
||||
({'status': http_client.OK}, b''),
|
||||
])
|
||||
self.jwt.authorize(h)
|
||||
h.request(self.url)
|
||||
token_1 = self.jwt.access_token
|
||||
|
||||
@@ -18,6 +18,7 @@ import unittest2
|
||||
|
||||
from oauth2client import client
|
||||
from oauth2client import transport
|
||||
from . import http_mock
|
||||
|
||||
|
||||
class TestMemoryCache(unittest2.TestCase):
|
||||
@@ -146,33 +147,35 @@ class Test_request(unittest2.TestCase):
|
||||
redirections = 3
|
||||
|
||||
def test_with_request_attr(self):
|
||||
http = mock.Mock()
|
||||
mock_result = object()
|
||||
mock_request = mock.Mock(return_value=mock_result)
|
||||
http.request = mock_request
|
||||
headers = {'foo': 'bar'}
|
||||
http = http_mock.HttpMock(headers=headers, data=mock_result)
|
||||
|
||||
result = transport.request(http, self.uri, method=self.method,
|
||||
body=self.body,
|
||||
response, content = transport.request(
|
||||
http, self.uri, method=self.method, body=self.body,
|
||||
redirections=self.redirections)
|
||||
self.assertIs(result, mock_result)
|
||||
# Verify mock.
|
||||
mock_request.assert_called_once_with(self.uri, method=self.method,
|
||||
body=self.body,
|
||||
redirections=self.redirections,
|
||||
headers=None,
|
||||
connection_type=None)
|
||||
self.assertEqual(response, headers)
|
||||
self.assertIs(content, mock_result)
|
||||
# Verify mocks.
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, self.uri)
|
||||
self.assertEqual(http.method, self.method)
|
||||
self.assertEqual(http.body, self.body)
|
||||
self.assertIsNone(http.headers)
|
||||
|
||||
def test_with_callable_http(self):
|
||||
headers = {}
|
||||
mock_result = object()
|
||||
http = mock.Mock(return_value=mock_result)
|
||||
del http.request # Make sure the mock doesn't have a request attr.
|
||||
http = http_mock.HttpMock(headers=headers, data=mock_result)
|
||||
|
||||
result = transport.request(http, self.uri, method=self.method,
|
||||
body=self.body,
|
||||
redirections=self.redirections)
|
||||
self.assertIs(result, mock_result)
|
||||
self.assertEqual(result, (headers, mock_result))
|
||||
# Verify mock.
|
||||
http.assert_called_once_with(self.uri, method=self.method,
|
||||
body=self.body,
|
||||
redirections=self.redirections,
|
||||
headers=None, connection_type=None)
|
||||
self.assertEqual(http.requests, 1)
|
||||
self.assertEqual(http.uri, self.uri)
|
||||
self.assertEqual(http.method, self.method)
|
||||
self.assertEqual(http.body, self.body)
|
||||
self.assertIsNone(http.headers)
|
||||
self.assertEqual(http.redirections, self.redirections)
|
||||
|
||||
Reference in New Issue
Block a user