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

Add CreateAllowedMetaData endpoint

parent e50dbabb
No related branches found
No related tags found
1 merge request!1482Add CreateAllowedMetaData endpoint
......@@ -1360,17 +1360,37 @@ class AllowedMetaDataPagination(PageNumberPagination):
page_size = 200
@extend_schema_view(get=extend_schema(operation_id='ListCorpusAllowedMetaDatas', tags=['corpora']))
class CorpusAllowedMetaData(CorpusACLMixin, ListAPIView):
@extend_schema(tags=['corpora'])
@extend_schema_view(
get=extend_schema(operation_id='ListCorpusAllowedMetaDatas'),
post=extend_schema(
operation_id='CreateAllowedMetaData',
description='Create an allowed meta data in a corpus',
)
)
class CorpusAllowedMetaData(CorpusACLMixin, ListCreateAPIView):
"""
List (type, name) couples allowed for corpus metadata
"""
serializer_class = CorpusAllowedMetaDataSerializer
pagination_class = AllowedMetaDataPagination
permission_classes = (IsVerifiedOrReadOnly, )
queryset = AllowedMetaData.objects.none()
@cached_property
def corpus(self):
role = Role.Guest
if self.request.method.lower() == 'post':
role = Role.Admin
return self.get_corpus(self.kwargs['pk'], role=role)
def get_queryset(self):
return AllowedMetaData.objects.filter(corpus=self.get_corpus(self.kwargs['pk']))
return AllowedMetaData.objects.filter(corpus=self.corpus)
def get_serializer_context(self):
context = super().get_serializer_context()
context['corpus_id'] = self.corpus.id
return context
@extend_schema(tags=['elements'])
......
......@@ -200,5 +200,14 @@ class CorpusAllowedMetaDataSerializer(serializers.ModelSerializer):
class Meta:
model = AllowedMetaData
fields = ('type', 'name', )
read_only_fields = ('type', 'name', )
fields = ('id', 'type', 'name', )
read_only_fields = ('id', )
def validate(self, data):
data = super().validate(data)
if AllowedMetaData.objects.filter(corpus_id=self.context['corpus_id'], name=data['name'], type=data['type']).exists():
raise serializers.ValidationError({
'detail': ['An AllowedMetaData with this type and name already exists in this corpus.'],
})
data['corpus_id'] = self.context['corpus_id']
return data
from unittest.mock import patch
from django.urls import reverse
from rest_framework import status
from arkindex.documents.models import AllowedMetaData, Corpus, MetaType
from arkindex.project.tests import FixtureAPITestCase
class TestAllowedMetaData(FixtureAPITestCase):
@classmethod
def setUpTestData(cls):
super().setUpTestData()
cls.private_corpus = Corpus.objects.create(name='private')
cls.allowed_meta = AllowedMetaData.objects.bulk_create(
AllowedMetaData(corpus=cls.corpus, type=t, name=n)
for t, n in (
(MetaType.Date, 'edition'),
(MetaType.Text, 'edition'),
(MetaType.Reference, '_id'),
)
)
@patch('arkindex.documents.api.elements.AllowedMetaDataPagination')
def test_list(self, pagination_mock):
pagination_mock.page_size = 3
with self.assertNumQueries(3):
response = self.client.get(
reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.corpus.id)}),
data={'page_size': 3}
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
expected_meta = [
{
"id": str(meta.id),
"name": meta.name,
"type": meta.type.value
}
for meta in self.corpus.allowed_metadatas.all()
]
self.assertEqual(data['count'], 6)
self.assertListEqual(
data['results'],
list(expected_meta[:3])
)
with self.assertNumQueries(3):
response = self.client.get(data['next'])
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertListEqual(
response.json()['results'],
list(expected_meta[3:])
)
def test_list_private_corpus(self):
response = self.client.get(
reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.private_corpus.id)}),
data={'page_size': 3}
)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_create(self):
self.client.force_login(self.user)
with self.assertNumQueries(8):
response = self.client.post(
reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.corpus.id)}),
data={'name': 'flan', 'type': 'text'}
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
new_meta = self.corpus.allowed_metadatas.get(name='flan', type=MetaType.Text)
self.assertDictEqual(response.json(), {
'id': str(new_meta.id),
'name': new_meta.name,
'type': new_meta.type.value,
})
def test_create_unique(self):
self.client.force_login(self.user)
self.corpus.allowed_metadatas.create(name='flan', type=MetaType.Text)
with self.assertNumQueries(7):
response = self.client.post(
reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.corpus.id)}),
data={'name': 'flan', 'type': 'text'}
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertDictEqual(response.json(), {
'detail': ['An AllowedMetaData with this type and name already exists in this corpus.'],
})
def test_create_requires_login(self):
response = self.client.post(
reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.corpus.id)}),
data={'name': 'flan', 'type': 'text'}
)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_create_requires_verified(self):
self.user.verified_email = False
self.user.save()
self.client.force_login(self.user)
response = self.client.post(
reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.corpus.id)}),
data={'name': 'flan', 'type': 'text'}
)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_create_private_corpus(self):
self.client.force_login(self.user)
response = self.client.post(
reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.private_corpus.id)}),
data={'name': 'flan', 'type': 'text'}
)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_create_invalid(self):
self.client.force_login(self.user)
with self.assertNumQueries(6):
response = self.client.post(
reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.corpus.id)}),
data={'name': 'flan', 'type': 'pouet'}
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertDictEqual(response.json(), {
'type': ['Value is not of type MetaType']
})
from unittest.mock import patch
from django.urls import reverse
from rest_framework import status
......@@ -44,44 +42,6 @@ class TestMetaData(FixtureAPITestCase):
response = self.client.post(reverse('api:metadata-edit', kwargs={'pk': str(self.metadata.id)}))
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
@patch('arkindex.documents.api.elements.AllowedMetaDataPagination')
def test_list_allowed_metadata(self, pagination_mock):
pagination_mock.page_size = 3
response = self.client.get(
reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.corpus.id)}),
data={'page_size': 3}
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
self.assertEqual(data['count'], 6)
self.assertListEqual(
data['results'],
[
{'type': 'date', 'name': 'date'},
{'type': 'date', 'name': 'edition'},
{'type': 'location', 'name': 'location'}
]
)
response = self.client.get(data['next'])
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertListEqual(
response.json()['results'],
[
{'type': 'reference', 'name': '_id'},
{'type': 'text', 'name': 'edition'},
{'type': 'text', 'name': 'folio'}
]
)
def test_allowed_metadata_methods(self):
"""
Allowed metadata is read-only endpoint
"""
methods = (self.client.post, self.client.patch, self.client.put, self.client.delete)
for method in methods:
response = method(reverse('api:corpus-allowed-metadata', kwargs={'pk': str(self.corpus.id)}))
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
def test_create_metadata_verified(self):
response = self.client.post(reverse('api:element-metadata', 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