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