Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: third_party/google-endpoints/endpoints/test/api_config_manager_test.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/google-endpoints/endpoints/test/api_config_manager_test.py
diff --git a/third_party/google-endpoints/endpoints/test/api_config_manager_test.py b/third_party/google-endpoints/endpoints/test/api_config_manager_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..6c9efd9e89acfd87735ea74c93fe542b354dee47
--- /dev/null
+++ b/third_party/google-endpoints/endpoints/test/api_config_manager_test.py
@@ -0,0 +1,338 @@
+# 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.
+
+"""Unit tests for the api_config_manager module."""
+
+import re
+import unittest
+
+import endpoints.api_config_manager as api_config_manager
+
+
+class ApiConfigManagerTest(unittest.TestCase):
+
+ def setUp(self):
+ """Make ApiConfigManager with a few helpful fakes."""
+ self.config_manager = api_config_manager.ApiConfigManager()
+
+ def test_process_api_config_empty_response(self):
+ self.config_manager.process_api_config_response({})
+ actual_method = self.config_manager.lookup_rpc_method('guestbook_api.get',
+ 'v1')
+ self.assertEqual(None, actual_method)
+
+ def test_process_api_config_invalid_response(self):
+ self.config_manager.process_api_config_response({'name': 'foo'})
+ actual_method = self.config_manager.lookup_rpc_method('guestbook_api.get',
+ 'v1')
+ self.assertEqual(None, actual_method)
+
+ def test_process_api_config(self):
+ fake_method = {'httpMethod': 'GET',
+ 'path': 'greetings/{gid}',
+ 'rosyMethod': 'baz.bim'}
+ config = {'name': 'guestbook_api',
+ 'version': 'X',
+ 'methods': {'guestbook_api.foo.bar': fake_method}}
+ self.config_manager.process_api_config_response({'items': [config]})
+ actual_method = self.config_manager.lookup_rpc_method(
+ 'guestbook_api.foo.bar', 'X')
+ self.assertEqual(fake_method, actual_method)
+
+ def test_process_api_config_order_length(self):
+ test_method_info = (
+ ('guestbook_api.foo.bar', 'greetings/{gid}', 'baz.bim'),
+ ('guestbook_api.list', 'greetings', 'greetings.list'),
+ ('guestbook_api.f3', 'greetings/{gid}/sender/property/blah',
+ 'greetings.f3'),
+ ('guestbook_api.shortgreet', 'greet', 'greetings.short_greeting'))
+ methods = {}
+ for method_name, path, rosy_method in test_method_info:
+ method = {'httpMethod': 'GET',
+ 'path': path,
+ 'rosyMethod': rosy_method}
+ methods[method_name] = method
+ config = {'name': 'guestbook_api',
+ 'version': 'X',
+ 'methods': methods}
+ self.config_manager.process_api_config_response(
+ {'items': [config]})
+ # Make sure all methods appear in the result.
+ for method_name, _, _ in test_method_info:
+ self.assertIsNotNone(
+ self.config_manager.lookup_rpc_method(method_name, 'X'))
+ # Make sure paths and partial paths return the right methods.
+ self.assertEqual(
+ self.config_manager.lookup_rest_method(
+ 'guestbook_api/X/greetings', 'GET')[0],
+ 'guestbook_api.list')
+ self.assertEqual(
+ self.config_manager.lookup_rest_method(
+ 'guestbook_api/X/greetings/1', 'GET')[0],
+ 'guestbook_api.foo.bar')
+ self.assertEqual(
+ self.config_manager.lookup_rest_method(
+ 'guestbook_api/X/greetings/2/sender/property/blah', 'GET')[0],
+ 'guestbook_api.f3')
+ self.assertEqual(
+ self.config_manager.lookup_rest_method(
+ 'guestbook_api/X/greet', 'GET')[0],
+ 'guestbook_api.shortgreet')
+
+ def test_get_sorted_methods1(self):
+ test_method_info = (
+ ('name1', 'greetings', 'POST'),
+ ('name2', 'greetings', 'GET'),
+ ('name3', 'short/but/many/constants', 'GET'),
+ ('name4', 'greetings', ''),
+ ('name5', 'greetings/{gid}', 'GET'),
+ ('name6', 'greetings/{gid}', 'PUT'),
+ ('name7', 'a/b/{var}/{var2}', 'GET'))
+ methods = {}
+ for method_name, path, http_method in test_method_info:
+ method = {'httpMethod': http_method,
+ 'path': path}
+ methods[method_name] = method
+ sorted_methods = self.config_manager._get_sorted_methods(methods)
+
+ expected_data = [
+ ('name3', 'short/but/many/constants', 'GET'),
+ ('name7', 'a/b/{var}/{var2}', 'GET'),
+ ('name4', 'greetings', ''),
+ ('name2', 'greetings', 'GET'),
+ ('name1', 'greetings', 'POST'),
+ ('name5', 'greetings/{gid}', 'GET'),
+ ('name6', 'greetings/{gid}', 'PUT')]
+ expected_methods = [(name, {'httpMethod': http_method, 'path': path})
+ for name, path, http_method in expected_data]
+ self.assertEqual(expected_methods, sorted_methods)
+
+ def test_get_sorted_methods2(self):
+ test_method_info = (
+ ('name1', 'abcdefghi', 'GET'),
+ ('name2', 'foo', 'GET'),
+ ('name3', 'greetings', 'GET'),
+ ('name4', 'bar', 'POST'),
+ ('name5', 'baz', 'GET'),
+ ('name6', 'baz', 'PUT'),
+ ('name7', 'baz', 'DELETE'))
+ methods = {}
+ for method_name, path, http_method in test_method_info:
+ method = {'httpMethod': http_method,
+ 'path': path}
+ methods[method_name] = method
+ sorted_methods = self.config_manager._get_sorted_methods(methods)
+
+ # Single-part paths should be sorted by path name, http_method.
+ expected_data = [
+ ('name1', 'abcdefghi', 'GET'),
+ ('name4', 'bar', 'POST'),
+ ('name7', 'baz', 'DELETE'),
+ ('name5', 'baz', 'GET'),
+ ('name6', 'baz', 'PUT'),
+ ('name2', 'foo', 'GET'),
+ ('name3', 'greetings', 'GET')]
+ expected_methods = [(name, {'httpMethod': http_method, 'path': path})
+ for name, path, http_method in expected_data]
+ self.assertEqual(expected_methods, sorted_methods)
+
+ def test_process_api_config_convert_https(self):
+ """Test that the parsed API config has switched HTTPS to HTTP."""
+ config = {'name': 'guestbook_api',
+ 'version': 'X',
+ 'adapter': {'bns': 'https://localhost/_ah/spi',
+ 'type': 'lily'},
+ 'root': 'https://localhost/_ah/api',
+ 'methods': {}}
+ self.config_manager.process_api_config_response({'items': [config]})
+
+ self.assertEqual(
+ 'https://localhost/_ah/spi',
+ self.config_manager.configs[('guestbook_api', 'X')]['adapter']['bns'])
+ self.assertEqual(
+ 'https://localhost/_ah/api',
+ self.config_manager.configs[('guestbook_api', 'X')]['root'])
+
+ def test_save_lookup_rpc_method(self):
+ # First attempt, guestbook.get does not exist
+ actual_method = self.config_manager.lookup_rpc_method('guestbook_api.get',
+ 'v1')
+ self.assertEqual(None, actual_method)
+
+ # Now we manually save it, and should find it
+ fake_method = {'some': 'object'}
+ self.config_manager._save_rpc_method('guestbook_api.get', 'v1', fake_method)
+ actual_method = self.config_manager.lookup_rpc_method('guestbook_api.get',
+ 'v1')
+ self.assertEqual(fake_method, actual_method)
+
+ def test_save_lookup_rest_method(self):
+ # First attempt, guestbook.get does not exist
+ method_spec = self.config_manager.lookup_rest_method(
+ 'guestbook_api/v1/greetings/i', 'GET')
+ self.assertEqual((None, None, None), method_spec)
+
+ # Now we manually save it, and should find it
+ fake_method = {'httpMethod': 'GET',
+ 'path': 'greetings/{id}'}
+ self.config_manager._save_rest_method('guestbook_api.get', 'guestbook_api',
+ 'v1', fake_method)
+ method_name, method_spec, params = self.config_manager.lookup_rest_method(
+ 'guestbook_api/v1/greetings/i', 'GET')
+ self.assertEqual('guestbook_api.get', method_name)
+ self.assertEqual(fake_method, method_spec)
+ self.assertEqual({'id': 'i'}, params)
+
+ def test_lookup_rest_method_with_colon(self):
+ fake_method = {'httpMethod': 'GET',
+ 'path': 'greetings:testcolon'}
+ self.config_manager._save_rest_method('guestbook_api.get', 'guestbook_api',
+ 'v1', fake_method)
+ method_name, method_spec, params = self.config_manager.lookup_rest_method(
+ 'guestbook_api/v1/greetings%3Atestcolon', 'GET')
+ self.assertEqual('guestbook_api.get', method_name)
+ self.assertEqual(fake_method, method_spec)
+
+ def test_trailing_slash_optional(self):
+ # Create a typical get resource URL.
+ fake_method = {'httpMethod': 'GET', 'path': 'trailingslash'}
+ self.config_manager._save_rest_method('guestbook_api.trailingslash',
+ 'guestbook_api', 'v1', fake_method)
+
+ # Make sure we get this method when we query without a slash.
+ method_name, method_spec, params = self.config_manager.lookup_rest_method(
+ 'guestbook_api/v1/trailingslash', 'GET')
+ self.assertEqual('guestbook_api.trailingslash', method_name)
+ self.assertEqual(fake_method, method_spec)
+ self.assertEqual({}, params)
+
+ # Make sure we get this method when we query with a slash.
+ method_name, method_spec, params = self.config_manager.lookup_rest_method(
+ 'guestbook_api/v1/trailingslash/', 'GET')
+ self.assertEqual('guestbook_api.trailingslash', method_name)
+ self.assertEqual(fake_method, method_spec)
+ self.assertEqual({}, params)
+
+
+class ParameterizedPathTest(unittest.TestCase):
+
+ # <scrub>
+ # See http://cs/spi/tools/devserver/ParameterizedPathTest.java
+ # </scrub>
+ def test_invalid_variable_name_leading_digit(self):
+ self.assertEqual(
+ None, re.match(api_config_manager._PATH_VARIABLE_PATTERN, '1abc'))
+
+ # Ensure users can not add variables starting with !
+ # This is used for reserved variables (e.g. !name and !version)
+ def test_invalid_var_name_leading_exclamation(self):
+ self.assertEqual(
+ None, re.match(api_config_manager._PATH_VARIABLE_PATTERN, '!abc'))
+
+ def test_valid_variable_name(self):
+ self.assertEqual(
+ 'AbC1', re.match(api_config_manager._PATH_VARIABLE_PATTERN,
+ 'AbC1').group(0))
+
+ def assert_no_match(self, path, param_path):
+ """Assert that the given path does not match param_path pattern.
+
+ For example, /xyz/123 does not match /abc/{x}.
+
+ Args:
+ path: A string, the inbound request path.
+ param_path: A string, the parameterized path pattern to match against
+ this path.
+ """
+ config_manager = api_config_manager.ApiConfigManager
+ params = config_manager._compile_path_pattern(param_path).match(path)
+ self.assertEqual(None, params)
+
+ def test_prefix_no_match(self):
+ self.assert_no_match('/xyz/123', '/abc/{x}')
+
+ def test_suffix_no_match(self):
+ self.assert_no_match('/abc/123', '/abc/{x}/456')
+
+ def test_suffix_no_match_with_more_variables(self):
+ self.assert_no_match('/abc/456/123/789', '/abc/{x}/123/{y}/xyz')
+
+ def test_no_match_collection_with_item(self):
+ self.assert_no_match('/api/v1/resources/123', '/{name}/{version}/resources')
+
+ def assert_match(self, path, param_path, param_count):
+ """Assert that the given path does match param_path pattern.
+
+ For example, /abc/123 does not match /abc/{x}.
+
+ Args:
+ path: A string, the inbound request path.
+ param_path: A string, the parameterized path pattern to match against
+ this path.
+ param_count: An int, the expected number of parameters to match in
+ pattern.
+
+ Returns:
+ Dict mapping path variable name to path variable value.
+ """
+ config_manager = api_config_manager.ApiConfigManager
+ match = config_manager._compile_path_pattern(param_path).match(path)
+ self.assertTrue(match is not None) # Will be None if path was not matched
+ params = config_manager._get_path_params(match)
+ self.assertEquals(param_count, len(params))
+ return params
+
+ def test_one_variable_match(self):
+ params = self.assert_match('/abc/123', '/abc/{x}', 1)
+ self.assertEquals('123', params.get('x'))
+
+ def test_two_variable_match(self):
+ params = self.assert_match('/abc/456/123/789', '/abc/{x}/123/{y}', 2)
+ self.assertEquals('456', params.get('x'))
+ self.assertEquals('789', params.get('y'))
+
+ def test_message_variable_match(self):
+ params = self.assert_match('/abc/123', '/abc/{x.y}', 1)
+ self.assertEquals('123', params.get('x.y'))
+
+ def test_message_and_simple_variable_match(self):
+ params = self.assert_match('/abc/123/456', '/abc/{x.y.z}/{t}', 2)
+ self.assertEquals('123', params.get('x.y.z'))
+ self.assertEquals('456', params.get('t'))
+
+ def test_space_in_path(self):
+ params = self.assert_match('/abc/foo+bar', '/abc/{x}', 1)
+ self.assertEquals('foo bar', params.get('x'))
+
+ def assert_invalid_value(self, value):
+ """Assert that the path parameter value is not valid.
+
+ For example, /abc/3!:2 is invalid for /abc/{x}.
+
+ Args:
+ value: A string containing a variable value to check for validity.
+ """
+ param_path = '/abc/{x}'
+ path = '/abc/%s' % value
+ config_manager = api_config_manager.ApiConfigManager
+ params = config_manager._compile_path_pattern(param_path).match(path)
+ self.assertEqual(None, params)
+
+ def test_invalid_values(self):
+ for reserved in [':', '?', '#', '[', ']', '{', '}']:
+ self.assert_invalid_value('123%s' % reserved)
+
+
+if __name__ == '__main__':
+ unittest.main()

Powered by Google App Engine
This is Rietveld 408576698