1# Copyright 2015 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 googleapiclient._helpers.""" 16 17import unittest 18 19import mock 20 21import six 22from six.moves import urllib 23 24from googleapiclient import _helpers 25 26 27class PositionalTests(unittest.TestCase): 28 29 def test_usage(self): 30 _helpers.positional_parameters_enforcement = ( 31 _helpers.POSITIONAL_EXCEPTION) 32 33 # 1 positional arg, 1 keyword-only arg. 34 @_helpers.positional(1) 35 def function(pos, kwonly=None): 36 return True 37 38 self.assertTrue(function(1)) 39 self.assertTrue(function(1, kwonly=2)) 40 with self.assertRaises(TypeError): 41 function(1, 2) 42 43 # No positional, but a required keyword arg. 44 @_helpers.positional(0) 45 def function2(required_kw): 46 return True 47 48 self.assertTrue(function2(required_kw=1)) 49 with self.assertRaises(TypeError): 50 function2(1) 51 52 # Unspecified positional, should automatically figure out 1 positional 53 # 1 keyword-only (same as first case above). 54 @_helpers.positional 55 def function3(pos, kwonly=None): 56 return True 57 58 self.assertTrue(function3(1)) 59 self.assertTrue(function3(1, kwonly=2)) 60 with self.assertRaises(TypeError): 61 function3(1, 2) 62 63 @mock.patch('googleapiclient._helpers.logger') 64 def test_enforcement_warning(self, mock_logger): 65 _helpers.positional_parameters_enforcement = ( 66 _helpers.POSITIONAL_WARNING) 67 68 @_helpers.positional(1) 69 def function(pos, kwonly=None): 70 return True 71 72 self.assertTrue(function(1, 2)) 73 self.assertTrue(mock_logger.warning.called) 74 75 @mock.patch('googleapiclient._helpers.logger') 76 def test_enforcement_ignore(self, mock_logger): 77 _helpers.positional_parameters_enforcement = _helpers.POSITIONAL_IGNORE 78 79 @_helpers.positional(1) 80 def function(pos, kwonly=None): 81 return True 82 83 self.assertTrue(function(1, 2)) 84 self.assertFalse(mock_logger.warning.called) 85 86 87class AddQueryParameterTests(unittest.TestCase): 88 89 def test__add_query_parameter(self): 90 self.assertEqual( 91 _helpers._add_query_parameter('/action', 'a', None), 92 '/action') 93 self.assertEqual( 94 _helpers._add_query_parameter('/action', 'a', 'b'), 95 '/action?a=b') 96 self.assertEqual( 97 _helpers._add_query_parameter('/action?a=b', 'a', 'c'), 98 '/action?a=c') 99 # Order is non-deterministic. 100 self.assertIn( 101 _helpers._add_query_parameter('/action?a=b', 'c', 'd'), 102 ['/action?a=b&c=d', '/action?c=d&a=b']) 103 self.assertEqual( 104 _helpers._add_query_parameter('/action', 'a', ' ='), 105 '/action?a=+%3D') 106 107 108def assertUrisEqual(testcase, expected, actual): 109 """Test that URIs are the same, up to reordering of query parameters.""" 110 expected = urllib.parse.urlparse(expected) 111 actual = urllib.parse.urlparse(actual) 112 testcase.assertEqual(expected.scheme, actual.scheme) 113 testcase.assertEqual(expected.netloc, actual.netloc) 114 testcase.assertEqual(expected.path, actual.path) 115 testcase.assertEqual(expected.params, actual.params) 116 testcase.assertEqual(expected.fragment, actual.fragment) 117 expected_query = urllib.parse.parse_qs(expected.query) 118 actual_query = urllib.parse.parse_qs(actual.query) 119 for name in expected_query.keys(): 120 testcase.assertEqual(expected_query[name], actual_query[name]) 121 for name in actual_query.keys(): 122 testcase.assertEqual(expected_query[name], actual_query[name]) 123 124 125class Test_update_query_params(unittest.TestCase): 126 127 def test_update_query_params_no_params(self): 128 uri = 'http://www.google.com' 129 updated = _helpers.update_query_params(uri, {'a': 'b'}) 130 self.assertEqual(updated, uri + '?a=b') 131 132 def test_update_query_params_existing_params(self): 133 uri = 'http://www.google.com?x=y' 134 updated = _helpers.update_query_params(uri, {'a': 'b', 'c': 'd&'}) 135 hardcoded_update = uri + '&a=b&c=d%26' 136 assertUrisEqual(self, updated, hardcoded_update) 137 138 def test_update_query_params_replace_param(self): 139 base_uri = 'http://www.google.com' 140 uri = base_uri + '?x=a' 141 updated = _helpers.update_query_params(uri, {'x': 'b', 'y': 'c'}) 142 hardcoded_update = base_uri + '?x=b&y=c' 143 assertUrisEqual(self, updated, hardcoded_update) 144 145 def test_update_query_params_repeated_params(self): 146 uri = 'http://www.google.com?x=a&x=b' 147 with self.assertRaises(ValueError): 148 _helpers.update_query_params(uri, {'a': 'c'}) 149 150 151class Test_parse_unique_urlencoded(unittest.TestCase): 152 153 def test_without_repeats(self): 154 content = 'a=b&c=d' 155 result = _helpers.parse_unique_urlencoded(content) 156 self.assertEqual(result, {'a': 'b', 'c': 'd'}) 157 158 def test_with_repeats(self): 159 content = 'a=b&a=d' 160 with self.assertRaises(ValueError): 161 _helpers.parse_unique_urlencoded(content) 162