diff --git a/apispec/core.py b/apispec/core.py index 332285db..a6c6f61d 100644 --- a/apispec/core.py +++ b/apispec/core.py @@ -156,15 +156,26 @@ def to_dict(self): ret['swagger'] = self.openapi_version.vstring ret['definitions'] = self._definitions ret['parameters'] = self._parameters + ret.update(self.options) elif self.openapi_version.version[0] == 3: ret['openapi'] = self.openapi_version.vstring - ret['components'] = { - 'schemas': self._definitions, - 'parameters': self._parameters, - } + options = self.options.copy() + components = options.pop('components', {}) + + # deep update components object + definitions = components.pop('schemas', {}) + definitions.update(self._definitions) + parameters = components.pop('parameters', {}) + parameters.update(self._parameters) + + ret['components'] = dict( + schemas=definitions, + parameters=parameters, + **components + ) + ret.update(options) - ret.update(self.options) return ret def to_yaml(self): diff --git a/tests/test_core.py b/tests/test_core.py index e0d6527b..c91d98c2 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -26,11 +26,28 @@ def spec(): @pytest.fixture() def spec_3(): + components = { + 'securitySchemes': { + 'bearerAuth': + dict(type='http', scheme='bearer', bearerFormat='JWT') + }, + 'schemas': { + 'ErrorResponse': { + 'type': 'object', + 'properties': { + 'ok': { + 'type': 'boolean', 'description': 'status indicator', 'example': False + } + }, + 'required': ['ok'] + } + } + } return APISpec( title='Swagger Petstore', version='1.0.0', info={'description': description}, - security=[{'apiKey': []}], + components=components, openapi_version='3.0.0' ) @@ -64,6 +81,26 @@ def test_swagger_metadata(self, spec): assert metadata['info']['version'] == '1.0.0' assert metadata['info']['description'] == description + def test_swagger_metadata_v3(self, spec_3): + metadata = spec_3.to_dict() + security_schemes = {'bearerAuth': dict(type='http', scheme='bearer', bearerFormat='JWT')} + assert metadata['components']['securitySchemes'] == security_schemes + assert metadata['components']['schemas'].get('ErrorResponse', False) + assert metadata['info']['title'] == 'Swagger Petstore' + assert metadata['info']['version'] == '1.0.0' + assert metadata['info']['description'] == description + + def test_swagger_metadata_merge_v3(self, spec_3): + properties = { + 'ok': { + 'type': 'boolean', 'description': 'property description', 'example': True + } + } + spec_3.definition('definition', properties=properties, description='definiton description') + metadata = spec_3.to_dict() + assert metadata['components']['schemas'].get('ErrorResponse', False) + assert metadata['components']['schemas'].get('definition', False) + class TestTags: