Skip to content
Snippets Groups Projects
Commit e50dbabb authored by Bastien Abadie's avatar Bastien Abadie
Browse files

Merge branch 'url-metadata' into 'master'

Add URL metadata type

Closes #844

See merge request !1480
parents 095d33a2 95baeb2f
No related branches found
No related tags found
1 merge request!1480Add URL metadata type
......@@ -625,6 +625,7 @@ class MetaType(Enum):
# Element's original structure reference (intended to be indexed)
Reference = 'reference'
Numeric = 'numeric'
URL = 'url'
class AllowedMetaData(models.Model):
......
......@@ -4,6 +4,8 @@ from collections import defaultdict
from uuid import UUID
from django.contrib.gis.geos import LinearRing
from django.core.exceptions import ValidationError as DjangoValidationError
from django.core.validators import URLValidator
from django.db import transaction
from django.utils.functional import cached_property
from drf_spectacular.utils import extend_schema_field
......@@ -83,6 +85,7 @@ class MetaDataBulkItemSerializer(MetaDataLightSerializer):
# Those can be None if someone messed up their input; DRF will catch it itself afterwards, so we ignore None.
meta_type = data.get('type', self.instance.type if self.instance else None)
value = data.get('value', self.instance.value if self.instance else None)
if meta_type == MetaType.Numeric and value is not None:
try:
# Python allows _ to separate numbers (123_456.789_101), but Postgres does not, so we forbid them.
......@@ -94,6 +97,15 @@ class MetaDataBulkItemSerializer(MetaDataLightSerializer):
raise serializers.ValidationError({
'value': ['The value of a numeric metadata should be a valid floating-point number.']
})
if meta_type == MetaType.URL and value is not None:
try:
URLValidator(schemes=['http', 'https'])(value)
except DjangoValidationError:
raise serializers.ValidationError({
'value': ['The value of a URL metadata must be a valid HTTP or HTTPS URL.']
})
return data
......
......@@ -586,6 +586,34 @@ class TestMetaData(FixtureAPITestCase):
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertDictEqual(response.json(), {'value': ['The value of a numeric metadata should be a valid floating-point number.']})
def test_create_url_metadata(self):
self.client.force_login(self.superuser)
response = self.client.post(
reverse('api:element-metadata', kwargs={'pk': str(self.vol.id)}),
data={'type': 'url', 'name': 'blah', 'value': 'http://nowhere.com'}
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
md = self.vol.metadatas.get(type=MetaType.URL, name='blah')
self.assertEqual(md.value, 'http://nowhere.com')
def test_create_url_metadata_invalid(self):
self.client.force_login(self.superuser)
response = self.client.post(
reverse('api:element-metadata', kwargs={'pk': str(self.vol.id)}),
data={'type': 'url', 'name': 'blah', 'value': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'}
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertDictEqual(response.json(), {'value': ['The value of a URL metadata must be a valid HTTP or HTTPS URL.']})
def test_create_url_metadata_scheme(self):
self.client.force_login(self.superuser)
response = self.client.post(
reverse('api:element-metadata', kwargs={'pk': str(self.vol.id)}),
data={'type': 'url', 'name': 'blah', 'value': 'git+https://gitlab.com/arkindex/backend.git'}
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertDictEqual(response.json(), {'value': ['The value of a URL metadata must be a valid HTTP or HTTPS URL.']})
def test_bulk_create_metadata_verified(self):
response = self.client.post(reverse('api:element-metadata-bulk', kwargs={'pk': str(self.vol.id)}))
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
......
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