Initial commit for tag API refactor.

This commit is contained in:
Roberto Rosario
2015-08-07 01:07:41 -04:00
parent c3564ca31d
commit 7b42c8e9ae
3 changed files with 274 additions and 57 deletions

View File

@@ -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)
'''

View File

@@ -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
View 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)
"""