def test_property_from_data_union_bad_type(self, mocker): name = "bad_union" required = mocker.MagicMock() data = oai.Schema(anyOf=[{"type": "garbage"}]) mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=name) from openapi_python_client.parser.properties import Schemas, property_from_data p, s = property_from_data(name=name, required=required, data=data, schemas=Schemas(), parent_name="parent") assert p == PropertyError(detail=f"Invalid property in union {name}", data=oai.Schema(type="garbage"))
def test_property_from_data_union_bad_type(self, mocker): name = mocker.MagicMock() required = mocker.MagicMock() data = oai.Schema(anyOf=[{}]) mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=name) from openapi_python_client.parser.properties import property_from_data p = property_from_data(name=name, required=required, data=data) assert p == PropertyError(detail=f"Invalid property in union {name}", data=oai.Schema())
def test_property_from_data_array_invalid_items(self, mocker): name = mocker.MagicMock() required = mocker.MagicMock() data = oai.Schema(type="array", items={},) mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=name) from openapi_python_client.parser.properties import property_from_data p = property_from_data(name=name, required=required, data=data) assert p == PropertyError(data=oai.Schema(), detail=f"invalid data in items of array {name}")
def test_schema_bad_types(self): import pydantic with pytest.raises(pydantic.ValidationError): oai.Schema(type="bad_type") with pytest.raises(pydantic.ValidationError): oai.Schema(anyOf=[{"type": "garbage"}]) with pytest.raises(pydantic.ValidationError): oai.Schema(properties={ "bad": oai.Schema(type="not_real"), }, )
def test_property_from_data_union(self, mocker): name = mocker.MagicMock() required = mocker.MagicMock() data = oai.Schema( anyOf=[{"type": "number", "default": "0.0"}], oneOf=[ {"type": "integer", "default": "0"}, ], ) UnionProperty = mocker.patch(f"{MODULE_NAME}.UnionProperty") FloatProperty = mocker.patch(f"{MODULE_NAME}.FloatProperty") IntProperty = mocker.patch(f"{MODULE_NAME}.IntProperty") mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=name) from openapi_python_client.parser.properties import Schemas, property_from_data p, s = property_from_data( name=name, required=required, data=data, schemas=Schemas(), parent_name="parent", config=MagicMock() ) FloatProperty.assert_called_once_with(name=name, required=required, default=0.0, nullable=False) IntProperty.assert_called_once_with(name=name, required=required, default=0, nullable=False) UnionProperty.assert_called_once_with( name=name, required=required, default=None, inner_properties=[FloatProperty.return_value, IntProperty.return_value], nullable=False, ) assert p == UnionProperty.return_value assert s == Schemas()
def test_property_from_data_union( self, union_property_factory, date_time_property_factory, string_property_factory ): from openapi_python_client.parser.properties import Schemas, property_from_data name = "union_prop" required = True data = oai.Schema( anyOf=[{"type": "string", "default": "a"}], oneOf=[ {"type": "string", "format": "date-time"}, ], ) expected = union_property_factory( name=name, required=required, inner_properties=[ string_property_factory(name=f"{name}_type_0", default="'a'"), date_time_property_factory(name=f"{name}_type_1"), ], ) p, s = property_from_data( name=name, required=required, data=data, schemas=Schemas(), parent_name="parent", config=MagicMock() ) assert p == expected assert s == Schemas()
def test_property_from_data_array(self, mocker): name = mocker.MagicMock() required = mocker.MagicMock() data = oai.Schema( type="array", items={ "type": "number", "default": "0.0" }, ) ListProperty = mocker.patch(f"{MODULE_NAME}.ListProperty") FloatProperty = mocker.patch(f"{MODULE_NAME}.FloatProperty") mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=name) from openapi_python_client.parser.properties import property_from_data p = property_from_data(name=name, required=required, data=data) FloatProperty.assert_called_once_with(name=name, required=True, default="0.0") ListProperty.assert_called_once_with( name=name, required=required, default=None, inner_property=FloatProperty.return_value) assert p == ListProperty.return_value
def test_build_list_property(self, mocker): from openapi_python_client.parser import properties name = "prop" required = mocker.MagicMock() data = oai.Schema( type="array", items={}, ) schemas = properties.Schemas() second_schemas = properties.Schemas(errors=["error"]) property_from_data = mocker.patch.object( properties, "property_from_data", return_value=(mocker.MagicMock(), second_schemas) ) mocker.patch("openapi_python_client.utils.snake_case", return_value=name) mocker.patch("openapi_python_client.utils.to_valid_python_identifier", return_value=name) config = MagicMock() p, new_schemas = properties.build_list_property( name=name, required=required, data=data, schemas=schemas, parent_name="parent", config=config ) assert isinstance(p, properties.ListProperty) assert p.inner_property == property_from_data.return_value[0] assert new_schemas == second_schemas assert schemas != new_schemas, "Schema was mutated" property_from_data.assert_called_once_with( name=f"{name}_item", required=True, data=data.items, schemas=schemas, parent_name="parent", config=config )
def test_property_from_data_object(self, mocker): from openapi_python_client.parser.properties import Schemas, property_from_data name = mocker.MagicMock() required = mocker.MagicMock() data = oai.Schema(type="object", ) build_model_property = mocker.patch( f"{MODULE_NAME}.build_model_property") mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=name) schemas = Schemas() config = MagicMock() response = property_from_data(name=name, required=required, data=data, schemas=schemas, parent_name="parent", config=config) assert response == build_model_property.return_value build_model_property.assert_called_once_with(data=data, name=name, required=required, schemas=schemas, parent_name="parent", config=config)
def test_build_list_property_invalid_items(self, mocker): from openapi_python_client.parser import properties name = "name" required = mocker.MagicMock() data = oai.Schema( type="array", items={}, ) schemas = properties.Schemas() second_schemas = properties.Schemas(errors=["error"]) property_from_data = mocker.patch.object( properties, "property_from_data", return_value=(properties.PropertyError(data="blah"), second_schemas)) config = MagicMock() p, new_schemas = properties.build_list_property(name=name, required=required, data=data, schemas=schemas, parent_name="parent", config=config) assert p == PropertyError( data="blah", detail=f"invalid data in items of array {name}") assert new_schemas == second_schemas assert schemas != new_schemas, "Schema was mutated" property_from_data.assert_called_once_with(name=f"{name}_item", required=True, data=data.items, schemas=schemas, parent_name="parent", config=config)
def test_bad_props_return_error(self): from openapi_python_client.parser.properties import Schemas, build_model_property data = oai.Schema( properties={ "bad": oai.Schema(type="not_real"), }, ) schemas = Schemas() err, new_schemas = build_model_property( data=data, name="prop", schemas=schemas, required=True, parent_name=None, config=MagicMock() ) assert new_schemas == schemas assert err == PropertyError(detail="unknown type not_real", data=oai.Schema(type="not_real"))
def test_model_bad_additional_properties(self): from openapi_python_client.parser.properties import Schemas, build_model_property additional_properties = oai.Schema( type="object", properties={ "bad": oai.Reference(ref="#/components/schemas/not_exist"), }, ) data = oai.Schema(additionalProperties=additional_properties) result = build_model_property(data=data, name="prop", schemas=Schemas(), required=True, parent_name="parent", config=Config())[0] assert isinstance(result, PropertyError)
def test_property_from_data_no_valid_props_in_data(self): from openapi_python_client.parser.errors import PropertyError from openapi_python_client.parser.properties import property_from_data data = oai.Schema() assert property_from_data(name="blah", required=True, data=data) == PropertyError( data=data, detail="Schemas must either have one of enum, anyOf, or type defined." )
def test_happy_path(self, model_property_factory, string_property_factory, date_time_property_factory): from openapi_python_client.parser.properties import Class, Schemas, build_model_property name = "prop" nullable = False required = True data = oai.Schema.construct( required=["req"], title="MyModel", properties={ "req": oai.Schema.construct(type="string"), "opt": oai.Schema(type="string", format="date-time"), }, description="A class called MyModel", nullable=nullable, ) schemas = Schemas(classes_by_reference={"OtherModel": None}, classes_by_name={"OtherModel": None}) model, new_schemas = build_model_property(data=data, name=name, schemas=schemas, required=required, parent_name="parent", config=Config()) assert new_schemas != schemas assert new_schemas.classes_by_name == { "OtherModel": None, "ParentMyModel": model, } assert new_schemas.classes_by_reference == { "OtherModel": None, } assert model == model_property_factory( name=name, required=required, nullable=nullable, class_info=Class(name="ParentMyModel", module_name="parent_my_model"), required_properties=[ string_property_factory(name="req", required=True) ], optional_properties=[ date_time_property_factory(name="opt", required=False) ], description=data.description, relative_imports={ "from dateutil.parser import isoparse", "from typing import cast", "import datetime", "from ..types import UNSET, Unset", "from typing import Union", }, additional_properties=True, )
def test_bad_additional_props_return_error(self): from openapi_python_client.parser.properties import Config, Schemas, build_model_property additional_properties = oai.Schema( type="object", properties={ "bad": oai.Schema(type="not_real"), }, ) data = oai.Schema(additionalProperties=additional_properties) schemas = Schemas() err, new_schemas = build_model_property( data=data, name="prop", schemas=schemas, required=True, parent_name=None, config=Config() ) assert new_schemas == schemas assert err == PropertyError(detail="unknown type not_real", data=oai.Schema(type="not_real"))
def test_property_from_data_validation_error(self, mocker): from openapi_python_client.parser.errors import PropertyError from openapi_python_client.parser.properties import property_from_data mocker.patch(f"{MODULE_NAME}._property_from_data").side_effect = ValidationError() data = oai.Schema() assert property_from_data(name="blah", required=True, data=data) == PropertyError( detail="Failed to validate default value", data=data )
def test_property_from_data_array_no_items(self, mocker): name = mocker.MagicMock() required = mocker.MagicMock() data = oai.Schema(type="array") from openapi_python_client.parser.properties import property_from_data p = property_from_data(name=name, required=required, data=data) assert p == PropertyError(data=data, detail="type array must have items defined")
def test_build_model_property_bad_prop(): from openapi_python_client.parser.properties import Schemas, build_model_property data = oai.Schema( properties={ "bad": oai.Schema(type="not_real"), }, ) schemas = Schemas(models={"OtherModel": None}) err, new_schemas = build_model_property( data=data, name="prop", schemas=schemas, required=True, parent_name=None, ) assert new_schemas == schemas assert err == PropertyError(detail="unknown type not_real", data=oai.Schema(type="not_real"))
def test_build_enum_property_conflict(mocker): from openapi_python_client.parser.properties import Schemas, build_enum_property data = oai.Schema() schemas = Schemas(classes_by_name={"Existing": mocker.MagicMock()}) err, schemas = build_enum_property( data=data, name="Existing", required=True, schemas=schemas, enum=[], parent_name=None, config=Config() ) assert schemas == schemas assert err == PropertyError(detail="Found conflicting enums named Existing with incompatible values.", data=data)
def test_property_from_data_no_valid_props_in_data(self): from openapi_python_client.parser.properties import NoneProperty, Schemas, property_from_data schemas = Schemas() data = oai.Schema() prop, new_schemas = property_from_data( name="blah", required=True, data=data, schemas=schemas, parent_name="parent", config=MagicMock() ) assert prop == NoneProperty(name="blah", required=True, nullable=False, default=None) assert new_schemas == schemas
def test_build_enum_property_bad_default(): from openapi_python_client.parser.properties import Schemas, build_enum_property data = oai.Schema(default="B") schemas = Schemas() err, schemas = build_enum_property( data=data, name="Existing", required=True, schemas=schemas, enum=["A"], parent_name=None, config=Config() ) assert schemas == schemas assert err == PropertyError(detail="B is an invalid default for enum Existing", data=data)
def test_build_enum_property_no_values(): from openapi_python_client.parser.properties import Schemas, build_enum_property data = oai.Schema() schemas = Schemas() err, schemas = build_enum_property( data=data, name="Existing", required=True, schemas=schemas, enum=[], parent_name=None, config=Config() ) assert schemas == schemas assert err == PropertyError(detail="No values provided for Enum", data=data)
def test_build_union_property_invalid_property(self, mocker): name = "bad_union" required = mocker.MagicMock() reference = oai.Reference.construct(ref="#/components/schema/NotExist") data = oai.Schema(anyOf=[reference]) mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=name) from openapi_python_client.parser.properties import Schemas, build_union_property p, s = build_union_property( name=name, required=required, data=data, schemas=Schemas(), parent_name="parent", config=MagicMock() ) assert p == PropertyError(detail=f"Invalid property in union {name}", data=reference)
def test_property_from_data_validation_error(self, mocker): from openapi_python_client.parser.errors import PropertyError from openapi_python_client.parser.properties import Schemas, property_from_data mocker.patch(f"{MODULE_NAME}._property_from_data").side_effect = ValidationError() schemas = Schemas() data = oai.Schema() err, new_schemas = property_from_data( name="blah", required=True, data=data, schemas=schemas, parent_name="parent", config=MagicMock() ) assert err == PropertyError(detail="Failed to validate default value", data=data) assert new_schemas == schemas
def test_model_bad_properties(self): from openapi_python_client.parser.properties import Schemas, build_model_property data = oai.Schema(properties={ "bad": oai.Reference.construct(ref="#/components/schema/NotExist"), }, ) result = build_model_property(data=data, name="prop", schemas=Schemas(), required=True, parent_name="parent", config=Config())[0] assert isinstance(result, PropertyError)
def test_process_properties_reference_not_exist(self): from openapi_python_client.parser.properties import Schemas from openapi_python_client.parser.properties.model_property import _process_properties data = oai.Schema(properties={ "bad": oai.Reference.construct(ref="#/components/schema/NotExist"), }, ) result = _process_properties(data=data, class_name="", schemas=Schemas(), config=Config()) assert isinstance(result, PropertyError)
def test_build_model_property(additional_properties_schema, expected_additional_properties): from openapi_python_client.parser.properties import Schemas, build_model_property data = oai.Schema.construct( required=["req"], title="MyModel", properties={ "req": oai.Schema.construct(type="string"), "opt": oai.Schema(type="string", format="date-time"), }, description="A class called MyModel", nullable=False, additionalProperties=additional_properties_schema, ) schemas = Schemas(models={"OtherModel": None}) model, new_schemas = build_model_property( data=data, name="prop", schemas=schemas, required=True, parent_name="parent", ) assert new_schemas != schemas assert new_schemas.models == { "OtherModel": None, "ParentMyModel": model, } assert model == ModelProperty( name="prop", required=True, nullable=False, default=None, reference=Reference(class_name="ParentMyModel", module_name="parent_my_model"), required_properties=[StringProperty(name="req", required=True, nullable=False, default=None)], optional_properties=[DateTimeProperty(name="opt", required=False, nullable=False, default=None)], description=data.description, relative_imports={ "from dateutil.parser import isoparse", "from typing import cast", "import datetime", "from ..types import UNSET, Unset", "from typing import Union", }, additional_properties=expected_additional_properties, )
def test_build_list_property(self, any_property_factory): from openapi_python_client.parser import properties name = "prop" data = oai.Schema( type="array", items={}, ) schemas = properties.Schemas(errors=["error"]) config = Config() p, new_schemas = properties.build_list_property( name=name, required=True, data=data, schemas=schemas, parent_name="parent", config=config ) assert isinstance(p, properties.ListProperty) assert p.inner_property == any_property_factory(name=f"{name}_item") assert new_schemas == schemas
def test_property_from_data_array(self, mocker): from openapi_python_client.parser.properties import Schemas, property_from_data name = mocker.MagicMock() required = mocker.MagicMock() data = oai.Schema( type="array", items={"type": "number", "default": "0.0"}, ) build_list_property = mocker.patch(f"{MODULE_NAME}.build_list_property") mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=name) schemas = Schemas() response = property_from_data(name=name, required=required, data=data, schemas=schemas, parent_name="parent") assert response == build_list_property.return_value build_list_property.assert_called_once_with( data=data, name=name, required=required, schemas=schemas, parent_name="parent" )
def test_property_from_data_union(self, mocker): name = mocker.MagicMock() required = mocker.MagicMock() data = oai.Schema(anyOf=[ { "type": "number", "default": "0.0" }, { "type": "integer", "default": "0" }, ]) UnionProperty = mocker.patch(f"{MODULE_NAME}.UnionProperty") FloatProperty = mocker.patch(f"{MODULE_NAME}.FloatProperty") IntProperty = mocker.patch(f"{MODULE_NAME}.IntProperty") mocker.patch("openapi_python_client.utils.remove_string_escapes", return_value=name) from openapi_python_client.parser.properties import property_from_data p = property_from_data(name=name, required=required, data=data) FloatProperty.assert_called_once_with(name=name, required=required, default="0.0") IntProperty.assert_called_once_with(name=name, required=required, default="0") UnionProperty.assert_called_once_with( name=name, required=required, default=None, inner_properties=[ FloatProperty.return_value, IntProperty.return_value ], ) assert p == UnionProperty.return_value