aboutsummaryrefslogtreecommitdiff
path: root/tests/test_tools.py
diff options
context:
space:
mode:
authorJon Wayne Parrott <jon.wayne.parrott@gmail.com>2016-03-15 19:39:51 -0700
committerJon Wayne Parrott <jon.wayne.parrott@gmail.com>2016-03-16 09:42:20 -0700
commit35aabeba999d567c1f00f6a80b2879527e512ff9 (patch)
tree48e11129d147d725178f931b83d3ca5caf8482b3 /tests/test_tools.py
parent5b280ec0a621a7bfd7c28bfcdc221efdd504b42f (diff)
downloadoauth2client-35aabeba999d567c1f00f6a80b2879527e512ff9.tar.gz
100% coverage for oauth2client.tools
Diffstat (limited to 'tests/test_tools.py')
-rw-r--r--tests/test_tools.py178
1 files changed, 173 insertions, 5 deletions
diff --git a/tests/test_tools.py b/tests/test_tools.py
index d0f0e10..b5e07db 100644
--- a/tests/test_tools.py
+++ b/tests/test_tools.py
@@ -1,12 +1,36 @@
-"""Unit tests for oauth2client.tools."""
+# Copyright 2016 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
-import unittest
-from oauth2client import tools
-from six.moves.urllib import request
+import socket
+import sys
import threading
+import mock
+from six.moves.urllib import request
+import unittest2
+
+from oauth2client.client import FlowExchangeError
+from oauth2client.client import OOB_CALLBACK_URN
+from oauth2client import tools
-class TestClientRedirectServer(unittest.TestCase):
+try:
+ import argparse
+except ImportError: # pragma: NO COVER
+ raise unittest2.SkipTest('argparase unavailable.')
+
+
+class TestClientRedirectServer(unittest2.TestCase):
"""Test the ClientRedirectServer and ClientRedirectHandler classes."""
def test_ClientRedirectServer(self):
@@ -27,5 +51,149 @@ class TestClientRedirectServer(unittest.TestCase):
self.assertEqual(httpd.query_params.get('code'), code)
+class TestRunFlow(unittest2.TestCase):
+
+ def setUp(self):
+ self.server = mock.Mock()
+ self.flow = mock.Mock()
+ self.storage = mock.Mock()
+ self.credentials = mock.Mock()
+
+ self.flow.step1_get_authorize_url.return_value = (
+ 'http://example.com/auth')
+ self.flow.step2_exchange.return_value = self.credentials
+
+ self.flags = argparse.Namespace(
+ noauth_local_webserver=True, logging_level='INFO')
+ self.server_flags = argparse.Namespace(
+ noauth_local_webserver=False,
+ logging_level='INFO',
+ auth_host_port=[8080,],
+ auth_host_name='localhost')
+
+ @mock.patch.object(sys, 'argv',
+ ['ignored', '--noauth_local_webserver'])
+ @mock.patch('oauth2client.tools.logging')
+ @mock.patch('oauth2client.tools.input')
+ def test_run_flow_no_webserver(self, input_mock, logging_mock):
+ input_mock.return_value = 'auth_code'
+
+ # Successful exchange.
+ returned_credentials = tools.run_flow(self.flow, self.storage)
+
+ self.assertEqual(self.credentials, returned_credentials)
+ self.assertEqual(self.flow.redirect_uri, OOB_CALLBACK_URN)
+ self.flow.step2_exchange.assert_called_once_with(
+ 'auth_code', http=None)
+ self.storage.put.assert_called_once_with(self.credentials)
+ self.credentials.set_store.assert_called_once_with(self.storage)
+
+ @mock.patch('oauth2client.tools.logging')
+ @mock.patch('oauth2client.tools.input')
+ def test_run_flow_no_webserver_explicit_flags(
+ self, input_mock, logging_mock):
+ input_mock.return_value = 'auth_code'
+
+ # Successful exchange.
+ returned_credentials = tools.run_flow(
+ self.flow, self.storage, flags=self.flags)
+
+ self.assertEqual(self.credentials, returned_credentials)
+ self.assertEqual(self.flow.redirect_uri, OOB_CALLBACK_URN)
+ self.flow.step2_exchange.assert_called_once_with(
+ 'auth_code', http=None)
+
+ @mock.patch('oauth2client.tools.logging')
+ @mock.patch('oauth2client.tools.input')
+ def test_run_flow_no_webserver_exchange_error(
+ self, input_mock, logging_mock):
+ input_mock.return_value = 'auth_code'
+ self.flow.step2_exchange.side_effect = FlowExchangeError()
+
+ # Error while exchanging.
+ with self.assertRaises(SystemExit):
+ tools.run_flow(self.flow, self.storage, flags=self.flags)
+
+ self.flow.step2_exchange.assert_called_once_with(
+ 'auth_code', http=None)
+
+ @mock.patch('oauth2client.tools.logging')
+ @mock.patch('oauth2client.tools.ClientRedirectServer')
+ @mock.patch('webbrowser.open')
+ def test_run_flow_webserver(
+ self, webbrowser_open_mock, server_ctor_mock, logging_mock):
+ server_ctor_mock.return_value = self.server
+ self.server.query_params = {'code': 'auth_code'}
+
+ # Successful exchange.
+ returned_credentials = tools.run_flow(
+ self.flow, self.storage, flags=self.server_flags)
+
+ self.assertEqual(self.credentials, returned_credentials)
+ self.assertEqual(self.flow.redirect_uri, 'http://localhost:8080/')
+ self.flow.step2_exchange.assert_called_once_with(
+ 'auth_code', http=None)
+ self.storage.put.assert_called_once_with(self.credentials)
+ self.credentials.set_store.assert_called_once_with(self.storage)
+ self.assertTrue(self.server.handle_request.called)
+ webbrowser_open_mock.assert_called_once_with(
+ 'http://example.com/auth', autoraise=True, new=1)
+
+ @mock.patch('oauth2client.tools.logging')
+ @mock.patch('oauth2client.tools.ClientRedirectServer')
+ @mock.patch('webbrowser.open')
+ def test_run_flow_webserver_exchange_error(
+ self, webbrowser_open_mock, server_ctor_mock, logging_mock):
+ server_ctor_mock.return_value = self.server
+ self.server.query_params = {'error': 'any error'}
+
+ # Exchange returned an error code.
+ with self.assertRaises(SystemExit):
+ returned_credentials = tools.run_flow(
+ self.flow, self.storage, flags=self.server_flags)
+
+ self.assertTrue(self.server.handle_request.called)
+
+ @mock.patch('oauth2client.tools.logging')
+ @mock.patch('oauth2client.tools.ClientRedirectServer')
+ @mock.patch('webbrowser.open')
+ def test_run_flow_webserver_no_code(
+ self, webbrowser_open_mock, server_ctor_mock, logging_mock):
+ server_ctor_mock.return_value = self.server
+ self.server.query_params = {}
+
+ # No code found in response
+ with self.assertRaises(SystemExit):
+ returned_credentials = tools.run_flow(
+ self.flow, self.storage, flags=self.server_flags)
+
+ self.assertTrue(self.server.handle_request.called)
+
+ @mock.patch('oauth2client.tools.logging')
+ @mock.patch('oauth2client.tools.ClientRedirectServer')
+ @mock.patch('oauth2client.tools.input')
+ def test_run_flow_webserver_fallback(
+ self, input_mock, server_ctor_mock, logging_mock):
+ server_ctor_mock.side_effect = socket.error()
+ input_mock.return_value = 'auth_code'
+
+ # It should catch the socket error and proceed as if
+ # noauth_local_webserver was specified.
+ returned_credentials = tools.run_flow(
+ self.flow, self.storage, flags=self.server_flags)
+
+ self.assertEqual(self.credentials, returned_credentials)
+ self.assertEqual(self.flow.redirect_uri, OOB_CALLBACK_URN)
+ self.flow.step2_exchange.assert_called_once_with(
+ 'auth_code', http=None)
+ self.assertTrue(server_ctor_mock.called)
+ self.assertFalse(self.server.handle_request.called)
+
+
+class TestMessageIfMissing(unittest2.TestCase):
+ def test_message_if_missing(self):
+ self.assertIn('somefile.txt', tools.message_if_missing('somefile.txt'))
+
+
if __name__ == '__main__': # pragma: NO COVER
unittest.main()