Skip to content
Snippets Groups Projects
Verified Commit 2d240d69 authored by Erwan Rouchet's avatar Erwan Rouchet
Browse files

Fix handling of polygons without images in CreateElement

parent 1c3c8bfc
No related branches found
No related tags found
1 merge request!1500Fix handling of polygons without images in CreateElement
......@@ -619,7 +619,7 @@ class ElementCreateSerializer(ElementLightSerializer):
self.fields['corpus'].queryset = corpora.prefetch_related('types')
# Avoid a stale read issue when creating a child on a freshly created parent
self.fields['parent'].queryset = Element.objects.filter(corpus__in=corpora).using('default')
self.fields['parent'].queryset = Element.objects.filter(corpus__in=corpora).select_related('image').using('default')
def validate(self, data):
errors = defaultdict(list)
......@@ -636,6 +636,9 @@ class ElementCreateSerializer(ElementLightSerializer):
})
parent = data.get('parent')
image = data.get('image')
polygon = data.get('polygon')
if parent:
if parent.corpus_id != data['corpus'].id:
errors['corpus'].append(
......@@ -649,7 +652,14 @@ class ElementCreateSerializer(ElementLightSerializer):
data.setdefault('rotation_angle', 0)
data.setdefault('mirrored', False)
image = data.get('image')
if polygon and not image:
# Deduce the image from the parent if there is one
if parent is not None and parent.image_id:
image = parent.image
data['image'] = image
else:
errors['polygon'].append('An image or a parent with an image is required to create an element with a polygon.')
if image and (image.width == 0 or image.height == 0):
# Element creation with images with a width or height equal to zero
# will lead to many errors everywhere as this would create impossible polygons
......
......@@ -27,6 +27,23 @@ class TestCreateElements(FixtureAPITestCase):
)
cls.worker_version = WorkerVersion.objects.get(worker__slug='dla')
# The image is always the same in API responses
cls.image_response = {
'id': str(cls.image.id),
's3_url': None,
'width': 42,
'height': 42,
'path': 'kingdom/far/away',
'url': 'http://server/kingdom/far/away',
'status': 'checked',
'server': {
'display_name': 'Test Server',
'max_height': None,
'max_width': None,
'url': 'http://server',
}
}
def make_create_request(self, name='default', corpus=None, elt_type='volume', **options):
request = {
'path': reverse('api:elements-create'),
......@@ -57,7 +74,6 @@ class TestCreateElements(FixtureAPITestCase):
data = response.json()
self.assertIn('id', data)
volume = Element.objects.get(id=data['id'])
# Assert the fully serialized response matches the created volume
self.assertDictEqual(
data,
{
......@@ -99,8 +115,6 @@ class TestCreateElements(FixtureAPITestCase):
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
data = response.json()
page = self.corpus.elements.get(id=data['id'])
# Assert the fully serialized response matches the created page (exclude image zone)
del data['zone']
self.assertDictEqual(
data,
{
......@@ -109,6 +123,7 @@ class TestCreateElements(FixtureAPITestCase):
'type': page.type.slug,
'thumbnail_put_url': None,
'thumbnail_url': None,
'created': page.created.isoformat().replace('+00:00', 'Z'),
'creator': 'Test user',
'rights': ['read', 'write', 'admin'],
'worker_version': None,
......@@ -118,15 +133,47 @@ class TestCreateElements(FixtureAPITestCase):
'name': page.corpus.name,
'public': page.corpus.public
},
'zone': {
'id': str(page.id),
'image': self.image_response,
'polygon': [[0, 0], [0, 42], [42, 42], [42, 0], [0, 0]],
'url': page.iiif_url,
},
'rotation_angle': 0,
'mirrored': False,
'created': page.created.isoformat().replace('+00:00', 'Z'),
}
)
self.assertEqual(page.name, 'The castle of my dreams')
self.assertEqual(page.type, self.page_type)
self.assertEqual(page.creator, self.user)
def test_create_inherit_parent_image(self):
"""
Creating an element with a parent, a polygon and no image should inherit the parent's image
"""
polygon = [[10, 10], [10, 40], [40, 40], [40, 10], [10, 10]]
self.vol.image = self.image
self.vol.polygon = polygon
self.vol.save()
self.client.force_login(self.user)
request = self.make_create_request(
parent=str(self.vol.id),
elt_type='page',
name='The castle of my dreams',
polygon=polygon,
)
with self.assertNumQueries(16):
response = self.client.post(**request)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
data = response.json()
page = self.corpus.elements.get(id=data['id'])
self.assertEqual(response.json()['zone'], {
'id': str(page.id),
'image': self.image_response,
'polygon': polygon,
'url': page.iiif_url,
})
def test_create_volume_act(self):
# Create an volume child of type Act
self.client.force_login(self.user)
......@@ -178,6 +225,20 @@ class TestCreateElements(FixtureAPITestCase):
'worker_version': ['Only an internal user can create an element with a worker version.'],
})
def test_create_element_polygon_no_image(self):
self.client.force_login(self.user)
request = self.make_create_request(
elt_type='page',
name='The castle of my dreams again',
polygon=[[10, 10], [10, 40], [40, 40], [40, 10], [10, 10]],
)
with self.assertNumQueries(6):
response = self.client.post(**request)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertDictEqual(response.json(), {
'polygon': ['An image or a parent with an image is required to create an element with a polygon.'],
})
def test_create_element_polygon_negative(self):
self.client.force_login(self.user)
request = self.make_create_request(
......@@ -210,8 +271,6 @@ class TestCreateElements(FixtureAPITestCase):
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
data = response.json()
page = self.corpus.elements.get(id=data['id'])
# Assert the fully serialized response matches the created element (exclude zone image field)
del data['zone']['image']
self.assertDictEqual(
data,
{
......@@ -232,7 +291,8 @@ class TestCreateElements(FixtureAPITestCase):
'zone': {
'id': str(page.id),
'polygon': polygon,
'url': str(page.iiif_url)
'image': self.image_response,
'url': page.iiif_url,
},
'rotation_angle': 0,
'mirrored': False,
......
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