From aa95a614510b41b37c35cb3fab3c6a691d108317 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Sun, 3 Feb 2019 23:37:52 -0400 Subject: [PATCH] Refactor metadata app Update permission variable name from "permission_document_metadata_" to "permission_metadata_". Fix failing tests. Add test for same metadata type mixin. Split metadata add and remove test into test for GET and POST requests. Remove use of urlencode and instead use furl. Simplify view using self.action_count and self.action_id_list. Use ExternalObjectMixin to remove repeated code. Move the repeated code to test for all documents to be of the same type into its own mixin. Signed-off-by: Roberto Rosario --- mayan/apps/metadata/api_views.py | 16 +- mayan/apps/metadata/apps.py | 12 +- mayan/apps/metadata/links.py | 12 +- mayan/apps/metadata/permissions.py | 8 +- mayan/apps/metadata/tests/test_api.py | 18 +- mayan/apps/metadata/tests/test_events.py | 4 +- mayan/apps/metadata/tests/test_views.py | 194 +++++++++----- mayan/apps/metadata/views.py | 311 ++++++++--------------- 8 files changed, 266 insertions(+), 309 deletions(-) diff --git a/mayan/apps/metadata/api_views.py b/mayan/apps/metadata/api_views.py index f23a518bca..042b8a903e 100644 --- a/mayan/apps/metadata/api_views.py +++ b/mayan/apps/metadata/api_views.py @@ -14,8 +14,8 @@ from mayan.apps.rest_api.permissions import MayanPermission from .models import MetadataType from .permissions import ( - permission_document_metadata_add, permission_document_metadata_remove, - permission_document_metadata_edit, permission_document_metadata_view, + permission_metadata_add, permission_metadata_remove, + permission_metadata_edit, permission_metadata_view, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) @@ -34,9 +34,9 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView): """ def get_document(self): if self.request.method == 'GET': - permission_required = permission_document_metadata_view + permission_required = permission_metadata_view else: - permission_required = permission_document_metadata_add + permission_required = permission_metadata_add document = get_object_or_404( klass=Document, pk=self.kwargs['document_pk'] @@ -90,13 +90,13 @@ class APIDocumentMetadataView(generics.RetrieveUpdateDestroyAPIView): def get_document(self): if self.request.method == 'GET': - permission_required = permission_document_metadata_view + permission_required = permission_metadata_view elif self.request.method == 'PUT': - permission_required = permission_document_metadata_edit + permission_required = permission_metadata_edit elif self.request.method == 'PATCH': - permission_required = permission_document_metadata_edit + permission_required = permission_metadata_edit elif self.request.method == 'DELETE': - permission_required = permission_document_metadata_remove + permission_required = permission_metadata_remove document = get_object_or_404( klass=Document, pk=self.kwargs['document_pk'] diff --git a/mayan/apps/metadata/apps.py b/mayan/apps/metadata/apps.py index 6058d3b977..99d227ccd8 100644 --- a/mayan/apps/metadata/apps.py +++ b/mayan/apps/metadata/apps.py @@ -48,8 +48,8 @@ from .links import ( ) from .methods import method_get_metadata from .permissions import ( - permission_document_metadata_add, permission_document_metadata_edit, - permission_document_metadata_remove, permission_document_metadata_view, + permission_metadata_add, permission_metadata_edit, + permission_metadata_remove, permission_metadata_view, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) @@ -130,10 +130,10 @@ class MetadataApp(MayanAppConfig): ModelPermission.register( model=Document, permissions=( - permission_document_metadata_add, - permission_document_metadata_edit, - permission_document_metadata_remove, - permission_document_metadata_view, + permission_metadata_add, + permission_metadata_edit, + permission_metadata_remove, + permission_metadata_view, ) ) ModelPermission.register( diff --git a/mayan/apps/metadata/links.py b/mayan/apps/metadata/links.py index b2b187578e..a93fea2e1a 100644 --- a/mayan/apps/metadata/links.py +++ b/mayan/apps/metadata/links.py @@ -15,32 +15,32 @@ from .icons import ( icon_metadata_type_edit, icon_metadata_type_list ) from .permissions import ( - permission_document_metadata_add, permission_document_metadata_edit, - permission_document_metadata_remove, permission_document_metadata_view, + permission_metadata_add, permission_metadata_edit, + permission_metadata_remove, permission_metadata_view, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) link_document_metadata_add = Link( icon_class=icon_document_metadata_add, kwargs={'document_id': 'object.pk'}, - permission=permission_document_metadata_add, text=_('Add metadata'), + permission=permission_metadata_add, text=_('Add metadata'), view='metadata:document_metadata_add', ) link_document_metadata_edit = Link( icon_class=icon_document_metadata_edit, kwargs={'document_id': 'object.pk'}, - permission=permission_document_metadata_edit, text=_('Edit metadata'), + permission=permission_metadata_edit, text=_('Edit metadata'), view='metadata:document_metadata_edit' ) link_document_metadata_remove = Link( icon_class=icon_document_metadata_remove, kwargs={'document_id': 'object.pk'}, - permission=permission_document_metadata_remove, + permission=permission_metadata_remove, text=_('Remove metadata'), view='metadata:document_metadata_remove' ) link_document_metadata_view = Link( icon_class=icon_document_metadata_view, kwargs={'document_id': 'resolved_object.pk'}, - permission=permission_document_metadata_view, text=_('Metadata'), + permission=permission_metadata_view, text=_('Metadata'), view='metadata:document_metadata_view' ) link_document_multiple_metadata_add = Link( diff --git a/mayan/apps/metadata/permissions.py b/mayan/apps/metadata/permissions.py index e1c35fa460..d1ec76f894 100644 --- a/mayan/apps/metadata/permissions.py +++ b/mayan/apps/metadata/permissions.py @@ -6,16 +6,16 @@ from mayan.apps.permissions import PermissionNamespace namespace = PermissionNamespace(label=_('Metadata'), name='metadata') -permission_document_metadata_add = namespace.add_permission( +permission_metadata_add = namespace.add_permission( label=_('Add metadata to a document'), name='metadata_document_add' ) -permission_document_metadata_edit = namespace.add_permission( +permission_metadata_edit = namespace.add_permission( label=_('Edit a document\'s metadata'), name='metadata_document_edit' ) -permission_document_metadata_remove = namespace.add_permission( +permission_metadata_remove = namespace.add_permission( label=_('Remove metadata from a document'), name='metadata_document_remove' ) -permission_document_metadata_view = namespace.add_permission( +permission_metadata_view = namespace.add_permission( label=_('View metadata from a document'), name='metadata_document_view' ) diff --git a/mayan/apps/metadata/tests/test_api.py b/mayan/apps/metadata/tests/test_api.py index 9092c0c3ad..860d09f7ab 100644 --- a/mayan/apps/metadata/tests/test_api.py +++ b/mayan/apps/metadata/tests/test_api.py @@ -11,8 +11,8 @@ from mayan.apps.rest_api.tests import BaseAPITestCase from ..models import DocumentTypeMetadataType, MetadataType from ..permissions import ( - permission_document_metadata_add, permission_document_metadata_edit, - permission_document_metadata_remove, permission_document_metadata_view, + permission_metadata_add, permission_metadata_edit, + permission_metadata_remove, permission_metadata_view, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) @@ -377,7 +377,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): self.assertEqual(self.document.metadata.count(), 0) def test_document_metadata_create_view_with_access(self): - self.grant_access(permission=permission_document_metadata_add, obj=self.document) + self.grant_access(permission=permission_metadata_add, obj=self.document) response = self._request_document_metadata_create_view() self.assertEqual(response.status_code, status.HTTP_201_CREATED) document_metadata = self.document.metadata.first() @@ -387,7 +387,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_create_duplicate_view(self): self._create_document_metadata() - self.grant_permission(permission=permission_document_metadata_add) + self.grant_permission(permission=permission_metadata_add) response = self._request_document_metadata_create_view() self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(list(response.data.keys())[0], 'non_field_errors') @@ -395,7 +395,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_create_invalid_lookup_value_view(self): self.metadata_type.lookup = 'invalid,lookup,values,on,purpose' self.metadata_type.save() - self.grant_permission(permission=permission_document_metadata_add) + self.grant_permission(permission=permission_metadata_add) response = self._request_document_metadata_create_view() self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(list(response.data.keys())[0], 'non_field_errors') @@ -418,7 +418,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_delete_view_with_access(self): self._create_document_metadata() self.grant_access( - permission=permission_document_metadata_remove, obj=self.document + permission=permission_metadata_remove, obj=self.document ) response = self._request_document_metadata_delete_view() self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) @@ -438,7 +438,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_list_view_with_access(self): self._create_document_metadata() self.grant_access( - permission=permission_document_metadata_view, obj=self.document + permission=permission_metadata_view, obj=self.document ) response = self._request_document_metadata_list_view() self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -477,7 +477,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_patch_view_with_access(self): self._create_document_metadata() self.grant_access( - permission=permission_document_metadata_edit, obj=self.document + permission=permission_metadata_edit, obj=self.document ) response = self._request_document_metadata_edit_view_via_patch() self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -510,7 +510,7 @@ class DocumentMetadataAPITestCase(BaseAPITestCase): def test_document_metadata_put_view_with_access(self): self._create_document_metadata() self.grant_access( - permission=permission_document_metadata_edit, obj=self.document + permission=permission_metadata_edit, obj=self.document ) response = self._request_document_metadata_edit_view_via_put() self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/mayan/apps/metadata/tests/test_events.py b/mayan/apps/metadata/tests/test_events.py index 75d8e30ecf..70027cd36c 100644 --- a/mayan/apps/metadata/tests/test_events.py +++ b/mayan/apps/metadata/tests/test_events.py @@ -38,7 +38,7 @@ class MetadataTypeEventsTestCase(MetadataTestsMixin, GenericDocumentViewTestCase self.assertEqual(event.verb, event_metadata_type_created.id) self.assertEqual(event.target, metadata_type) - self.assertEqual(event.actor, self.user) + self.assertEqual(event.actor, self._test_case_user) def test_metadata_type_edit_event_no_permissions(self): self._create_metadata_type() @@ -66,4 +66,4 @@ class MetadataTypeEventsTestCase(MetadataTestsMixin, GenericDocumentViewTestCase self.assertEqual(event.verb, event_metadata_type_edited.id) self.assertEqual(event.target, self.metadata_type) - self.assertEqual(event.actor, self.user) + self.assertEqual(event.actor, self._test_case_user) diff --git a/mayan/apps/metadata/tests/test_views.py b/mayan/apps/metadata/tests/test_views.py index f483319b92..a4a457ced4 100644 --- a/mayan/apps/metadata/tests/test_views.py +++ b/mayan/apps/metadata/tests/test_views.py @@ -2,6 +2,8 @@ from __future__ import unicode_literals import logging +from django.utils.encoding import force_text + from mayan.apps.common.tests import GenericViewTestCase from mayan.apps.documents.models import DocumentType from mayan.apps.documents.permissions import ( @@ -13,8 +15,8 @@ from mayan.apps.documents.tests import ( from ..models import MetadataType from ..permissions import ( - permission_document_metadata_add, permission_document_metadata_remove, - permission_document_metadata_edit, permission_metadata_type_create, + permission_metadata_add, permission_metadata_remove, + permission_metadata_edit, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) @@ -28,51 +30,114 @@ from .literals import ( from .mixins import MetadataTestsMixin -class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): +class DocumentMetadataViewTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): def setUp(self): - super(DocumentMetadataTestCase, self).setUp() - self.login_user() + super(DocumentMetadataViewTestCase, self).setUp() self._create_metadata_type() self.document_type.metadata.create(metadata_type=self.metadata_type) - def _request_get_document_metadata_add_view(self): + def _request_document_metadata_add_get_view(self): return self.get( viewname='metadata:document_metadata_add', - kwargs={'document_id': self.document.pk}, + kwargs={'document_id': self.test_document.pk}, ) - def _request_post_document_metadata_add_view(self): + def _request_document_multiple_metadata_add_get_view(self): + return self.get( + viewname='metadata:document_multiple_metadata_add', + data={'id_list': ','.join([force_text(pk) for pk in self.id_list])}, + ) + + def _request_document_metadata_add_post_view(self): return self.post( viewname='metadata:document_metadata_add', - kwargs={'document_id': self.document.pk}, + kwargs={'document_id': self.test_document.pk}, data={'metadata_type': self.metadata_type.pk} ) - def test_document_metadata_add_view_no_permission(self): - response = self._request_get_document_metadata_add_view() + def test_document_metadata_add_get_view_no_permission(self): + response = self._request_document_metadata_add_get_view() self.assertNotContains( - response, text=self.metadata_type.label, status_code=200 + response, text=self.metadata_type.label, status_code=404 ) - response = self._request_post_document_metadata_add_view() - self.assertEqual(response.status_code, 200) - - self.assertEqual(len(self.document.metadata.all()), 0) - - def test_document_metadata_add_view_with_document_access(self): + def test_document_metadata_add_get_view_with_full_access(self): self.grant_access( - permission=permission_document_metadata_add, obj=self.document + obj=self.test_document, permission=permission_metadata_add ) - response = self._request_get_document_metadata_add_view() + response = self._request_document_metadata_add_get_view() self.assertContains( response, text=self.metadata_type.label, status_code=200 ) - response = self._request_post_document_metadata_add_view() + def test_document_individual_metadata_same_type_mixin_with_access(self): + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + self._create_document_type_random() + self.test_document_type.metadata.create(metadata_type=self.metadata_type) + self._create_document() + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + response = self._request_document_metadata_add_get_view() + self.assertContains( + response, text=self.metadata_type.label, status_code=200 + ) + + def test_document_single_metadata_same_type_mixin_with_access(self): + self.id_list = [self.test_document.pk] + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + self._create_document_type_random() + self.test_document_type.metadata.create(metadata_type=self.metadata_type) + self._create_document() + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + response = self._request_document_multiple_metadata_add_get_view() + self.assertContains( + response, text=self.metadata_type.label, status_code=200 + ) + + def test_document_multiple_metadata_same_type_mixin_with_access(self): + self.id_list = [self.test_document.pk] + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + self._create_document_type_random() + self.test_document_type.metadata.create(metadata_type=self.metadata_type) + self._create_document() + self.id_list.append(self.test_document.pk) + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + + response = self._request_document_multiple_metadata_add_get_view() + self.assertNotContains( + response, text=self.metadata_type.label, status_code=302 + ) + + def test_document_metadata_add_post_view_no_permission(self): + response = self._request_document_metadata_add_post_view() + self.assertEqual(response.status_code, 404) + + self.assertEqual(len(self.document.metadata.all()), 0) + + def test_document_metadata_add_post_view_with_full_access(self): + self.grant_access( + obj=self.test_document, permission=permission_metadata_add + ) + response = self._request_document_metadata_add_post_view() self.assertEqual(response.status_code, 302) self.assertEqual(len(self.document.metadata.all()), 1) - self.assertQuerysetEqual( qs=self.document.metadata.values('metadata_type',), values=[ @@ -86,13 +151,6 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): # Gitlab issue #204 # Problems to add required metadata after changing the document type - self.grant_access( - permission=permission_document_properties_edit, obj=self.document - ) - self.grant_access( - permission=permission_document_metadata_edit, obj=self.document - ) - document_type_2 = DocumentType.objects.create( label=TEST_DOCUMENT_TYPE_2_LABEL ) @@ -105,6 +163,12 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): metadata_type=metadata_type_2, required=True ) + self.grant_access( + obj=self.document, permission=permission_document_properties_edit + ) + self.grant_access( + obj=self.document, permission=permission_metadata_edit + ) self.document.set_document_type(document_type=document_type_2) response = self.get( @@ -133,13 +197,13 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): TEST_DOCUMENT_METADATA_VALUE_2 ) - def _request_get_document_document_metadata_remove_view(self): + def _request_document_document_metadata_remove_get_view(self): return self.get( viewname='metadata:document_metadata_remove', kwargs={'document_id': self.document.pk} ) - def _request_post_document_document_metadata_remove_view(self): + def _request_document_document_metadata_remove_post_view(self): return self.post( viewname='metadata:document_metadata_remove', kwargs={'document_id': self.document.pk}, data={ @@ -151,38 +215,24 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): } ) - def test_document_metadata_remove_view_no_permission(self): + def test_document_metadata_remove_get_view_no_permission(self): self.document_metadata = self.document.metadata.create( metadata_type=self.metadata_type, value='' ) - response = self._request_get_document_document_metadata_remove_view() + response = self._request_document_document_metadata_remove_get_view() self.assertNotContains( - response, text=self.metadata_type.label, status_code=200 + response=response, text=self.metadata_type.label, status_code=404 ) - response = self._request_post_document_document_metadata_remove_view() - self.assertEqual(response.status_code, 404) - - self.assertEqual(len(self.document.metadata.all()), 1) - - self.assertQuerysetEqual( - qs=self.document.metadata.values('metadata_type',), - values=[ - { - 'metadata_type': self.metadata_type.pk, - } - ], transform=dict - ) - - def test_document_metadata_remove_view_with_document_access(self): + def test_document_metadata_remove_get_view_with_full_access(self): self.document_metadata = self.document.metadata.create( metadata_type=self.metadata_type, value='' ) self.grant_access( - permission=permission_document_metadata_remove, obj=self.document + obj=self.document, permission=permission_metadata_remove, ) # Silence unrelated logging @@ -190,14 +240,32 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): level=logging.CRITICAL ) - response = self._request_get_document_document_metadata_remove_view() - + response = self._request_document_document_metadata_remove_get_view() self.assertContains( response, text=self.metadata_type.label, status_code=200 ) - response = self._request_post_document_document_metadata_remove_view() + def test_document_metadata_remove_post_view_no_permission(self): + self.document_metadata = self.document.metadata.create( + metadata_type=self.metadata_type, value='' + ) + response = self._request_document_document_metadata_remove_get_view() + self.assertNotContains( + response=response, text=self.metadata_type.label, status_code=404 + ) + + self.assertEqual(len(self.document.metadata.all()), 1) + + def test_document_metadata_remove_post_view_with_access(self): + self.document_metadata = self.document.metadata.create( + metadata_type=self.metadata_type, value='' + ) + + self.grant_access( + obj=self.test_document, permission=permission_metadata_remove + ) + response = self._request_document_document_metadata_remove_post_view() self.assertEqual(response.status_code, 302) self.assertEqual(len(self.document.metadata.all()), 0) @@ -227,10 +295,10 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): self.document_2 = self.upload_document() self.grant_access( - permission=permission_document_metadata_edit, obj=self.document + permission=permission_metadata_edit, obj=self.document ) self.grant_access( - permission=permission_document_metadata_edit, obj=self.document_2 + permission=permission_metadata_edit, obj=self.document_2 ) self.document_metadata = self.document.metadata.create( @@ -277,10 +345,10 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): def test_document_multiple_metadata_remove_with_access(self): self.document_2 = self.upload_document() self.grant_access( - permission=permission_document_metadata_remove, obj=self.document + permission=permission_metadata_remove, obj=self.document ) self.grant_access( - permission=permission_document_metadata_remove, obj=self.document_2 + permission=permission_metadata_remove, obj=self.document_2 ) self.document_metadata = self.document.metadata.create( @@ -311,10 +379,10 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): self.document_2 = self.upload_document() self.grant_access( - permission=permission_document_metadata_add, obj=self.document + permission=permission_metadata_add, obj=self.document ) self.grant_access( - permission=permission_document_metadata_add, obj=self.document_2 + permission=permission_metadata_add, obj=self.document_2 ) response = self._request_post_document_document_metadata_add_view() @@ -326,7 +394,7 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): def test_single_document_multiple_metadata_add_view_with_access(self): self.grant_access( - permission=permission_document_metadata_add, obj=self.document + permission=permission_metadata_add, obj=self.document ) metadata_type_2 = MetadataType.objects.create( name=TEST_METADATA_TYPE_NAME_2, label=TEST_METADATA_TYPE_LABEL_2 @@ -351,14 +419,10 @@ class DocumentMetadataTestCase(MetadataTestsMixin, GenericDocumentViewTestCase): ) -class MetadataTypeViewTestCase(DocumentTestMixin, MetadataTestsMixin, GenericViewTestCase): +class MetadataTypeViewViewTestCase(DocumentTestMixin, MetadataTestsMixin, GenericViewTestCase): auto_create_document_type = False auto_upload_document = False - def setUp(self): - super(MetadataTypeViewTestCase, self).setUp() - self.login_user() - def test_metadata_type_create_view_no_permission(self): response = self._request_metadata_type_create_view() diff --git a/mayan/apps/metadata/views.py b/mayan/apps/metadata/views.py index ca7846a875..ab5533b993 100644 --- a/mayan/apps/metadata/views.py +++ b/mayan/apps/metadata/views.py @@ -1,5 +1,7 @@ from __future__ import absolute_import, unicode_literals +from furl import furl + from django.conf import settings from django.contrib import messages from django.core.exceptions import ValidationError @@ -8,7 +10,6 @@ from django.shortcuts import get_object_or_404 from django.template import RequestContext from django.urls import reverse, reverse_lazy from django.utils.encoding import force_text -from django.utils.http import urlencode from django.utils.translation import ugettext_lazy as _, ungettext from mayan.apps.acls.models import AccessControlList @@ -16,6 +17,7 @@ from mayan.apps.common.generics import ( FormView, MultipleObjectFormActionView, SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView ) +from mayan.apps.common.mixins import ExternalObjectMixin from mayan.apps.documents.models import Document, DocumentType from mayan.apps.documents.permissions import ( permission_document_type_edit @@ -34,29 +36,20 @@ from .links import ( ) from .models import DocumentMetadata, MetadataType from .permissions import ( - permission_document_metadata_add, permission_document_metadata_edit, - permission_document_metadata_remove, permission_document_metadata_view, + permission_metadata_add, permission_metadata_edit, + permission_metadata_remove, permission_metadata_view, permission_metadata_type_create, permission_metadata_type_delete, permission_metadata_type_edit, permission_metadata_type_view ) -class DocumentMetadataAddView(MultipleObjectFormActionView): - form_class = DocumentMetadataAddForm - model = Document - object_permission = permission_document_metadata_add - pk_url_kwarg = 'document_id' - success_message = _('Metadata add request performed on %(count)d document') - success_message_plural = _( - 'Metadata add request performed on %(count)d documents' - ) - +class DocumentMetadataSameTypeMixin(object): def dispatch(self, request, *args, **kwargs): - result = super( - DocumentMetadataAddView, self - ).dispatch(request, *args, **kwargs) + result = super(DocumentMetadataSameTypeMixin, self).dispatch( + request, *args, **kwargs + ) - queryset = self.get_queryset() + queryset = self.get_object_list() for document in queryset: document.add_as_recent_document_for_user(request.user) @@ -71,40 +64,35 @@ class DocumentMetadataAddView(MultipleObjectFormActionView): return result - def form_valid(self, form): - result = super(DocumentMetadataAddView, self).form_valid(form=form) - queryset = self.get_queryset() +class DocumentMetadataAddView(DocumentMetadataSameTypeMixin, MultipleObjectFormActionView): + form_class = DocumentMetadataAddForm + model = Document + object_permission = permission_metadata_add + pk_url_kwarg = 'document_id' + success_message = _('Metadata add request performed on %(count)d document') + success_message_plural = _( + 'Metadata add request performed on %(count)d documents' + ) + def get_post_object_action_url(self): if self.action_count == 1: - return HttpResponseRedirect( - redirect_to=reverse( - viewname='metadata:document_metadata_edit', - kwargs={'document_id': queryset.first().pk} - ) - ) - elif self.action_count > 1: - return HttpResponseRedirect( - redirect_to='%s?%s' % ( - reverse( - viewname='metadata:document_multiple_metadata_edit' - ), urlencode( - { - 'id_list': ','.join( - map( - force_text, - queryset.values_list('pk', flat=True) - ) - ) - } - ) - ) + return reverse( + viewname='metadata:document_metadata_edit', + kwargs={'document_id': self.action_id_list[0]} ) - return result + elif self.action_count > 1: + url = furl( + path=reverse( + viewname='metadata:document_multiple_metadata_edit' + ), args={'id_list': self.action_id_list} + ) + + return url.tostr() def get_extra_context(self): - queryset = self.get_queryset() + queryset = self.get_object_list() result = { 'submit_label': _('Add'), @@ -128,7 +116,7 @@ class DocumentMetadataAddView(MultipleObjectFormActionView): return result def get_form_extra_kwargs(self): - queryset = self.get_queryset() + queryset = self.get_object_list() result = {} @@ -209,10 +197,10 @@ class DocumentMetadataAddView(MultipleObjectFormActionView): ) -class DocumentMetadataEditView(MultipleObjectFormActionView): +class DocumentMetadataEditView(DocumentMetadataSameTypeMixin, MultipleObjectFormActionView): form_class = DocumentMetadataFormSet model = Document - object_permission = permission_document_metadata_edit + object_permission = permission_metadata_edit pk_url_kwarg = 'document_id' success_message = _( 'Metadata edit request performed on %(count)d document' @@ -221,61 +209,8 @@ class DocumentMetadataEditView(MultipleObjectFormActionView): 'Metadata edit request performed on %(count)d documents' ) - def dispatch(self, request, *args, **kwargs): - result = super( - DocumentMetadataEditView, self - ).dispatch(request, *args, **kwargs) - - queryset = self.get_queryset() - - for document in queryset: - document.add_as_recent_document_for_user(request.user) - - if len(set([document.document_type.pk for document in queryset])) > 1: - messages.error( - message=_( - 'Selected documents must be of the same type.' - ), request=request - ) - return HttpResponseRedirect(redirect_to=self.previous_url) - - return result - - def form_valid(self, form): - result = super(DocumentMetadataEditView, self).form_valid(form=form) - - queryset = self.get_queryset() - - if self.action_count == 1: - return HttpResponseRedirect( - redirect_to=reverse( - viewname='metadata:document_metadata_edit', - kwargs={'document_id': queryset.first().pk} - ) - ) - elif self.action_count > 1: - return HttpResponseRedirect( - redirect_to='%s?%s' % ( - reverse( - viewname='metadata:document_multiple_metadata_edit' - ), urlencode( - { - 'id_list': ','.join( - map( - force_text, queryset.values_list( - 'pk', flat=True - ) - ) - ) - } - ) - ) - ) - - return result - def get_extra_context(self): - queryset = self.get_queryset() + queryset = self.get_object_list() id_list = ','.join( map( @@ -328,7 +263,7 @@ class DocumentMetadataEditView(MultipleObjectFormActionView): return result def get_initial(self): - queryset = self.get_queryset() + queryset = self.get_object_list() metadata_dict = {} initial = [] @@ -355,6 +290,22 @@ class DocumentMetadataEditView(MultipleObjectFormActionView): return initial + def get_post_object_action_url(self): + if self.action_count == 1: + return reverse( + viewname='metadata:document_metadata_edit', + kwargs={'document_id': self.action_id_list[0]} + ) + + elif self.action_count > 1: + url = furl( + path=reverse( + viewname='metadata:document_multiple_metadata_edit' + ), args={'id_list': self.action_id_list} + ) + + return url.tostr() + def object_action(self, form, instance): errors = [] for form in form.forms: @@ -393,25 +344,20 @@ class DocumentMetadataEditView(MultipleObjectFormActionView): ) -class DocumentMetadataListView(SingleObjectListView): - def get_document(self): - queryset = AccessControlList.objects.restrict_queryset( - permission=permission_document_metadata_view, - queryset=Document.objects.all(), - user=self.request.user - ) - - return get_object_or_404(klass=queryset, pk=self.kwargs['document_id']) +class DocumentMetadataListView(ExternalObjectMixin, SingleObjectListView): + external_object_class = Document + external_object_permission = permission_metadata_view + external_object_pk_url_kwarg = 'document_id' def get_extra_context(self): - document = self.get_document() + return { 'hide_object': True, - 'object': document, + 'object': self.external_object, 'no_results_icon': icon_metadata, 'no_results_main_link': link_document_metadata_add.resolve( context=RequestContext( - request=self.request, dict_={'object': document} + request=self.request, dict_={'object': self.external_object} ) ), 'no_results_text': _( @@ -421,17 +367,17 @@ class DocumentMetadataListView(SingleObjectListView): 'values.' ), 'no_results_title': _('This document doesn\'t have any metadata'), - 'title': _('Metadata for document: %s') % document, + 'title': _('Metadata for document: %s') % self.external_object, } - def get_object_list(self): - return self.get_document().metadata.all() + def get_source_queryset(self): + return self.external_object.metadata.all() -class DocumentMetadataRemoveView(MultipleObjectFormActionView): +class DocumentMetadataRemoveView(DocumentMetadataSameTypeMixin, MultipleObjectFormActionView): form_class = DocumentMetadataRemoveFormSet model = Document - object_permission = permission_document_metadata_remove + object_permission = permission_metadata_remove pk_url_kwarg = 'document_id' success_message = _( 'Metadata remove request performed on %(count)d document' @@ -440,60 +386,8 @@ class DocumentMetadataRemoveView(MultipleObjectFormActionView): 'Metadata remove request performed on %(count)d documents' ) - def dispatch(self, request, *args, **kwargs): - result = super( - DocumentMetadataRemoveView, self - ).dispatch(request, *args, **kwargs) - - queryset = self.get_queryset() - - for document in queryset: - document.add_as_recent_document_for_user(request.user) - - if len(set([document.document_type.pk for document in queryset])) > 1: - messages.error( - message=_( - 'Selected documents must be of the same type.' - ), request=request - ) - return HttpResponseRedirect(redirect_to=self.previous_url) - - return result - - def form_valid(self, form): - result = super(DocumentMetadataRemoveView, self).form_valid(form=form) - - queryset = self.get_queryset() - - if self.action_count == 1: - return HttpResponseRedirect( - redirect_to=reverse( - viewname='metadata:document_metadata_edit', - kwargs={'document_id': queryset.first().pk} - ) - ) - elif self.action_count > 1: - return HttpResponseRedirect( - redirect_to='%s?%s' % ( - reverse( - viewname='metadata:document_multiple_metadata_edit' - ), urlencode( - { - 'id_list': ','.join( - map( - force_text, - queryset.values_list('pk', flat=True) - ) - ) - } - ) - ) - ) - - return result - def get_extra_context(self): - queryset = self.get_queryset() + queryset = self.get_object_list() result = { 'form_display_mode_table': True, @@ -518,7 +412,7 @@ class DocumentMetadataRemoveView(MultipleObjectFormActionView): return result def get_initial(self): - queryset = self.get_queryset() + queryset = self.get_object_list() metadata = {} for document in queryset: @@ -545,6 +439,21 @@ class DocumentMetadataRemoveView(MultipleObjectFormActionView): ) return initial + def get_post_object_action_url(self): + if self.action_count == 1: + return reverse( + viewname='metadata:document_metadata_edit', + kwargs={'document_id': self.action_id_list[0]} + ) + elif self.action_count > 1: + url = furl( + path=reverse( + viewname='metadata:document_multiple_metadata_edit' + ), args={'id_list': self.action_id_list} + ) + + return url.tostr() + def object_action(self, form, instance): for form in form.forms: if form.cleaned_data['update']: @@ -651,15 +560,18 @@ class MetadataTypeListView(SingleObjectListView): 'title': _('Metadata types'), } - def get_object_list(self): + def get_source_queryset(self): return MetadataType.objects.all() -class SetupDocumentTypeMetadataTypes(FormView): +class SetupDocumentTypeMetadataTypes(ExternalObjectMixin, FormView): + external_object_class = DocumentType + external_object_permission = permission_metadata_type_edit + external_object_pk_url_kwarg = 'document_type_id' form_class = DocumentTypeMetadataTypeRelationshipFormSet main_model = 'document_type' - model = DocumentType submodel = MetadataType + submodel_permission = permission_metadata_type_edit def form_valid(self, form): try: @@ -693,10 +605,10 @@ class SetupDocumentTypeMetadataTypes(FormView): 'to this document type.' ), 'no_results_title': _('There are no metadata types available'), - 'object': self.get_object(), + 'object': self.external_object, 'title': _( 'Metadata types for document type: %s' - ) % self.get_object() + ) % self.external_object } def get_form_extra_kwargs(self): @@ -705,44 +617,36 @@ class SetupDocumentTypeMetadataTypes(FormView): } def get_initial(self): - obj = self.get_object() initial = [] - for element in self.get_queryset(): + for element in self.get_object_list(): initial.append( { - 'document_type': obj, + 'document_type': self.external_object, 'main_model': self.main_model, 'metadata_type': element, } ) return initial - def get_object(self): - queryset = AccessControlList.objects.restrict_queryset( - permission=permission_metadata_type_edit, - queryset=self.model.objects.all(), + def get_object_list(self): + return AccessControlList.objects.restrict_queryset( + permission=self.submodel_permission, + queryset=self.submodel._meta.default_manager.all(), user=self.request.user ) - return get_object_or_404( - klass=queryset, pk=self.kwargs['document_type_id'] - ) def get_post_action_redirect(self): return reverse(viewname='documents:document_type_list') - def get_queryset(self): - queryset = self.submodel.objects.all() - return AccessControlList.objects.restrict_queryset( - permission=permission_document_type_edit, - user=self.request.user, queryset=queryset - ) - class SetupMetadataTypesDocumentTypes(SetupDocumentTypeMetadataTypes): + external_object_class = MetadataType + external_object_permission = permission_metadata_type_edit + external_object_pk_url_kwarg = 'metadata_type_id' main_model = 'metadata_type' - model = MetadataType submodel = DocumentType + submodel_permission = permission_document_type_edit def get_extra_context(self): return { @@ -754,28 +658,17 @@ class SetupMetadataTypesDocumentTypes(SetupDocumentTypeMetadataTypes): } def get_initial(self): - obj = self.get_object() initial = [] - for element in self.get_queryset(): + for element in self.get_object_list(): initial.append( { 'document_type': element, 'main_model': self.main_model, - 'metadata_type': obj, + 'metadata_type': self.external_object, } ) return initial - def get_object(self): - queryset = AccessControlList.objects.restrict_queryset( - permission=permission_metadata_type_edit, - queryset=self.model.objects.all(), - user=self.request.user - ) - return get_object_or_404( - klass=queryset, pk=self.kwargs['metadata_type_id'] - ) - def get_post_action_redirect(self): return reverse(viewname='metadata:metadata_type_list')