def test_unmarshal_model_with_none_model_type(petstore_spec): model_spec = {'x-model': 'Foobar'} with pytest.raises(SwaggerMappingError) as excinfo: unmarshal_model(petstore_spec, model_spec, {}) assert 'Unknown model Foobar' in str(excinfo.value)
def test_value_is_not_dict_like_raises_error(petstore_dict): petstore_spec = Spec.from_dict(petstore_dict) pet_spec = petstore_spec.spec_dict['definitions']['Pet'] with pytest.raises(SwaggerMappingError) as excinfo: unmarshal_model(petstore_spec, pet_spec, 'i am not a dict') assert 'Expected type to be dict' in str(excinfo.value)
def test_non_nullable_array_properties(petstore_dict, pet_dict): pet_spec_dict = petstore_dict['definitions']['Pet'] pet_spec_dict['required'].append('tags') petstore_spec = Spec.from_dict(petstore_dict) pet_spec = petstore_spec.spec_dict['definitions']['Pet'] pet_dict['tags'] = None with pytest.raises(SwaggerMappingError): unmarshal_model(petstore_spec, pet_spec, pet_dict)
def test_marshal_as_dict_recursive(polymorphic_spec, recursive): list_of_pets_dict = { 'number_of_pets': 2, 'list': [ { 'name': 'a dog name', 'type': 'Dog', 'birth_date': '2017-03-09', }, { 'name': 'a cat name', 'type': 'Cat', 'color': 'white', }, ] } pet_list = unmarshal_model( swagger_spec=polymorphic_spec, model_spec=polymorphic_spec.spec_dict['definitions']['PetList'], model_value=list_of_pets_dict, ) dictionary = pet_list._as_dict(recursive=recursive) assert all( # if recursive is True the pet from the dictionary should not be a Model isinstance(pet, Model) is not recursive for pet in dictionary['list'] )
def json_to_model(self, model_name, j): """Take a json strust and a model name, and return a model instance""" if model_name not in self.swagger_dict['definitions']: raise ValidationError("Swagger spec has no definition for model %s" % model_name) model_def = self.swagger_dict['definitions'][model_name] log.debug("Unmarshalling json into %s" % model_name) return unmarshal_model(self.spec, model_def, j)
def test_Nones_are_reintroduced_for_declared_properties_that_are_not_present( petstore_dict, pet_dict): petstore_spec = Spec.from_dict(petstore_dict) Pet = petstore_spec.definitions['Pet'] Tag = petstore_spec.definitions['Tag'] pet_spec = petstore_spec.spec_dict['definitions']['Pet'] # Deleting "status" and "category" from pet_dict means that should still be # attrs on Pet with a None value after unmarshaling del pet_dict['status'] del pet_dict['category'] pet = unmarshal_model(petstore_spec, pet_spec, pet_dict) assert isinstance(pet, Pet) assert 1 == pet.id assert 'Fido' == pet.name assert pet.status is None assert ['wagtail.png', 'bark.png'] == pet.photoUrls assert pet.category is None assert isinstance(pet.tags, list) assert 2 == len(pet.tags) assert isinstance(pet.tags[0], Tag) assert 99 == pet.tags[0].id assert 'mini' == pet.tags[0].name assert isinstance(pet.tags[1], Tag) assert 100 == pet.tags[1].id assert 'brown' == pet.tags[1].name
def test_marshal_as_dict_recursive(polymorphic_spec, recursive): list_of_pets_dict = { 'number_of_pets': 2, 'list': [ { 'name': 'a dog name', 'type': 'Dog', 'birth_date': '2017-03-09', }, { 'name': 'a cat name', 'type': 'Cat', 'color': 'white', }, ] } pet_list = unmarshal_model( swagger_spec=polymorphic_spec, model_spec=polymorphic_spec.spec_dict['definitions']['PetList'], model_value=list_of_pets_dict, ) dictionary = pet_list._as_dict(recursive=recursive) assert all( # if recursive is True the pet from the dictionary should not be a Model isinstance(pet, Model) is not recursive for pet in dictionary['list'])
def test_unmarshal_model_polymorphic_specs(polymorphic_spec): list_of_pets_dict = { 'number_of_pets': 2, 'list': [ { 'name': 'a dog name', 'type': 'Dog', 'birth_date': '2017-03-09', }, { 'name': 'a cat name', 'type': 'Cat', 'color': 'white', }, ] } pet_list = unmarshal_model( swagger_spec=polymorphic_spec, model_spec=polymorphic_spec.spec_dict['definitions']['PetList'], model_value=list_of_pets_dict, ) assert isinstance(pet_list, polymorphic_spec.definitions['PetList']) assert pet_list.number_of_pets == list_of_pets_dict['number_of_pets'] assert len(pet_list.list) == len(list_of_pets_dict['list']) for list_item_model, list_item_dict in zip(pet_list.list, list_of_pets_dict['list']): assert isinstance(list_item_model, polymorphic_spec.definitions[list_item_dict['type']]) assert list_item_model._marshal() == list_item_dict
def test_pet(petstore_dict, pet_dict): # Covers: # - model with primitives properties # - model with an array # - model with a nested model petstore_spec = Spec.from_dict(petstore_dict) Pet = petstore_spec.definitions['Pet'] Category = petstore_spec.definitions['Category'] Tag = petstore_spec.definitions['Tag'] pet_spec = petstore_spec.spec_dict['definitions']['Pet'] pet = unmarshal_model(petstore_spec, pet_spec, pet_dict) assert isinstance(pet, Pet) assert 1 == pet.id assert 'Fido' == pet.name assert 'sold' == pet.status assert ['wagtail.png', 'bark.png'] == pet.photoUrls assert isinstance(pet.category, Category) assert 200 == pet.category.id assert 'friendly' == pet.category.name assert isinstance(pet.tags, list) assert 2 == len(pet.tags) assert isinstance(pet.tags[0], Tag) assert 99 == pet.tags[0].id assert 'mini' == pet.tags[0].name assert isinstance(pet.tags[1], Tag) assert 100 == pet.tags[1].id assert 'brown' == pet.tags[1].name
def test_definitions_with_ref(composition_spec, releaseDate): PongClone = composition_spec.definitions['pongClone'] pong_clone_spec = composition_spec.spec_dict['definitions']['pongClone'] pong_clone_dict = { 'pang': 'hello', 'additionalFeature': 'new!', 'gameSystem': 'Fatari', } if releaseDate: pong_clone_dict['releaseDate'] = releaseDate pong_clone = unmarshal_model( composition_spec, pong_clone_spec, pong_clone_dict, ) assert isinstance(pong_clone, PongClone) assert 'hello' == pong_clone.pang assert 'new!' == pong_clone.additionalFeature assert 'Fatari' == pong_clone.gameSystem if releaseDate or composition_spec.config['include_missing_properties']: assert hasattr(pong_clone, 'releaseDate') is True assert releaseDate == pong_clone.releaseDate else: assert hasattr(pong_clone, 'releaseDate') is False
def _unmarshal(cls, val): """Unmarshal a dict into an instance of the model. :type val: dict :rtype: .Model """ from bravado_core.unmarshal import unmarshal_model return unmarshal_model(cls._swagger_spec, cls._model_spec, val)
def test_model_isinstance(polymorphic_spec, instance_dict, object_type, possible_object_types): model = unmarshal_model( swagger_spec=polymorphic_spec, model_spec=polymorphic_spec.spec_dict['definitions'][object_type], model_value=instance_dict) assert any( isinstance(model, polymorphic_spec.definitions[possible_object_type]) for possible_object_type in possible_object_types)
def test_model_isinstance(polymorphic_spec, instance_dict, object_type, possible_object_types): model = unmarshal_model( swagger_spec=polymorphic_spec, model_spec=polymorphic_spec.spec_dict['definitions'][object_type], model_value=instance_dict ) assert any( isinstance(model, polymorphic_spec.definitions[possible_object_type]) for possible_object_type in possible_object_types )
def test_nullable_array_properties(petstore_dict, pet_dict): pet_spec_dict = petstore_dict['definitions']['Pet'] pet_spec_dict['properties']['tags']['x-nullable'] = True pet_spec_dict['required'].append('tags') petstore_spec = Spec.from_dict(petstore_dict) Pet = petstore_spec.definitions['Pet'] pet_spec = petstore_spec.spec_dict['definitions']['Pet'] pet_dict['tags'] = None pet = unmarshal_model(petstore_spec, pet_spec, pet_dict) assert isinstance(pet, Pet) assert pet.tags is None
def test_unmarshal_model_with_additional_properties(minimal_swagger_dict, additionalProperties, value, expected): MyModel_spec = { 'properties': { 'property': { 'type': 'string', 'format': 'date-time', }, }, 'type': 'object', 'x-model': 'MyModel', } if additionalProperties is not None: MyModel_spec['additionalProperties'] = additionalProperties minimal_swagger_dict['definitions']['MyModel'] = MyModel_spec spec = Spec.from_dict(minimal_swagger_dict) assert unmarshal_model(spec, MyModel_spec, value)._as_dict() == expected
def test_definitions_with_ref(composition_spec): PongClone = composition_spec.definitions['pongClone'] pong_clone_spec = composition_spec.spec_dict['definitions']['pongClone'] pong_clone_dict = { 'pang': 'hello', 'additionalFeature': 'new!', 'gameSystem': 'Fatari', 'releaseDate': '1981' } pong_clone = unmarshal_model(composition_spec, pong_clone_spec, pong_clone_dict) assert isinstance(pong_clone, PongClone) assert 'hello' == pong_clone.pang assert 'new!' == pong_clone.additionalFeature assert 'Fatari' == pong_clone.gameSystem assert '1981' == pong_clone.releaseDate
def from_json(cls, j, keep_datetime=False): """Take a json dictionary and return a model instance""" log.debug("Unmarshalling json into %s" % getattr(cls, '__model_name')) datetimes = {} if keep_datetime: for k in list(j.keys()): if j[k].__class__.__name__ in ('datetime', 'DatetimeWithNanoseconds'): datetimes[k] = j[k] del j[k] m = unmarshal_model(getattr(cls, '__swagger_spec'), getattr(cls, '__swagger_dict'), j) if datetimes: for k in datetimes: setattr(m, k, datetimes[k]) return cls.from_bravado(m)
def create_model_type(swagger_spec, model_name, model_spec): """Create a dynamic class from the model data defined in the swagger spec. The docstring for this class is dynamically generated because generating the docstring is relatively expensive, and would only be used in rare cases for interactive debugging in a REPL. :type swagger_spec: :class:`bravado_core.spec.Spec` :param model_name: model name :param model_spec: json-like dict that describes a model. :returns: dynamic type created with attributes, docstrings attached :rtype: type """ from bravado_core.marshal import marshal_model from bravado_core.unmarshal import unmarshal_model doc = docstring_property( partial(create_model_docstring, swagger_spec, model_spec)) def create(cls, kwargs): self = cls.__new__(cls) model_constructor(self, model_spec, swagger_spec, kwargs) return self methods = dict( __doc__=doc, __eq__=lambda self, other: compare(self, other), __init__=lambda self, **kwargs: model_constructor( self, model_spec, swagger_spec, kwargs), __repr__=lambda self: create_model_repr(self, model_spec, swagger_spec ), __dir__=lambda self: model_dir(self, model_spec, swagger_spec), create=classmethod(create), marshal=lambda self: marshal_model(swagger_spec, model_spec, self), unmarshal=staticmethod( lambda val: unmarshal_model(swagger_spec, model_spec, val)), ) return type(str(model_name), (object, ), methods)
def test_custom_format(self): api = API('somename', yaml_str=yaml_str, formats=[foo_format]) self.assertTrue(hasattr(api.model, 'Foo')) # marshal and unmarshal f = api.model.Foo(foo='123') j = api.api_spec.model_to_json(f) self.assertDictEqual(j, {'foo': '123'}) model_def = api.api_spec.swagger_dict['definitions']['Foo'] f = unmarshal_model(api.api_spec.spec, model_def, j) self.assertEqual(f.foo, '123') # validate validate_object(api.api_spec.spec, model_def, {'foo': 'foo'}) try: validate_object(api.api_spec.spec, model_def, {'foo': '123'}) except ValidationError as e: self.assertTrue("'123' is not a 'foo'" in str(e)) else: assert 0
def test_custom_format(self): api = API("somename", yaml_str=yaml_str, formats=[foo_format]) self.assertTrue(hasattr(api.model, "Foo")) # marshal and unmarshal f = api.model.Foo(foo="123") j = api.api_spec.model_to_json(f) self.assertDictEqual(j, {"foo": "123"}) model_def = api.api_spec.swagger_dict["definitions"]["Foo"] f = unmarshal_model(api.api_spec.spec, model_def, j) self.assertEqual(f.foo, "123") # validate validate_object(api.api_spec.spec, model_def, {"foo": "foo"}) try: validate_object(api.api_spec.spec, model_def, {"foo": "123"}) except ValidationError as e: self.assertTrue("'123' is not a 'foo'" in str(e)) else: assert 0