Use a consistent structure for field errors
This commit is contained in:
parent
f6e1bacfa1
commit
b9f13c6c75
|
|
@ -547,6 +547,41 @@ class SiteTestCase(APIViewTestCases.APIViewTestCase):
|
|||
site.refresh_from_db()
|
||||
self.assertEqual(site.description, '')
|
||||
|
||||
def test_bulk_write_objects_null_entry(self):
|
||||
"""
|
||||
Address a list endpoint with a list containing a null entry. A null fails before any field
|
||||
is considered, so its error arrives as a bare list of messages; it must still be reported
|
||||
as a mapping keyed by field name, as the schema declares.
|
||||
"""
|
||||
obj_perm = ObjectPermission(name='Test permission', actions=['change', 'delete'])
|
||||
obj_perm.save()
|
||||
obj_perm.users.add(self.user)
|
||||
obj_perm.object_types.add(ObjectType.objects.get_for_model(self.model))
|
||||
|
||||
site = Site.objects.get(slug='site-1')
|
||||
initial_count = Site.objects.count()
|
||||
|
||||
for method in ('patch', 'put', 'delete'):
|
||||
with self.subTest(method=method):
|
||||
data = [{'id': site.pk, 'description': 'x'}, None]
|
||||
response = getattr(self.client, method)(
|
||||
self._get_list_url(), data, format='json', **self.header
|
||||
)
|
||||
|
||||
self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(len(response.data['errors']), 1)
|
||||
self.assertEqual(response.data['errors'][0]['index'], 1)
|
||||
|
||||
# Reported under the key which every other non-field error uses
|
||||
entry_errors = response.data['errors'][0]['errors']
|
||||
self.assertIsInstance(entry_errors, dict)
|
||||
self.assertIn('__all__', entry_errors)
|
||||
|
||||
# The valid entry must not have been applied
|
||||
site.refresh_from_db()
|
||||
self.assertEqual(site.description, '')
|
||||
self.assertEqual(Site.objects.count(), initial_count, 'No objects should have been deleted')
|
||||
|
||||
def test_bulk_update_objects_duplicate_id_invalid_entry(self):
|
||||
"""
|
||||
PATCH a set of objects in which one object is named twice, once with invalid data and once
|
||||
|
|
|
|||
|
|
@ -107,6 +107,17 @@ def get_non_list_response(data):
|
|||
return Response({'detail': detail}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
def _as_field_errors(item_errors):
|
||||
"""
|
||||
Return the errors reported for one entry of a bulk request as a mapping of field name to
|
||||
messages.
|
||||
"""
|
||||
if isinstance(item_errors, dict):
|
||||
return item_errors
|
||||
|
||||
return {api_settings.NON_FIELD_ERRORS_KEY: item_errors}
|
||||
|
||||
|
||||
def get_invalid_entries_response(entry_errors):
|
||||
"""
|
||||
Return a structured error Response for the entries of a bulk request which could not be
|
||||
|
|
@ -124,7 +135,7 @@ def get_invalid_entries_response(entry_errors):
|
|||
entry per object in the request (an empty dict where that object was interpretable).
|
||||
"""
|
||||
errors = [
|
||||
{'index': i, 'errors': item_errors}
|
||||
{'index': i, 'errors': _as_field_errors(item_errors)}
|
||||
for i, item_errors in enumerate(entry_errors)
|
||||
if item_errors
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in New Issue