def test_retrieve(self): """ Confirm that existing instances of models w/ ArrayModelFields can still be retrieved and serialized correctly """ # Set up the initial data class TestSerializer(rmd_ser.DjongoModelSerializer): class Meta: model = ArrayContainerModel fields = '__all__' embed_data_1 = {'int_field': 1234, 'char_field': 'foo'} embed_data_2 = {'int_field': 4321, 'char_field': 'bar'} embed_list = [EmbedModel(**embed_data_1), EmbedModel(**embed_data_2)] # Attempt to serialize an instance of the model using the data above instance = ArrayContainerModel.objects.create(embed_list=embed_list) serializer = TestSerializer(instance) expected_data = { '_id': str(instance._id), 'embed_list': [OrderedDict(embed_data_1), OrderedDict(embed_data_2)] } self.assertDictEqual(expected_data, serializer.data)
def test_null_retrieve_filled(self): """ Test whether nullable lists are possible """ # Set up the initial data class TestSerializer(rmd_ser.DjongoModelSerializer): class Meta: model = NullArrayContainerModel fields = '__all__' embed_data_1 = {'int_field': 1234, 'char_field': 'foo'} embed_data_2 = {'int_field': 4321, 'char_field': 'bar'} embed_list = [EmbedModel(**embed_data_1), EmbedModel(**embed_data_2)] # Attempt to serialize an instance of the model using the data above instance = NullArrayContainerModel.objects.create( nullable_list=embed_list) serializer = TestSerializer(instance) expected_data = { '_id': str(instance._id), 'nullable_list': [embed_data_1, embed_data_2] } expected_str = format_dict(expected_data) observed_str = format_dict(serializer.data) assert observed_str == expected_str
def embed_instance(self): embed_data = { 'int_field': 1234, 'char_field': 'Embed' } embed_instance = EmbedModel(**embed_data) return embed_instance
def test_null_update_filled(self): """ Confirm that existing instances of models w/ ArrayModelFields can still be updated when provided with new raw data """ # Set up the initial data embed_data_1 = {'int_field': 1234, 'char_field': 'foo'} embed_data_2 = {'int_field': 4321, 'char_field': 'bar'} embed_list = [EmbedModel(**embed_data_1), EmbedModel(**embed_data_2)] initial_data = {'embed_list': embed_list} instance = ArrayContainerModel.objects.create(**initial_data) initial_data.update({'pk': instance.pk}) # Attempt to update the instance above class TestSerializer(rmd_ser.DjongoModelSerializer): class Meta: model = NullArrayContainerModel fields = '__all__' embed_data_1.update({'char_field': 'baz'}) new_data = { 'nullable_list': [embed_data_1, embed_data_2, embed_data_1] } serializer = TestSerializer(instance, data=new_data) # Confirm that the update is valid assert serializer.is_valid(), serializer.errors # Confirm that the serializer saves the updated instance correctly serializer.save() assert instance.pk == initial_data['pk'] assert instance.nullable_list[0].int_field == embed_data_1['int_field'] assert instance.nullable_list[0].char_field == embed_data_1[ 'char_field'] assert instance.nullable_list[1].int_field == embed_data_2['int_field'] assert instance.nullable_list[2].char_field == embed_data_1[ 'char_field']
def test_null_update_empty(self): """ Confirm that existing instances of models w/ ArrayModelFields can still be updated when provided with new raw data """ # Set up the initial data embed_data_1 = {'int_field': 1234, 'char_field': 'foo'} embed_data_2 = {'int_field': 4321, 'char_field': 'bar'} embed_list = [EmbedModel(**embed_data_1), EmbedModel(**embed_data_2)] initial_data = {'embed_list': embed_list} instance = ArrayContainerModel.objects.create(**initial_data) initial_data.update({'pk': instance.pk}) # Attempt to update the instance above class TestSerializer(rmd_ser.DjongoModelSerializer): class Meta: model = NullArrayContainerModel fields = '__all__' embed_data_1.update({'char_field': 'baz'}) new_data = {'nullable_list': None} serializer = TestSerializer(instance, data=new_data) # Confirm that the update is valid assert serializer.is_valid(), serializer.errors # Confirm that the serializer saves the updated instance correctly serializer.save() expected_data = {'_id': str(instance.pk), 'nullable_list': None} expected_str = format_dict(expected_data) observed_str = format_dict(serializer.data) assert observed_str == expected_str
class TestDataParsing(object): obj_data = {'int_field': 123, 'char_field': "Hello"} instance = EmbedModel(**obj_data) djm_embed = get_model_meta(ContainerModel).get_field('embed_field') rmd_embed = EmbeddedModelField(model_field=djm_embed) @fixture def errors(self, build_tuple): from rest_framework.exceptions import ValidationError err_dict = {'ValidationError': ValidationError, 'TypeError': TypeError} return build_tuple('Errors', err_dict) def test_to_internal_val(self): new_instance = self.rmd_embed.to_internal_value(self.obj_data) assert str(self.instance) == str(new_instance) def test_to_representation(self): new_data = self.rmd_embed.to_representation(self.instance) assert self.obj_data == new_data def test_conversion_equivalence(self): data = self.rmd_embed.to_representation(self.instance) new_instance = self.rmd_embed.to_internal_value(data) assert str(self.instance) == str(new_instance) @mark.error def test_invalid_rejection(self, error_raised): # Non-dictionary values are rejected not_a_dict = 1234 with error_raised: self.rmd_embed.run_validation(not_a_dict) # Dictionaries denoting fields which do not exist are rejected wrong_dict = {'bool_field': True, 'char_field': 'error'} with error_raised: self.rmd_embed.run_validation(wrong_dict)
class TestDataParsing(object): embed_data = [ {'int_field': 34, 'char_field': "Hello"}, {'int_field': 431, 'char_field': "Bye!"} ] embed_list = [EmbedModel(**val) for val in embed_data] instance = ArrayContainerModel(embed_list=embed_list) array_field = ArrayModelField( model_field=get_model_meta(instance).get_field('embed_list') ) def test_to_internal_val(self): new_list = self.array_field.to_internal_value(self.embed_data) assert self.embed_list == new_list def test_to_representation(self): new_list = self.array_field.to_representation(self.embed_list) assert self.embed_data == new_list def test_conversion_equivalence(self): rep_list = self.array_field.to_representation(self.embed_list) new_list = self.array_field.to_internal_value(rep_list) assert self.embed_list == new_list @mark.error def test_invalid_rejection(self, error_raised): # Non-list values are caught not_a_list = 1234 with error_raised: self.array_field.run_validation(not_a_list) # List contents with invalid fields are caught invalid_list_field = self.embed_data.copy() invalid_list_field.append({'int_field': 34, 'bool_field': True}) with error_raised: self.array_field.run_validation(invalid_list_field)
def test_non_list_field_caught(self): """ Check that single values passed into list fields are caught """ # Set up data to use for creation class TestSerializer(rmd_ser.DjongoModelSerializer): class Meta: model = ArrayContainerModel fields = '__all__' embed_data_1 = {'int_field': 123, 'char_field': 'foo'} embed_obj = EmbedModel(**embed_data_1) data = {'embed_list': embed_obj} # Serializer should NOT validate correctly serializer = TestSerializer(data=data) assert not serializer.is_valid() # Confirm that the errors caught are correct print(serializer.errors)
class TestEmbeddingIntegration(object): # -- DB Setup fixtures -- # @fixture def embed_instance(self): embed_data = { 'int_field': 1234, 'char_field': 'Embed' } embed_instance = EmbedModel(**embed_data) return embed_instance @fixture def container_instance(self, embed_instance): """Prepares a default ContainerModel instance in the DB""" from collections import namedtuple container_data = { 'embed_field': embed_instance } container_instance = ContainerModel.objects.create(**container_data) data_tuple = namedtuple('ModelData', ['embedded', 'container']) data = { 'embedded': embed_instance, 'container': container_instance, } return data_tuple(**data) @fixture def deep_container_instance(self, container_instance): from collections import namedtuple deep_data = { 'str_id': 'identifier', 'deep_embed': container_instance.container } deep_instance = DeepContainerModel.objects.create(**deep_data) data_tuple = namedtuple( 'ModelData', ['embedded', 'container', 'deep_container'] ) data = { 'embedded': container_instance.embedded, 'container': container_instance.container, 'deep_container': deep_instance } return data_tuple(**data) # -- Actual Test Code -- # @mark.parametrize( ["serializer", "expected", "missing"], [ param( # Generic test {'target': ContainerModel}, {'control_val': "CONTROL", 'embed_field': OrderedDict({ 'int_field': 1234, 'char_field': 'Embed' })}, None, id='basic' ), param( # Fields meta, in the root model, is respected {'target': ContainerModel, 'meta_fields': ['embed_field']}, {'embed_field': OrderedDict({ 'int_field': 1234, 'char_field': 'Embed' })}, {'control_val': 'CONTROL'}, id='respects_fields' ), param( # Exclude meta, in the root model, is respected {'target': ContainerModel, 'meta_exclude': ['embed_field']}, {'control_val': 'CONTROL'}, {'embed_field': OrderedDict({ 'int_field': 1234, 'char_field': 'Embed' })}, id='respects_exclude' ), param( # Fields meta, in the contained model, is respected {'target': ContainerModel, 'custom_fields': { 'embed_field': { 'target': EmbedModel, 'base_class': EmbeddedModelSerializer, 'meta_fields': ['int_field'] } }}, {'control_val': "CONTROL", 'embed_field': OrderedDict({'int_field': 1234})}, {'embed_field': OrderedDict({'char_field': 'Embed'})}, id='respects_nested_fields' ), param( # Exclude meta, in the contained model, is respected {'target': ContainerModel, 'custom_fields': { 'embed_field': { 'target': EmbedModel, 'base_class': EmbeddedModelSerializer, 'meta_exclude': ['int_field'] } }}, {'control_val': "CONTROL", 'embed_field': OrderedDict({'char_field': 'Embed'})}, {'embed_field': OrderedDict({'int_field': 1234})}, id='respects_nested_exclude' ) ]) def test_basic_retrieve(self, build_serializer, does_a_subset_b, container_instance, serializer, expected, missing): # Prepare the test environment TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(container_instance.container) # Make sure fields which should exist do if expected: does_a_subset_b(expected, serializer.data) # Make sure fields which should be ignored are if missing: with raises(AssertionError): does_a_subset_b(missing, serializer.data) @mark.parametrize( ["serializer", "expected", "missing"], [ param( # Generic test {'target': DeepContainerModel}, {'control_val': "CONTROL", 'deep_embed': OrderedDict({ 'control_val': "CONTROL", 'embed_field': OrderedDict({ 'int_field': 1234, 'char_field': "Embed" }) })}, None, id='basic' ), param( # Fields meta, in the topmost model, is respected {'target': DeepContainerModel, 'meta_fields': ['deep_embed']}, {'deep_embed': OrderedDict({ 'control_val': "CONTROL", 'embed_field': OrderedDict({ 'int_field': 1234, 'char_field': "Embed" }) })}, {'control_val': "CONTROL"}, id='respects_root_fields' ), param( # Exclude meta, in the topmost model, is respected {'target': DeepContainerModel, 'meta_exclude': ['deep_embed']}, {'control_val': "CONTROL"}, {'deep_embed': OrderedDict({ 'control_val': "CONTROL", 'embed_field': OrderedDict({ 'int_field': 1234, 'char_field': "Embed" }) })}, id='respects_root_exclude' ), param( # Fields meta, in the intermediary model, is respected {'target': DeepContainerModel, 'custom_fields': { 'deep_embed': { 'target': ContainerModel, 'meta_fields': ['embed_field'] }, }}, {'control_val': "CONTROL", 'deep_embed': OrderedDict({ 'embed_field': OrderedDict({ 'int_field': 1234, 'char_field': "Embed" }) })}, {'deep_embed': OrderedDict({ 'control_val': "CONTROL" })}, id='respects_intermediary_fields' ), param( # Exclude meta, in the intermediary model, is respected {'target': DeepContainerModel, 'custom_fields': { 'deep_embed': { 'target': ContainerModel, 'meta_exclude': ['embed_field'] }, }}, {'deep_embed': OrderedDict({ 'control_val': "CONTROL" })}, {'control_val': "CONTROL", 'deep_embed': OrderedDict({ 'embed_field': OrderedDict({ 'int_field': 1234, 'char_field': "Embed" }) })}, id='respects_intermediary_exclude' ), param( # Field meta, in the deepest model, is respected {'target': DeepContainerModel, 'custom_fields': { 'deep_embed': { 'target': ContainerModel, 'custom_fields': { 'embed_field': { 'target': EmbedModel, 'meta_fields': ['char_field'] } } }, }}, {'control_val': "CONTROL", 'deep_embed': OrderedDict({ 'control_val': "CONTROL", 'embed_field': OrderedDict({ 'char_field': "Embed" }) })}, {'deep_embed': OrderedDict({ 'embed_field': OrderedDict({ 'int_field': 1234, }) })}, id='respects_deep_fields' ), param( # Field meta, in the deepest model, is respected {'target': DeepContainerModel, 'custom_fields': { 'deep_embed': { 'target': ContainerModel, 'custom_fields': { 'embed_field': { 'target': EmbedModel, 'meta_exclude': ['char_field'] } } }, }}, {'control_val': "CONTROL", 'deep_embed': OrderedDict({ 'control_val': "CONTROL", 'embed_field': OrderedDict({ 'int_field': 1234, }) })}, {'deep_embed': OrderedDict({ 'embed_field': OrderedDict({ 'char_field': "Embed", }) })}, id='respects_deep_exclude' ) ]) def test_deep_retrieve(self, build_serializer, does_a_subset_b, deep_container_instance, serializer, expected, missing): # Prepare the test environment TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(deep_container_instance.deep_container) # Make sure fields which should exist do if expected: does_a_subset_b(expected, serializer.data) # Make sure fields which should be ignored are if missing: with raises(AssertionError): does_a_subset_b(missing, serializer.data) @mark.parametrize( ["initial", "serializer", "expected"], [ param( # Basic test (Shallowly nested models) {'embed_field': { 'int_field': 1357, 'char_field': "Bar" }}, {'target': ContainerModel}, {'control_val': "CONTROL", 'embed_field': EmbedModel( int_field=1357, char_field="Bar" )}, id='basic_root' ), param( # Basic test (deeply nested models) {'str_id': "identifier", 'deep_embed': { 'embed_field': { 'int_field': 1357, 'char_field': "Bar" }}, }, {'target': DeepContainerModel}, {'str_id': "identifier", 'control_val': "CONTROL", 'deep_embed': ContainerModel( control_val="CONTROL", embed_field=EmbedModel( int_field=1357, char_field="Bar" ), )}, id='basic_deep' ), param( # Custom fields are valid in the root model {}, {'target': ContainerModel, 'custom_fields': { 'embed_field': { 'target': EmbedModel, 'required': False, } }}, {'control_val': "CONTROL"}, id='custom_field_root' ), param( # Custom fields are valid (intermediary field) {'str_id': "identifier"}, {'target': DeepContainerModel, 'custom_fields': { 'deep_embed': { 'target': ContainerModel, 'required': False, 'default': { 'embed_field': { 'int_field': 1357, 'char_field': "Bar" } } } }}, {'control_val': "CONTROL", 'deep_embed': ContainerModel( control_val="CONTROL", embed_field=EmbedModel( int_field=1357, char_field="Bar" ) )}, id='custom_field_intermediate' ), param( # Custom fields are valid (deeply nested field) {'str_id': 'identifier', 'deep_embed': { 'embed_field': { 'int_field': 1357 }}, }, {'target': DeepContainerModel, 'custom_fields': { 'deep_embed': { 'target': ContainerModel, 'custom_fields': { 'embed_field': { 'target': EmbedModel, 'custom_fields': { 'char_field': CharField(default="Foo") } } } } }}, {'str_id': 'identifier', 'deep_embed': ContainerModel( control_val="CONTROL", embed_field=EmbedModel( int_field=1357, char_field="Foo" )) }, id='custom_field_deep' ), ]) def test_valid_create(self, build_serializer, instance_matches_data, initial, serializer, expected): # Test environment preparation TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(data=initial) # Confirm that input data is valid assert serializer.is_valid(), serializer.errors # Make sure the serializer can save the data instance = serializer.save() # Confirm that the data was saved correctly instance_matches_data(instance, expected) @mark.parametrize( ["initial", "serializer", "error"], [ param( # Invalid values in the root model are caught {'control_val': "WAY_TOO_LONG"}, {'target': ContainerModel}, AssertionError, id='root_validation' ), param( # Invalid values in the intermediary model are caught {'deep_embed': { 'control_val': "WAY_TOO_LONG" }}, {'target': DeepContainerModel}, AssertionError, id='intermediate_validation' ), param( # Invalid values in the deepest model are caught {'deep_embed': { 'control_val': { 'int_val': 1357, 'char_val': "TOO_LONG" } }}, {'target': DeepContainerModel}, AssertionError, id='deep_validation' ), param( # Missing values in the deepest model are caught {'deep_embed': { 'control_val': { 'int_val': 1357, } }}, {'target': DeepContainerModel}, AssertionError, id='deep_validation' ), ]) def test_invalid_create(self, build_serializer, instance_matches_data, initial, serializer, error): # Prepare the test environment TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(data=initial) # Confirm that the serializer throws the designated error with raises(error): assert serializer.is_valid(), serializer.errors serializer.save() @mark.parametrize( ["update", "serializer", "expected"], [ param( # Generic test {'control_val': "NEW_VAL", 'embed_field': { 'int_field': 2468, 'char_field': "Baz" }}, {'target': ContainerModel}, {'control_val': "NEW_VAL", 'embed_field': EmbedModel( int_field=2468, char_field="Baz" )}, id='basic' ), param( # Values can be set to null after submission {'control_val': "NEW_VAL", 'embed_field': None}, {'target': ContainerModel}, {'control_val': "NEW_VAL", 'embed_field': None}, id='null_set' ), param( # Meta `fields` functions in root {'control_val': "NEW_VAL"}, {'target': ContainerModel, 'meta_fields': ['control_val']}, {'control_val': "NEW_VAL", 'embed_field': EmbedModel( int_field=1234, char_field="Embed" )}, id='respects_root_fields' ), param( # Meta `fields` functions in a nested model {'control_val': "NEW_VAL", 'embed_field': { 'int_field': 1470 }}, {'target': ContainerModel, 'custom_fields': { 'embed_field': { 'target': EmbedModel, 'meta_fields': ['int_field'] } }}, {'control_val': "NEW_VAL", 'embed_field': EmbedModel( int_field=1470, char_field="Embed" )}, id='respects_deep_fields' ), param( # Meta `exclude` functions in root model {'embed_field': { 'int_field': 1369, 'char_field': "Baz", }}, {'target': ContainerModel, 'meta_exclude': ['control_val']}, {'control_val': "CONTROL", 'embed_field': EmbedModel( int_field=1369, char_field="Baz" )}, id='respects_root_exclude' ), param( # Meta `exclude` functions in a nested model {'control_val': "NEW_VAL", 'embed_field': { 'char_field': "Baz" }}, {'target': ContainerModel, 'custom_fields': { 'embed_field': { 'target': EmbedModel, 'meta_exclude': ['int_field'] } }}, {'control_val': "NEW_VAL", 'embed_field': EmbedModel( int_field=1234, char_field="Baz" )}, id='respects_deep_exclude' ), ]) def test_valid_basic_update(self, build_serializer, instance_matches_data, container_instance, update, serializer, expected): # Prepare the test environment TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(container_instance.container, data=update) # Confirm the serializer is valid assert serializer.is_valid(), serializer.errors # Confirm that the serializer can save the new data instance = serializer.save() # Confirm that the update went as planned instance_matches_data(instance, expected) @mark.parametrize( ['update', 'serializer', 'error'], [ param( # Missing value caught in root model {'embed_field': { 'int_field': 1357, 'char_field': "Bar" }}, {'target': ContainerModel, 'custom_fields': { 'control_val': CharField(required=True) }}, AssertionError, id='missing_root_value' ), param( # Missing value caught in deep model {'embed_field': { 'char_field': "Bar" }}, {'target': ContainerModel}, AssertionError, id='missing_deep_value' ), param( # Invalid values in the root model are caught {'control_val': "WAY_TOO_LONG", 'embed_field': { 'int_field': 1357, 'char_field': "Bar" }}, {'target': ContainerModel}, AssertionError, id='invalid_root_value' ), param( # Invalid values in nested models are caught {'embed_field': { 'int_field': "Not_An_Int", 'char_field': "Bar" }}, {'target': ContainerModel}, AssertionError, id='invalid_deep_value' ), ]) def test_invalid_basic_update(self, build_serializer, instance_matches_data, container_instance, update, serializer, error): TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(container_instance.container, data=update) # Confirm that the serializer throws the designated error with raises(error): assert serializer.is_valid(), serializer.errors serializer.save() @mark.parametrize( ["update", "serializer", "expected"], [ param( # Generic test {'str_id': "new_id", 'deep_embed': { 'embed_field': { 'int_field': 1357, 'char_field': "Bar" } }}, {'target': DeepContainerModel}, {'str_id': "new_id", 'deep_embed': ContainerModel( control_val="CONTROL", embed_field=EmbedModel( int_field=1357, char_field="Bar" ) )}, id='basic' ), param( # Intermediate `fields` respected {'str_id': "new_id", 'deep_embed': { 'control_val': "NEW_VAL" }}, {'target': DeepContainerModel, 'custom_fields': { 'deep_embed': { 'target': ContainerModel, 'meta_fields': ['control_val'] } }}, {'str_id': "new_id", 'deep_embed': ContainerModel( control_val="NEW_VAL", embed_field=EmbedModel( int_field=1234, char_field="Embed" ) )}, id='respects_intermediate_fields' ), param( # Intermediate `exclude` respected {'str_id': "new_id", 'deep_embed': { 'control_val': "NEW_VAL" }}, {'target': DeepContainerModel, 'custom_fields': { 'deep_embed': { 'target': ContainerModel, 'meta_exclude': ['embed_field'] } }}, {'str_id': "new_id", 'deep_embed': ContainerModel( control_val="NEW_VAL", embed_field=EmbedModel( int_field=1234, char_field="Embed" ) )}, id='respects_intermediate_exclude' ), ]) def test_valid_deep_update(self, build_serializer, instance_matches_data, deep_container_instance, update, serializer, expected): # Prepare the test environment TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(deep_container_instance.deep_container, data=update) # Confirm that serializer data is valid assert serializer.is_valid(), serializer.errors # Confirm that the serializer can save the data instance = serializer.save() # Confirm that the update went as planned instance_matches_data(instance, expected) @mark.parametrize( ["update", "serializer", "error"], [ param( # Missing fields are caught (root field) {'deep_embed': { 'embed_field': { 'int_field': 1357, 'char_field': "Bar" } }}, {'target': DeepContainerModel}, AssertionError, id="root_missing" ), param( # Missing fields are caught (intermediate field) {'str_id': "identifier", 'deep_embed': { 'embed_field': { 'int_field': 1357, 'char_field': "Baz" } }}, {'target': DeepContainerModel, 'custom_fields': { 'control_val': CharField(required=True) }}, AssertionError, id="intermediate_missing" ), param( # Missing fields are caught (deep field) {'str_id': "identifier", 'deep_embed': { 'embed_field': { 'char_field': "Baz" } }}, {'target': DeepContainerModel}, AssertionError, id="deep_missing" ), param( # Invalid fields are caught (root field) {'str_id': "very_very_very_long", 'deep_embed': { 'embed_field': { 'int_field': 1324, 'char_field': "Baz" } }}, {'target': DeepContainerModel}, AssertionError, id="root_invalid" ), param( # Invalid fields are caught (intermediate field) {'str_id': "identifier", 'deep_embed': { 'embed_field': 1324 }}, {'target': DeepContainerModel}, AssertionError, id="intermediate_invalid" ), param( # Invalid fields are caught (deep field) {'str_id': "intermediate", 'deep_embed': { 'embed_field': { 'int_field': "Wrong", 'char_field': "Baz" } }}, {'target': DeepContainerModel}, AssertionError, id="deep_invalid" ), ]) def test_invalid_update(self, build_serializer, instance_matches_data, deep_container_instance, update, serializer, error): # Prepare the test environment TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(deep_container_instance.deep_container, data=update) with raises(error): # Confirm that serializer data is valid assert serializer.is_valid(), serializer.errors # Confirm that the serializer can save the data serializer.save() @mark.parametrize( ["update", "serializer", "expected"], [ param( # Generic test (root fields) {'embed_field': { 'char_field': "Baz", 'int_field': 1324 }}, {'target': ContainerModel}, {'control_val': "CONTROL", 'embed_field': EmbedModel( int_field=1324, char_field="Baz" )}, id="basic_root" ), param( # Generic test (deep fields) {'embed_field': { 'int_field': 1324 }}, {'target': ContainerModel}, {'control_val': "CONTROL", 'embed_field': EmbedModel( int_field=1324, char_field='Embed' )}, id="basic_root" ), ]) def test_valid_basic_partial_update(self, build_serializer, instance_matches_data, container_instance, update, serializer, expected): # Prepare the test environment TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(container_instance.container, data=update, partial=True) # Confirm that serializer data is valid assert serializer.is_valid(), serializer.errors # Confirm that the serializer can save the data instance = serializer.save() # Confirm that the update went as planned instance_matches_data(instance, expected) @mark.parametrize( ["update", "serializer", "expected"], [ param( # Generic test (root fields) {'deep_embed': { 'embed_field': { 'char_field': "Baz", 'int_field': 1324 } }}, {'target': DeepContainerModel}, {'control_val': "CONTROL", 'deep_embed': ContainerModel( control_val="CONTROL", embed_field=EmbedModel( int_field=1324, char_field="Baz" ) )}, id="basic_root" ), param( # Generic test (intermediate fields) {'deep_embed': { 'control_val': "NEW_VAL" }}, {'target': DeepContainerModel}, {'control_val': "CONTROL", 'deep_embed': ContainerModel( control_val="NEW_VAL", embed_field=EmbedModel( int_field=1234, char_field='Embed' ) )}, id="basic_intermediate" ), param( # Generic test (intermediate fields) {'deep_embed': { 'embed_field': { 'int_field': 1324 } }}, {'target': DeepContainerModel}, {'control_val': "CONTROL", 'deep_embed': ContainerModel( control_val="CONTROL", embed_field=EmbedModel( int_field=1324, char_field='Embed' ) )}, id="basic_deep" ), ]) def test_valid_deep_partial_update(self, build_serializer, instance_matches_data, deep_container_instance, update, serializer, expected): # Prepare the test environment TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(deep_container_instance.deep_container, data=update, partial=True) # Confirm that serializer data is valid assert serializer.is_valid(), serializer.errors # Confirm that the serializer can save the data instance = serializer.save() # Confirm that the update went as planned instance_matches_data(instance, expected) @mark.parametrize( ['update', 'serializer', 'error'], [ param( # Invalid fields are caught (root field) {'str_id': "very_very_very_long"}, {'target': DeepContainerModel}, AssertionError, id="root_invalid" ), param( # Invalid fields are caught (intermediate field) {'deep_embed': { 'control_field': "NEW_VAL", 'embed_field': 1324, }}, {'target': DeepContainerModel}, AssertionError, id="intermediate_invalid" ), param( # Invalid fields are caught (deep field) {'deep_embed': { 'control_field': "NEW_VAL", 'embed_field': { 'int_field': "NOT_AN_INT", 'char_field': "Foo" }, }}, {'target': DeepContainerModel}, AssertionError, id="deep_invalid" ), ] ) def test_invalid_partial_update(self, build_serializer, instance_matches_data, deep_container_instance, update, serializer, error): # Prepare the test environment TestSerializer, _ = build_serializer(**serializer) serializer = TestSerializer(deep_container_instance.deep_container, data=update, partial=True) with raises(error): assert serializer.is_valid(), serializer.errors # Confirm that the serializer can save the data serializer.save()
def embedded(self): from tests.models import EmbedModel return EmbedModel()