Skip to content
Snippets Groups Projects
Commit 7428ba0c authored by ml bonhomme's avatar ml bonhomme :bee: Committed by Erwan Rouchet
Browse files

don't allow duplicates in metadata_list when creating metadata in bulk

parent 9b46ecdf
No related branches found
No related tags found
1 merge request!1628don't allow duplicates in metadata_list when creating metadata in bulk
......@@ -172,6 +172,32 @@ class MetaDataBulkSerializer(serializers.Serializer):
super().__init__(*args, **kwargs)
self.fields['metadata_list'] = MetaDataBulkItemSerializer(many=True, allow_empty=False, context=self.context)
def make_metadata_tuples(self, meta_list):
tuples_list = []
for item in meta_list:
item_tuple = (
item.get('name'),
item.get('type').value,
item.get('value')
)
tuples_list.append(item_tuple)
return tuples_list
def validate(self, data):
data = super().validate(data)
request_metadata = self.make_metadata_tuples(data['metadata_list'])
unique_metadata = set(request_metadata)
if len(unique_metadata) != len(request_metadata):
raise ValidationError('Metadata in metadata list must make a unique set.')
names = [item['name'] for item in data['metadata_list']]
types = [item['type'] for item in data['metadata_list']]
filtered_metadata = MetaData.objects.filter(element=self.context['element'].id, name__in=names, type__in=types).values()
existing_metadata = self.make_metadata_tuples(filtered_metadata)
meta_matches = set(request_metadata) & set(existing_metadata)
if meta_matches:
raise ValidationError(f'Metadata {meta_matches} already exist(s) on this element.')
return data
def create(self, validated_data):
validated_data['metadata_list'] = MetaData.objects.bulk_create([
MetaData(
......
......@@ -967,3 +967,45 @@ class TestMetaData(FixtureAPITestCase):
{'name': 'not allowed', 'type': MetaType.Location}
]
)
def test_bulk_create_metadata_unique(self):
"""
The metadata created with the bulk endpoint must be unique
"""
self.client.force_login(self.user)
with self.assertNumQueries(5):
response = self.client.post(
reverse('api:element-metadata-bulk', kwargs={'pk': str(self.vol.id)}),
data={'metadata_list': [
{'type': 'location', 'name': 'location', 'value': 'Texas'},
{'type': 'location', 'name': 'location', 'value': 'Texas'}
]},
format='json'
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertDictEqual(response.json(), {
'non_field_errors': ['Metadata in metadata list must make a unique set.']
})
def test_bulk_create_metadata_no_duplicates(self):
"""
Do not create metadata that already exist on the element
"""
self.client.force_login(self.user)
response_1 = self.client.post(
reverse('api:element-metadata', kwargs={'pk': str(self.vol.id)}),
data={'type': 'location', 'name': 'location', 'value': 'Texas'}
)
self.assertEqual(response_1.status_code, status.HTTP_201_CREATED)
with self.assertNumQueries(4):
response_2 = self.client.post(
reverse('api:element-metadata-bulk', kwargs={'pk': str(self.vol.id)}),
data={'metadata_list': [
{'type': 'location', 'name': 'location', 'value': 'Texas'}
]},
format='json'
)
self.assertEqual(response_2.status_code, status.HTTP_400_BAD_REQUEST)
self.assertDictEqual(response_2.json(), {
'non_field_errors': ["Metadata {('location', 'location', 'Texas')} already exist(s) on this element."]
})
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment