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

Unified Diff: third_party/google-endpoints/endpoints/test/openapi_generator_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/openapi_generator_test.py
diff --git a/third_party/google-endpoints/endpoints/test/openapi_generator_test.py b/third_party/google-endpoints/endpoints/test/openapi_generator_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..5ee656cc3cac04eb0ec364b020a52cc1ef1646a5
--- /dev/null
+++ b/third_party/google-endpoints/endpoints/test/openapi_generator_test.py
@@ -0,0 +1,913 @@
+# 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.
+
+"""Tests for endpoints.openapi_generator."""
+
+import json
+import unittest
+
+import endpoints.api_config as api_config
+
+from protorpc import message_types
+from protorpc import messages
+from protorpc import remote
+
+import endpoints.resource_container as resource_container
+import endpoints.openapi_generator as openapi_generator
+import test_util
+
+
+package = 'OpenApiGeneratorTest'
+
+
+class Nested(messages.Message):
+ """Message class to be used in a message field."""
+ int_value = messages.IntegerField(1)
+ string_value = messages.StringField(2)
+
+
+class SimpleEnum(messages.Enum):
+ """Simple enumeration type."""
+ VAL1 = 1
+ VAL2 = 2
+
+
+class AllFields(messages.Message):
+ """Contains all field types."""
+
+ bool_value = messages.BooleanField(1, variant=messages.Variant.BOOL)
+ bytes_value = messages.BytesField(2, variant=messages.Variant.BYTES)
+ double_value = messages.FloatField(3, variant=messages.Variant.DOUBLE)
+ enum_value = messages.EnumField(SimpleEnum, 4)
+ float_value = messages.FloatField(5, variant=messages.Variant.FLOAT)
+ int32_value = messages.IntegerField(6, variant=messages.Variant.INT32)
+ int64_value = messages.IntegerField(7, variant=messages.Variant.INT64)
+ string_value = messages.StringField(8, variant=messages.Variant.STRING)
+ uint32_value = messages.IntegerField(9, variant=messages.Variant.UINT32)
+ uint64_value = messages.IntegerField(10, variant=messages.Variant.UINT64)
+ sint32_value = messages.IntegerField(11, variant=messages.Variant.SINT32)
+ sint64_value = messages.IntegerField(12, variant=messages.Variant.SINT64)
+ message_field_value = messages.MessageField(Nested, 13)
+ datetime_value = message_types.DateTimeField(14)
+
+
+# This is used test "all fields" as query parameters instead of the body
+# in a request.
+ALL_FIELDS_AS_PARAMETERS = resource_container.ResourceContainer(
+ **{field.name: field for field in AllFields.all_fields()})
+
+
+class BaseOpenApiGeneratorTest(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.maxDiff = None
+
+ def setUp(self):
+ self.generator = openapi_generator.OpenApiGenerator()
+
+ def _def_path(self, path):
+ return '#/definitions/' + path
+
+
+class OpenApiGeneratorTest(BaseOpenApiGeneratorTest):
+
+ def testAllFieldTypes(self):
+
+ class PutRequest(messages.Message):
+ """Message with just a body field."""
+ body = messages.MessageField(AllFields, 1)
+
+ # pylint: disable=invalid-name
+ class ItemsPutRequest(messages.Message):
+ """Message with path params and a body field."""
+ body = messages.MessageField(AllFields, 1)
+ entryId = messages.StringField(2, required=True)
+
+ class ItemsPutRequestForContainer(messages.Message):
+ """Message with path params and a body field."""
+ body = messages.MessageField(AllFields, 1)
+ items_put_request_container = resource_container.ResourceContainer(
+ ItemsPutRequestForContainer,
+ entryId=messages.StringField(2, required=True))
+
+ # pylint: disable=invalid-name
+ class EntryPublishRequest(messages.Message):
+ """Message with two required params, one in path, one in body."""
+ title = messages.StringField(1, required=True)
+ entryId = messages.StringField(2, required=True)
+
+ class EntryPublishRequestForContainer(messages.Message):
+ """Message with two required params, one in path, one in body."""
+ title = messages.StringField(1, required=True)
+ entry_publish_request_container = resource_container.ResourceContainer(
+ EntryPublishRequestForContainer,
+ entryId=messages.StringField(2, required=True))
+
+ class BooleanMessageResponse(messages.Message):
+ result = messages.BooleanField(1, required=True)
+
+ @api_config.api(name='root', hostname='example.appspot.com', version='v1')
+ class MyService(remote.Service):
+ """Describes MyService."""
+
+ @api_config.method(AllFields, message_types.VoidMessage, path='entries',
+ http_method='GET', name='entries.get')
+ def entries_get(self, unused_request):
+ """All field types in the query parameters."""
+ return message_types.VoidMessage()
+
+ @api_config.method(ALL_FIELDS_AS_PARAMETERS, message_types.VoidMessage,
+ path='entries/container', http_method='GET',
+ name='entries.getContainer')
+ def entries_get_container(self, unused_request):
+ """All field types in the query parameters."""
+ return message_types.VoidMessage()
+
+ @api_config.method(PutRequest, BooleanMessageResponse, path='entries',
+ name='entries.put')
+ def entries_put(self, unused_request):
+ """Request body is in the body field."""
+ return BooleanMessageResponse(result=True)
+
+ @api_config.method(AllFields, message_types.VoidMessage, path='process',
+ name='entries.process')
+ def entries_process(self, unused_request):
+ """Message is the request body."""
+ return message_types.VoidMessage()
+
+ @api_config.method(message_types.VoidMessage, message_types.VoidMessage,
+ name='entries.nested.collection.action',
+ path='nested')
+ def entries_nested_collection_action(self, unused_request):
+ """A VoidMessage for a request body."""
+ return message_types.VoidMessage()
+
+ @api_config.method(AllFields, AllFields, name='entries.roundtrip',
+ path='roundtrip')
+ def entries_roundtrip(self, unused_request):
+ """All field types in the request and response."""
+ pass
+
+ # Test a method with a required parameter in the request body.
+ @api_config.method(EntryPublishRequest, message_types.VoidMessage,
+ path='entries/{entryId}/publish',
+ name='entries.publish')
+ def entries_publish(self, unused_request):
+ """Path has a parameter and request body has a required param."""
+ return message_types.VoidMessage()
+
+ @api_config.method(entry_publish_request_container,
+ message_types.VoidMessage,
+ path='entries/container/{entryId}/publish',
+ name='entries.publishContainer')
+ def entries_publish_container(self, unused_request):
+ """Path has a parameter and request body has a required param."""
+ return message_types.VoidMessage()
+
+ # Test a method with a parameter in the path and a request body.
+ @api_config.method(ItemsPutRequest, message_types.VoidMessage,
+ path='entries/{entryId}/items',
+ name='entries.items.put')
+ def items_put(self, unused_request):
+ """Path has a parameter and request body is in the body field."""
+ return message_types.VoidMessage()
+
+ @api_config.method(items_put_request_container, message_types.VoidMessage,
+ path='entries/container/{entryId}/items',
+ name='entries.items.putContainer')
+ def items_put_container(self, unused_request):
+ """Path has a parameter and request body is in the body field."""
+ return message_types.VoidMessage()
+
+ api = json.loads(self.generator.pretty_print_config_to_json(MyService))
+
+ # Some constants to shorten line length in expected OpenAPI output
+ prefix = 'OpenApiGeneratorTest'
+ boolean_response = prefix + 'BooleanMessageResponse'
+ all_fields = prefix + 'AllFields'
+ nested = prefix + 'Nested'
+ entry_publish_request = prefix + 'EntryPublishRequest'
+ publish_request_for_container = prefix + 'EntryPublishRequestForContainer'
+ items_put_request = prefix + 'ItemsPutRequest'
+ put_request_for_container = prefix + 'ItemsPutRequestForContainer'
+ put_request = prefix + 'PutRequest'
+
+ expected_openapi = {
+ 'swagger': '2.0',
+ 'info': {
+ 'title': 'root',
+ 'description': 'Describes MyService.',
+ 'version': 'v1',
+ },
+ 'host': 'example.appspot.com',
+ 'consumes': ['application/json'],
+ 'produces': ['application/json'],
+ 'schemes': ['https'],
+ 'basePath': '/_ah/api',
+ 'paths': {
+ '/root/v1/entries': {
+ 'get': {
+ 'operationId': 'MyService_entriesGet',
+ 'parameters': [
+ {
+ 'name': 'bool_value',
+ 'in': 'query',
+ 'type': 'boolean',
+ },
+ {
+ 'name': 'bytes_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'format': 'byte',
+ },
+ {
+ 'name': 'double_value',
+ 'in': 'query',
+ 'type': 'number',
+ 'format': 'double',
+ },
+ {
+ 'name': 'enum_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'enum': [
+ 'VAL1',
+ 'VAL2',
+ ],
+ },
+ {
+ 'name': 'float_value',
+ 'in': 'query',
+ 'type': 'number',
+ 'format': 'float',
+ },
+ {
+ 'name': 'int32_value',
+ 'in': 'query',
+ 'type': 'integer',
+ 'format': 'int32',
+ },
+ {
+ 'name': 'int64_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'format': 'int64',
+ },
+ {
+ 'name': 'string_value',
+ 'in': 'query',
+ 'type': 'string',
+ },
+ {
+ 'name': 'uint32_value',
+ 'in': 'query',
+ 'type': 'integer',
+ 'format': 'uint32',
+ },
+ {
+ 'name': 'uint64_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'format': 'uint64',
+ },
+ {
+ 'name': 'sint32_value',
+ 'in': 'query',
+ 'type': 'integer',
+ 'format': 'int32',
+ },
+ {
+ 'name': 'sint64_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'format': 'int64',
+ }
+ ],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ 'post': {
+ 'operationId': 'MyService_entriesPut',
+ 'parameters': [],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ 'schema': {
+ '$ref': self._def_path(boolean_response),
+ },
+ },
+ },
+ },
+ },
+ '/root/v1/entries/container': {
+ 'get': {
+ 'operationId': 'MyService_entriesGetContainer',
+ 'parameters': [
+ {
+ 'name': 'bool_value',
+ 'in': 'query',
+ 'type': 'boolean',
+ },
+ {
+ 'name': 'bytes_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'format': 'byte',
+ },
+ {
+ 'name': 'double_value',
+ 'in': 'query',
+ 'type': 'number',
+ 'format': 'double',
+ },
+ {
+ 'name': 'enum_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'enum': [
+ 'VAL1',
+ 'VAL2',
+ ],
+ },
+ {
+ 'name': 'float_value',
+ 'in': 'query',
+ 'type': 'number',
+ 'format': 'float',
+ },
+ {
+ 'name': 'int32_value',
+ 'in': 'query',
+ 'type': 'integer',
+ 'format': 'int32',
+ },
+ {
+ 'name': 'int64_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'format': 'int64',
+ },
+ {
+ 'name': 'string_value',
+ 'in': 'query',
+ 'type': 'string',
+ },
+ {
+ 'name': 'uint32_value',
+ 'in': 'query',
+ 'type': 'integer',
+ 'format': 'uint32',
+ },
+ {
+ 'name': 'uint64_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'format': 'uint64',
+ },
+ {
+ 'name': 'sint32_value',
+ 'in': 'query',
+ 'type': 'integer',
+ 'format': 'int32',
+ },
+ {
+ 'name': 'sint64_value',
+ 'in': 'query',
+ 'type': 'string',
+ 'format': 'int64',
+ },
+ ],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ '/root/v1/entries/container/{entryId}/items': {
+ 'post': {
+ 'operationId': 'MyService_itemsPutContainer',
+ 'parameters': [
+ {
+ 'name': 'entryId',
+ 'in': 'path',
+ 'required': True,
+ 'type': 'string',
+ },
+ ],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ '/root/v1/entries/container/{entryId}/publish': {
+ 'post': {
+ 'operationId': 'MyService_entriesPublishContainer',
+ 'parameters': [
+ {
+ 'name': 'entryId',
+ 'in': 'path',
+ 'required': True,
+ 'type': 'string',
+ },
+ ],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ '/root/v1/entries/{entryId}/items': {
+ 'post': {
+ 'operationId': 'MyService_itemsPut',
+ 'parameters': [
+ {
+ 'name': 'entryId',
+ 'in': 'path',
+ 'required': True,
+ 'type': 'string',
+ },
+ ],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ '/root/v1/entries/{entryId}/publish': {
+ 'post': {
+ 'operationId': 'MyService_entriesPublish',
+ 'parameters': [
+ {
+ 'name': 'entryId',
+ 'in': 'path',
+ 'required': True,
+ 'type': 'string',
+ },
+ ],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ '/root/v1/nested': {
+ 'post': {
+ 'operationId': 'MyService_entriesNestedCollectionAction',
+ 'parameters': [],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ '/root/v1/process': {
+ 'post': {
+ 'operationId': 'MyService_entriesProcess',
+ 'parameters': [],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ '/root/v1/roundtrip': {
+ 'post': {
+ 'operationId': 'MyService_entriesRoundtrip',
+ 'parameters': [],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ 'schema': {
+ '$ref': self._def_path(all_fields)
+ },
+ },
+ },
+ },
+ },
+ },
+ 'definitions': {
+ all_fields: {
+ 'type': 'object',
+ 'properties': {
+ 'bool_value': {
+ 'type': 'boolean',
+ },
+ 'bytes_value': {
+ 'type': 'string',
+ 'format': 'byte',
+ },
+ 'datetime_value': {
+ 'type': 'string',
+ 'format': 'date-time',
+ },
+ 'double_value': {
+ 'type': 'number',
+ 'format': 'double',
+ },
+ 'enum_value': {
+ 'type': 'string',
+ 'enum': [
+ 'VAL1',
+ 'VAL2',
+ ],
+ },
+ 'float_value': {
+ 'type': 'number',
+ 'format': 'float',
+ },
+ 'int32_value': {
+ 'type': 'integer',
+ 'format': 'int32',
+ },
+ 'int64_value': {
+ 'type': 'string',
+ 'format': 'int64',
+ },
+ 'message_field_value': {
+ '$ref': self._def_path(nested),
+ 'description':
+ 'Message class to be used in a message field.',
+ },
+ 'sint32_value': {
+ 'type': 'integer',
+ 'format': 'int32',
+ },
+ 'sint64_value': {
+ 'type': 'string',
+ 'format': 'int64',
+ },
+ 'string_value': {
+ 'type': 'string',
+ },
+ 'uint32_value': {
+ 'type': 'integer',
+ 'format': 'uint32',
+ },
+ 'uint64_value': {
+ 'type': 'string',
+ 'format': 'uint64',
+ },
+ },
+ },
+ boolean_response: {
+ 'type': 'object',
+ 'properties': {
+ 'result': {
+ 'type': 'boolean',
+ },
+ },
+ 'required': ['result'],
+ },
+ entry_publish_request: {
+ 'type': 'object',
+ 'properties': {
+ 'entryId': {
+ 'type': 'string',
+ },
+ 'title': {
+ 'type': 'string',
+ },
+ },
+ 'required': [
+ 'entryId',
+ 'title',
+ ]
+ },
+ publish_request_for_container: {
+ 'type': 'object',
+ 'properties': {
+ 'title': {
+ 'type': 'string',
+ },
+ },
+ 'required': [
+ 'title',
+ ]
+ },
+ items_put_request: {
+ 'type': 'object',
+ 'properties': {
+ 'body': {
+ '$ref': self._def_path(all_fields),
+ 'description': 'Contains all field types.'
+ },
+ 'entryId': {
+ 'type': 'string',
+ },
+ },
+ 'required': [
+ 'entryId',
+ ]
+ },
+ nested: {
+ 'type': 'object',
+ 'properties': {
+ 'int_value': {
+ 'type': 'string',
+ 'format': 'int64',
+ },
+ 'string_value': {
+ 'type': 'string',
+ },
+ },
+ },
+ put_request: {
+ 'type': 'object',
+ 'properties': {
+ 'body': {
+ '$ref': self._def_path(all_fields),
+ 'description': 'Contains all field types.',
+ },
+ },
+ },
+ put_request_for_container: {
+ 'type': 'object',
+ 'properties': {
+ 'body': {
+ '$ref': self._def_path(all_fields),
+ 'description': 'Contains all field types.',
+ },
+ },
+ },
+ },
+ 'securityDefinitions': {
+ 'google_id_token': {
+ 'authorizationUrl': '',
+ 'flow': 'implicit',
+ 'type': 'oauth2',
+ 'x-issuer': 'accounts.google.com',
+ 'x-jwks_uri': 'https://www.googleapis.com/oauth2/v1/certs',
+ },
+ },
+ }
+
+ test_util.AssertDictEqual(expected_openapi, api, self)
+
+ def testLocalhost(self):
+ @api_config.api(name='root', hostname='localhost:8080', version='v1')
+ class MyService(remote.Service):
+ """Describes MyService."""
+
+ @api_config.method(message_types.VoidMessage, message_types.VoidMessage,
+ path='noop', http_method='GET', name='noop')
+ def noop_get(self, unused_request):
+ return message_types.VoidMessage()
+
+ api = json.loads(self.generator.pretty_print_config_to_json(MyService))
+
+ expected_openapi = {
+ 'swagger': '2.0',
+ 'info': {
+ 'title': 'root',
+ 'description': 'Describes MyService.',
+ 'version': 'v1',
+ },
+ 'host': 'localhost:8080',
+ 'consumes': ['application/json'],
+ 'produces': ['application/json'],
+ 'schemes': ['http'],
+ 'basePath': '/_ah/api',
+ 'paths': {
+ '/root/v1/noop': {
+ 'get': {
+ 'operationId': 'MyService_noopGet',
+ 'parameters': [],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ },
+ 'securityDefinitions': {
+ 'google_id_token': {
+ 'authorizationUrl': '',
+ 'flow': 'implicit',
+ 'type': 'oauth2',
+ 'x-issuer': 'accounts.google.com',
+ 'x-jwks_uri': 'https://www.googleapis.com/oauth2/v1/certs',
+ },
+ },
+ }
+
+ test_util.AssertDictEqual(expected_openapi, api, self)
+
+ def testApiKeyRequired(self):
+
+ @api_config.api(name='root', hostname='example.appspot.com', version='v1',
+ api_key_required=True)
+ class MyService(remote.Service):
+ """Describes MyService."""
+
+ @api_config.method(message_types.VoidMessage, message_types.VoidMessage,
+ path='noop', http_method='GET', name='noop')
+ def noop_get(self, unused_request):
+ return message_types.VoidMessage()
+
+ @api_config.method(message_types.VoidMessage, message_types.VoidMessage,
+ path='override', http_method='GET', name='override',
+ api_key_required=False)
+ def override_get(self, unused_request):
+ return message_types.VoidMessage()
+
+ api = json.loads(self.generator.pretty_print_config_to_json(MyService))
+
+ expected_openapi = {
+ 'swagger': '2.0',
+ 'info': {
+ 'title': 'root',
+ 'description': 'Describes MyService.',
+ 'version': 'v1',
+ },
+ 'host': 'example.appspot.com',
+ 'consumes': ['application/json'],
+ 'produces': ['application/json'],
+ 'schemes': ['https'],
+ 'basePath': '/_ah/api',
+ 'paths': {
+ '/root/v1/noop': {
+ 'get': {
+ 'operationId': 'MyService_noopGet',
+ 'parameters': [],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ 'security': [
+ {
+ 'api_key': [],
+ }
+ ],
+ },
+ },
+ '/root/v1/override': {
+ 'get': {
+ 'operationId': 'MyService_overrideGet',
+ 'parameters': [],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ },
+ 'securityDefinitions': {
+ 'google_id_token': {
+ 'authorizationUrl': '',
+ 'flow': 'implicit',
+ 'type': 'oauth2',
+ 'x-issuer': 'accounts.google.com',
+ 'x-jwks_uri': 'https://www.googleapis.com/oauth2/v1/certs',
+ },
+ 'api_key': {
+ 'type': 'apiKey',
+ 'name': 'key',
+ 'in': 'query',
+ },
+ },
+ }
+
+ test_util.AssertDictEqual(expected_openapi, api, self)
+
+ def testCustomUrl(self):
+
+ @api_config.api(name='root', hostname='example.appspot.com', version='v1',
+ base_path='/my/base/path/')
+ class MyService(remote.Service):
+ """Describes MyService."""
+
+ @api_config.method(message_types.VoidMessage, message_types.VoidMessage,
+ path='noop', http_method='GET', name='noop')
+ def noop_get(self, unused_request):
+ return message_types.VoidMessage()
+
+ api = json.loads(self.generator.pretty_print_config_to_json(MyService))
+
+ expected_openapi = {
+ 'swagger': '2.0',
+ 'info': {
+ 'title': 'root',
+ 'description': 'Describes MyService.',
+ 'version': 'v1',
+ },
+ 'host': 'example.appspot.com',
+ 'consumes': ['application/json'],
+ 'produces': ['application/json'],
+ 'schemes': ['https'],
+ 'basePath': '/my/base/path',
+ 'paths': {
+ '/root/v1/noop': {
+ 'get': {
+ 'operationId': 'MyService_noopGet',
+ 'parameters': [],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ },
+ 'securityDefinitions': {
+ 'google_id_token': {
+ 'authorizationUrl': '',
+ 'flow': 'implicit',
+ 'type': 'oauth2',
+ 'x-issuer': 'accounts.google.com',
+ 'x-jwks_uri': 'https://www.googleapis.com/oauth2/v1/certs',
+ },
+ },
+ }
+
+ test_util.AssertDictEqual(expected_openapi, api, self)
+
+class DevServerOpenApiGeneratorTest(BaseOpenApiGeneratorTest,
+ test_util.DevServerTest):
+
+ def setUp(self):
+ super(DevServerOpenApiGeneratorTest, self).setUp()
+ self.env_key, self.orig_env_value = (test_util.DevServerTest.
+ setUpDevServerEnv())
+ self.addCleanup(test_util.DevServerTest.restoreEnv,
+ self.env_key, self.orig_env_value)
+
+ def testDevServerOpenApi(self):
+
+ @api_config.api(name='root', hostname='example.appspot.com', version='v1')
+ class MyService(remote.Service):
+ """Describes MyService."""
+
+ @api_config.method(message_types.VoidMessage, message_types.VoidMessage,
+ path='noop', http_method='GET', name='noop')
+ def noop_get(self, unused_request):
+ return message_types.VoidMessage()
+
+ api = json.loads(self.generator.pretty_print_config_to_json(MyService))
+
+ expected_openapi = {
+ 'swagger': '2.0',
+ 'info': {
+ 'title': 'root',
+ 'description': 'Describes MyService.',
+ 'version': 'v1',
+ },
+ 'host': 'example.appspot.com',
+ 'consumes': ['application/json'],
+ 'produces': ['application/json'],
+ 'schemes': ['http'],
+ 'basePath': '/_ah/api',
+ 'paths': {
+ '/root/v1/noop': {
+ 'get': {
+ 'operationId': 'MyService_noopGet',
+ 'parameters': [],
+ 'responses': {
+ '200': {
+ 'description': 'A successful response',
+ },
+ },
+ },
+ },
+ },
+ 'securityDefinitions': {
+ 'google_id_token': {
+ 'authorizationUrl': '',
+ 'flow': 'implicit',
+ 'type': 'oauth2',
+ 'x-issuer': 'accounts.google.com',
+ 'x-jwks_uri': 'https://www.googleapis.com/oauth2/v1/certs',
+ },
+ },
+ }
+
+ test_util.AssertDictEqual(expected_openapi, api, self)
+
+
+if __name__ == '__main__':
+ unittest.main()

Powered by Google App Engine
This is Rietveld 408576698