Skip to content
This repository has been archived by the owner on Nov 5, 2019. It is now read-only.

Commit

Permalink
Merge pull request #605 from dhermes/unify-http-mocks
Browse files Browse the repository at this point in the history
Clean up usage of HTTP mocks in tests.
  • Loading branch information
dhermes committed Aug 10, 2016
2 parents 724181f + 8299c58 commit 2c44207
Show file tree
Hide file tree
Showing 7 changed files with 255 additions and 180 deletions.
86 changes: 61 additions & 25 deletions tests/contrib/appengine/test_appengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
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
Expand All @@ -50,6 +51,8 @@
"refresh_token": "foo_refresh_token"
}
"""
BASIC_TOKEN = 'bar'
BASIC_RESP = json.dumps({'access_token': BASIC_TOKEN})


def datafile(filename):
Expand Down Expand Up @@ -356,13 +359,6 @@ def test_validate(self):
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):
Expand Down Expand Up @@ -407,16 +403,36 @@ def test__is_ndb(self):
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')

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(
Expand All @@ -425,16 +441,17 @@ def test_get_and_put_cached(self):
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.
Expand All @@ -443,6 +460,9 @@ def test_get_and_put_cached(self):
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)
Expand All @@ -455,9 +475,13 @@ def test_get_and_put_set_store_on_cache_retrieval(self):
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
Expand All @@ -467,12 +491,16 @@ def test_get_and_put_ndb(self):

# 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(
Expand All @@ -498,14 +526,18 @@ def test_get_and_put_mixed_ndb_storage_db_get(self):

# 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(
Expand All @@ -514,14 +546,18 @@ def test_get_and_put_mixed_db_storage_ndb_get(self):

# 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(
Expand Down Expand Up @@ -981,11 +1017,11 @@ def test_decorator_from_client_secrets_with_optional_settings(self):
'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
})

Expand Down
25 changes: 17 additions & 8 deletions tests/contrib/test_gce.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@

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):
Expand Down Expand Up @@ -85,16 +86,24 @@ def test_refresh_token(self, get_info, get_token):
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()
Expand Down
77 changes: 44 additions & 33 deletions tests/contrib/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,52 +28,59 @@
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',
Expand All @@ -88,18 +95,22 @@ def test_get_token_success(self, now):
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)
Loading

0 comments on commit 2c44207

Please sign in to comment.