1# Copyright 2014 Google Inc. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Unit tests for oauth2client.clientsecrets.""" 16 17__author__ = 'jcgregorio@google.com (Joe Gregorio)' 18 19 20import os 21import unittest 22from io import StringIO 23 24import httplib2 25 26from oauth2client import clientsecrets 27 28 29DATA_DIR = os.path.join(os.path.dirname(__file__), 'data') 30VALID_FILE = os.path.join(DATA_DIR, 'client_secrets.json') 31INVALID_FILE = os.path.join(DATA_DIR, 'unfilled_client_secrets.json') 32NONEXISTENT_FILE = os.path.join(__file__, '..', 'afilethatisntthere.json') 33 34class OAuth2CredentialsTests(unittest.TestCase): 35 36 def setUp(self): 37 pass 38 39 def tearDown(self): 40 pass 41 42 def test_validate_error(self): 43 ERRORS = [ 44 ('{}', 'Invalid'), 45 ('{"foo": {}}', 'Unknown'), 46 ('{"web": {}}', 'Missing'), 47 ('{"web": {"client_id": "dkkd"}}', 'Missing'), 48 ("""{ 49 "web": { 50 "client_id": "[[CLIENT ID REQUIRED]]", 51 "client_secret": "[[CLIENT SECRET REQUIRED]]", 52 "redirect_uris": ["http://localhost:8080/oauth2callback"], 53 "auth_uri": "", 54 "token_uri": "" 55 } 56 } 57 """, 'Property'), 58 ] 59 for src, match in ERRORS: 60 # Ensure that it is unicode 61 try: 62 src = src.decode('utf-8') 63 except AttributeError: 64 pass 65 # Test load(s) 66 try: 67 clientsecrets.loads(src) 68 self.fail(src + ' should not be a valid client_secrets file.') 69 except clientsecrets.InvalidClientSecretsError as e: 70 self.assertTrue(str(e).startswith(match)) 71 72 # Test loads(fp) 73 try: 74 fp = StringIO(src) 75 clientsecrets.load(fp) 76 self.fail(src + ' should not be a valid client_secrets file.') 77 except clientsecrets.InvalidClientSecretsError as e: 78 self.assertTrue(str(e).startswith(match)) 79 80 def test_load_by_filename(self): 81 try: 82 clientsecrets._loadfile(NONEXISTENT_FILE) 83 self.fail('should fail to load a missing client_secrets file.') 84 except clientsecrets.InvalidClientSecretsError as e: 85 self.assertTrue(str(e).startswith('File')) 86 87 88class CachedClientsecretsTests(unittest.TestCase): 89 90 class CacheMock(object): 91 def __init__(self): 92 self.cache = {} 93 self.last_get_ns = None 94 self.last_set_ns = None 95 96 def get(self, key, namespace=''): 97 # ignoring namespace for easier testing 98 self.last_get_ns = namespace 99 return self.cache.get(key, None) 100 101 def set(self, key, value, namespace=''): 102 # ignoring namespace for easier testing 103 self.last_set_ns = namespace 104 self.cache[key] = value 105 106 def setUp(self): 107 self.cache_mock = self.CacheMock() 108 109 def test_cache_miss(self): 110 client_type, client_info = clientsecrets.loadfile( 111 VALID_FILE, cache=self.cache_mock) 112 self.assertEqual('web', client_type) 113 self.assertEqual('foo_client_secret', client_info['client_secret']) 114 115 cached = self.cache_mock.cache[VALID_FILE] 116 self.assertEqual({client_type: client_info}, cached) 117 118 # make sure we're using non-empty namespace 119 ns = self.cache_mock.last_set_ns 120 self.assertTrue(bool(ns)) 121 # make sure they're equal 122 self.assertEqual(ns, self.cache_mock.last_get_ns) 123 124 def test_cache_hit(self): 125 self.cache_mock.cache[NONEXISTENT_FILE] = { 'web': 'secret info' } 126 127 client_type, client_info = clientsecrets.loadfile( 128 NONEXISTENT_FILE, cache=self.cache_mock) 129 self.assertEqual('web', client_type) 130 self.assertEqual('secret info', client_info) 131 # make sure we didn't do any set() RPCs 132 self.assertEqual(None, self.cache_mock.last_set_ns) 133 134 def test_validation(self): 135 try: 136 clientsecrets.loadfile(INVALID_FILE, cache=self.cache_mock) 137 self.fail('Expected InvalidClientSecretsError to be raised ' 138 'while loading %s' % INVALID_FILE) 139 except clientsecrets.InvalidClientSecretsError: 140 pass 141 142 def test_without_cache(self): 143 # this also ensures loadfile() is backward compatible 144 client_type, client_info = clientsecrets.loadfile(VALID_FILE) 145 self.assertEqual('web', client_type) 146 self.assertEqual('foo_client_secret', client_info['client_secret']) 147 148 149if __name__ == '__main__': 150 unittest.main() 151