Merge pull request #103 from craigcitro/master
Finish switching to mock from mox.
This commit is contained in:
@@ -33,7 +33,7 @@ import urlparse
|
||||
|
||||
import dev_appserver
|
||||
dev_appserver.fix_sys_path()
|
||||
import mox
|
||||
import mock
|
||||
import webapp2
|
||||
|
||||
from google.appengine.api import apiproxy_stub
|
||||
@@ -159,13 +159,9 @@ class TestAppAssertionCredentials(unittest.TestCase):
|
||||
'memcache', memcache_stub.MemcacheServiceStub())
|
||||
|
||||
scope = 'http://www.googleapis.com/scope'
|
||||
try:
|
||||
credentials = AppAssertionCredentials(scope)
|
||||
http = httplib2.Http()
|
||||
credentials.refresh(http)
|
||||
self.fail('Should have raised an AccessTokenRefreshError')
|
||||
except AccessTokenRefreshError:
|
||||
pass
|
||||
credentials = AppAssertionCredentials(scope)
|
||||
http = httplib2.Http()
|
||||
self.assertRaises(AccessTokenRefreshError, credentials.refresh, http)
|
||||
|
||||
def test_get_access_token_on_refresh(self):
|
||||
app_identity_stub = self.AppIdentityStubImpl()
|
||||
@@ -201,19 +197,19 @@ class TestAppAssertionCredentials(unittest.TestCase):
|
||||
def test_custom_service_account(self):
|
||||
scope = "http://www.googleapis.com/scope"
|
||||
account_id = "service_account_name_2@appspot.com"
|
||||
m = mox.Mox()
|
||||
m.StubOutWithMock(app_identity, 'get_access_token')
|
||||
app_identity.get_access_token(
|
||||
[scope], service_account_id=account_id).AndReturn(('a_token_456', None))
|
||||
m.ReplayAll()
|
||||
|
||||
credentials = AppAssertionCredentials(scope, service_account_id=account_id)
|
||||
http = httplib2.Http()
|
||||
credentials.refresh(http)
|
||||
m.VerifyAll()
|
||||
m.UnsetStubs()
|
||||
self.assertEqual('a_token_456', credentials.access_token)
|
||||
self.assertEqual(scope, credentials.scope)
|
||||
with mock.patch.object(app_identity, 'get_access_token',
|
||||
return_value=('a_token_456', None),
|
||||
autospec=True) as get_access_token:
|
||||
credentials = AppAssertionCredentials(
|
||||
scope, service_account_id=account_id)
|
||||
http = httplib2.Http()
|
||||
credentials.refresh(http)
|
||||
|
||||
self.assertEqual('a_token_456', credentials.access_token)
|
||||
self.assertEqual(scope, credentials.scope)
|
||||
get_access_token.assert_called_once_with(
|
||||
[scope], service_account_id=account_id)
|
||||
|
||||
def test_create_scoped_required_without_scopes(self):
|
||||
credentials = AppAssertionCredentials([])
|
||||
@@ -538,7 +534,8 @@ class DecoratorTests(unittest.TestCase):
|
||||
'wsgi.url_scheme': 'http',
|
||||
'HTTP_HOST': 'localhost',
|
||||
})
|
||||
users.get_current_user = user_mock()
|
||||
self.current_user = user_mock()
|
||||
users.get_current_user = self.current_user
|
||||
self.httplib2_orig = httplib2.Http
|
||||
httplib2.Http = Http2Mock
|
||||
|
||||
@@ -562,30 +559,28 @@ class DecoratorTests(unittest.TestCase):
|
||||
self.assertEqual('code', q['response_type'][0])
|
||||
self.assertEqual(False, self.decorator.has_credentials())
|
||||
|
||||
m = mox.Mox()
|
||||
m.StubOutWithMock(appengine, '_parse_state_value')
|
||||
appengine._parse_state_value('foo_path:xsrfkey123',
|
||||
mox.IgnoreArg()).AndReturn('foo_path')
|
||||
m.ReplayAll()
|
||||
with mock.patch.object(appengine, '_parse_state_value',
|
||||
return_value='foo_path',
|
||||
autospec=True) as parse_state_value:
|
||||
# Now simulate the callback to /oauth2callback.
|
||||
response = self.app.get('/oauth2callback', {
|
||||
'code': 'foo_access_code',
|
||||
'state': 'foo_path:xsrfkey123',
|
||||
})
|
||||
parts = response.headers['Location'].split('?', 1)
|
||||
self.assertEqual('http://localhost/foo_path', parts[0])
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
if self.decorator._token_response_param:
|
||||
response_query = urlparse.parse_qs(parts[1])
|
||||
response = response_query[self.decorator._token_response_param][0]
|
||||
self.assertEqual(Http2Mock.content,
|
||||
json.loads(urllib.unquote(response)))
|
||||
self.assertEqual(self.decorator.flow, self.decorator._tls.flow)
|
||||
self.assertEqual(self.decorator.credentials,
|
||||
self.decorator._tls.credentials)
|
||||
|
||||
# Now simulate the callback to /oauth2callback.
|
||||
response = self.app.get('/oauth2callback', {
|
||||
'code': 'foo_access_code',
|
||||
'state': 'foo_path:xsrfkey123',
|
||||
})
|
||||
parts = response.headers['Location'].split('?', 1)
|
||||
self.assertEqual('http://localhost/foo_path', parts[0])
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
if self.decorator._token_response_param:
|
||||
response = urlparse.parse_qs(
|
||||
parts[1])[self.decorator._token_response_param][0]
|
||||
self.assertEqual(Http2Mock.content, json.loads(urllib.unquote(response)))
|
||||
self.assertEqual(self.decorator.flow, self.decorator._tls.flow)
|
||||
self.assertEqual(self.decorator.credentials,
|
||||
self.decorator._tls.credentials)
|
||||
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
parse_state_value.assert_called_once_with(
|
||||
'foo_path:xsrfkey123', self.current_user)
|
||||
|
||||
# Now requesting the decorated path should work.
|
||||
response = self.app.get('/foo_path')
|
||||
@@ -599,13 +594,9 @@ class DecoratorTests(unittest.TestCase):
|
||||
|
||||
# Raising an exception still clears the Credentials.
|
||||
self.should_raise = True
|
||||
try:
|
||||
response = self.app.get('/foo_path')
|
||||
self.fail('Should have raised an exception.')
|
||||
except Exception:
|
||||
pass
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
self.assertRaises(Exception, self.app.get, '/foo_path')
|
||||
self.should_raise = False
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
|
||||
# Invalidate the stored Credentials.
|
||||
self.found_credentials.invalid = True
|
||||
@@ -623,37 +614,34 @@ class DecoratorTests(unittest.TestCase):
|
||||
response = self.app.get('/foo_path')
|
||||
self.assertTrue(response.status.startswith('302'))
|
||||
|
||||
m = mox.Mox()
|
||||
m.StubOutWithMock(appengine, '_parse_state_value')
|
||||
appengine._parse_state_value('foo_path:xsrfkey123',
|
||||
mox.IgnoreArg()).AndReturn('foo_path')
|
||||
m.ReplayAll()
|
||||
with mock.patch.object(appengine, '_parse_state_value',
|
||||
return_value='foo_path',
|
||||
autospec=True) as parse_state_value:
|
||||
# Now simulate the callback to /oauth2callback.
|
||||
response = self.app.get('/oauth2callback', {
|
||||
'code': 'foo_access_code',
|
||||
'state': 'foo_path:xsrfkey123',
|
||||
})
|
||||
self.assertEqual('http://localhost/foo_path', response.headers['Location'])
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
|
||||
# Now simulate the callback to /oauth2callback.
|
||||
response = self.app.get('/oauth2callback', {
|
||||
'code': 'foo_access_code',
|
||||
'state': 'foo_path:xsrfkey123',
|
||||
})
|
||||
self.assertEqual('http://localhost/foo_path', response.headers['Location'])
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
# Now requesting the decorated path should work.
|
||||
response = self.app.get('/foo_path')
|
||||
|
||||
# Now requesting the decorated path should work.
|
||||
response = self.app.get('/foo_path')
|
||||
self.assertTrue(self.had_credentials)
|
||||
|
||||
self.assertTrue(self.had_credentials)
|
||||
# Credentials should be cleared after each call.
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
|
||||
# Credentials should be cleared after each call.
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
# Invalidate the stored Credentials.
|
||||
self.found_credentials.store.delete()
|
||||
|
||||
# Invalidate the stored Credentials.
|
||||
self.found_credentials.store.delete()
|
||||
# Invalid Credentials should start the OAuth dance again.
|
||||
response = self.app.get('/foo_path')
|
||||
self.assertTrue(response.status.startswith('302'))
|
||||
|
||||
# Invalid Credentials should start the OAuth dance again.
|
||||
response = self.app.get('/foo_path')
|
||||
self.assertTrue(response.status.startswith('302'))
|
||||
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
parse_state_value.assert_called_once_with(
|
||||
'foo_path:xsrfkey123', self.current_user)
|
||||
|
||||
def test_aware(self):
|
||||
# An initial request to an oauth_aware decorated path should not redirect.
|
||||
@@ -670,23 +658,20 @@ class DecoratorTests(unittest.TestCase):
|
||||
q['state'][0].rsplit(':', 1)[0])
|
||||
self.assertEqual('code', q['response_type'][0])
|
||||
|
||||
m = mox.Mox()
|
||||
m.StubOutWithMock(appengine, '_parse_state_value')
|
||||
appengine._parse_state_value('bar_path:xsrfkey456',
|
||||
mox.IgnoreArg()).AndReturn('bar_path')
|
||||
m.ReplayAll()
|
||||
with mock.patch.object(appengine, '_parse_state_value',
|
||||
return_value='bar_path',
|
||||
autospec=True) as parse_state_value:
|
||||
# Now simulate the callback to /oauth2callback.
|
||||
url = self.decorator.authorize_url()
|
||||
response = self.app.get('/oauth2callback', {
|
||||
'code': 'foo_access_code',
|
||||
'state': 'bar_path:xsrfkey456',
|
||||
})
|
||||
|
||||
# Now simulate the callback to /oauth2callback.
|
||||
url = self.decorator.authorize_url()
|
||||
response = self.app.get('/oauth2callback', {
|
||||
'code': 'foo_access_code',
|
||||
'state': 'bar_path:xsrfkey456',
|
||||
})
|
||||
self.assertEqual('http://localhost/bar_path', response.headers['Location'])
|
||||
self.assertEqual(False, self.decorator.has_credentials())
|
||||
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
self.assertEqual('http://localhost/bar_path', response.headers['Location'])
|
||||
self.assertEqual(False, self.decorator.has_credentials())
|
||||
parse_state_value.assert_called_once_with(
|
||||
'bar_path:xsrfkey456', self.current_user)
|
||||
|
||||
# Now requesting the decorated path will have credentials.
|
||||
response = self.app.get('/bar_path/2012/01')
|
||||
@@ -703,13 +688,9 @@ class DecoratorTests(unittest.TestCase):
|
||||
|
||||
# Raising an exception still clears the Credentials.
|
||||
self.should_raise = True
|
||||
try:
|
||||
response = self.app.get('/bar_path/2012/01')
|
||||
self.fail('Should have raised an exception.')
|
||||
except Exception:
|
||||
pass
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
self.assertRaises(Exception, self.app.get, '/bar_path/2012/01')
|
||||
self.should_raise = False
|
||||
self.assertEqual(None, self.decorator.credentials)
|
||||
|
||||
|
||||
def test_error_in_step2(self):
|
||||
|
||||
@@ -20,13 +20,11 @@ Unit tests for oauth2client.gce.
|
||||
|
||||
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
|
||||
import httplib2
|
||||
try:
|
||||
from mox3 import mox
|
||||
except ImportError:
|
||||
import mox
|
||||
import unittest
|
||||
|
||||
import httplib2
|
||||
import mock
|
||||
|
||||
from oauth2client.client import AccessTokenRefreshError
|
||||
from oauth2client.client import Credentials
|
||||
from oauth2client.client import save_to_well_known_file
|
||||
@@ -36,56 +34,29 @@ from oauth2client.gce import AppAssertionCredentials
|
||||
class AssertionCredentialsTests(unittest.TestCase):
|
||||
|
||||
def test_good_refresh(self):
|
||||
m = mox.Mox()
|
||||
|
||||
httplib2_response = m.CreateMock(object)
|
||||
httplib2_response.status = 200
|
||||
|
||||
httplib2_request = m.CreateMock(object)
|
||||
httplib2_request.__call__(
|
||||
('http://metadata.google.internal/0.1/meta-data/service-accounts/'
|
||||
'default/acquire'
|
||||
'?scope=http%3A%2F%2Fexample.com%2Fa%20http%3A%2F%2Fexample.com%2Fb'
|
||||
)).AndReturn((httplib2_response, '{"accessToken": "this-is-a-token"}'))
|
||||
|
||||
m.ReplayAll()
|
||||
http = mock.MagicMock()
|
||||
http.request = mock.MagicMock(
|
||||
return_value=(mock.Mock(status=200),
|
||||
'{"accessToken": "this-is-a-token"}'))
|
||||
|
||||
c = AppAssertionCredentials(scope=['http://example.com/a',
|
||||
'http://example.com/b'])
|
||||
|
||||
c._refresh(httplib2_request)
|
||||
|
||||
self.assertEquals(None, c.access_token)
|
||||
c.refresh(http)
|
||||
self.assertEquals('this-is-a-token', c.access_token)
|
||||
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
http.request.assert_called_exactly_once_with(
|
||||
'http://metadata.google.internal/0.1/meta-data/service-accounts/'
|
||||
'default/acquire'
|
||||
'?scope=http%3A%2F%2Fexample.com%2Fa%20http%3A%2F%2Fexample.com%2Fb')
|
||||
|
||||
def test_fail_refresh(self):
|
||||
m = mox.Mox()
|
||||
|
||||
httplib2_response = m.CreateMock(object)
|
||||
httplib2_response.status = 400
|
||||
|
||||
httplib2_request = m.CreateMock(object)
|
||||
httplib2_request.__call__(
|
||||
('http://metadata.google.internal/0.1/meta-data/service-accounts/'
|
||||
'default/acquire'
|
||||
'?scope=http%3A%2F%2Fexample.com%2Fa%20http%3A%2F%2Fexample.com%2Fb'
|
||||
)).AndReturn((httplib2_response, '{"accessToken": "this-is-a-token"}'))
|
||||
|
||||
m.ReplayAll()
|
||||
http = mock.MagicMock()
|
||||
http.request = mock.MagicMock(return_value=(mock.Mock(status=400), '{}'))
|
||||
|
||||
c = AppAssertionCredentials(scope=['http://example.com/a',
|
||||
'http://example.com/b'])
|
||||
|
||||
try:
|
||||
c._refresh(httplib2_request)
|
||||
self.fail('Should have raised exception on 400')
|
||||
except AccessTokenRefreshError:
|
||||
pass
|
||||
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
self.assertRaises(AccessTokenRefreshError, c.refresh, http)
|
||||
|
||||
def test_to_from_json(self):
|
||||
c = AppAssertionCredentials(scope=['http://example.com/a',
|
||||
@@ -111,30 +82,19 @@ class AssertionCredentialsTests(unittest.TestCase):
|
||||
self.assertEqual('dummy_scope', new_credentials.scope)
|
||||
|
||||
def test_get_access_token(self):
|
||||
m = mox.Mox()
|
||||
|
||||
httplib2_response = m.CreateMock(object)
|
||||
httplib2_response.status = 200
|
||||
|
||||
httplib2_request = m.CreateMock(object)
|
||||
httplib2_request.__call__(
|
||||
('http://metadata.google.internal/0.1/meta-data/service-accounts/'
|
||||
'default/acquire?scope=dummy_scope'
|
||||
)).AndReturn((httplib2_response, '{"accessToken": "this-is-a-token"}'))
|
||||
|
||||
m.ReplayAll()
|
||||
http = mock.MagicMock()
|
||||
http.request = mock.MagicMock(
|
||||
return_value=(mock.Mock(status=200),
|
||||
'{"accessToken": "this-is-a-token"}'))
|
||||
|
||||
credentials = AppAssertionCredentials(['dummy_scope'])
|
||||
|
||||
http = httplib2.Http()
|
||||
http.request = httplib2_request
|
||||
|
||||
token = credentials.get_access_token(http=http)
|
||||
self.assertEqual('this-is-a-token', token.access_token)
|
||||
self.assertEqual(None, token.expires_in)
|
||||
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
http.request.assert_called_exactly_once_with(
|
||||
'http://metadata.google.internal/0.1/meta-data/service-accounts/'
|
||||
'default/acquire?scope=dummy_scope')
|
||||
|
||||
def test_save_to_well_known_file(self):
|
||||
credentials = AppAssertionCredentials([])
|
||||
|
||||
@@ -23,10 +23,8 @@ __author__ = 'jcgregorio@google.com (Joe Gregorio)'
|
||||
import datetime
|
||||
import keyring
|
||||
import unittest
|
||||
try:
|
||||
from mox3 import mox
|
||||
except ImportError:
|
||||
import mox
|
||||
|
||||
import mock
|
||||
|
||||
from oauth2client import GOOGLE_TOKEN_URI
|
||||
from oauth2client.client import OAuth2Credentials
|
||||
@@ -36,32 +34,22 @@ from oauth2client.keyring_storage import Storage
|
||||
class OAuth2ClientKeyringTests(unittest.TestCase):
|
||||
|
||||
def test_non_existent_credentials_storage(self):
|
||||
m = mox.Mox()
|
||||
m.StubOutWithMock(keyring, 'get_password')
|
||||
m.StubOutWithMock(keyring, 'set_password')
|
||||
keyring.get_password('my_unit_test', 'me').AndReturn(None)
|
||||
m.ReplayAll()
|
||||
|
||||
s = Storage('my_unit_test', 'me')
|
||||
credentials = s.get()
|
||||
self.assertEquals(None, credentials)
|
||||
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
with mock.patch.object(keyring, 'get_password',
|
||||
return_value=None,
|
||||
autospec=True) as get_password:
|
||||
s = Storage('my_unit_test', 'me')
|
||||
credentials = s.get()
|
||||
self.assertEquals(None, credentials)
|
||||
get_password.assert_called_once_with('my_unit_test', 'me')
|
||||
|
||||
def test_malformed_credentials_in_storage(self):
|
||||
m = mox.Mox()
|
||||
m.StubOutWithMock(keyring, 'get_password')
|
||||
m.StubOutWithMock(keyring, 'set_password')
|
||||
keyring.get_password('my_unit_test', 'me').AndReturn('{')
|
||||
m.ReplayAll()
|
||||
|
||||
s = Storage('my_unit_test', 'me')
|
||||
credentials = s.get()
|
||||
self.assertEquals(None, credentials)
|
||||
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
with mock.patch.object(keyring, 'get_password',
|
||||
return_value='{',
|
||||
autospec=True) as get_password:
|
||||
s = Storage('my_unit_test', 'me')
|
||||
credentials = s.get()
|
||||
self.assertEquals(None, credentials)
|
||||
get_password.assert_called_once_with('my_unit_test', 'me')
|
||||
|
||||
def test_json_credentials_storage(self):
|
||||
access_token = 'foo'
|
||||
@@ -76,22 +64,28 @@ class OAuth2ClientKeyringTests(unittest.TestCase):
|
||||
refresh_token, token_expiry, GOOGLE_TOKEN_URI,
|
||||
user_agent)
|
||||
|
||||
m = mox.Mox()
|
||||
m.StubOutWithMock(keyring, 'get_password')
|
||||
m.StubOutWithMock(keyring, 'set_password')
|
||||
keyring.get_password('my_unit_test', 'me').AndReturn(None)
|
||||
keyring.set_password('my_unit_test', 'me', credentials.to_json())
|
||||
keyring.get_password('my_unit_test', 'me').AndReturn(credentials.to_json())
|
||||
m.ReplayAll()
|
||||
# Setting autospec on a mock with an iterable side_effect is
|
||||
# currently broken (http://bugs.python.org/issue17826), so instead
|
||||
# we patch twice.
|
||||
with mock.patch.object(keyring, 'get_password',
|
||||
return_value=None,
|
||||
autospec=True) as get_password:
|
||||
with mock.patch.object(keyring, 'set_password',
|
||||
return_value=None,
|
||||
autospec=True) as set_password:
|
||||
s = Storage('my_unit_test', 'me')
|
||||
self.assertEquals(None, s.get())
|
||||
|
||||
s = Storage('my_unit_test', 'me')
|
||||
self.assertEquals(None, s.get())
|
||||
s.put(credentials)
|
||||
|
||||
s.put(credentials)
|
||||
set_password.assert_called_once_with(
|
||||
'my_unit_test', 'me', credentials.to_json())
|
||||
get_password.assert_called_once_with('my_unit_test', 'me')
|
||||
|
||||
restored = s.get()
|
||||
self.assertEqual('foo', restored.access_token)
|
||||
self.assertEqual('some_client_id', restored.client_id)
|
||||
|
||||
m.UnsetStubs()
|
||||
m.VerifyAll()
|
||||
with mock.patch.object(keyring, 'get_password',
|
||||
return_value=credentials.to_json(),
|
||||
autospec=True) as get_password:
|
||||
restored = s.get()
|
||||
self.assertEqual('foo', restored.access_token)
|
||||
self.assertEqual('some_client_id', restored.client_id)
|
||||
get_password.assert_called_once_with('my_unit_test', 'me')
|
||||
|
||||
@@ -206,16 +206,19 @@ class GoogleCredentialsTests(unittest.TestCase):
|
||||
|
||||
def test_get_environment_gce_production(self):
|
||||
os.environ['SERVER_SOFTWARE'] = ''
|
||||
with mock.patch.object(urllib.request, 'urlopen') as urlopen:
|
||||
urlopen.return_value = MockResponse(['Metadata-Flavor: Google\r\n'])
|
||||
response = MockResponse(['Metadata-Flavor: Google\r\n'])
|
||||
with mock.patch.object(urllib.request, 'urlopen',
|
||||
return_value=response,
|
||||
autospec=True) as urlopen:
|
||||
self.assertEqual('GCE_PRODUCTION', _get_environment())
|
||||
urlopen.assert_called_once_with(
|
||||
'http://metadata.google.internal/', timeout=1)
|
||||
|
||||
def test_get_environment_unknown(self):
|
||||
os.environ['SERVER_SOFTWARE'] = ''
|
||||
with mock.patch.object(urllib.request, 'urlopen') as urlopen:
|
||||
urlopen.return_value = MockResponse([])
|
||||
with mock.patch.object(urllib.request, 'urlopen',
|
||||
return_value=MockResponse([]),
|
||||
autospec=True) as urlopen:
|
||||
self.assertEqual(DEFAULT_ENV_NAME, _get_environment())
|
||||
urlopen.assert_called_once_with(
|
||||
'http://metadata.google.internal/', timeout=1)
|
||||
|
||||
Reference in New Issue
Block a user