Initial commit for tag API refactor.
This commit is contained in:
@@ -9,54 +9,81 @@ from rest_framework.response import Response
|
||||
from acls.models import AccessControlList
|
||||
from documents.models import Document
|
||||
from documents.permissions import permission_document_view
|
||||
from documents.serializers import DocumentSerializer
|
||||
from permissions import Permission
|
||||
from rest_api.filters import MayanObjectPermissionsFilter
|
||||
from rest_api.permissions import MayanPermission
|
||||
|
||||
from .models import Tag
|
||||
from .permissions import (
|
||||
permission_tag_attach, permission_tag_remove, permission_tag_view
|
||||
permission_tag_attach, permission_tag_create, permission_tag_delete,
|
||||
permission_tag_edit, permission_tag_remove, permission_tag_view
|
||||
)
|
||||
from .serializers import (
|
||||
DocumentTagSerializer, NewDocumentTagSerializer, TagSerializer
|
||||
)
|
||||
from .serializers import TagSerializer
|
||||
|
||||
|
||||
class APITagView(generics.RetrieveUpdateDestroyAPIView):
|
||||
serializer_class = TagSerializer
|
||||
filter_backends = (MayanObjectPermissionsFilter,)
|
||||
mayan_object_permissions = {
|
||||
'DELETE': (permission_tag_delete,),
|
||||
'GET': (permission_tag_view,),
|
||||
'PATCH': (permission_tag_edit,),
|
||||
'PUT': (permission_tag_edit,)
|
||||
}
|
||||
queryset = Tag.objects.all()
|
||||
|
||||
permission_classes = (MayanPermission,)
|
||||
mayan_object_permissions = {'GET': [permission_tag_view]}
|
||||
serializer_class = TagSerializer
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
"""Delete the selected tag."""
|
||||
"""
|
||||
Delete the selected tag.
|
||||
"""
|
||||
|
||||
return super(APITagView, self).delete(*args, **kwargs)
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""Return the details of the selected tag."""
|
||||
"""
|
||||
Return the details of the selected tag.
|
||||
"""
|
||||
|
||||
return super(APITagView, self).get(*args, **kwargs)
|
||||
|
||||
def patch(self, *args, **kwargs):
|
||||
"""Edit the selected tag."""
|
||||
"""
|
||||
Edit the selected tag.
|
||||
"""
|
||||
|
||||
return super(APITagView, self).patch(*args, **kwargs)
|
||||
|
||||
def put(self, *args, **kwargs):
|
||||
"""Edit the selected tag."""
|
||||
"""
|
||||
Edit the selected tag.
|
||||
"""
|
||||
|
||||
return super(APITagView, self).put(*args, **kwargs)
|
||||
|
||||
|
||||
class APITagListView(generics.ListCreateAPIView):
|
||||
serializer_class = TagSerializer
|
||||
queryset = Tag.objects.all()
|
||||
|
||||
filter_backends = (MayanObjectPermissionsFilter,)
|
||||
mayan_object_permissions = {'GET': [permission_tag_view]}
|
||||
mayan_object_permissions = {'GET': (permission_tag_view,)}
|
||||
mayan_view_permissions = {'POST': (permission_tag_create,)}
|
||||
permission_classes = (MayanPermission,)
|
||||
queryset = Tag.objects.all()
|
||||
serializer_class = TagSerializer
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""Returns a list of all the tags."""
|
||||
"""
|
||||
Returns a list of all the tags.
|
||||
"""
|
||||
|
||||
return super(APITagListView, self).get(*args, **kwargs)
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
"""Create a new tag."""
|
||||
"""
|
||||
Create a new tag.
|
||||
"""
|
||||
|
||||
return super(APITagListView, self).post(*args, **kwargs)
|
||||
|
||||
|
||||
@@ -66,61 +93,91 @@ class APITagDocumentListView(generics.ListAPIView):
|
||||
"""
|
||||
|
||||
filter_backends = (MayanObjectPermissionsFilter,)
|
||||
mayan_object_permissions = {'GET': [permission_document_view]}
|
||||
|
||||
def get_serializer_class(self):
|
||||
from documents.serializers import DocumentSerializer
|
||||
return DocumentSerializer
|
||||
mayan_object_permissions = {'GET': (permission_document_view,)}
|
||||
serializer_class = DocumentSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
tag = get_object_or_404(Tag, pk=self.kwargs['pk'])
|
||||
try:
|
||||
Permission.check_permissions(
|
||||
self.request.user, [permission_tag_view]
|
||||
self.request.user, (permission_tag_view,)
|
||||
)
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(
|
||||
permission_tag_view, self.request.user, tag
|
||||
)
|
||||
|
||||
queryset = tag.documents.all()
|
||||
return queryset
|
||||
return tag.documents.all()
|
||||
|
||||
|
||||
class APIDocumentTagListView(generics.ListAPIView):
|
||||
###
|
||||
class APIDocumentTagListView(generics.ListCreateAPIView):
|
||||
"""
|
||||
Returns a list of all the tags attached to a document.
|
||||
"""
|
||||
|
||||
serializer_class = TagSerializer
|
||||
|
||||
filter_backends = (MayanObjectPermissionsFilter,)
|
||||
mayan_object_permissions = {'GET': [permission_tag_view]}
|
||||
mayan_object_permissions = {'GET': (permission_tag_view,)}
|
||||
|
||||
def get_document(self):
|
||||
return get_object_or_404(Document, pk=self.kwargs['pk'])
|
||||
|
||||
def get_queryset(self):
|
||||
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
||||
document = self.get_document()
|
||||
try:
|
||||
Permission.check_permissions(
|
||||
self.request.user, [permission_document_view]
|
||||
self.request.user, (permission_document_view,)
|
||||
)
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(
|
||||
permission_document_view, self.request.user, document
|
||||
)
|
||||
|
||||
queryset = document.tags.all()
|
||||
return queryset
|
||||
return document.tags.all()
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.request.method == 'GET':
|
||||
return DocumentTagSerializer
|
||||
elif self.request.method == 'POST':
|
||||
return NewDocumentTagSerializer
|
||||
|
||||
def perform_create(self, serializer):
|
||||
serializer.save(document=self.get_document())
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
Attach a tag to a document.
|
||||
"""
|
||||
|
||||
return super(APIDocumentTagListView, self).post(request, *args, **kwargs)
|
||||
|
||||
|
||||
class APIDocumentTagView(views.APIView):
|
||||
class APIDocumentTagView(generics.RetrieveDestroyAPIView):
|
||||
serialize_class = DocumentTagSerializer
|
||||
|
||||
def get_folder(self):
|
||||
return get_object_or_404(Document, pk=self.kwargs['document_pk'])
|
||||
|
||||
def get_serializer_context(self):
|
||||
"""
|
||||
Extra context provided to the serializer class.
|
||||
"""
|
||||
return {
|
||||
'document': self.get_document(),
|
||||
'format': self.format_kwarg,
|
||||
'request': self.request,
|
||||
'view': self
|
||||
}
|
||||
|
||||
'''
|
||||
def delete(self, request, *args, **kwargs):
|
||||
"""
|
||||
Remove a tag from a document.
|
||||
"""
|
||||
|
||||
document = get_object_or_404(Document, pk=self.kwargs['document_pk'])
|
||||
|
||||
try:
|
||||
Permission.check_permissions(request.user, [permission_tag_remove])
|
||||
Permission.check_permissions(request.user, (permission_tag_remove,))
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(
|
||||
permission_tag_remove, request.user, document
|
||||
@@ -130,19 +187,4 @@ class APIDocumentTagView(views.APIView):
|
||||
tag.documents.remove(document)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""
|
||||
Attach a tag to a document.
|
||||
"""
|
||||
|
||||
document = get_object_or_404(Document, pk=self.kwargs['document_pk'])
|
||||
try:
|
||||
Permission.check_permissions(request.user, [permission_tag_attach])
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(
|
||||
permission_tag_attach, request.user, document
|
||||
)
|
||||
|
||||
tag = get_object_or_404(Tag, pk=self.kwargs['pk'])
|
||||
tag.documents.add(document)
|
||||
return Response(status=status.HTTP_201_CREATED)
|
||||
'''
|
||||
|
||||
@@ -1,16 +1,65 @@
|
||||
from __future__ import unicode_literals
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
from acls.models import AccessControlList
|
||||
from permissions import Permission
|
||||
|
||||
from .models import Tag
|
||||
from .permissions import permission_tag_attach
|
||||
|
||||
|
||||
class TagSerializer(serializers.ModelSerializer):
|
||||
documents = serializers.SerializerMethodField('get_documents_count')
|
||||
class TagSerializer(serializers.HyperlinkedModelSerializer):
|
||||
documents = serializers.HyperlinkedIdentityField(view_name='rest_api:tag-document-list')
|
||||
documents_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
fields = ('id', 'label', 'color', 'documents')
|
||||
extra_kwargs = {
|
||||
'url': {'view_name': 'rest_api:tag-detail'},
|
||||
}
|
||||
fields = ('color', 'documents', 'documents_count', 'id', 'label', 'url')
|
||||
model = Tag
|
||||
|
||||
def get_documents_count(self, obj):
|
||||
return obj.documents.count()
|
||||
def get_documents_count(self, instance):
|
||||
return instance.documents.count()
|
||||
|
||||
|
||||
class NewDocumentTagSerializer(serializers.Serializer):
|
||||
tag = serializers.IntegerField(help_text=_('Primary key of the tag to be added.'))
|
||||
|
||||
def create(self, validated_data):
|
||||
try:
|
||||
tag = Tag.objects.get(pk=validated_data['tag'])
|
||||
|
||||
try:
|
||||
Permission.check_permissions(self.context['request'].user, (permission_tag_attach,))
|
||||
except PermissionDenied:
|
||||
AccessControlList.objects.check_access(
|
||||
permission_tag_attach, self.context['request'], document
|
||||
)
|
||||
|
||||
tag.documents.add(validated_data['document'])
|
||||
except Exception as exception:
|
||||
raise ValidationError(exception)
|
||||
|
||||
return {'tag': tag.pk}
|
||||
|
||||
|
||||
class DocumentTagSerializer(TagSerializer):
|
||||
remove = serializers.SerializerMethodField()
|
||||
|
||||
def get_remove(self, instance):
|
||||
return reverse(
|
||||
'rest_api:document-tag', args=(
|
||||
self.context['document'].pk, instance.pk
|
||||
), request=self.context['request'], format=self.context['format']
|
||||
)
|
||||
|
||||
class Meta(TagSerializer.Meta):
|
||||
fields = TagSerializer.Meta.fields + ('remove',)
|
||||
read_only_fields = TagSerializer.Meta.fields
|
||||
|
||||
126
mayan/apps/tags/test_api.py
Normal file
126
mayan/apps/tags/test_api.py
Normal file
@@ -0,0 +1,126 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from json import loads
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.files import File
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from documents.models import DocumentType
|
||||
from documents.test_models import (
|
||||
TEST_ADMIN_EMAIL, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME,
|
||||
TEST_DOCUMENT_FILENAME, TEST_DOCUMENT_PATH, TEST_DOCUMENT_TYPE,
|
||||
TEST_SMALL_DOCUMENT_FILENAME, TEST_SMALL_DOCUMENT_PATH,
|
||||
)
|
||||
|
||||
from .models import Tag
|
||||
|
||||
TEST_TAG_LABEL = 'test tag'
|
||||
TEST_TAG_LABEL_ALTERNATE = 'test tag alternate'
|
||||
TEST_TAG_COLOR = '#001122'
|
||||
TEST_TAG_COLOR_ALTERNATE = '#221100'
|
||||
|
||||
|
||||
class TagAPITestCase(APITestCase):
|
||||
"""
|
||||
Test the tag API endpoints
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.admin_user = User.objects.create_superuser(
|
||||
username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL,
|
||||
password=TEST_ADMIN_PASSWORD
|
||||
)
|
||||
|
||||
self.client.force_authenticate(user=self.admin_user)
|
||||
|
||||
def tearDown(self):
|
||||
self.admin_user.delete()
|
||||
|
||||
def test_tag_create(self):
|
||||
self.client.post(
|
||||
reverse('rest_api:tag-list'), {
|
||||
'label': TEST_TAG_LABEL, 'color': TEST_TAG_COLOR
|
||||
}
|
||||
)
|
||||
|
||||
tag = Tag.objects.first()
|
||||
|
||||
self.assertEqual(Tag.objects.count(), 1)
|
||||
self.assertEqual(tag.label, TEST_TAG_LABEL)
|
||||
self.assertEqual(tag.color, TEST_TAG_COLOR)
|
||||
|
||||
def test_tag_delete(self):
|
||||
tag = Tag.objects.create(color=TEST_TAG_COLOR, label=TEST_TAG_LABEL)
|
||||
|
||||
self.client.delete(reverse('rest_api:tag-detail', args=(tag.pk,)))
|
||||
|
||||
self.assertEqual(Tag.objects.count(), 0)
|
||||
|
||||
def test_tag_edit(self):
|
||||
tag = Tag.objects.create(color=TEST_TAG_COLOR, label=TEST_TAG_LABEL)
|
||||
|
||||
self.client.put(
|
||||
reverse('rest_api:tag-detail', args=(tag.pk,)),
|
||||
{
|
||||
'label': TEST_TAG_LABEL_ALTERNATE,
|
||||
'color': TEST_TAG_COLOR_ALTERNATE
|
||||
}
|
||||
)
|
||||
|
||||
tag = Tag.objects.first()
|
||||
|
||||
self.assertEqual(tag.label, TEST_TAG_LABEL_ALTERNATE)
|
||||
self.assertEqual(tag.color, TEST_TAG_COLOR_ALTERNATE)
|
||||
|
||||
def test_tag_add_document(self):
|
||||
tag = Tag.objects.create(color=TEST_TAG_COLOR, label=TEST_TAG_LABEL)
|
||||
|
||||
document_type = DocumentType.objects.create(
|
||||
label=TEST_DOCUMENT_TYPE
|
||||
)
|
||||
|
||||
ocr_settings = document_type.ocr_settings
|
||||
ocr_settings.auto_ocr = False
|
||||
ocr_settings.save()
|
||||
|
||||
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
|
||||
document = document_type.new_document(
|
||||
file_object=File(file_object),
|
||||
)
|
||||
|
||||
self.client.post(
|
||||
reverse('rest_api:document-tag-list', args=(document.pk,)),
|
||||
{'tag': tag.pk}
|
||||
)
|
||||
|
||||
self.assertEqual(tag.documents.count(), 1)
|
||||
|
||||
"""
|
||||
def test_tag_remove_document(self):
|
||||
tag = Tag.objects.create(color=TEST_TAG_COLOR, label=TEST_TAG_LABEL)
|
||||
|
||||
document_type = DocumentType.objects.create(
|
||||
label=TEST_DOCUMENT_TYPE
|
||||
)
|
||||
|
||||
ocr_settings = document_type.ocr_settings
|
||||
ocr_settings.auto_ocr = False
|
||||
ocr_settings.save()
|
||||
|
||||
with open(TEST_SMALL_DOCUMENT_PATH) as file_object:
|
||||
document = document_type.new_document(
|
||||
file_object=File(file_object),
|
||||
)
|
||||
|
||||
tag.documents.add(document)
|
||||
|
||||
self.client.delete(
|
||||
reverse('rest_api:tag-document', args=(tag.pk, document.pk)),
|
||||
)
|
||||
|
||||
self.assertEqual(tag.documents.count(), 0)
|
||||
"""
|
||||
Reference in New Issue
Block a user