mirror of
https://github.com/correl/openapi-core.git
synced 2024-11-22 03:00:10 +00:00
Model extension refactor
This commit is contained in:
parent
11f0233ef2
commit
af07200b7b
6 changed files with 76 additions and 40 deletions
|
@ -4,9 +4,15 @@ from openapi_core.extensions.models.models import BaseModel
|
||||||
|
|
||||||
class ModelFactory(object):
|
class ModelFactory(object):
|
||||||
|
|
||||||
def create(self, properties, name=None):
|
base_class = BaseModel
|
||||||
model = BaseModel
|
default_name = 'Model'
|
||||||
if name is not None:
|
|
||||||
model = type(name, (BaseModel, ), {})
|
|
||||||
|
|
||||||
return model(**properties)
|
def __init__(self, name=None):
|
||||||
|
self.name = name or self.default_name
|
||||||
|
|
||||||
|
def __call__(self, **properties):
|
||||||
|
model_class = self._get_model_class(**properties)
|
||||||
|
return model_class()
|
||||||
|
|
||||||
|
def _get_model_class(self, **attrs):
|
||||||
|
return type(self.name, (self.base_class, ), attrs)
|
||||||
|
|
|
@ -1,17 +1,5 @@
|
||||||
"""OpenAPI X-Model extension models module"""
|
"""OpenAPI X-Model extension models module"""
|
||||||
|
|
||||||
|
|
||||||
class BaseModel(dict):
|
class BaseModel(object):
|
||||||
"""Base class for OpenAPI X-Model."""
|
"""Base class for OpenAPI models."""
|
||||||
|
|
||||||
def __getattr__(self, attr_name):
|
|
||||||
"""Only search through properties if attribute not found normally.
|
|
||||||
:type attr_name: str
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return self[attr_name]
|
|
||||||
except KeyError:
|
|
||||||
raise AttributeError(
|
|
||||||
'type object {0!r} has no attribute {1!r}'
|
|
||||||
.format(type(self).__name__, attr_name)
|
|
||||||
)
|
|
||||||
|
|
|
@ -169,7 +169,11 @@ class Schema(object):
|
||||||
else:
|
else:
|
||||||
properties = self._unmarshal_properties(value)
|
properties = self._unmarshal_properties(value)
|
||||||
|
|
||||||
return ModelFactory().create(properties, name=self.model)
|
return self.model_factory(**properties)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def model_factory(self):
|
||||||
|
return ModelFactory(self.model)
|
||||||
|
|
||||||
def _unmarshal_properties(self, value, one_of_schema=None):
|
def _unmarshal_properties(self, value, one_of_schema=None):
|
||||||
all_props = self.get_all_properties()
|
all_props = self.get_all_properties()
|
||||||
|
|
57
tests/integration/test_models.py
Normal file
57
tests/integration/test_models.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import json
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from openapi_core.extensions.models.models import BaseModel
|
||||||
|
from openapi_core.schema.media_types.exceptions import (
|
||||||
|
InvalidContentType, InvalidMediaTypeValue,
|
||||||
|
)
|
||||||
|
from openapi_core.schema.operations.exceptions import InvalidOperation
|
||||||
|
from openapi_core.schema.parameters.exceptions import MissingRequiredParameter
|
||||||
|
from openapi_core.schema.request_bodies.exceptions import MissingRequestBody
|
||||||
|
from openapi_core.schema.responses.exceptions import (
|
||||||
|
MissingResponseContent, InvalidResponse,
|
||||||
|
)
|
||||||
|
from openapi_core.schema.servers.exceptions import InvalidServer
|
||||||
|
from openapi_core.shortcuts import create_spec
|
||||||
|
from openapi_core.validation.request.validators import RequestValidator
|
||||||
|
from openapi_core.validation.response.validators import ResponseValidator
|
||||||
|
from openapi_core.wrappers.mock import MockRequest, MockResponse
|
||||||
|
|
||||||
|
|
||||||
|
class TestModelsExtension(object):
|
||||||
|
|
||||||
|
host_url = 'http://petstore.swagger.io'
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def spec_dict(self, factory):
|
||||||
|
return factory.spec_from_file("data/v3.0/petstore.yaml")
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def spec(self, spec_dict):
|
||||||
|
return create_spec(spec_dict)
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def validator(self, spec):
|
||||||
|
return ResponseValidator(spec)
|
||||||
|
|
||||||
|
def test_get_pets(self, validator):
|
||||||
|
request = MockRequest(self.host_url, 'get', '/v1/pets')
|
||||||
|
response_json = {
|
||||||
|
'data': [
|
||||||
|
{
|
||||||
|
'id': 1,
|
||||||
|
'name': 'Sparky'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
response_data = json.dumps(response_json)
|
||||||
|
response = MockResponse(response_data)
|
||||||
|
|
||||||
|
result = validator.validate(request, response)
|
||||||
|
|
||||||
|
assert result.errors == []
|
||||||
|
assert list(result.data.keys()) == ['data', ]
|
||||||
|
assert len(result.data['data']) == 1
|
||||||
|
assert isinstance(result.data['data'][0], BaseModel)
|
||||||
|
assert result.data['data'][0].id == 1
|
||||||
|
assert result.data['data'][0].name == 'Sparky'
|
|
@ -638,7 +638,7 @@ class TestPetstore(object):
|
||||||
response_result = response_validator.validate(request, response)
|
response_result = response_validator.validate(request, response)
|
||||||
|
|
||||||
assert response_result.errors == []
|
assert response_result.errors == []
|
||||||
assert response_result.data == data_json
|
assert list(response_result.data.keys()) == ['data', ]
|
||||||
|
|
||||||
def test_get_pet_not_found(self, spec, response_validator):
|
def test_get_pet_not_found(self, spec, response_validator):
|
||||||
host_url = 'http://petstore.swagger.io/v1'
|
host_url = 'http://petstore.swagger.io/v1'
|
||||||
|
|
|
@ -268,22 +268,3 @@ class TestResponseValidator(object):
|
||||||
assert type(result.errors[0]) == InvalidMediaTypeValue
|
assert type(result.errors[0]) == InvalidMediaTypeValue
|
||||||
assert result.data is None
|
assert result.data is None
|
||||||
assert result.headers == {}
|
assert result.headers == {}
|
||||||
|
|
||||||
def test_get_pets(self, validator):
|
|
||||||
request = MockRequest(self.host_url, 'get', '/v1/pets')
|
|
||||||
response_json = {
|
|
||||||
'data': [
|
|
||||||
{
|
|
||||||
'id': 1,
|
|
||||||
'name': 'Sparky'
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
response_data = json.dumps(response_json)
|
|
||||||
response = MockResponse(response_data)
|
|
||||||
|
|
||||||
result = validator.validate(request, response)
|
|
||||||
|
|
||||||
assert result.errors == []
|
|
||||||
assert result.data == response_json
|
|
||||||
assert result.headers == {}
|
|
||||||
|
|
Loading…
Reference in a new issue