Backport common mixin and generics improvements
* Rename get_object_list to get_source_queryset. * Add uniqueness validation to SingleObjectCreateView. * Remove MultipleInstanceActionMixin. * Backport MultipleObjectMixin improvements. * Remove ObjectListPermissionFilterMixin. * Add and improve tests. Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -235,6 +235,11 @@
|
|||||||
workflow proxy instance menu list.
|
workflow proxy instance menu list.
|
||||||
* Fix translation of the source upload forms
|
* Fix translation of the source upload forms
|
||||||
using dropzone.js
|
using dropzone.js
|
||||||
|
* Rename get_object_list to get_source_queryset.
|
||||||
|
* Add uniqueness validation to SingleObjectCreateView.
|
||||||
|
* Remove MultipleInstanceActionMixin.
|
||||||
|
* Backport MultipleObjectMixin improvements.
|
||||||
|
* Remove ObjectListPermissionFilterMixin.
|
||||||
|
|
||||||
3.1.11 (2019-04-XX)
|
3.1.11 (2019-04-XX)
|
||||||
===================
|
===================
|
||||||
|
|||||||
@@ -268,6 +268,11 @@ Other changes
|
|||||||
workflow proxy instance menu list.
|
workflow proxy instance menu list.
|
||||||
* Fix translation of the source upload forms
|
* Fix translation of the source upload forms
|
||||||
using dropzone.js
|
using dropzone.js
|
||||||
|
* Rename get_object_list to get_source_queryset.
|
||||||
|
* Add uniqueness validation to SingleObjectCreateView.
|
||||||
|
* Remove MultipleInstanceActionMixin.
|
||||||
|
* Backport MultipleObjectMixin improvements.
|
||||||
|
* Remove ObjectListPermissionFilterMixin.
|
||||||
|
|
||||||
Removals
|
Removals
|
||||||
--------
|
--------
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import CharField, Value as V, Q
|
from django.db.models import CharField, Value, Q
|
||||||
from django.db.models.functions import Concat
|
from django.db.models.functions import Concat
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import ugettext
|
||||||
@@ -60,14 +60,15 @@ class AccessControlListManager(models.Manager):
|
|||||||
# id combinations
|
# id combinations
|
||||||
content_type_object_id_queryset = queryset.annotate(
|
content_type_object_id_queryset = queryset.annotate(
|
||||||
ct_fk_combination=Concat(
|
ct_fk_combination=Concat(
|
||||||
related_field.ct_field, V('-'), related_field.fk_field,
|
related_field.ct_field, Value('-'),
|
||||||
output_field=CharField()
|
related_field.fk_field, output_field=CharField()
|
||||||
)
|
)
|
||||||
).values('ct_fk_combination')
|
).values('ct_fk_combination')
|
||||||
|
|
||||||
acl_filter = self.annotate(
|
acl_filter = self.annotate(
|
||||||
ct_fk_combination=Concat(
|
ct_fk_combination=Concat(
|
||||||
'content_type', V('-'), 'object_id', output_field=CharField()
|
'content_type', Value('-'), 'object_id',
|
||||||
|
output_field=CharField()
|
||||||
)
|
)
|
||||||
).filter(
|
).filter(
|
||||||
permissions=stored_permission, role__groups__user=user,
|
permissions=stored_permission, role__groups__user=user,
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ class ACLListView(SingleObjectListView):
|
|||||||
'title': _('Access control lists for: %s' % self.content_object),
|
'title': _('Access control lists for: %s' % self.content_object),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return AccessControlList.objects.filter(
|
return AccessControlList.objects.filter(
|
||||||
content_type=self.object_content_type,
|
content_type=self.object_content_type,
|
||||||
object_id=self.content_object.pk
|
object_id=self.content_object.pk
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from mayan.apps.common.tests import GenericViewTestCase
|
from mayan.apps.common.tests import GenericViewTestCase
|
||||||
|
from mayan.apps.documents.permissions import permission_document_view
|
||||||
from mayan.apps.documents.tests import GenericDocumentViewTestCase
|
from mayan.apps.documents.tests import GenericDocumentViewTestCase
|
||||||
|
|
||||||
from ..models import Cabinet
|
from ..models import Cabinet
|
||||||
@@ -47,7 +48,7 @@ class CabinetViewTestCase(CabinetTestMixin, CabinetViewTestMixin, GenericViewTes
|
|||||||
self._create_test_cabinet()
|
self._create_test_cabinet()
|
||||||
|
|
||||||
response = self._request_test_cabinet_delete_view()
|
response = self._request_test_cabinet_delete_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Cabinet.objects.count(), 1)
|
self.assertEqual(Cabinet.objects.count(), 1)
|
||||||
|
|
||||||
@@ -66,7 +67,7 @@ class CabinetViewTestCase(CabinetTestMixin, CabinetViewTestMixin, GenericViewTes
|
|||||||
self._create_test_cabinet()
|
self._create_test_cabinet()
|
||||||
|
|
||||||
response = self._request_test_cabinet_edit_view()
|
response = self._request_test_cabinet_edit_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.test_cabinet.refresh_from_db()
|
self.test_cabinet.refresh_from_db()
|
||||||
self.assertEqual(self.test_cabinet.label, TEST_CABINET_LABEL)
|
self.assertEqual(self.test_cabinet.label, TEST_CABINET_LABEL)
|
||||||
@@ -84,6 +85,25 @@ class CabinetViewTestCase(CabinetTestMixin, CabinetViewTestMixin, GenericViewTes
|
|||||||
self.test_cabinet.refresh_from_db()
|
self.test_cabinet.refresh_from_db()
|
||||||
self.assertEqual(self.test_cabinet.label, TEST_CABINET_LABEL_EDITED)
|
self.assertEqual(self.test_cabinet.label, TEST_CABINET_LABEL_EDITED)
|
||||||
|
|
||||||
|
def test_cabinet_list_view_no_permission(self):
|
||||||
|
self._create_test_cabinet()
|
||||||
|
|
||||||
|
response = self._request_test_cabinet_list_view()
|
||||||
|
self.assertNotContains(
|
||||||
|
response, text=self.test_cabinet.label, status_code=200
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_cabinet_list_view_with_access(self):
|
||||||
|
self._create_test_cabinet()
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_cabinet, permission=permission_cabinet_view
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self._request_test_cabinet_list_view()
|
||||||
|
self.assertContains(
|
||||||
|
response, text=self.test_cabinet.label, status_code=200
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CabinetChildViewTestCase(CabinetTestMixin, CabinetViewTestMixin, GenericViewTestCase):
|
class CabinetChildViewTestCase(CabinetTestMixin, CabinetViewTestMixin, GenericViewTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@@ -94,7 +114,7 @@ class CabinetChildViewTestCase(CabinetTestMixin, CabinetViewTestMixin, GenericVi
|
|||||||
cabinet_count = Cabinet.objects.count()
|
cabinet_count = Cabinet.objects.count()
|
||||||
|
|
||||||
response = self._request_test_cabinet_child_create_view()
|
response = self._request_test_cabinet_child_create_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Cabinet.objects.count(), cabinet_count)
|
self.assertEqual(Cabinet.objects.count(), cabinet_count)
|
||||||
|
|
||||||
@@ -115,7 +135,7 @@ class CabinetChildViewTestCase(CabinetTestMixin, CabinetViewTestMixin, GenericVi
|
|||||||
cabinet_count = Cabinet.objects.count()
|
cabinet_count = Cabinet.objects.count()
|
||||||
|
|
||||||
response = self._request_test_cabinet_child_delete_view()
|
response = self._request_test_cabinet_child_delete_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Cabinet.objects.count(), cabinet_count)
|
self.assertEqual(Cabinet.objects.count(), cabinet_count)
|
||||||
|
|
||||||
@@ -149,9 +169,7 @@ class CabinetDocumentViewTestCase(CabinetTestMixin, CabinetViewTestMixin, Generi
|
|||||||
self.grant_permission(permission=permission_cabinet_view)
|
self.grant_permission(permission=permission_cabinet_view)
|
||||||
|
|
||||||
response = self._add_document_to_cabinet()
|
response = self._add_document_to_cabinet()
|
||||||
self.assertContains(
|
self.assertEqual(response.status_code, 404)
|
||||||
response=response, text='Select a valid choice.', status_code=200
|
|
||||||
)
|
|
||||||
|
|
||||||
self.test_cabinet.refresh_from_db()
|
self.test_cabinet.refresh_from_db()
|
||||||
self.assertEqual(self.test_cabinet.documents.count(), 0)
|
self.assertEqual(self.test_cabinet.documents.count(), 0)
|
||||||
@@ -184,9 +202,7 @@ class CabinetDocumentViewTestCase(CabinetTestMixin, CabinetViewTestMixin, Generi
|
|||||||
self.grant_permission(permission=permission_cabinet_view)
|
self.grant_permission(permission=permission_cabinet_view)
|
||||||
|
|
||||||
response = self._request_test_document_multiple_cabinet_multiple_add_view_cabinet()
|
response = self._request_test_document_multiple_cabinet_multiple_add_view_cabinet()
|
||||||
self.assertContains(
|
self.assertEqual(response.status_code, 404)
|
||||||
response=response, text='Select a valid choice', status_code=200
|
|
||||||
)
|
|
||||||
|
|
||||||
self.test_cabinet.refresh_from_db()
|
self.test_cabinet.refresh_from_db()
|
||||||
self.assertEqual(self.test_cabinet.documents.count(), 0)
|
self.assertEqual(self.test_cabinet.documents.count(), 0)
|
||||||
@@ -216,9 +232,7 @@ class CabinetDocumentViewTestCase(CabinetTestMixin, CabinetViewTestMixin, Generi
|
|||||||
self.test_cabinet.documents.add(self.test_document)
|
self.test_cabinet.documents.add(self.test_document)
|
||||||
|
|
||||||
response = self._request_test_document_cabinet_multiple_remove_view()
|
response = self._request_test_document_cabinet_multiple_remove_view()
|
||||||
self.assertContains(
|
self.assertEqual(response.status_code, 404)
|
||||||
response=response, text='Select a valid choice', status_code=200
|
|
||||||
)
|
|
||||||
|
|
||||||
self.test_cabinet.refresh_from_db()
|
self.test_cabinet.refresh_from_db()
|
||||||
self.assertEqual(self.test_cabinet.documents.count(), 1)
|
self.assertEqual(self.test_cabinet.documents.count(), 1)
|
||||||
@@ -243,21 +257,72 @@ class CabinetDocumentViewTestCase(CabinetTestMixin, CabinetViewTestMixin, Generi
|
|||||||
self.test_cabinet.refresh_from_db()
|
self.test_cabinet.refresh_from_db()
|
||||||
self.assertEqual(self.test_cabinet.documents.count(), 0)
|
self.assertEqual(self.test_cabinet.documents.count(), 0)
|
||||||
|
|
||||||
def test_cabinet_list_view_no_permission(self):
|
def _request_test_cabinet_document_list_view(self):
|
||||||
self._create_test_cabinet()
|
return self.get(
|
||||||
|
viewname='cabinets:cabinet_view', kwargs={
|
||||||
response = self._request_test_cabinet_list_view()
|
'pk': self.test_cabinet.pk
|
||||||
self.assertNotContains(
|
}
|
||||||
response, text=self.test_cabinet.label, status_code=200
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_cabinet_list_view_with_access(self):
|
def test_cabinet_document_list_view_no_permission(self):
|
||||||
self._create_test_cabinet()
|
self._create_test_cabinet()
|
||||||
|
self.test_cabinet.documents.add(self.test_document)
|
||||||
|
|
||||||
|
response = self._request_test_cabinet_document_list_view()
|
||||||
|
self.assertNotContains(
|
||||||
|
response, text=self.test_cabinet.label, status_code=404
|
||||||
|
)
|
||||||
|
self.assertNotContains(
|
||||||
|
response, text=self.test_document.label, status_code=404
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_cabinet_document_list_view_with_cabinet_access(self):
|
||||||
|
self._create_test_cabinet()
|
||||||
|
self.test_cabinet.documents.add(self.test_document)
|
||||||
|
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.test_cabinet, permission=permission_cabinet_view
|
obj=self.test_cabinet, permission=permission_cabinet_view
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_test_cabinet_list_view()
|
response = self._request_test_cabinet_document_list_view()
|
||||||
self.assertContains(
|
self.assertContains(
|
||||||
response, text=self.test_cabinet.label, status_code=200
|
response, text=self.test_cabinet.label, status_code=200
|
||||||
)
|
)
|
||||||
|
self.assertNotContains(
|
||||||
|
response, text=self.test_document.label, status_code=200
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_cabinet_document_list_view_with_document_access(self):
|
||||||
|
self._create_test_cabinet()
|
||||||
|
self.test_cabinet.documents.add(self.test_document)
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document, permission=permission_document_view
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self._request_test_cabinet_document_list_view()
|
||||||
|
self.assertNotContains(
|
||||||
|
response, text=self.test_cabinet.label, status_code=404
|
||||||
|
)
|
||||||
|
self.assertNotContains(
|
||||||
|
response, text=self.test_document.label, status_code=404
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_cabinet_document_list_view_with_full_access(self):
|
||||||
|
self._create_test_cabinet()
|
||||||
|
self.test_cabinet.documents.add(self.test_document)
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_cabinet, permission=permission_cabinet_view
|
||||||
|
)
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document, permission=permission_document_view
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self._request_test_cabinet_document_list_view()
|
||||||
|
self.assertContains(
|
||||||
|
response, text=self.test_cabinet.label, status_code=200
|
||||||
|
)
|
||||||
|
self.assertContains(
|
||||||
|
response, text=self.test_document.label, status_code=200
|
||||||
|
)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from mayan.apps.common.generics import (
|
|||||||
MultipleObjectFormActionView, SingleObjectCreateView,
|
MultipleObjectFormActionView, SingleObjectCreateView,
|
||||||
SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView
|
SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView
|
||||||
)
|
)
|
||||||
|
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||||
from mayan.apps.documents.permissions import permission_document_view
|
from mayan.apps.documents.permissions import permission_document_view
|
||||||
from mayan.apps.documents.models import Document
|
from mayan.apps.documents.models import Document
|
||||||
from mayan.apps.documents.views import DocumentListView
|
from mayan.apps.documents.views import DocumentListView
|
||||||
@@ -45,38 +46,25 @@ class CabinetCreateView(SingleObjectCreateView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CabinetChildAddView(SingleObjectCreateView):
|
class CabinetChildAddView(ExternalObjectMixin, SingleObjectCreateView):
|
||||||
fields = ('label',)
|
fields = ('label',)
|
||||||
model = Cabinet
|
external_object_class = Cabinet
|
||||||
|
external_object_permission = permission_cabinet_edit
|
||||||
def form_valid(self, form):
|
|
||||||
"""
|
|
||||||
If the form is valid, save the associated model.
|
|
||||||
"""
|
|
||||||
self.object = form.save(commit=False)
|
|
||||||
self.object.parent = self.get_object()
|
|
||||||
self.object.save()
|
|
||||||
|
|
||||||
return super(CabinetChildAddView, self).form_valid(form=form)
|
|
||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
|
||||||
cabinet = super(CabinetChildAddView, self).get_object(*args, **kwargs)
|
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=cabinet.get_root(), permissions=(permission_cabinet_edit,),
|
|
||||||
user=self.request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
return cabinet
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'title': _(
|
'title': _(
|
||||||
'Add new level to: %s'
|
'Add new level to: %s'
|
||||||
) % self.get_object().get_full_path(),
|
) % self.external_object.get_full_path(),
|
||||||
'object': self.get_object()
|
'object': self.external_object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return self.external_object.get_descendants()
|
||||||
|
|
||||||
|
def get_save_extra_data(self):
|
||||||
|
return {'parent': self.external_object}
|
||||||
|
|
||||||
|
|
||||||
class CabinetDeleteView(SingleObjectDeleteView):
|
class CabinetDeleteView(SingleObjectDeleteView):
|
||||||
model = Cabinet
|
model = Cabinet
|
||||||
@@ -90,34 +78,34 @@ class CabinetDeleteView(SingleObjectDeleteView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CabinetDetailView(DocumentListView):
|
class CabinetDetailView(ExternalObjectMixin, DocumentListView):
|
||||||
|
external_object_class = Cabinet
|
||||||
|
external_object_permission = permission_cabinet_view
|
||||||
template_name = 'cabinets/cabinet_details.html'
|
template_name = 'cabinets/cabinet_details.html'
|
||||||
|
|
||||||
def get_document_queryset(self):
|
def get_document_queryset(self):
|
||||||
queryset = AccessControlList.objects.filter_by_access(
|
return self.external_object.documents.all()
|
||||||
permission=permission_document_view,
|
|
||||||
queryset=self.get_object().documents.all(), user=self.request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
return queryset
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(CabinetDetailView, self).get_context_data(**kwargs)
|
context = super(CabinetDetailView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
cabinet = self.get_object()
|
|
||||||
|
|
||||||
context.update(
|
context.update(
|
||||||
{
|
{
|
||||||
'column_class': 'col-xs-12 col-sm-6 col-md-4 col-lg-3',
|
'column_class': 'col-xs-12 col-sm-6 col-md-4 col-lg-3',
|
||||||
'hide_links': True,
|
'hide_links': True,
|
||||||
'jstree_data': '\n'.join(
|
'jstree_data': '\n'.join(
|
||||||
jstree_data(node=cabinet.get_root(), selected_node=cabinet)
|
jstree_data(
|
||||||
|
node=self.external_object.get_root(),
|
||||||
|
selected_node=self.external_object
|
||||||
|
)
|
||||||
),
|
),
|
||||||
'list_as_items': True,
|
'list_as_items': True,
|
||||||
'no_results_icon': icon_cabinet,
|
'no_results_icon': icon_cabinet,
|
||||||
'no_results_main_link': link_cabinet_child_add.resolve(
|
'no_results_main_link': link_cabinet_child_add.resolve(
|
||||||
context=RequestContext(
|
context=RequestContext(
|
||||||
request=self.request, dict_={'object': cabinet}
|
request=self.request, dict_={
|
||||||
|
'object': self.external_object
|
||||||
|
}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'no_results_text': _(
|
'no_results_text': _(
|
||||||
@@ -126,28 +114,15 @@ class CabinetDetailView(DocumentListView):
|
|||||||
'select the cabinet view of a document view.'
|
'select the cabinet view of a document view.'
|
||||||
),
|
),
|
||||||
'no_results_title': _('This cabinet level is empty'),
|
'no_results_title': _('This cabinet level is empty'),
|
||||||
'object': cabinet,
|
'object': self.external_object,
|
||||||
'title': _('Details of cabinet: %s') % cabinet.get_full_path(),
|
'title': _(
|
||||||
|
'Details of cabinet: %s'
|
||||||
|
) % self.external_object.get_full_path(),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_object(self):
|
|
||||||
cabinet = get_object_or_404(klass=Cabinet, pk=self.kwargs['pk'])
|
|
||||||
|
|
||||||
if cabinet.is_root_node():
|
|
||||||
permission_object = cabinet
|
|
||||||
else:
|
|
||||||
permission_object = cabinet.get_root()
|
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=permission_object, permissions=(permission_cabinet_view,),
|
|
||||||
user=self.request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
return cabinet
|
|
||||||
|
|
||||||
|
|
||||||
class CabinetEditView(SingleObjectEditView):
|
class CabinetEditView(SingleObjectEditView):
|
||||||
fields = ('label',)
|
fields = ('label',)
|
||||||
@@ -182,7 +157,7 @@ class CabinetListView(SingleObjectListView):
|
|||||||
'no_results_title': _('No cabinets available'),
|
'no_results_title': _('No cabinets available'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
# Add explicit ordering of root nodes since the queryset returned
|
# Add explicit ordering of root nodes since the queryset returned
|
||||||
# is not affected by the model's order Meta option.
|
# is not affected by the model's order Meta option.
|
||||||
return Cabinet.objects.root_nodes().order_by('label')
|
return Cabinet.objects.root_nodes().order_by('label')
|
||||||
@@ -220,7 +195,7 @@ class DocumentCabinetListView(CabinetListView):
|
|||||||
'title': _('Cabinets containing document: %s') % self.document,
|
'title': _('Cabinets containing document: %s') % self.document,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.document.document_cabinets()
|
return self.document.document_cabinets()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -119,14 +119,11 @@ class DocumentCheckoutViewTestCase(DocumentCheckoutTestMixin, GenericDocumentVie
|
|||||||
|
|
||||||
def test_checkout_detail_view_no_permission(self):
|
def test_checkout_detail_view_no_permission(self):
|
||||||
self._check_out_test_document()
|
self._check_out_test_document()
|
||||||
self.grant_access(
|
|
||||||
obj=self.test_document,
|
|
||||||
permission=permission_document_check_out
|
|
||||||
)
|
|
||||||
|
|
||||||
response = self._request_check_out_detail_view()
|
response = self._request_check_out_detail_view()
|
||||||
|
|
||||||
self.assertNotContains(
|
self.assertNotContains(
|
||||||
response, text=STATE_LABELS[STATE_CHECKED_OUT], status_code=403
|
response, text=STATE_LABELS[STATE_CHECKED_OUT], status_code=404
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_checkout_detail_view_with_access(self):
|
def test_checkout_detail_view_with_access(self):
|
||||||
|
|||||||
@@ -24,6 +24,64 @@ from .permissions import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentCheckinView(ConfirmView):
|
||||||
|
def get_extra_context(self):
|
||||||
|
document = self.get_object()
|
||||||
|
|
||||||
|
context = {
|
||||||
|
'object': document,
|
||||||
|
}
|
||||||
|
|
||||||
|
if document.get_check_out_info().user != self.request.user:
|
||||||
|
context['title'] = _(
|
||||||
|
'You didn\'t originally checked out this document. '
|
||||||
|
'Forcefully check in the document: %s?'
|
||||||
|
) % document
|
||||||
|
else:
|
||||||
|
context['title'] = _('Check in the document: %s?') % document
|
||||||
|
|
||||||
|
return context
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
|
def get_post_action_redirect(self):
|
||||||
|
return reverse(
|
||||||
|
viewname='checkouts:check_out_info', kwargs={
|
||||||
|
'pk': self.get_object().pk
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def view_action(self):
|
||||||
|
document = self.get_object()
|
||||||
|
|
||||||
|
if document.get_check_out_info().user == self.request.user:
|
||||||
|
AccessControlList.objects.check_access(
|
||||||
|
obj=document, permissions=(permission_document_check_in,),
|
||||||
|
user=self.request.user
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
AccessControlList.objects.check_access(
|
||||||
|
obj=document,
|
||||||
|
permissions=(permission_document_check_in_override,),
|
||||||
|
user=self.request.user
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
document.check_in(user=self.request.user)
|
||||||
|
except DocumentNotCheckedOut:
|
||||||
|
messages.error(
|
||||||
|
message=_('Document has not been checked out.'),
|
||||||
|
request=self.request
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
messages.success(
|
||||||
|
message=_(
|
||||||
|
'Document "%s" checked in successfully.'
|
||||||
|
) % document, request=self.request
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CheckoutDocumentView(SingleObjectCreateView):
|
class CheckoutDocumentView(SingleObjectCreateView):
|
||||||
form_class = DocumentCheckoutForm
|
form_class = DocumentCheckoutForm
|
||||||
|
|
||||||
@@ -125,69 +183,8 @@ class CheckoutDetailView(SingleObjectDetailView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'object': self.get_object(),
|
'object': self.object,
|
||||||
'title': _(
|
'title': _(
|
||||||
'Check out details for document: %s'
|
'Check out details for document: %s'
|
||||||
) % self.get_object()
|
) % self.object
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object(self):
|
|
||||||
return get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentCheckinView(ConfirmView):
|
|
||||||
def get_extra_context(self):
|
|
||||||
document = self.get_object()
|
|
||||||
|
|
||||||
context = {
|
|
||||||
'object': document,
|
|
||||||
}
|
|
||||||
|
|
||||||
if document.get_check_out_info().user != self.request.user:
|
|
||||||
context['title'] = _(
|
|
||||||
'You didn\'t originally checked out this document. '
|
|
||||||
'Forcefully check in the document: %s?'
|
|
||||||
) % document
|
|
||||||
else:
|
|
||||||
context['title'] = _('Check in the document: %s?') % document
|
|
||||||
|
|
||||||
return context
|
|
||||||
|
|
||||||
def get_object(self):
|
|
||||||
return get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
|
||||||
|
|
||||||
def get_post_action_redirect(self):
|
|
||||||
return reverse(
|
|
||||||
viewname='checkouts:check_out_info', kwargs={
|
|
||||||
'pk': self.get_object().pk
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def view_action(self):
|
|
||||||
document = self.get_object()
|
|
||||||
|
|
||||||
if document.get_check_out_info().user == self.request.user:
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=document, permissions=(permission_document_check_in,),
|
|
||||||
user=self.request.user
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=document,
|
|
||||||
permissions=(permission_document_check_in_override,),
|
|
||||||
user=self.request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
document.check_in(user=self.request.user)
|
|
||||||
except DocumentNotCheckedOut:
|
|
||||||
messages.error(
|
|
||||||
message=_('Document has not been checked out.'),
|
|
||||||
request=self.request
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
messages.success(
|
|
||||||
message=_(
|
|
||||||
'Document "%s" checked in successfully.'
|
|
||||||
) % document, request=self.request
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
@@ -36,7 +36,7 @@ from .literals import (
|
|||||||
from .mixins import (
|
from .mixins import (
|
||||||
DeleteExtraDataMixin, DynamicFormViewMixin, ExternalObjectMixin,
|
DeleteExtraDataMixin, DynamicFormViewMixin, ExternalObjectMixin,
|
||||||
ExtraContextMixin, FormExtraKwargsMixin, MultipleObjectMixin,
|
ExtraContextMixin, FormExtraKwargsMixin, MultipleObjectMixin,
|
||||||
ObjectActionMixin, ObjectListPermissionFilterMixin, ObjectNameMixin,
|
ObjectActionMixin, ObjectNameMixin,
|
||||||
ObjectPermissionCheckMixin, RedirectionMixin, RestrictedQuerysetMixin,
|
ObjectPermissionCheckMixin, RedirectionMixin, RestrictedQuerysetMixin,
|
||||||
ViewPermissionCheckMixin
|
ViewPermissionCheckMixin
|
||||||
)
|
)
|
||||||
@@ -138,7 +138,10 @@ class MultiFormView(DjangoFormView):
|
|||||||
return self.forms_invalid(forms=self.forms)
|
return self.forms_invalid(forms=self.forms)
|
||||||
|
|
||||||
|
|
||||||
class AddRemoveView(ExternalObjectMixin, ExtraContextMixin, ViewPermissionCheckMixin, RestrictedQuerysetMixin, MultiFormView):
|
class AddRemoveView(
|
||||||
|
ExternalObjectMixin, ExtraContextMixin, ViewPermissionCheckMixin,
|
||||||
|
RestrictedQuerysetMixin, MultiFormView
|
||||||
|
):
|
||||||
form_classes = {'form_available': ChoiceForm, 'form_added': ChoiceForm}
|
form_classes = {'form_available': ChoiceForm, 'form_added': ChoiceForm}
|
||||||
list_added_help_text = _(
|
list_added_help_text = _(
|
||||||
'Select entries to be removed. Hold Control to select multiple '
|
'Select entries to be removed. Hold Control to select multiple '
|
||||||
@@ -384,15 +387,21 @@ class AddRemoveView(ExternalObjectMixin, ExtraContextMixin, ViewPermissionCheckM
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ConfirmView(ObjectListPermissionFilterMixin, ObjectPermissionCheckMixin, ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, TemplateView):
|
class ConfirmView(
|
||||||
|
RestrictedQuerysetMixin, ViewPermissionCheckMixin, ExtraContextMixin,
|
||||||
|
RedirectionMixin, TemplateView
|
||||||
|
):
|
||||||
template_name = 'appearance/generic_confirm.html'
|
template_name = 'appearance/generic_confirm.html'
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
self.view_action()
|
self.view_action()
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
return HttpResponseRedirect(redirect_to=self.get_success_url())
|
||||||
|
|
||||||
|
|
||||||
class FormView(ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, FormExtraKwargsMixin, DjangoFormView):
|
class FormView(
|
||||||
|
ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin,
|
||||||
|
FormExtraKwargsMixin, DjangoFormView
|
||||||
|
):
|
||||||
template_name = 'appearance/generic_form.html'
|
template_name = 'appearance/generic_form.html'
|
||||||
|
|
||||||
|
|
||||||
@@ -400,7 +409,11 @@ class DynamicFormView(DynamicFormViewMixin, FormView):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MultipleObjectFormActionView(ObjectActionMixin, MultipleObjectMixin, FormExtraKwargsMixin, ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, DjangoFormView):
|
class MultipleObjectFormActionView(
|
||||||
|
ExtraContextMixin, ObjectActionMixin, ViewPermissionCheckMixin,
|
||||||
|
RestrictedQuerysetMixin, MultipleObjectMixin, FormExtraKwargsMixin,
|
||||||
|
RedirectionMixin, DjangoFormView
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
This view will present a form and upon receiving a POST request will
|
This view will present a form and upon receiving a POST request will
|
||||||
perform an action on an object or queryset
|
perform an action on an object or queryset
|
||||||
@@ -413,7 +426,7 @@ class MultipleObjectFormActionView(ObjectActionMixin, MultipleObjectMixin, FormE
|
|||||||
if self.__class__.mro()[0].get_queryset != MultipleObjectFormActionView.get_queryset:
|
if self.__class__.mro()[0].get_queryset != MultipleObjectFormActionView.get_queryset:
|
||||||
raise ImproperlyConfigured(
|
raise ImproperlyConfigured(
|
||||||
'%(cls)s is overloading the get_queryset method. Subclasses '
|
'%(cls)s is overloading the get_queryset method. Subclasses '
|
||||||
'should implement the get_object_list method instead. ' % {
|
'should implement the get_source_queryset method instead. ' % {
|
||||||
'cls': self.__class__.__name__
|
'cls': self.__class__.__name__
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -428,23 +441,50 @@ class MultipleObjectFormActionView(ObjectActionMixin, MultipleObjectMixin, FormE
|
|||||||
try:
|
try:
|
||||||
return super(MultipleObjectFormActionView, self).get_queryset()
|
return super(MultipleObjectFormActionView, self).get_queryset()
|
||||||
except ImproperlyConfigured:
|
except ImproperlyConfigured:
|
||||||
self.queryset = self.get_object_list()
|
self.queryset = self.get_source_queryset()
|
||||||
return super(MultipleObjectFormActionView, self).get_queryset()
|
return super(MultipleObjectFormActionView, self).get_queryset()
|
||||||
|
|
||||||
|
|
||||||
class MultipleObjectConfirmActionView(ObjectActionMixin, MultipleObjectMixin, ObjectListPermissionFilterMixin, ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, TemplateView):
|
class MultipleObjectConfirmActionView(
|
||||||
|
ExtraContextMixin, ObjectActionMixin, ViewPermissionCheckMixin,
|
||||||
|
RestrictedQuerysetMixin, MultipleObjectMixin, RedirectionMixin, TemplateView
|
||||||
|
):
|
||||||
template_name = 'appearance/generic_confirm.html'
|
template_name = 'appearance/generic_confirm.html'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
result = super(MultipleObjectConfirmActionView, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
if self.__class__.mro()[0].get_queryset != MultipleObjectConfirmActionView.get_queryset:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
'%(cls)s is overloading the get_queryset method. Subclasses '
|
||||||
|
'should implement the get_source_queryset method instead. ' % {
|
||||||
|
'cls': self.__class__.__name__
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
try:
|
||||||
|
return super(MultipleObjectConfirmActionView, self).get_queryset()
|
||||||
|
except ImproperlyConfigured:
|
||||||
|
self.queryset = self.get_source_queryset()
|
||||||
|
return super(MultipleObjectConfirmActionView, self).get_queryset()
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
self.view_action()
|
self.view_action()
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
return HttpResponseRedirect(redirect_to=self.get_success_url())
|
||||||
|
|
||||||
|
|
||||||
class SimpleView(ViewPermissionCheckMixin, ExtraContextMixin, TemplateView):
|
class SimpleView(ViewPermissionCheckMixin, ExtraContextMixin, TemplateView):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SingleObjectCreateView(ObjectNameMixin, ViewPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, FormExtraKwargsMixin, CreateView):
|
class SingleObjectCreateView(
|
||||||
|
ObjectNameMixin, ViewPermissionCheckMixin, ExtraContextMixin,
|
||||||
|
RedirectionMixin, FormExtraKwargsMixin, CreateView
|
||||||
|
):
|
||||||
|
error_message_duplicate = None
|
||||||
template_name = 'appearance/generic_form.html'
|
template_name = 'appearance/generic_form.html'
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
@@ -461,42 +501,78 @@ class SingleObjectCreateView(ObjectNameMixin, ViewPermissionCheckMixin, ExtraCon
|
|||||||
else:
|
else:
|
||||||
save_extra_data = {}
|
save_extra_data = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.object.validate_unique()
|
||||||
|
except ValidationError as exception:
|
||||||
|
context = self.get_context_data()
|
||||||
|
|
||||||
|
error_message = self.get_error_message_duplicate() or _(
|
||||||
|
'Duplicate data error: %(error)s'
|
||||||
|
) % {
|
||||||
|
'error': '\n'.join(exception.messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
messages.error(
|
||||||
|
message=error_message, request=self.request
|
||||||
|
)
|
||||||
|
return super(
|
||||||
|
SingleObjectCreateView, self
|
||||||
|
).form_invalid(form=form)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.object.save(**save_extra_data)
|
self.object.save(**save_extra_data)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
context = self.get_context_data()
|
context = self.get_context_data()
|
||||||
|
|
||||||
messages.error(
|
messages.error(
|
||||||
self.request,
|
message=_('%(object)s not created, error: %(error)s') % {
|
||||||
_('%(object)s not created, error: %(error)s') % {
|
|
||||||
'object': self.get_object_name(context=context),
|
'object': self.get_object_name(context=context),
|
||||||
'error': exception
|
'error': exception
|
||||||
}
|
}, request=self.request
|
||||||
)
|
)
|
||||||
|
return super(
|
||||||
|
SingleObjectCreateView, self
|
||||||
|
).form_invalid(form=form)
|
||||||
else:
|
else:
|
||||||
context = self.get_context_data()
|
context = self.get_context_data()
|
||||||
|
|
||||||
messages.success(
|
messages.success(
|
||||||
self.request,
|
message=_(
|
||||||
_(
|
|
||||||
'%(object)s created successfully.'
|
'%(object)s created successfully.'
|
||||||
) % {'object': self.get_object_name(context=context)}
|
) % {'object': self.get_object_name(context=context)},
|
||||||
|
request=self.request
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
return HttpResponseRedirect(redirect_to=self.get_success_url())
|
||||||
|
|
||||||
|
def get_error_message_duplicate(self):
|
||||||
|
return self.error_message_duplicate
|
||||||
|
|
||||||
|
|
||||||
class SingleObjectDynamicFormCreateView(DynamicFormViewMixin, SingleObjectCreateView):
|
class SingleObjectDynamicFormCreateView(
|
||||||
|
DynamicFormViewMixin, SingleObjectCreateView
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SingleObjectDeleteView(ObjectNameMixin, DeleteExtraDataMixin, ViewPermissionCheckMixin, ObjectPermissionCheckMixin, ExtraContextMixin, RedirectionMixin, DeleteView):
|
class SingleObjectDeleteView(
|
||||||
|
ObjectNameMixin, DeleteExtraDataMixin, ViewPermissionCheckMixin,
|
||||||
|
RestrictedQuerysetMixin, ExtraContextMixin, RedirectionMixin, DeleteView
|
||||||
|
):
|
||||||
template_name = 'appearance/generic_confirm.html'
|
template_name = 'appearance/generic_confirm.html'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
context = super(SingleObjectDeleteView, self).get_context_data(**kwargs)
|
result = super(SingleObjectDeleteView, self).__init__(*args, **kwargs)
|
||||||
context.update({'delete_view': True})
|
|
||||||
return context
|
if self.__class__.mro()[0].get_queryset != SingleObjectDeleteView.get_queryset:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
'%(cls)s is overloading the get_queryset method. Subclasses '
|
||||||
|
'should implement the get_source_queryset method instead. ' % {
|
||||||
|
'cls': self.__class__.__name__
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def delete(self, request, *args, **kwargs):
|
def delete(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
@@ -507,40 +583,77 @@ class SingleObjectDeleteView(ObjectNameMixin, DeleteExtraDataMixin, ViewPermissi
|
|||||||
result = super(SingleObjectDeleteView, self).delete(request, *args, **kwargs)
|
result = super(SingleObjectDeleteView, self).delete(request, *args, **kwargs)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
messages.error(
|
messages.error(
|
||||||
self.request,
|
message=_('%(object)s not deleted, error: %(error)s.') % {
|
||||||
_('%(object)s not deleted, error: %(error)s.') % {
|
|
||||||
'object': object_name,
|
'object': object_name,
|
||||||
'error': exception
|
'error': exception
|
||||||
}
|
}, request=self.request
|
||||||
)
|
)
|
||||||
|
|
||||||
raise exception
|
raise exception
|
||||||
else:
|
else:
|
||||||
messages.success(
|
messages.success(
|
||||||
self.request,
|
message=_(
|
||||||
_(
|
|
||||||
'%(object)s deleted successfully.'
|
'%(object)s deleted successfully.'
|
||||||
) % {'object': object_name}
|
) % {'object': object_name},
|
||||||
|
request=self.request
|
||||||
)
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(SingleObjectDeleteView, self).get_context_data(**kwargs)
|
||||||
|
context.update({'delete_view': True})
|
||||||
|
return context
|
||||||
|
|
||||||
class SingleObjectDetailView(ViewPermissionCheckMixin, ObjectPermissionCheckMixin, FormExtraKwargsMixin, ExtraContextMixin, ModelFormMixin, DetailView):
|
def get_queryset(self):
|
||||||
|
try:
|
||||||
|
return super(SingleObjectDeleteView, self).get_queryset()
|
||||||
|
except ImproperlyConfigured:
|
||||||
|
self.queryset = self.get_source_queryset()
|
||||||
|
return super(SingleObjectDeleteView, self).get_queryset()
|
||||||
|
|
||||||
|
|
||||||
|
class SingleObjectDetailView(
|
||||||
|
ViewPermissionCheckMixin, RestrictedQuerysetMixin, FormExtraKwargsMixin,
|
||||||
|
ExtraContextMixin, ModelFormMixin, DetailView
|
||||||
|
):
|
||||||
template_name = 'appearance/generic_form.html'
|
template_name = 'appearance/generic_form.html'
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
result = super(SingleObjectDetailView, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
if self.__class__.mro()[0].get_queryset != SingleObjectDetailView.get_queryset:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
'%(cls)s is overloading the get_queryset method. Subclasses '
|
||||||
|
'should implement the get_source_queryset method instead. ' % {
|
||||||
|
'cls': self.__class__.__name__
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(SingleObjectDetailView, self).get_context_data(**kwargs)
|
context = super(SingleObjectDetailView, self).get_context_data(**kwargs)
|
||||||
context.update({'read_only': True, 'form': self.get_form()})
|
context.update({'read_only': True, 'form': self.get_form()})
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
try:
|
||||||
|
return super(SingleObjectDetailView, self).get_queryset()
|
||||||
|
except ImproperlyConfigured:
|
||||||
|
self.queryset = self.get_source_queryset()
|
||||||
|
return super(SingleObjectDetailView, self).get_queryset()
|
||||||
|
|
||||||
|
|
||||||
class SingleObjectDownloadView(ViewPermissionCheckMixin, ObjectPermissionCheckMixin, VirtualDownloadView, SingleObjectMixin):
|
class SingleObjectDownloadView(ViewPermissionCheckMixin, ObjectPermissionCheckMixin, VirtualDownloadView, SingleObjectMixin):
|
||||||
TextIteratorIO = TextIteratorIO
|
TextIteratorIO = TextIteratorIO
|
||||||
VirtualFile = VirtualFile
|
VirtualFile = VirtualFile
|
||||||
|
|
||||||
|
|
||||||
class SingleObjectEditView(ObjectNameMixin, ViewPermissionCheckMixin, ObjectPermissionCheckMixin, ExtraContextMixin, FormExtraKwargsMixin, RedirectionMixin, UpdateView):
|
class SingleObjectEditView(
|
||||||
|
ObjectNameMixin, ViewPermissionCheckMixin, RestrictedQuerysetMixin,
|
||||||
|
ExtraContextMixin, FormExtraKwargsMixin, RedirectionMixin, UpdateView
|
||||||
|
):
|
||||||
template_name = 'appearance/generic_form.html'
|
template_name = 'appearance/generic_form.html'
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
@@ -564,23 +677,22 @@ class SingleObjectEditView(ObjectNameMixin, ViewPermissionCheckMixin, ObjectPerm
|
|||||||
self.object.save(**save_extra_data)
|
self.object.save(**save_extra_data)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
messages.error(
|
messages.error(
|
||||||
self.request,
|
message=_('%(object)s not updated, error: %(error)s.') % {
|
||||||
_('%(object)s not updated, error: %(error)s.') % {
|
|
||||||
'object': object_name,
|
'object': object_name,
|
||||||
'error': exception
|
'error': exception
|
||||||
}
|
}, request=self.request
|
||||||
)
|
)
|
||||||
|
return super(
|
||||||
raise exception
|
SingleObjectEditView, self
|
||||||
|
).form_invalid(form=form)
|
||||||
else:
|
else:
|
||||||
messages.success(
|
messages.success(
|
||||||
self.request,
|
message=_(
|
||||||
_(
|
|
||||||
'%(object)s updated successfully.'
|
'%(object)s updated successfully.'
|
||||||
) % {'object': object_name}
|
) % {'object': object_name}, request=self.request
|
||||||
)
|
)
|
||||||
|
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
return HttpResponseRedirect(redirect_to=self.get_success_url())
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
obj = super(SingleObjectEditView, self).get_object(queryset=queryset)
|
obj = super(SingleObjectEditView, self).get_object(queryset=queryset)
|
||||||
@@ -592,11 +704,16 @@ class SingleObjectEditView(ObjectNameMixin, ViewPermissionCheckMixin, ObjectPerm
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
class SingleObjectDynamicFormEditView(DynamicFormViewMixin, SingleObjectEditView):
|
class SingleObjectDynamicFormEditView(
|
||||||
|
DynamicFormViewMixin, SingleObjectEditView
|
||||||
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SingleObjectListView(PaginationMixin, ViewPermissionCheckMixin, ObjectListPermissionFilterMixin, ExtraContextMixin, RedirectionMixin, ListView):
|
class SingleObjectListView(
|
||||||
|
PaginationMixin, ViewPermissionCheckMixin, RestrictedQuerysetMixin,
|
||||||
|
ExtraContextMixin, RedirectionMixin, ListView
|
||||||
|
):
|
||||||
template_name = 'appearance/generic_list.html'
|
template_name = 'appearance/generic_list.html'
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -605,7 +722,7 @@ class SingleObjectListView(PaginationMixin, ViewPermissionCheckMixin, ObjectList
|
|||||||
if self.__class__.mro()[0].get_queryset != SingleObjectListView.get_queryset:
|
if self.__class__.mro()[0].get_queryset != SingleObjectListView.get_queryset:
|
||||||
raise ImproperlyConfigured(
|
raise ImproperlyConfigured(
|
||||||
'%(cls)s is overloading the get_queryset method. Subclasses '
|
'%(cls)s is overloading the get_queryset method. Subclasses '
|
||||||
'should implement the get_object_list method instead. ' % {
|
'should implement the get_source_queryset method instead. ' % {
|
||||||
'cls': self.__class__.__name__
|
'cls': self.__class__.__name__
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -631,7 +748,7 @@ class SingleObjectListView(PaginationMixin, ViewPermissionCheckMixin, ObjectList
|
|||||||
try:
|
try:
|
||||||
queryset = super(SingleObjectListView, self).get_queryset()
|
queryset = super(SingleObjectListView, self).get_queryset()
|
||||||
except ImproperlyConfigured:
|
except ImproperlyConfigured:
|
||||||
self.queryset = self.get_object_list()
|
self.queryset = self.get_source_queryset()
|
||||||
queryset = super(SingleObjectListView, self).get_queryset()
|
queryset = super(SingleObjectListView, self).get_queryset()
|
||||||
|
|
||||||
self.field_name = self.get_sort_field()
|
self.field_name = self.get_sort_field()
|
||||||
|
|||||||
@@ -5,11 +5,14 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
DEFAULT_COMMON_HOME_VIEW = 'common:home'
|
DEFAULT_COMMON_HOME_VIEW = 'common:home'
|
||||||
DELETE_STALE_UPLOADS_INTERVAL = 60 * 10 # 10 minutes
|
DELETE_STALE_UPLOADS_INTERVAL = 60 * 10 # 10 minutes
|
||||||
DJANGO_SQLITE_BACKEND = 'django.db.backends.sqlite3'
|
DJANGO_SQLITE_BACKEND = 'django.db.backends.sqlite3'
|
||||||
|
|
||||||
MESSAGE_SQLITE_WARNING = _(
|
MESSAGE_SQLITE_WARNING = _(
|
||||||
'Your database backend is set to use SQLite. SQLite should only be used '
|
'Your database backend is set to use SQLite. SQLite should only be used '
|
||||||
'for development and testing, not for production.'
|
'for development and testing, not for production.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
PK_LIST_SEPARATOR = ','
|
||||||
|
|
||||||
TEXT_SORT_FIELD_PARAMETER = '_sort_field'
|
TEXT_SORT_FIELD_PARAMETER = '_sort_field'
|
||||||
TEXT_SORT_FIELD_VARIABLE_NAME = 'sort_field'
|
TEXT_SORT_FIELD_VARIABLE_NAME = 'sort_field'
|
||||||
TEXT_SORT_ORDER_CHOICE_ASCENDING = 'asc'
|
TEXT_SORT_ORDER_CHOICE_ASCENDING = 'asc'
|
||||||
|
|||||||
@@ -3,27 +3,23 @@ from __future__ import unicode_literals
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
|
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
|
||||||
from django.db.models.query import QuerySet
|
from django.http import Http404, HttpResponseRedirect
|
||||||
from django.http import HttpResponseRedirect
|
|
||||||
from django.shortcuts import get_object_or_404, resolve_url
|
from django.shortcuts import get_object_or_404, resolve_url
|
||||||
from django.utils.translation import ungettext, ugettext_lazy as _
|
from django.utils.translation import ungettext, ugettext_lazy as _
|
||||||
|
from django.views.generic.detail import SingleObjectMixin
|
||||||
|
|
||||||
from mayan.apps.acls.models import AccessControlList
|
from mayan.apps.acls.models import AccessControlList
|
||||||
from mayan.apps.permissions import Permission
|
from mayan.apps.permissions import Permission
|
||||||
|
|
||||||
from .exceptions import ActionError
|
from .exceptions import ActionError
|
||||||
from .forms import DynamicForm
|
from .forms import DynamicForm
|
||||||
|
from .literals import PK_LIST_SEPARATOR
|
||||||
__all__ = (
|
|
||||||
'DeleteExtraDataMixin', 'DynamicFormViewMixin', 'ExtraContextMixin',
|
|
||||||
'FormExtraKwargsMixin', 'MultipleObjectMixin', 'ObjectActionMixin',
|
|
||||||
'ObjectListPermissionFilterMixin', 'ObjectNameMixin',
|
|
||||||
'ObjectPermissionCheckMixin', 'RedirectionMixin',
|
|
||||||
'ViewPermissionCheckMixin'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteExtraDataMixin(object):
|
class DeleteExtraDataMixin(object):
|
||||||
|
"""
|
||||||
|
Mixin to populate the extra data needed for delete views
|
||||||
|
"""
|
||||||
def delete(self, request, *args, **kwargs):
|
def delete(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
success_url = self.get_success_url()
|
success_url = self.get_success_url()
|
||||||
@@ -44,7 +40,28 @@ class DynamicFormViewMixin(object):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class ExtraContextMixin(object):
|
||||||
|
"""
|
||||||
|
Mixin that allows views to pass extra context to the template much easier
|
||||||
|
than overloading .get_context_data().
|
||||||
|
"""
|
||||||
|
extra_context = {}
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
return self.extra_context
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(ExtraContextMixin, self).get_context_data(**kwargs)
|
||||||
|
context.update(self.get_extra_context())
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class ExternalObjectMixin(object):
|
class ExternalObjectMixin(object):
|
||||||
|
"""
|
||||||
|
Mixin to allow views to load an object with minimal code but with all
|
||||||
|
the filtering and configurability possible. This object is often use as
|
||||||
|
the main or master object in multi object views.
|
||||||
|
"""
|
||||||
external_object_class = None
|
external_object_class = None
|
||||||
external_object_permission = None
|
external_object_permission = None
|
||||||
external_object_pk_url_kwarg = 'pk'
|
external_object_pk_url_kwarg = 'pk'
|
||||||
@@ -100,21 +117,6 @@ class ExternalObjectMixin(object):
|
|||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class ExtraContextMixin(object):
|
|
||||||
"""
|
|
||||||
Mixin that allows views to pass extra context to the template
|
|
||||||
"""
|
|
||||||
extra_context = {}
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
|
||||||
return self.extra_context
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super(ExtraContextMixin, self).get_context_data(**kwargs)
|
|
||||||
context.update(self.get_extra_context())
|
|
||||||
return context
|
|
||||||
|
|
||||||
|
|
||||||
class FormExtraKwargsMixin(object):
|
class FormExtraKwargsMixin(object):
|
||||||
"""
|
"""
|
||||||
Mixin that allows a view to pass extra keyword arguments to forms
|
Mixin that allows a view to pass extra keyword arguments to forms
|
||||||
@@ -130,62 +132,103 @@ class FormExtraKwargsMixin(object):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class MultipleInstanceActionMixin(object):
|
class MultipleObjectMixin(SingleObjectMixin):
|
||||||
# TODO: Deprecated, replace views using this with
|
|
||||||
# MultipleObjectFormActionView or MultipleObjectConfirmActionView
|
|
||||||
|
|
||||||
model = None
|
|
||||||
success_message = _('Operation performed on %(count)d object')
|
|
||||||
success_message_plural = _('Operation performed on %(count)d objects')
|
|
||||||
|
|
||||||
def get_pk_list(self):
|
|
||||||
return self.request.GET.get(
|
|
||||||
'id_list', self.request.POST.get('id_list', '')
|
|
||||||
).split(',')
|
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
return self.model.objects.filter(pk__in=self.get_pk_list())
|
|
||||||
|
|
||||||
def get_success_message(self, count):
|
|
||||||
return ungettext(
|
|
||||||
self.success_message,
|
|
||||||
self.success_message_plural,
|
|
||||||
count
|
|
||||||
) % {
|
|
||||||
'count': count,
|
|
||||||
}
|
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
|
||||||
count = 0
|
|
||||||
for instance in self.get_queryset():
|
|
||||||
try:
|
|
||||||
self.object_action(instance=instance)
|
|
||||||
except PermissionDenied:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
count += 1
|
|
||||||
|
|
||||||
messages.success(
|
|
||||||
self.request,
|
|
||||||
self.get_success_message(count=count)
|
|
||||||
)
|
|
||||||
|
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
|
||||||
|
|
||||||
|
|
||||||
class MultipleObjectMixin(object):
|
|
||||||
"""
|
"""
|
||||||
Mixin that allows a view to work on a single or multiple objects
|
Mixin that allows a view to work on a single or multiple objects. It can
|
||||||
|
receive a pk, a slug or a list of IDs via an id_list query.
|
||||||
|
The pk, slug, and ID list parameter name can be changed using the
|
||||||
|
attributes: pk_url_kwargs, slug_url_kwarg, and pk_list_key.
|
||||||
"""
|
"""
|
||||||
model = None
|
|
||||||
object_permission = None
|
|
||||||
pk_list_key = 'id_list'
|
pk_list_key = 'id_list'
|
||||||
pk_list_separator = ','
|
pk_list_separator = PK_LIST_SEPARATOR
|
||||||
pk_url_kwarg = 'pk'
|
|
||||||
queryset = None
|
def dispatch(self, request, *args, **kwargs):
|
||||||
slug_url_kwarg = 'slug'
|
self.object_list = self.get_object_list()
|
||||||
|
if self.view_mode_single:
|
||||||
|
self.object = self.object_list.first()
|
||||||
|
|
||||||
|
return super(MultipleObjectMixin, self).dispatch(request=request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Override BaseDetailView.get()
|
||||||
|
"""
|
||||||
|
return super(SingleObjectMixin, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
"""
|
||||||
|
Override SingleObjectMixin.get_context_data()
|
||||||
|
"""
|
||||||
|
return super(SingleObjectMixin, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
"""
|
||||||
|
Remove this method from the subclass
|
||||||
|
"""
|
||||||
|
raise AttributeError
|
||||||
|
|
||||||
|
def get_object_list(self, queryset=None):
|
||||||
|
"""
|
||||||
|
Returns the list of objects the view is displaying.
|
||||||
|
|
||||||
|
By default this requires `self.queryset` and a `pk`, `slug` ro
|
||||||
|
`pk_list' argument in the URLconf, but subclasses can override this
|
||||||
|
to return any object.
|
||||||
|
"""
|
||||||
|
self.view_mode_single = False
|
||||||
|
self.view_mode_multiple = False
|
||||||
|
|
||||||
|
# Use a custom queryset if provided; this is required for subclasses
|
||||||
|
# like DateDetailView
|
||||||
|
if queryset is None:
|
||||||
|
queryset = self.get_queryset()
|
||||||
|
|
||||||
|
# Next, try looking up by primary key.
|
||||||
|
pk = self.kwargs.get(self.pk_url_kwarg)
|
||||||
|
slug = self.kwargs.get(self.slug_url_kwarg)
|
||||||
|
pk_list = self.get_pk_list()
|
||||||
|
|
||||||
|
if pk is not None:
|
||||||
|
queryset = queryset.filter(pk=pk)
|
||||||
|
self.view_mode_single = True
|
||||||
|
|
||||||
|
# Next, try looking up by slug.
|
||||||
|
if slug is not None and (pk is None or self.query_pk_and_slug):
|
||||||
|
slug_field = self.get_slug_field()
|
||||||
|
queryset = queryset.filter(**{slug_field: slug})
|
||||||
|
self.view_mode_single = True
|
||||||
|
|
||||||
|
if pk_list is not None:
|
||||||
|
queryset = queryset.filter(pk__in=self.get_pk_list())
|
||||||
|
self.view_mode_multiple = True
|
||||||
|
|
||||||
|
# If none of those are defined, it's an error.
|
||||||
|
if pk is None and slug is None and pk_list is None:
|
||||||
|
raise AttributeError(
|
||||||
|
'View %s must be called with '
|
||||||
|
'either an object pk, a slug or an pk list.'
|
||||||
|
% self.__class__.__name__
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get the single item from the filtered queryset
|
||||||
|
queryset.get()
|
||||||
|
except queryset.model.MultipleObjectsReturned:
|
||||||
|
# Queryset has more than one item, this is good.
|
||||||
|
return queryset
|
||||||
|
except queryset.model.DoesNotExist:
|
||||||
|
raise Http404(
|
||||||
|
_('No %(verbose_name)s found matching the query') %
|
||||||
|
{'verbose_name': queryset.model._meta.verbose_name}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Queryset has one item, this is good.
|
||||||
|
return queryset
|
||||||
|
|
||||||
def get_pk_list(self):
|
def get_pk_list(self):
|
||||||
|
# Accept pk_list even on POST request to allowing direct requests
|
||||||
|
# to the view bypassing the initial GET request to submit the form.
|
||||||
|
# Example: when the view is called from a test or a custom UI
|
||||||
result = self.request.GET.get(
|
result = self.request.GET.get(
|
||||||
self.pk_list_key, self.request.POST.get(self.pk_list_key)
|
self.pk_list_key, self.request.POST.get(self.pk_list_key)
|
||||||
)
|
)
|
||||||
@@ -195,43 +238,6 @@ class MultipleObjectMixin(object):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
if self.queryset is not None:
|
|
||||||
queryset = self.queryset
|
|
||||||
if isinstance(queryset, QuerySet):
|
|
||||||
queryset = queryset.all()
|
|
||||||
elif self.model is not None:
|
|
||||||
queryset = self.model._default_manager.all()
|
|
||||||
|
|
||||||
pk = self.kwargs.get(self.pk_url_kwarg)
|
|
||||||
slug = self.kwargs.get(self.slug_url_kwarg)
|
|
||||||
pk_list = self.get_pk_list()
|
|
||||||
|
|
||||||
if pk is not None:
|
|
||||||
queryset = queryset.filter(pk=pk)
|
|
||||||
|
|
||||||
# Next, try looking up by slug.
|
|
||||||
if slug is not None and (pk is None or self.query_pk_and_slug):
|
|
||||||
slug_field = self.get_slug_field()
|
|
||||||
queryset = queryset.filter(**{slug_field: slug})
|
|
||||||
|
|
||||||
if pk_list is not None:
|
|
||||||
queryset = queryset.filter(pk__in=self.get_pk_list())
|
|
||||||
|
|
||||||
if pk is None and slug is None and pk_list is None:
|
|
||||||
raise AttributeError(
|
|
||||||
'Generic detail view %s must be called with '
|
|
||||||
'either an object pk, a slug or an id list.'
|
|
||||||
% self.__class__.__name__
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.object_permission:
|
|
||||||
return AccessControlList.objects.filter_by_access(
|
|
||||||
self.object_permission, self.request.user, queryset=queryset
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return queryset
|
|
||||||
|
|
||||||
|
|
||||||
class ObjectActionMixin(object):
|
class ObjectActionMixin(object):
|
||||||
"""
|
"""
|
||||||
@@ -275,34 +281,6 @@ class ObjectActionMixin(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ObjectListPermissionFilterMixin(object):
|
|
||||||
"""
|
|
||||||
access_object_retrieve_method is have the entire view check against
|
|
||||||
an object permission and not the individual secondary items.
|
|
||||||
"""
|
|
||||||
access_object_retrieve_method = None
|
|
||||||
object_permission = None
|
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
|
||||||
if self.access_object_retrieve_method and self.object_permission:
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=getattr(self, self.access_object_retrieve_method)(),
|
|
||||||
permissions=(self.object_permission,), user=request.user
|
|
||||||
)
|
|
||||||
return super(ObjectListPermissionFilterMixin, self).dispatch(request, *args, **kwargs)
|
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
queryset = super(ObjectListPermissionFilterMixin, self).get_queryset()
|
|
||||||
|
|
||||||
if not self.access_object_retrieve_method and self.object_permission:
|
|
||||||
return AccessControlList.objects.filter_by_access(
|
|
||||||
queryset=queryset, permission=self.object_permission,
|
|
||||||
user=self.request.user
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return queryset
|
|
||||||
|
|
||||||
|
|
||||||
class ObjectNameMixin(object):
|
class ObjectNameMixin(object):
|
||||||
def get_object_name(self, context=None):
|
def get_object_name(self, context=None):
|
||||||
if not context:
|
if not context:
|
||||||
@@ -319,6 +297,7 @@ class ObjectNameMixin(object):
|
|||||||
return object_name
|
return object_name
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: Remove this mixin and replace with restricted queryset
|
||||||
class ObjectPermissionCheckMixin(object):
|
class ObjectPermissionCheckMixin(object):
|
||||||
object_permission = None
|
object_permission = None
|
||||||
|
|
||||||
@@ -425,6 +404,12 @@ class RestrictedQuerysetMixin(object):
|
|||||||
|
|
||||||
|
|
||||||
class ViewPermissionCheckMixin(object):
|
class ViewPermissionCheckMixin(object):
|
||||||
|
"""
|
||||||
|
Restrict access to the view based on the user's direct permissions from
|
||||||
|
roles. This mixing is used for views whose objects don't support ACLs or
|
||||||
|
for views that perform actions that are not related to a specify object or
|
||||||
|
object's permission like maintenance views.
|
||||||
|
"""
|
||||||
view_permission = None
|
view_permission = None
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ class ObjectErrorLogEntryListView(SingleObjectListView):
|
|||||||
klass=content_type.model_class(), pk=self.kwargs['object_id']
|
klass=content_type.model_class(), pk=self.kwargs['object_id']
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_object().error_logs.all()
|
return self.get_object().error_logs.all()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -232,5 +232,5 @@ class TransformationListView(SingleObjectListView):
|
|||||||
'title': _('Transformations for: %s') % self.content_object,
|
'title': _('Transformations for: %s') % self.content_object,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return Transformation.objects.get_for_object(obj=self.content_object)
|
return Transformation.objects.get_for_object(obj=self.content_object)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class DependencyGroupEntryListView(SingleObjectListView):
|
|||||||
'title': _('Entries for dependency group: %s') % self.get_object(),
|
'title': _('Entries for dependency group: %s') % self.get_object(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_object().get_entries()
|
return self.get_object().get_entries()
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
@@ -75,7 +75,7 @@ class DependencyGroupListView(SingleObjectListView):
|
|||||||
'title': _('Dependency groups'),
|
'title': _('Dependency groups'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return DependencyGroup.get_all()
|
return DependencyGroup.get_all()
|
||||||
|
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ class DependencyGroupEntryDetailView(SingleObjectListView):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_dependency_group_entry().get_dependencies()
|
return self.get_dependency_group_entry().get_dependencies()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ class KeyQueryResultView(SingleObjectListView):
|
|||||||
'title': _('Key query results'),
|
'title': _('Key query results'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
term = self.request.GET.get('term')
|
term = self.request.GET.get('term')
|
||||||
if term:
|
if term:
|
||||||
return Key.objects.search(query=term)
|
return Key.objects.search(query=term)
|
||||||
@@ -156,7 +156,7 @@ class KeyUploadView(SingleObjectCreateView):
|
|||||||
|
|
||||||
class PrivateKeyListView(SingleObjectListView):
|
class PrivateKeyListView(SingleObjectListView):
|
||||||
object_permission = permission_key_view
|
object_permission = permission_key_view
|
||||||
queryset = Key.objects.private_keys()
|
source_queryset = Key.objects.private_keys()
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -179,7 +179,7 @@ class PrivateKeyListView(SingleObjectListView):
|
|||||||
|
|
||||||
class PublicKeyListView(SingleObjectListView):
|
class PublicKeyListView(SingleObjectListView):
|
||||||
object_permission = permission_key_view
|
object_permission = permission_key_view
|
||||||
queryset = Key.objects.public_keys()
|
source_queryset = Key.objects.public_keys()
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ class DocumentCommentListView(SingleObjectListView):
|
|||||||
'title': _('Comments for document: %s') % self.get_document(),
|
'title': _('Comments for document: %s') % self.get_document(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_document(), permissions=(permission_comment_view,),
|
obj=self.get_document(), permissions=(permission_comment_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
|
|||||||
@@ -96,6 +96,13 @@ class DocumentIndexingApp(MayanAppConfig):
|
|||||||
permission_document_indexing_view,
|
permission_document_indexing_view,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
ModelPermission.register_inheritance(
|
||||||
|
model=IndexTemplateNode, related='index'
|
||||||
|
)
|
||||||
|
|
||||||
|
ModelPermission.register_inheritance(
|
||||||
|
model=IndexInstanceNode, related='index_template_node__index'
|
||||||
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
attribute='label', is_identifier=True, is_sortable=True,
|
attribute='label', is_identifier=True, is_sortable=True,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class IndexViewTestCase(IndexTestMixin, IndexViewTestMixin, GenericDocumentViewT
|
|||||||
self._create_test_index()
|
self._create_test_index()
|
||||||
|
|
||||||
response = self._request_test_index_delete_view()
|
response = self._request_test_index_delete_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Index.objects.count(), 1)
|
self.assertEqual(Index.objects.count(), 1)
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ class IndexViewTestCase(IndexTestMixin, IndexViewTestMixin, GenericDocumentViewT
|
|||||||
self._create_test_index()
|
self._create_test_index()
|
||||||
|
|
||||||
response = self._request_test_index_edit_view()
|
response = self._request_test_index_edit_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.test_index.refresh_from_db()
|
self.test_index.refresh_from_db()
|
||||||
self.assertEqual(self.test_index.label, TEST_INDEX_LABEL)
|
self.assertEqual(self.test_index.label, TEST_INDEX_LABEL)
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ class SetupIndexTreeTemplateListView(SingleObjectListView):
|
|||||||
def get_index(self):
|
def get_index(self):
|
||||||
return get_object_or_404(klass=Index, pk=self.kwargs['pk'])
|
return get_object_or_404(klass=Index, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_index().template_root.get_descendants(
|
return self.get_index().template_root.get_descendants(
|
||||||
include_self=True
|
include_self=True
|
||||||
)
|
)
|
||||||
@@ -231,7 +231,6 @@ class TemplateNodeCreateView(SingleObjectCreateView):
|
|||||||
class TemplateNodeDeleteView(SingleObjectDeleteView):
|
class TemplateNodeDeleteView(SingleObjectDeleteView):
|
||||||
model = IndexTemplateNode
|
model = IndexTemplateNode
|
||||||
object_permission = permission_document_indexing_edit
|
object_permission = permission_document_indexing_edit
|
||||||
object_permission_related = 'index'
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -255,7 +254,6 @@ class TemplateNodeEditView(SingleObjectEditView):
|
|||||||
form_class = IndexTemplateNodeForm
|
form_class = IndexTemplateNodeForm
|
||||||
model = IndexTemplateNode
|
model = IndexTemplateNode
|
||||||
object_permission = permission_document_indexing_edit
|
object_permission = permission_document_indexing_edit
|
||||||
object_permission_related = 'index'
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -294,7 +292,7 @@ class IndexListView(SingleObjectListView):
|
|||||||
'title': _('Indexes'),
|
'title': _('Indexes'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
queryset = IndexInstance.objects.filter(enabled=True)
|
queryset = IndexInstance.objects.filter(enabled=True)
|
||||||
return queryset.filter(
|
return queryset.filter(
|
||||||
node_templates__index_instance_nodes__isnull=False
|
node_templates__index_instance_nodes__isnull=False
|
||||||
@@ -355,10 +353,10 @@ class IndexInstanceNodeView(DocumentListView):
|
|||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
if self.index_instance_node:
|
if self.index_instance_node:
|
||||||
if self.index_instance_node.index_template_node.link_documents:
|
if self.index_instance_node.index_template_node.link_documents:
|
||||||
return super(IndexInstanceNodeView, self).get_object_list()
|
return super(IndexInstanceNodeView, self).get_source_queryset()
|
||||||
else:
|
else:
|
||||||
self.object_permission = None
|
self.object_permission = None
|
||||||
return self.index_instance_node.get_children().order_by(
|
return self.index_instance_node.get_children().order_by(
|
||||||
@@ -374,7 +372,6 @@ class DocumentIndexNodeListView(SingleObjectListView):
|
|||||||
Show a list of indexes where the current document can be found
|
Show a list of indexes where the current document can be found
|
||||||
"""
|
"""
|
||||||
object_permission = permission_document_indexing_instance_view
|
object_permission = permission_document_indexing_instance_view
|
||||||
object_permission_related = 'index'
|
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
@@ -407,7 +404,7 @@ class DocumentIndexNodeListView(SingleObjectListView):
|
|||||||
) % self.get_document(),
|
) % self.get_document(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return DocumentIndexInstanceNode.objects.get_for(
|
return DocumentIndexInstanceNode.objects.get_for(
|
||||||
document=self.get_document()
|
document=self.get_document()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class DocumentContentViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_document_content_view_no_permissions(self):
|
def test_document_content_view_no_permissions(self):
|
||||||
response = self._request_document_content_view()
|
response = self._request_document_content_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_content_view_with_access(self):
|
def test_document_content_view_with_access(self):
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
@@ -51,7 +51,7 @@ class DocumentContentViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_document_page_content_view_no_permissions(self):
|
def test_document_page_content_view_no_permissions(self):
|
||||||
response = self._request_document_page_content_view()
|
response = self._request_document_page_content_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_page_content_view_with_access(self):
|
def test_document_page_content_view_with_access(self):
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
@@ -96,7 +96,7 @@ class DocumentContentViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_document_type_parsing_settings_view_no_permission(self):
|
def test_document_type_parsing_settings_view_no_permission(self):
|
||||||
response = self._request_test_document_type_parsing_settings()
|
response = self._request_test_document_type_parsing_settings()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_type_parsing_settings_view_with_access(self):
|
def test_document_type_parsing_settings_view_with_access(self):
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from mayan.apps.common.generics import (
|
|||||||
FormView, MultipleObjectConfirmActionView, SingleObjectDetailView,
|
FormView, MultipleObjectConfirmActionView, SingleObjectDetailView,
|
||||||
SingleObjectDownloadView, SingleObjectEditView, SingleObjectListView
|
SingleObjectDownloadView, SingleObjectEditView, SingleObjectListView
|
||||||
)
|
)
|
||||||
|
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||||
from mayan.apps.documents.forms import DocumentTypeFilteredSelectForm
|
from mayan.apps.documents.forms import DocumentTypeFilteredSelectForm
|
||||||
from mayan.apps.documents.models import Document, DocumentPage, DocumentType
|
from mayan.apps.documents.models import Document, DocumentPage, DocumentType
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ class DocumentParsingErrorsListView(SingleObjectListView):
|
|||||||
) % self.get_document(),
|
) % self.get_document(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_document().latest_version.parsing_errors.all()
|
return self.get_document().latest_version.parsing_errors.all()
|
||||||
|
|
||||||
|
|
||||||
@@ -136,19 +137,21 @@ class DocumentSubmitView(MultipleObjectConfirmActionView):
|
|||||||
instance.submit_for_parsing()
|
instance.submit_for_parsing()
|
||||||
|
|
||||||
|
|
||||||
class DocumentTypeSettingsEditView(SingleObjectEditView):
|
class DocumentTypeSettingsEditView(ExternalObjectMixin, SingleObjectEditView):
|
||||||
|
external_object_class = DocumentType
|
||||||
|
external_object_permission = permission_document_type_parsing_setup
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
fields = ('auto_parsing',)
|
fields = ('auto_parsing',)
|
||||||
object_permission = permission_document_type_parsing_setup
|
post_action_redirect = reverse_lazy(viewname='documents:document_type_list')
|
||||||
post_action_redirect = reverse_lazy('documents:document_type_list')
|
|
||||||
|
|
||||||
def get_document_type(self):
|
def get_document_type(self):
|
||||||
return get_object_or_404(klass=DocumentType, pk=self.kwargs['pk'])
|
return self.external_object
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'object': self.get_document_type(),
|
'object': self.get_document_type(),
|
||||||
'title': _(
|
'title': _(
|
||||||
'Edit parsing settings for document type: %s'
|
'Edit parsing settings for document type: %s.'
|
||||||
) % self.get_document_type()
|
) % self.get_document_type()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,5 +198,5 @@ class ParseErrorListView(SingleObjectListView):
|
|||||||
}
|
}
|
||||||
view_permission = permission_document_type_parsing_setup
|
view_permission = permission_document_type_parsing_setup
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return DocumentVersionParseError.objects.all()
|
return DocumentVersionParseError.objects.all()
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ class SignaturesViewTestCase(SignaturesTestMixin, GenericDocumentViewTestCase):
|
|||||||
self._create_test_detached_signature()
|
self._create_test_detached_signature()
|
||||||
|
|
||||||
response = self._request_document_version_signature_details_view()
|
response = self._request_document_version_signature_details_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_signature_detail_view_with_access(self):
|
def test_signature_detail_view_with_access(self):
|
||||||
self._create_test_key()
|
self._create_test_key()
|
||||||
@@ -186,7 +186,7 @@ class SignaturesViewTestCase(SignaturesTestMixin, GenericDocumentViewTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_version_signature_delete_view()
|
response = self._request_document_version_signature_delete_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
self.assertEqual(DetachedSignature.objects.count(), 1)
|
self.assertEqual(DetachedSignature.objects.count(), 1)
|
||||||
|
|
||||||
def test_signature_delete_view_with_access(self):
|
def test_signature_delete_view_with_access(self):
|
||||||
|
|||||||
@@ -232,7 +232,6 @@ class DocumentVersionEmbeddedSignatureCreateView(FormView):
|
|||||||
class DocumentVersionSignatureDeleteView(SingleObjectDeleteView):
|
class DocumentVersionSignatureDeleteView(SingleObjectDeleteView):
|
||||||
model = DetachedSignature
|
model = DetachedSignature
|
||||||
object_permission = permission_document_version_signature_delete
|
object_permission = permission_document_version_signature_delete
|
||||||
object_permission_related = 'document_version.document'
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -251,7 +250,6 @@ class DocumentVersionSignatureDeleteView(SingleObjectDeleteView):
|
|||||||
class DocumentVersionSignatureDetailView(SingleObjectDetailView):
|
class DocumentVersionSignatureDetailView(SingleObjectDetailView):
|
||||||
form_class = DocumentVersionSignatureDetailForm
|
form_class = DocumentVersionSignatureDetailForm
|
||||||
object_permission = permission_document_version_signature_view
|
object_permission = permission_document_version_signature_view
|
||||||
object_permission_related = 'document_version.document'
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -263,14 +261,13 @@ class DocumentVersionSignatureDetailView(SingleObjectDetailView):
|
|||||||
) % self.get_object(),
|
) % self.get_object(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_source_queryset(self):
|
||||||
return SignatureBaseModel.objects.select_subclasses()
|
return SignatureBaseModel.objects.select_subclasses()
|
||||||
|
|
||||||
|
|
||||||
class DocumentVersionSignatureDownloadView(SingleObjectDownloadView):
|
class DocumentVersionSignatureDownloadView(SingleObjectDownloadView):
|
||||||
model = DetachedSignature
|
model = DetachedSignature
|
||||||
object_permission = permission_document_version_signature_download
|
object_permission = permission_document_version_signature_download
|
||||||
object_permission_related = 'document_version.document'
|
|
||||||
|
|
||||||
def get_file(self):
|
def get_file(self):
|
||||||
signature = self.get_object()
|
signature = self.get_object()
|
||||||
@@ -335,7 +332,7 @@ class DocumentVersionSignatureListView(SingleObjectListView):
|
|||||||
) % self.get_document_version(),
|
) % self.get_document_version(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_document_version().signatures.all()
|
return self.get_document_version().signatures.all()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class WorkflowViewTestCase(WorkflowTestMixin, GenericViewTestCase):
|
|||||||
self._create_test_workflow()
|
self._create_test_workflow()
|
||||||
|
|
||||||
response = self._request_workflow_delete_view()
|
response = self._request_workflow_delete_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(self.test_workflow in Workflow.objects.all())
|
self.assertTrue(self.test_workflow in Workflow.objects.all())
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ class WorkflowViewTestCase(WorkflowTestMixin, GenericViewTestCase):
|
|||||||
self._create_test_workflow()
|
self._create_test_workflow()
|
||||||
|
|
||||||
response = self._request_workflow_edit_view()
|
response = self._request_workflow_edit_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
self.test_workflow.refresh_from_db()
|
self.test_workflow.refresh_from_db()
|
||||||
self.assertEqual(self.test_workflow.label, TEST_WORKFLOW_LABEL)
|
self.assertEqual(self.test_workflow.label, TEST_WORKFLOW_LABEL)
|
||||||
@@ -137,7 +137,7 @@ class WorkflowViewTestCase(WorkflowTestMixin, GenericViewTestCase):
|
|||||||
self._create_test_workflow()
|
self._create_test_workflow()
|
||||||
|
|
||||||
response = self._request_workflow_preview_view()
|
response = self._request_workflow_preview_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(self.test_workflow in Workflow.objects.all())
|
self.assertTrue(self.test_workflow in Workflow.objects.all())
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ class WorkflowStateViewTestCase(WorkflowTestMixin, GenericViewTestCase):
|
|||||||
self._create_test_workflow()
|
self._create_test_workflow()
|
||||||
|
|
||||||
response = self._request_workflow_state_create_view()
|
response = self._request_workflow_state_create_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEquals(WorkflowState.objects.count(), 0)
|
self.assertEquals(WorkflowState.objects.count(), 0)
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ class WorkflowStateViewTestCase(WorkflowTestMixin, GenericViewTestCase):
|
|||||||
self._create_test_workflow_states()
|
self._create_test_workflow_states()
|
||||||
|
|
||||||
response = self._request_workflow_state_delete_view()
|
response = self._request_workflow_state_delete_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEquals(WorkflowState.objects.count(), 2)
|
self.assertEquals(WorkflowState.objects.count(), 2)
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ class WorkflowStateViewTestCase(WorkflowTestMixin, GenericViewTestCase):
|
|||||||
workflow_state_label = self.test_workflow_state_1.label
|
workflow_state_label = self.test_workflow_state_1.label
|
||||||
|
|
||||||
response = self._request_workflow_state_edit_view()
|
response = self._request_workflow_state_edit_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
self.test_workflow_state_1.refresh_from_db()
|
self.test_workflow_state_1.refresh_from_db()
|
||||||
self.assertEquals(
|
self.assertEquals(
|
||||||
@@ -290,7 +290,7 @@ class WorkflowStateViewTestCase(WorkflowTestMixin, GenericViewTestCase):
|
|||||||
self._create_test_workflow_states()
|
self._create_test_workflow_states()
|
||||||
|
|
||||||
response = self._request_workflow_state_list_view()
|
response = self._request_workflow_state_list_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
def test_workflow_state_list_with_access(self):
|
def test_workflow_state_list_with_access(self):
|
||||||
self._create_test_workflow()
|
self._create_test_workflow()
|
||||||
@@ -357,7 +357,7 @@ class WorkflowTransitionViewTestCase(WorkflowTestMixin, GenericDocumentViewTestC
|
|||||||
self._create_test_workflow_states()
|
self._create_test_workflow_states()
|
||||||
|
|
||||||
response = self._request_workflow_transition_create_view()
|
response = self._request_workflow_transition_create_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEquals(WorkflowTransition.objects.count(), 0)
|
self.assertEquals(WorkflowTransition.objects.count(), 0)
|
||||||
|
|
||||||
@@ -392,13 +392,13 @@ class WorkflowTransitionViewTestCase(WorkflowTestMixin, GenericDocumentViewTestC
|
|||||||
kwargs={'pk': self.test_workflow_transition.pk}
|
kwargs={'pk': self.test_workflow_transition.pk}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_delete_workflow_transition_no_access(self):
|
def test_delete_workflow_transition_no_permissions(self):
|
||||||
self._create_test_workflow()
|
self._create_test_workflow()
|
||||||
self._create_test_workflow_states()
|
self._create_test_workflow_states()
|
||||||
self._create_test_workflow_transition()
|
self._create_test_workflow_transition()
|
||||||
|
|
||||||
response = self._request_workflow_transition_delete_view()
|
response = self._request_workflow_transition_delete_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
self.test_workflow_transition in WorkflowTransition.objects.all()
|
self.test_workflow_transition in WorkflowTransition.objects.all()
|
||||||
@@ -434,7 +434,7 @@ class WorkflowTransitionViewTestCase(WorkflowTestMixin, GenericDocumentViewTestC
|
|||||||
self._create_test_workflow_transition()
|
self._create_test_workflow_transition()
|
||||||
|
|
||||||
response = self._request_workflow_transition_edit_view()
|
response = self._request_workflow_transition_edit_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
self.test_workflow_transition.refresh_from_db()
|
self.test_workflow_transition.refresh_from_db()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -471,9 +471,10 @@ class WorkflowTransitionViewTestCase(WorkflowTestMixin, GenericDocumentViewTestC
|
|||||||
self._create_test_workflow_transition()
|
self._create_test_workflow_transition()
|
||||||
|
|
||||||
response = self._request_workflow_transition_list_view()
|
response = self._request_workflow_transition_list_view()
|
||||||
|
self.assertNotContains(
|
||||||
self.assertEquals(response.status_code, 200)
|
response=response, text=self.test_workflow_transition.label,
|
||||||
self.assertNotContains(response, text=self.test_workflow_transition.label)
|
status_code=404
|
||||||
|
)
|
||||||
|
|
||||||
def test_workflow_transition_list_with_access(self):
|
def test_workflow_transition_list_with_access(self):
|
||||||
self._create_test_workflow()
|
self._create_test_workflow()
|
||||||
@@ -485,8 +486,10 @@ class WorkflowTransitionViewTestCase(WorkflowTestMixin, GenericDocumentViewTestC
|
|||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_workflow_transition_list_view()
|
response = self._request_workflow_transition_list_view()
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertContains(
|
||||||
self.assertContains(response, text=self.test_workflow_transition.label)
|
response=response, text=self.test_workflow_transition.label,
|
||||||
|
status_code=200
|
||||||
|
)
|
||||||
|
|
||||||
def _request_workflow_transition(self):
|
def _request_workflow_transition(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
@@ -510,6 +513,7 @@ class WorkflowTransitionViewTestCase(WorkflowTestMixin, GenericDocumentViewTestC
|
|||||||
|
|
||||||
response = self._request_workflow_transition()
|
response = self._request_workflow_transition()
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
# Workflow should remain in the same initial state
|
# Workflow should remain in the same initial state
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.test_workflow_instance.get_current_state(),
|
self.test_workflow_instance.get_current_state(),
|
||||||
@@ -574,7 +578,7 @@ class WorkflowTransitionEventViewTestCase(WorkflowTestMixin, GenericDocumentView
|
|||||||
self._create_test_workflow_transition()
|
self._create_test_workflow_transition()
|
||||||
|
|
||||||
response = self._request_workflow_transition_event_list_view()
|
response = self._request_workflow_transition_event_list_view()
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 404)
|
||||||
|
|
||||||
def test_workflow_transition_event_list_with_access(self):
|
def test_workflow_transition_event_list_with_access(self):
|
||||||
self._create_test_workflow()
|
self._create_test_workflow()
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class DocumentWorkflowInstanceListView(SingleObjectListView):
|
|||||||
) % self.get_document(),
|
) % self.get_document(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_document().workflows.all()
|
return self.get_document().workflows.all()
|
||||||
|
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ class WorkflowInstanceDetailView(SingleObjectListView):
|
|||||||
'workflow_instance': self.get_workflow_instance(),
|
'workflow_instance': self.get_workflow_instance(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_workflow_instance().log_entries.order_by('-datetime')
|
return self.get_workflow_instance().log_entries.order_by('-datetime')
|
||||||
|
|
||||||
def get_workflow_instance(self):
|
def get_workflow_instance(self):
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class WorkflowListView(SingleObjectListView):
|
|||||||
'title': _('Workflows'),
|
'title': _('Workflows'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return WorkflowRuntimeProxy.objects.all()
|
return WorkflowRuntimeProxy.objects.all()
|
||||||
|
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ class WorkflowStateListView(SingleObjectListView):
|
|||||||
'title': _('States of workflow: %s') % self.get_workflow()
|
'title': _('States of workflow: %s') % self.get_workflow()
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return WorkflowStateRuntimeProxy.objects.filter(
|
return WorkflowStateRuntimeProxy.objects.filter(
|
||||||
workflow=self.get_workflow()
|
workflow=self.get_workflow()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,20 +3,19 @@ from __future__ import absolute_import, unicode_literals
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.utils import IntegrityError
|
|
||||||
from django.http import Http404, HttpResponseRedirect
|
from django.http import Http404, HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from mayan.apps.acls.models import AccessControlList
|
|
||||||
from mayan.apps.common.generics import (
|
from mayan.apps.common.generics import (
|
||||||
AddRemoveView, ConfirmView, FormView, SingleObjectCreateView,
|
AddRemoveView, ConfirmView, FormView, SingleObjectCreateView,
|
||||||
SingleObjectDeleteView, SingleObjectDetailView,
|
SingleObjectDeleteView, SingleObjectDetailView,
|
||||||
SingleObjectDynamicFormCreateView, SingleObjectDynamicFormEditView,
|
SingleObjectDynamicFormCreateView, SingleObjectDynamicFormEditView,
|
||||||
SingleObjectDownloadView, SingleObjectEditView, SingleObjectListView
|
SingleObjectDownloadView, SingleObjectEditView, SingleObjectListView
|
||||||
)
|
)
|
||||||
|
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||||
from mayan.apps.documents.events import event_document_type_edited
|
from mayan.apps.documents.events import event_document_type_edited
|
||||||
from mayan.apps.documents.models import DocumentType
|
from mayan.apps.documents.models import DocumentType
|
||||||
from mayan.apps.documents.permissions import permission_document_type_edit
|
from mayan.apps.documents.permissions import permission_document_type_edit
|
||||||
@@ -366,7 +365,7 @@ class SetupWorkflowStateActionListView(SingleObjectListView):
|
|||||||
def get_form_schema(self):
|
def get_form_schema(self):
|
||||||
return {'fields': self.get_class().fields}
|
return {'fields': self.get_class().fields}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_workflow_state().actions.all()
|
return self.get_workflow_state().actions.all()
|
||||||
|
|
||||||
def get_workflow_state(self):
|
def get_workflow_state(self):
|
||||||
@@ -403,7 +402,10 @@ class SetupWorkflowStateActionSelectionView(FormView):
|
|||||||
# Workflow states
|
# Workflow states
|
||||||
|
|
||||||
|
|
||||||
class SetupWorkflowStateCreateView(SingleObjectCreateView):
|
class SetupWorkflowStateCreateView(ExternalObjectMixin, SingleObjectCreateView):
|
||||||
|
external_object_class = Workflow
|
||||||
|
external_object_permission = permission_workflow_edit
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
form_class = WorkflowStateForm
|
form_class = WorkflowStateForm
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
@@ -414,34 +416,26 @@ class SetupWorkflowStateCreateView(SingleObjectCreateView):
|
|||||||
) % self.get_workflow()
|
) % self.get_workflow()
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_instance_extra_data(self):
|
||||||
|
return {'workflow': self.get_workflow()}
|
||||||
|
|
||||||
|
def get_source_queryset(self):
|
||||||
return self.get_workflow().states.all()
|
return self.get_workflow().states.all()
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse(
|
return reverse(
|
||||||
viewname='document_states:setup_workflow_state_list', kwargs={
|
viewname='document_states:setup_workflow_state_list',
|
||||||
'pk': self.kwargs['pk']
|
kwargs={'pk': self.kwargs['pk']}
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_workflow(self):
|
def get_workflow(self):
|
||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
return self.get_external_object()
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=workflow, permissions=(permission_workflow_edit,),
|
|
||||||
user=self.request.user
|
|
||||||
)
|
|
||||||
return workflow
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
self.object = form.save(commit=False)
|
|
||||||
self.object.workflow = self.get_workflow()
|
|
||||||
self.object.save()
|
|
||||||
return super(SetupWorkflowStateCreateView, self).form_valid(form)
|
|
||||||
|
|
||||||
|
|
||||||
class SetupWorkflowStateDeleteView(SingleObjectDeleteView):
|
class SetupWorkflowStateDeleteView(SingleObjectDeleteView):
|
||||||
model = WorkflowState
|
model = WorkflowState
|
||||||
object_permission = permission_workflow_edit
|
object_permission = permission_workflow_edit
|
||||||
|
pk_url_kwarg = 'pk'
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -450,28 +444,18 @@ class SetupWorkflowStateDeleteView(SingleObjectDeleteView):
|
|||||||
'workflow_instance': self.get_object().workflow,
|
'workflow_instance': self.get_object().workflow,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
|
||||||
return self.get_workflow().states.all()
|
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse(
|
return reverse(
|
||||||
viewname='document_states:setup_workflow_state_list',
|
viewname='document_states:setup_workflow_state_list',
|
||||||
kwargs={'pk': self.get_object().workflow.pk}
|
kwargs={'pk': self.get_object().workflow.pk}
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_workflow(self):
|
|
||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=workflow, permissions=(permission_workflow_edit,),
|
|
||||||
user=self.request.user
|
|
||||||
)
|
|
||||||
return workflow
|
|
||||||
|
|
||||||
|
|
||||||
class SetupWorkflowStateEditView(SingleObjectEditView):
|
class SetupWorkflowStateEditView(SingleObjectEditView):
|
||||||
form_class = WorkflowStateForm
|
form_class = WorkflowStateForm
|
||||||
model = WorkflowState
|
model = WorkflowState
|
||||||
object_permission = permission_workflow_edit
|
object_permission = permission_workflow_edit
|
||||||
|
pk_url_kwarg = 'pk'
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -487,27 +471,19 @@ class SetupWorkflowStateEditView(SingleObjectEditView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class SetupWorkflowStateListView(SingleObjectListView):
|
class SetupWorkflowStateListView(ExternalObjectMixin, SingleObjectListView):
|
||||||
|
external_object_class = Workflow
|
||||||
|
external_object_permission = permission_workflow_view
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
object_permission = permission_workflow_view
|
object_permission = permission_workflow_view
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=self.get_workflow(), permissions=(permission_workflow_view,),
|
|
||||||
user=request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
return super(
|
|
||||||
SetupWorkflowStateListView, self
|
|
||||||
).dispatch(request, *args, **kwargs)
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'hide_link': True,
|
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'no_results_icon': icon_workflow_state,
|
'no_results_icon': icon_workflow_state,
|
||||||
'no_results_main_link': link_setup_workflow_state_create.resolve(
|
'no_results_main_link': link_setup_workflow_state_create.resolve(
|
||||||
context=RequestContext(
|
context=RequestContext(
|
||||||
request=self.request, dict_={'object': self.get_workflow()}
|
self.request, {'object': self.get_workflow()}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'no_results_text': _(
|
'no_results_text': _(
|
||||||
@@ -520,35 +496,22 @@ class SetupWorkflowStateListView(SingleObjectListView):
|
|||||||
'title': _('States of workflow: %s') % self.get_workflow()
|
'title': _('States of workflow: %s') % self.get_workflow()
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_workflow().states.all()
|
return self.get_workflow().states.all()
|
||||||
|
|
||||||
def get_workflow(self):
|
def get_workflow(self):
|
||||||
return get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
return self.get_external_object()
|
||||||
|
|
||||||
|
|
||||||
# Transitions
|
# Transitions
|
||||||
|
|
||||||
|
|
||||||
class SetupWorkflowTransitionCreateView(SingleObjectCreateView):
|
class SetupWorkflowTransitionCreateView(ExternalObjectMixin, SingleObjectCreateView):
|
||||||
|
external_object_class = Workflow
|
||||||
|
external_object_permission = permission_workflow_edit
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
form_class = WorkflowTransitionForm
|
form_class = WorkflowTransitionForm
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
self.object = form.save(commit=False)
|
|
||||||
self.object.workflow = self.get_workflow()
|
|
||||||
try:
|
|
||||||
self.object.save()
|
|
||||||
except IntegrityError:
|
|
||||||
messages.error(
|
|
||||||
message=_('Unable to save transition; integrity error.'),
|
|
||||||
request=self.request
|
|
||||||
)
|
|
||||||
return super(
|
|
||||||
SetupWorkflowTransitionCreateView, self
|
|
||||||
).form_invalid(form)
|
|
||||||
else:
|
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'object': self.get_workflow(),
|
'object': self.get_workflow(),
|
||||||
@@ -564,7 +527,10 @@ class SetupWorkflowTransitionCreateView(SingleObjectCreateView):
|
|||||||
kwargs['workflow'] = self.get_workflow()
|
kwargs['workflow'] = self.get_workflow()
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_instance_extra_data(self):
|
||||||
|
return {'workflow': self.get_workflow()}
|
||||||
|
|
||||||
|
def get_source_queryset(self):
|
||||||
return self.get_workflow().transitions.all()
|
return self.get_workflow().transitions.all()
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
@@ -574,17 +540,13 @@ class SetupWorkflowTransitionCreateView(SingleObjectCreateView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_workflow(self):
|
def get_workflow(self):
|
||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
return self.get_external_object()
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=workflow, permissions=(permission_workflow_edit,),
|
|
||||||
user=self.request.user
|
|
||||||
)
|
|
||||||
return workflow
|
|
||||||
|
|
||||||
|
|
||||||
class SetupWorkflowTransitionDeleteView(SingleObjectDeleteView):
|
class SetupWorkflowTransitionDeleteView(SingleObjectDeleteView):
|
||||||
model = WorkflowTransition
|
model = WorkflowTransition
|
||||||
object_permission = permission_workflow_edit
|
object_permission = permission_workflow_edit
|
||||||
|
pk_url_kwarg = 'pk'
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -604,6 +566,7 @@ class SetupWorkflowTransitionEditView(SingleObjectEditView):
|
|||||||
form_class = WorkflowTransitionForm
|
form_class = WorkflowTransitionForm
|
||||||
model = WorkflowTransition
|
model = WorkflowTransition
|
||||||
object_permission = permission_workflow_edit
|
object_permission = permission_workflow_edit
|
||||||
|
pk_url_kwarg = 'pk'
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -626,17 +589,19 @@ class SetupWorkflowTransitionEditView(SingleObjectEditView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class SetupWorkflowTransitionListView(SingleObjectListView):
|
class SetupWorkflowTransitionListView(ExternalObjectMixin, SingleObjectListView):
|
||||||
|
external_object_class = Workflow
|
||||||
|
external_object_permission = permission_workflow_view
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
object_permission = permission_workflow_view
|
object_permission = permission_workflow_view
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'hide_link': True,
|
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'no_results_icon': icon_workflow_transition,
|
'no_results_icon': icon_workflow_transition,
|
||||||
'no_results_main_link': link_setup_workflow_transition_create.resolve(
|
'no_results_main_link': link_setup_workflow_transition_create.resolve(
|
||||||
context=RequestContext(
|
context=RequestContext(
|
||||||
request=self.request, dict_={'object': self.get_workflow()}
|
self.request, {'object': self.get_workflow()}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'no_results_text': _(
|
'no_results_text': _(
|
||||||
@@ -652,24 +617,20 @@ class SetupWorkflowTransitionListView(SingleObjectListView):
|
|||||||
) % self.get_workflow()
|
) % self.get_workflow()
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_workflow().transitions.all()
|
return self.get_workflow().transitions.all()
|
||||||
|
|
||||||
def get_workflow(self):
|
def get_workflow(self):
|
||||||
return get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
return self.get_external_object()
|
||||||
|
|
||||||
|
|
||||||
class SetupWorkflowTransitionTriggerEventListView(FormView):
|
class SetupWorkflowTransitionTriggerEventListView(ExternalObjectMixin, FormView):
|
||||||
|
external_object_class = WorkflowTransition
|
||||||
|
external_object_permission = permission_workflow_edit
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
form_class = WorkflowTransitionTriggerEventRelationshipFormSet
|
form_class = WorkflowTransitionTriggerEventRelationshipFormSet
|
||||||
submodel = StoredEventType
|
|
||||||
|
|
||||||
def dispatch(self, *args, **kwargs):
|
def dispatch(self, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=self.get_object().workflow,
|
|
||||||
permissions=(permission_workflow_edit,),
|
|
||||||
user=self.request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
EventType.refresh()
|
EventType.refresh()
|
||||||
return super(
|
return super(
|
||||||
SetupWorkflowTransitionTriggerEventListView, self
|
SetupWorkflowTransitionTriggerEventListView, self
|
||||||
@@ -684,6 +645,7 @@ class SetupWorkflowTransitionTriggerEventListView(FormView):
|
|||||||
message=_(
|
message=_(
|
||||||
'Error updating workflow transition trigger events; %s'
|
'Error updating workflow transition trigger events; %s'
|
||||||
) % exception, request=self.request
|
) % exception, request=self.request
|
||||||
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
messages.success(
|
messages.success(
|
||||||
@@ -697,7 +659,7 @@ class SetupWorkflowTransitionTriggerEventListView(FormView):
|
|||||||
).form_valid(form=form)
|
).form_valid(form=form)
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
return get_object_or_404(klass=WorkflowTransition, pk=self.kwargs['pk'])
|
return self.get_external_object()
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_document_type_delete_view_no_permission(self):
|
def test_document_type_delete_view_no_permission(self):
|
||||||
response = self._request_document_type_delete()
|
response = self._request_document_type_delete()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(DocumentType.objects.count(), 1)
|
self.assertEqual(DocumentType.objects.count(), 1)
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
def test_document_type_edit_view_no_permission(self):
|
def test_document_type_edit_view_no_permission(self):
|
||||||
response = self._request_document_type_edit()
|
response = self._request_document_type_edit()
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
self.test_document_type.refresh_from_db()
|
self.test_document_type.refresh_from_db()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -123,7 +123,7 @@ class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, Gener
|
|||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_quick_label_create()
|
response = self._request_quick_label_create()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(self.test_document_type.filenames.count(), 0)
|
self.assertEqual(self.test_document_type.filenames.count(), 0)
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, Gener
|
|||||||
def test_document_type_quick_label_delete_no_access(self):
|
def test_document_type_quick_label_delete_no_access(self):
|
||||||
self._create_test_quick_label()
|
self._create_test_quick_label()
|
||||||
response = self._request_quick_label_delete()
|
response = self._request_quick_label_delete()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.test_document_type.filenames.count(), 1
|
self.test_document_type.filenames.count(), 1
|
||||||
@@ -178,7 +178,7 @@ class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, Gener
|
|||||||
self._create_test_quick_label()
|
self._create_test_quick_label()
|
||||||
|
|
||||||
response = self._request_quick_label_edit()
|
response = self._request_quick_label_edit()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.test_document_type_filename.refresh_from_db()
|
self.test_document_type_filename.refresh_from_db()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -212,7 +212,7 @@ class DocumentTypeQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, Gener
|
|||||||
self._create_test_quick_label()
|
self._create_test_quick_label()
|
||||||
|
|
||||||
response = self._request_quick_label_list_view()
|
response = self._request_quick_label_list_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_type_quick_label_list_with_access(self):
|
def test_document_type_quick_label_list_with_access(self):
|
||||||
self._create_test_quick_label()
|
self._create_test_quick_label()
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class DocumentVersionTestCase(DocumentVersionTestMixin, GenericDocumentViewTestC
|
|||||||
self._upload_new_version()
|
self._upload_new_version()
|
||||||
|
|
||||||
response = self._request_document_version_list_view()
|
response = self._request_document_version_list_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_version_list_with_access(self):
|
def test_document_version_list_with_access(self):
|
||||||
self._upload_new_version()
|
self._upload_new_version()
|
||||||
@@ -46,7 +46,7 @@ class DocumentVersionTestCase(DocumentVersionTestMixin, GenericDocumentViewTestC
|
|||||||
response = self._request_document_version_revert_view(
|
response = self._request_document_version_revert_view(
|
||||||
document_version=first_version
|
document_version=first_version
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(self.document.versions.count(), 2)
|
self.assertEqual(self.document.versions.count(), 2)
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_document_view_no_permissions(self):
|
def test_document_view_no_permissions(self):
|
||||||
response = self._request_document_properties_view()
|
response = self._request_document_properties_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_view_with_permissions(self):
|
def test_document_view_with_permissions(self):
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
@@ -84,7 +84,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
response = self._request_document_type_edit(
|
response = self._request_document_type_edit(
|
||||||
document_type=document_type_2
|
document_type=document_type_2
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
Document.objects.get(pk=self.test_document.pk).document_type,
|
Document.objects.get(pk=self.test_document.pk).document_type,
|
||||||
@@ -138,7 +138,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
response = self._request_multiple_document_type_edit(
|
response = self._request_multiple_document_type_edit(
|
||||||
document_type=document_type_2
|
document_type=document_type_2
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
Document.objects.first().document_type, self.test_document_type
|
Document.objects.first().document_type, self.test_document_type
|
||||||
@@ -327,7 +327,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
self.assertEqual(self.test_document.pages.count(), 0)
|
self.assertEqual(self.test_document.pages.count(), 0)
|
||||||
|
|
||||||
response = self._request_document_update_page_count_view()
|
response = self._request_document_update_page_count_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(self.test_document.pages.count(), 0)
|
self.assertEqual(self.test_document.pages.count(), 0)
|
||||||
|
|
||||||
@@ -356,7 +356,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
self.assertEqual(self.test_document.pages.count(), 0)
|
self.assertEqual(self.test_document.pages.count(), 0)
|
||||||
|
|
||||||
response = self._request_document_multiple_update_page_count_view()
|
response = self._request_document_multiple_update_page_count_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(self.test_document.pages.count(), 0)
|
self.assertEqual(self.test_document.pages.count(), 0)
|
||||||
|
|
||||||
@@ -397,7 +397,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_clear_transformations_view()
|
response = self._request_document_clear_transformations_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Transformation.objects.get_for_object(obj=document_page),
|
Transformation.objects.get_for_object(obj=document_page),
|
||||||
@@ -454,7 +454,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
self.grant_permission(permission=permission_document_view)
|
self.grant_permission(permission=permission_document_view)
|
||||||
|
|
||||||
response = self._request_document_multiple_clear_transformations()
|
response = self._request_document_multiple_clear_transformations()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Transformation.objects.get_for_object(obj=document_page),
|
Transformation.objects.get_for_object(obj=document_page),
|
||||||
(repr(transformation),)
|
(repr(transformation),)
|
||||||
@@ -578,7 +578,7 @@ class DocumentsQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericD
|
|||||||
self._create_test_quick_label()
|
self._create_test_quick_label()
|
||||||
|
|
||||||
response = self._request_document_quick_label_edit_view()
|
response = self._request_document_quick_label_edit_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_quick_label_with_access(self):
|
def test_document_quick_label_with_access(self):
|
||||||
self._create_test_quick_label()
|
self._create_test_quick_label()
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class DocumentEventsTestCase(GenericDocumentViewTestCase):
|
|||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
response = self._request_test_document_preview_view()
|
response = self._request_test_document_preview_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(list(Action.objects.any(obj=self.test_document)), [])
|
self.assertEqual(list(Action.objects.any(obj=self.test_document)), [])
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class FavoriteDocumentsTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_document_add_to_favorites_view_no_permission(self):
|
def test_document_add_to_favorites_view_no_permission(self):
|
||||||
response = self._request_document_add_to_favorites_view()
|
response = self._request_document_add_to_favorites_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
self.assertEqual(FavoriteDocument.objects.count(), 0)
|
self.assertEqual(FavoriteDocument.objects.count(), 0)
|
||||||
|
|
||||||
def test_document_add_to_favorites_view_with_access(self):
|
def test_document_add_to_favorites_view_with_access(self):
|
||||||
@@ -62,7 +62,7 @@ class FavoriteDocumentsTestCase(GenericDocumentViewTestCase):
|
|||||||
def test_document_remove_from_favorites_view_no_permission(self):
|
def test_document_remove_from_favorites_view_no_permission(self):
|
||||||
self._document_add_to_favorites()
|
self._document_add_to_favorites()
|
||||||
response = self._request_document_remove_from_favorites()
|
response = self._request_document_remove_from_favorites()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
self.assertEqual(FavoriteDocument.objects.count(), 1)
|
self.assertEqual(FavoriteDocument.objects.count(), 1)
|
||||||
|
|
||||||
def test_document_remove_from_favorites_view_with_access(self):
|
def test_document_remove_from_favorites_view_with_access(self):
|
||||||
|
|||||||
@@ -10,24 +10,25 @@ from .base import GenericDocumentViewTestCase
|
|||||||
|
|
||||||
|
|
||||||
class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
||||||
def _request_document_restore_view(self):
|
def _request_document_restore_get_view(self):
|
||||||
return self.post(
|
return self.get(
|
||||||
viewname='documents:document_restore', kwargs={
|
viewname='documents:document_restore', kwargs={
|
||||||
'pk': self.test_document.pk
|
'pk': self.test_document.pk
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_document_restore_view_no_permission(self):
|
def test_document_restore_get_view_no_permission(self):
|
||||||
self.test_document.delete()
|
self.test_document.delete()
|
||||||
self.assertEqual(Document.objects.count(), 0)
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
|
||||||
response = self._request_document_restore_view()
|
document_count = Document.objects.count()
|
||||||
self.assertEqual(response.status_code, 302)
|
|
||||||
|
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 1)
|
response = self._request_document_restore_get_view()
|
||||||
self.assertEqual(Document.objects.count(), 0)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_restore_view_with_access(self):
|
self.assertEqual(Document.objects.count(), document_count)
|
||||||
|
|
||||||
|
def test_document_restore_get_view_with_access(self):
|
||||||
self.test_document.delete()
|
self.test_document.delete()
|
||||||
self.assertEqual(Document.objects.count(), 0)
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
|
||||||
@@ -35,56 +36,118 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
|||||||
obj=self.test_document, permission=permission_document_restore
|
obj=self.test_document, permission=permission_document_restore
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_restore_view()
|
document_count = Document.objects.count()
|
||||||
|
|
||||||
|
response = self._request_document_restore_get_view()
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
self.assertEqual(Document.objects.count(), document_count)
|
||||||
|
|
||||||
|
def _request_document_restore_post_view(self):
|
||||||
|
return self.post(
|
||||||
|
viewname='documents:document_restore', kwargs={
|
||||||
|
'pk': self.test_document.pk
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_document_restore_post_view_no_permission(self):
|
||||||
|
self.test_document.delete()
|
||||||
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
|
||||||
|
response = self._request_document_restore_post_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
|
||||||
|
def test_document_restore_post_view_with_access(self):
|
||||||
|
self.test_document.delete()
|
||||||
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document, permission=permission_document_restore
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self._request_document_restore_post_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 0)
|
self.assertEqual(DeletedDocument.objects.count(), 0)
|
||||||
self.assertEqual(Document.objects.count(), 1)
|
self.assertEqual(Document.objects.count(), 1)
|
||||||
|
|
||||||
def _request_document_trash_view(self):
|
def _request_document_trash_get_view(self):
|
||||||
|
return self.get(
|
||||||
|
viewname='documents:document_trash', kwargs={
|
||||||
|
'pk': self.test_document.pk
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_document_trash_get_view_no_permissions(self):
|
||||||
|
document_count = Document.objects.count()
|
||||||
|
|
||||||
|
response = self._request_document_trash_get_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
self.assertEqual(Document.objects.count(), document_count)
|
||||||
|
|
||||||
|
def test_document_trash_get_view_with_access(self):
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document, permission=permission_document_trash
|
||||||
|
)
|
||||||
|
|
||||||
|
document_count = Document.objects.count()
|
||||||
|
|
||||||
|
response = self._request_document_trash_get_view()
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
self.assertEqual(Document.objects.count(), document_count)
|
||||||
|
|
||||||
|
def _request_document_trash_post_view(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='documents:document_trash', kwargs={
|
viewname='documents:document_trash', kwargs={
|
||||||
'pk': self.test_document.pk
|
'pk': self.test_document.pk
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_document_trash_no_permissions(self):
|
def test_document_trash_post_view_no_permissions(self):
|
||||||
response = self._request_document_trash_view()
|
response = self._request_document_trash_post_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 0)
|
self.assertEqual(DeletedDocument.objects.count(), 0)
|
||||||
self.assertEqual(Document.objects.count(), 1)
|
self.assertEqual(Document.objects.count(), 1)
|
||||||
|
|
||||||
def test_document_trash_with_access(self):
|
def test_document_trash_post_view_with_access(self):
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.test_document, permission=permission_document_trash
|
obj=self.test_document, permission=permission_document_trash
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_trash_view()
|
response = self._request_document_trash_post_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 1)
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
self.assertEqual(Document.objects.count(), 0)
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
|
||||||
def _request_document_delete_view(self):
|
def _request_document_delete_get_view(self):
|
||||||
return self.post(
|
return self.get(
|
||||||
viewname='documents:document_delete', kwargs={
|
viewname='documents:document_delete', kwargs={
|
||||||
'pk': self.test_document.pk
|
'pk': self.test_document.pk
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_document_delete_no_permissions(self):
|
def test_document_delete_get_view_no_permissions(self):
|
||||||
self.test_document.delete()
|
self.test_document.delete()
|
||||||
self.assertEqual(Document.objects.count(), 0)
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 1)
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
|
|
||||||
response = self._request_document_delete_view()
|
trashed_document_count = DeletedDocument.objects.count()
|
||||||
self.assertEqual(response.status_code, 302)
|
|
||||||
|
|
||||||
self.assertEqual(Document.objects.count(), 0)
|
response = self._request_document_delete_get_view()
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 1)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_delete_with_access(self):
|
self.assertEqual(
|
||||||
|
DeletedDocument.objects.count(), trashed_document_count
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_document_delete_get_view_with_access(self):
|
||||||
self.test_document.delete()
|
self.test_document.delete()
|
||||||
self.assertEqual(Document.objects.count(), 0)
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 1)
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
@@ -93,7 +156,43 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
|||||||
obj=self.test_document, permission=permission_document_delete
|
obj=self.test_document, permission=permission_document_delete
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_delete_view()
|
trashed_document_count = DeletedDocument.objects.count()
|
||||||
|
|
||||||
|
response = self._request_document_delete_get_view()
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
DeletedDocument.objects.count(), trashed_document_count
|
||||||
|
)
|
||||||
|
|
||||||
|
def _request_document_delete_post_view(self):
|
||||||
|
return self.post(
|
||||||
|
viewname='documents:document_delete', kwargs={
|
||||||
|
'pk': self.test_document.pk
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_document_delete_post_view_no_permissions(self):
|
||||||
|
self.test_document.delete()
|
||||||
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
|
|
||||||
|
response = self._request_document_delete_post_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
|
|
||||||
|
def test_document_delete_post_view_with_access(self):
|
||||||
|
self.test_document.delete()
|
||||||
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document, permission=permission_document_delete
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self._request_document_delete_post_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 0)
|
self.assertEqual(DeletedDocument.objects.count(), 0)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class DocumentPageListView(SingleObjectListView):
|
|||||||
'title': _('Pages for document: %s') % self.get_document(),
|
'title': _('Pages for document: %s') % self.get_document(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_document().pages.all()
|
return self.get_document().pages.all()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ from django.template import RequestContext
|
|||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from mayan.apps.acls.models import AccessControlList
|
|
||||||
from mayan.apps.common.generics import (
|
from mayan.apps.common.generics import (
|
||||||
SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView,
|
SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView,
|
||||||
SingleObjectListView
|
SingleObjectListView
|
||||||
)
|
)
|
||||||
|
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||||
|
|
||||||
from ..forms import DocumentTypeFilenameForm_create
|
from ..forms import DocumentTypeFilenameForm_create
|
||||||
from ..icons import (
|
from ..icons import (
|
||||||
@@ -133,22 +133,14 @@ class DocumentTypeEditView(SingleObjectEditView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class DocumentTypeFilenameCreateView(SingleObjectCreateView):
|
class DocumentTypeFilenameCreateView(ExternalObjectMixin, SingleObjectCreateView):
|
||||||
|
external_object_class = DocumentType
|
||||||
|
external_object_permission = permission_document_type_edit
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
form_class = DocumentTypeFilenameForm_create
|
form_class = DocumentTypeFilenameForm_create
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=self.get_document_type(),
|
|
||||||
permissions=(permission_document_type_edit,),
|
|
||||||
user=request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
return super(DocumentTypeFilenameCreateView, self).dispatch(
|
|
||||||
request, *args, **kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_document_type(self):
|
def get_document_type(self):
|
||||||
return get_object_or_404(klass=DocumentType, pk=self.kwargs['pk'])
|
return self.get_external_object()
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -163,10 +155,37 @@ class DocumentTypeFilenameCreateView(SingleObjectCreateView):
|
|||||||
return {'document_type': self.get_document_type()}
|
return {'document_type': self.get_document_type()}
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentTypeFilenameDeleteView(SingleObjectDeleteView):
|
||||||
|
model = DocumentTypeFilename
|
||||||
|
object_permission = permission_document_type_edit
|
||||||
|
pk_url_kwarg = 'pk'
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
return {
|
||||||
|
'document_type': self.get_object().document_type,
|
||||||
|
'filename': self.get_object(),
|
||||||
|
'navigation_object_list': ('document_type', 'filename',),
|
||||||
|
'title': _(
|
||||||
|
'Delete the quick label: %(label)s, from document type '
|
||||||
|
'"%(document_type)s"?'
|
||||||
|
) % {
|
||||||
|
'document_type': self.get_object().document_type,
|
||||||
|
'label': self.get_object()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_post_action_redirect(self):
|
||||||
|
return reverse(
|
||||||
|
viewname='documents:document_type_filename_list',
|
||||||
|
kwargs={'pk': self.get_object().document_type.pk}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DocumentTypeFilenameEditView(SingleObjectEditView):
|
class DocumentTypeFilenameEditView(SingleObjectEditView):
|
||||||
fields = ('enabled', 'filename',)
|
fields = ('enabled', 'filename',)
|
||||||
model = DocumentTypeFilename
|
model = DocumentTypeFilename
|
||||||
object_permission = permission_document_type_edit
|
object_permission = permission_document_type_edit
|
||||||
|
pk_url_kwarg = 'pk'
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
document_type_filename = self.get_object()
|
document_type_filename = self.get_object()
|
||||||
@@ -186,42 +205,18 @@ class DocumentTypeFilenameEditView(SingleObjectEditView):
|
|||||||
|
|
||||||
def get_post_action_redirect(self):
|
def get_post_action_redirect(self):
|
||||||
return reverse(
|
return reverse(
|
||||||
'documents:document_type_filename_list',
|
viewname='documents:document_type_filename_list',
|
||||||
args=(self.get_object().document_type.pk,)
|
kwargs={'pk': self.get_object().document_type.pk}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DocumentTypeFilenameDeleteView(SingleObjectDeleteView):
|
class DocumentTypeFilenameListView(ExternalObjectMixin, SingleObjectListView):
|
||||||
model = DocumentTypeFilename
|
external_object_class = DocumentType
|
||||||
object_permission = permission_document_type_edit
|
external_object_permission = permission_document_type_view
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
def get_extra_context(self):
|
|
||||||
return {
|
|
||||||
'document_type': self.get_object().document_type,
|
|
||||||
'filename': self.get_object(),
|
|
||||||
'navigation_object_list': ('document_type', 'filename',),
|
|
||||||
'title': _(
|
|
||||||
'Delete the quick label: %(label)s, from document type '
|
|
||||||
'"%(document_type)s"?'
|
|
||||||
) % {
|
|
||||||
'document_type': self.get_object().document_type,
|
|
||||||
'label': self.get_object()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_post_action_redirect(self):
|
|
||||||
return reverse(
|
|
||||||
'documents:document_type_filename_list',
|
|
||||||
args=(self.get_object().document_type.pk,)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentTypeFilenameListView(SingleObjectListView):
|
|
||||||
access_object_retrieve_method = 'get_document_type'
|
|
||||||
object_permission = permission_document_type_view
|
|
||||||
|
|
||||||
def get_document_type(self):
|
def get_document_type(self):
|
||||||
return get_object_or_404(klass=DocumentType, pk=self.kwargs['pk'])
|
return self.get_external_object()
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -251,5 +246,5 @@ class DocumentTypeFilenameListView(SingleObjectListView):
|
|||||||
) % self.get_document_type(),
|
) % self.get_document_type(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_document_type().filenames.all()
|
return self.get_document_type().filenames.all()
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from mayan.apps.acls.models import AccessControlList
|
|||||||
from mayan.apps.common.generics import (
|
from mayan.apps.common.generics import (
|
||||||
ConfirmView, SingleObjectDetailView, SingleObjectListView
|
ConfirmView, SingleObjectDetailView, SingleObjectListView
|
||||||
)
|
)
|
||||||
|
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||||
|
|
||||||
from ..events import event_document_view
|
from ..events import event_document_view
|
||||||
from ..forms import DocumentVersionDownloadForm, DocumentVersionPreviewForm
|
from ..forms import DocumentVersionDownloadForm, DocumentVersionPreviewForm
|
||||||
@@ -22,71 +23,13 @@ from ..permissions import (
|
|||||||
from .document_views import DocumentDownloadFormView, DocumentDownloadView
|
from .document_views import DocumentDownloadFormView, DocumentDownloadView
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'DocumentVersionListView', 'DocumentVersionRevertView',
|
|
||||||
'DocumentVersionDownloadFormView', 'DocumentVersionDownloadView',
|
'DocumentVersionDownloadFormView', 'DocumentVersionDownloadView',
|
||||||
|
'DocumentVersionListView', 'DocumentVersionRevertView',
|
||||||
'DocumentVersionView'
|
'DocumentVersionView'
|
||||||
)
|
)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DocumentVersionListView(SingleObjectListView):
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
obj=self.get_document(),
|
|
||||||
permissions=(permission_document_version_view,),
|
|
||||||
user=request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
self.get_document().add_as_recent_document_for_user(request.user)
|
|
||||||
|
|
||||||
return super(
|
|
||||||
DocumentVersionListView, self
|
|
||||||
).dispatch(request, *args, **kwargs)
|
|
||||||
|
|
||||||
def get_document(self):
|
|
||||||
return get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
|
||||||
return {
|
|
||||||
'hide_object': True,
|
|
||||||
'list_as_items': True,
|
|
||||||
'object': self.get_document(),
|
|
||||||
'title': _('Versions of document: %s') % self.get_document(),
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_object_list(self):
|
|
||||||
return self.get_document().versions.order_by('-timestamp')
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentVersionRevertView(ConfirmView):
|
|
||||||
object_permission = permission_document_version_revert
|
|
||||||
object_permission_related = 'document'
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
|
||||||
return {
|
|
||||||
'message': _(
|
|
||||||
'All later version after this one will be deleted too.'
|
|
||||||
),
|
|
||||||
'object': self.get_object().document,
|
|
||||||
'title': _('Revert to this version?'),
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_object(self):
|
|
||||||
return get_object_or_404(klass=DocumentVersion, pk=self.kwargs['pk'])
|
|
||||||
|
|
||||||
def view_action(self):
|
|
||||||
try:
|
|
||||||
self.get_object().revert(_user=self.request.user)
|
|
||||||
messages.success(
|
|
||||||
self.request, _('Document version reverted successfully')
|
|
||||||
)
|
|
||||||
except Exception as exception:
|
|
||||||
messages.error(
|
|
||||||
self.request,
|
|
||||||
_('Error reverting document version; %s') % exception
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentVersionDownloadFormView(DocumentDownloadFormView):
|
class DocumentVersionDownloadFormView(DocumentDownloadFormView):
|
||||||
form_class = DocumentVersionDownloadForm
|
form_class = DocumentVersionDownloadForm
|
||||||
model = DocumentVersion
|
model = DocumentVersion
|
||||||
@@ -146,6 +89,61 @@ class DocumentVersionDownloadView(DocumentDownloadView):
|
|||||||
return self.get_object().mimetype
|
return self.get_object().mimetype
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentVersionListView(ExternalObjectMixin, SingleObjectListView):
|
||||||
|
external_object_class = Document
|
||||||
|
external_object_permission = permission_document_version_view
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
|
|
||||||
|
def get_document(self):
|
||||||
|
document = self.get_external_object()
|
||||||
|
document.add_as_recent_document_for_user(user=self.request.user)
|
||||||
|
return document
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
return {
|
||||||
|
'hide_object': True,
|
||||||
|
'list_as_items': True,
|
||||||
|
'object': self.get_document(),
|
||||||
|
'table_cell_container_classes': 'td-container-thumbnail',
|
||||||
|
'title': _('Versions of document: %s') % self.get_document(),
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_source_queryset(self):
|
||||||
|
return self.get_document().versions.order_by('-timestamp')
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentVersionRevertView(ExternalObjectMixin, ConfirmView):
|
||||||
|
external_object_class = DocumentVersion
|
||||||
|
external_object_permission = permission_document_version_revert
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
return {
|
||||||
|
'message': _(
|
||||||
|
'All later version after this one will be deleted too.'
|
||||||
|
),
|
||||||
|
'object': self.get_object().document,
|
||||||
|
'title': _('Revert to this version?'),
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return self.get_external_object()
|
||||||
|
|
||||||
|
def view_action(self):
|
||||||
|
try:
|
||||||
|
self.get_object().revert(_user=self.request.user)
|
||||||
|
messages.success(
|
||||||
|
message=_(
|
||||||
|
'Document version reverted successfully'
|
||||||
|
), request=self.request
|
||||||
|
)
|
||||||
|
except Exception as exception:
|
||||||
|
messages.error(
|
||||||
|
message=_('Error reverting document version; %s') % exception,
|
||||||
|
request=self.request
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DocumentVersionView(SingleObjectDetailView):
|
class DocumentVersionView(SingleObjectDetailView):
|
||||||
form_class = DocumentVersionPreviewForm
|
form_class = DocumentVersionPreviewForm
|
||||||
model = DocumentVersion
|
model = DocumentVersion
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class DocumentListView(SingleObjectListView):
|
|||||||
'title': _('All documents'),
|
'title': _('All documents'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_document_queryset()
|
return self.get_document_queryset()
|
||||||
|
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ class DocumentDuplicatesListView(DocumentListView):
|
|||||||
)
|
)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
try:
|
try:
|
||||||
return DuplicatedDocument.objects.get(
|
return DuplicatedDocument.objects.get(
|
||||||
document=self.get_document()
|
document=self.get_document()
|
||||||
|
|||||||
@@ -41,11 +41,11 @@ class DocumentTrashView(MultipleObjectConfirmActionView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
queryset = self.get_object_list()
|
queryset = self.get_queryset()
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
'title': ungettext(
|
'title': ungettext(
|
||||||
single='Move the selected document to the trash?',
|
singular='Move the selected document to the trash?',
|
||||||
plural='Move the selected documents to the trash?',
|
plural='Move the selected documents to the trash?',
|
||||||
number=queryset.count()
|
number=queryset.count()
|
||||||
)
|
)
|
||||||
@@ -72,7 +72,9 @@ class EmptyTrashCanView(ConfirmView):
|
|||||||
kwargs={'trashed_document_id': deleted_document.pk}
|
kwargs={'trashed_document_id': deleted_document.pk}
|
||||||
)
|
)
|
||||||
|
|
||||||
messages.success(self.request, _('Trash emptied successfully'))
|
messages.success(
|
||||||
|
message=_('Trash emptied successfully'), request=self.request
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TrashedDocumentDeleteView(MultipleObjectConfirmActionView):
|
class TrashedDocumentDeleteView(MultipleObjectConfirmActionView):
|
||||||
@@ -87,11 +89,11 @@ class TrashedDocumentDeleteView(MultipleObjectConfirmActionView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
queryset = self.get_object_list()
|
queryset = self.get_queryset()
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
'title': ungettext(
|
'title': ungettext(
|
||||||
single='Delete the selected trashed document?',
|
singular='Delete the selected trashed document?',
|
||||||
plural='Delete the selected trashed documents?',
|
plural='Delete the selected trashed documents?',
|
||||||
number=queryset.count()
|
number=queryset.count()
|
||||||
)
|
)
|
||||||
@@ -147,11 +149,11 @@ class TrashedDocumentRestoreView(MultipleObjectConfirmActionView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
queryset = self.get_object_list()
|
queryset = self.get_queryset()
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
'title': ungettext(
|
'title': ungettext(
|
||||||
single='Restore the selected trashed document?',
|
singular='Restore the selected trashed document?',
|
||||||
plural='Restore the selected trashed documents?',
|
plural='Restore the selected trashed documents?',
|
||||||
number=queryset.count()
|
number=queryset.count()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class ResultsView(SearchModelMixin, SingleObjectListView):
|
|||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
self.search_model = self.get_search_model()
|
self.search_model = self.get_search_model()
|
||||||
|
|
||||||
if self.request.GET:
|
if self.request.GET:
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class EventListView(SingleObjectListView):
|
|||||||
'title': _('Events'),
|
'title': _('Events'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return Action.objects.all()
|
return Action.objects.all()
|
||||||
|
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ class NotificationListView(SingleObjectListView):
|
|||||||
'title': _('Notifications'),
|
'title': _('Notifications'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.request.user.notifications.all()
|
return self.request.user.notifications.all()
|
||||||
|
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ class ObjectEventListView(EventListView):
|
|||||||
klass=queryset, pk=self.kwargs['object_id']
|
klass=queryset, pk=self.kwargs['object_id']
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return any_stream(self.object)
|
return any_stream(self.object)
|
||||||
|
|
||||||
|
|
||||||
@@ -281,5 +281,5 @@ class VerbEventListView(SingleObjectListView):
|
|||||||
) % EventType.get(name=self.kwargs['verb']),
|
) % EventType.get(name=self.kwargs['verb']),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return Action.objects.filter(verb=self.kwargs['verb'])
|
return Action.objects.filter(verb=self.kwargs['verb'])
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class FileMetadataViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
self.document.latest_version.file_metadata_drivers.all().delete()
|
self.document.latest_version.file_metadata_drivers.all().delete()
|
||||||
|
|
||||||
response = self._request_document_submit_view()
|
response = self._request_document_submit_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.document.latest_version.file_metadata_drivers.count(), 0
|
self.document.latest_version.file_metadata_drivers.count(), 0
|
||||||
@@ -103,7 +103,7 @@ class FileMetadataViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
self.document.latest_version.file_metadata_drivers.all().delete()
|
self.document.latest_version.file_metadata_drivers.all().delete()
|
||||||
|
|
||||||
response = self._request_multiple_document_submit_view()
|
response = self._request_multiple_document_submit_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.document.latest_version.file_metadata_drivers.count(), 0
|
self.document.latest_version.file_metadata_drivers.count(), 0
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class DocumentDriverListView(ExternalObjectMixin, SingleObjectListView):
|
|||||||
) % self.external_object,
|
) % self.external_object,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.external_object.latest_version.file_metadata_drivers.all()
|
return self.external_object.latest_version.file_metadata_drivers.all()
|
||||||
|
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ class DocumentVersionDriverEntryFileMetadataListView(ExternalObjectMixin, Single
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.external_object.entries.all()
|
return self.external_object.entries.all()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class SmartLinkViewTestCase(SmartLinkTestMixin, SmartLinkViewTestMixin, GenericV
|
|||||||
self._create_test_smart_link()
|
self._create_test_smart_link()
|
||||||
|
|
||||||
response = self._request_test_smart_link_delete_view()
|
response = self._request_test_smart_link_delete_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(SmartLink.objects.count(), 1)
|
self.assertEqual(SmartLink.objects.count(), 1)
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ class SmartLinkViewTestCase(SmartLinkTestMixin, SmartLinkViewTestMixin, GenericV
|
|||||||
self._create_test_smart_link()
|
self._create_test_smart_link()
|
||||||
|
|
||||||
response = self._request_test_smart_link_edit_view()
|
response = self._request_test_smart_link_edit_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.test_smart_link.refresh_from_db()
|
self.test_smart_link.refresh_from_db()
|
||||||
self.assertEqual(self.test_smart_link.label, TEST_SMART_LINK_LABEL)
|
self.assertEqual(self.test_smart_link.label, TEST_SMART_LINK_LABEL)
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ class SmartLinkListView(SingleObjectListView):
|
|||||||
'title': _('Smart links'),
|
'title': _('Smart links'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_smart_link_queryset()
|
return self.get_smart_link_queryset()
|
||||||
|
|
||||||
def get_smart_link_queryset(self):
|
def get_smart_link_queryset(self):
|
||||||
@@ -311,7 +311,7 @@ class SmartLinkConditionListView(SingleObjectListView):
|
|||||||
) % self.get_smart_link(),
|
) % self.get_smart_link(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_smart_link().conditions.all()
|
return self.get_smart_link().conditions.all()
|
||||||
|
|
||||||
def get_smart_link(self):
|
def get_smart_link(self):
|
||||||
|
|||||||
@@ -26,10 +26,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
self._create_test_user_mailer()
|
self._create_test_user_mailer()
|
||||||
|
|
||||||
response = self._request_test_document_link_send_view()
|
response = self._request_test_document_link_send_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
self.assertContains(
|
|
||||||
response=response, text='Select a valid choice', status_code=200
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_mail_link_view_with_access(self):
|
def test_mail_link_view_with_access(self):
|
||||||
self._create_test_user_mailer()
|
self._create_test_user_mailer()
|
||||||
@@ -41,7 +38,9 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
obj=self.test_user_mailer, permission=permission_user_mailer_use
|
obj=self.test_user_mailer, permission=permission_user_mailer_use
|
||||||
)
|
)
|
||||||
|
|
||||||
self._request_test_document_link_send_view()
|
response = self._request_test_document_link_send_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
||||||
self.assertEqual(mail.outbox[0].to, [TEST_EMAIL_ADDRESS])
|
self.assertEqual(mail.outbox[0].to, [TEST_EMAIL_ADDRESS])
|
||||||
@@ -50,9 +49,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
self._create_test_user_mailer()
|
self._create_test_user_mailer()
|
||||||
|
|
||||||
response = self._request_test_document_send_view()
|
response = self._request_test_document_send_view()
|
||||||
self.assertContains(
|
self.assertEqual(response.status_code, 404)
|
||||||
response=response, text='Select a valid choice', status_code=200
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_mail_document_view_with_access(self):
|
def test_mail_document_view_with_access(self):
|
||||||
self._create_test_user_mailer()
|
self._create_test_user_mailer()
|
||||||
@@ -64,7 +61,9 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
obj=self.test_user_mailer, permission=permission_user_mailer_use
|
obj=self.test_user_mailer, permission=permission_user_mailer_use
|
||||||
)
|
)
|
||||||
|
|
||||||
self._request_test_document_send_view()
|
response = self._request_test_document_send_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
||||||
self.assertEqual(mail.outbox[0].to, [TEST_EMAIL_ADDRESS])
|
self.assertEqual(mail.outbox[0].to, [TEST_EMAIL_ADDRESS])
|
||||||
@@ -92,7 +91,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
self._create_test_user_mailer()
|
self._create_test_user_mailer()
|
||||||
|
|
||||||
response = self._request_test_user_mailer_delete_view()
|
response = self._request_test_user_mailer_delete_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
UserMailer.objects.all(), (repr(self.test_user_mailer),)
|
UserMailer.objects.all(), (repr(self.test_user_mailer),)
|
||||||
@@ -150,6 +149,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
|
|
||||||
response = self._request_test_user_mailer_test_view()
|
response = self._request_test_user_mailer_test_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
||||||
self.assertEqual(mail.outbox[0].to, [TEST_EMAIL_ADDRESS])
|
self.assertEqual(mail.outbox[0].to, [TEST_EMAIL_ADDRESS])
|
||||||
@@ -164,6 +164,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_COMMA
|
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_COMMA
|
||||||
response = self._request_test_user_mailer_test_view()
|
response = self._request_test_user_mailer_test_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -180,6 +181,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_MIXED
|
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_MIXED
|
||||||
response = self._request_test_user_mailer_test_view()
|
response = self._request_test_user_mailer_test_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -194,8 +196,10 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_SEMICOLON
|
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_SEMICOLON
|
||||||
|
|
||||||
response = self._request_test_user_mailer_test_view()
|
response = self._request_test_user_mailer_test_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
self.assertEqual(mail.outbox[0].from_email, TEST_EMAIL_FROM_ADDRESS)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -213,6 +217,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_COMMA
|
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_COMMA
|
||||||
|
|
||||||
response = self._request_test_document_link_send_view()
|
response = self._request_test_document_link_send_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
@@ -233,6 +238,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_MIXED
|
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_MIXED
|
||||||
|
|
||||||
response = self._request_test_document_link_send_view()
|
response = self._request_test_document_link_send_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
@@ -253,6 +259,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_SEMICOLON
|
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_SEMICOLON
|
||||||
|
|
||||||
response = self._request_test_document_link_send_view()
|
response = self._request_test_document_link_send_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
@@ -273,6 +280,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_COMMA
|
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_COMMA
|
||||||
|
|
||||||
response = self._request_test_document_send_view()
|
response = self._request_test_document_send_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
@@ -293,6 +301,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_MIXED
|
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_MIXED
|
||||||
|
|
||||||
response = self._request_test_document_send_view()
|
response = self._request_test_document_send_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
@@ -313,6 +322,7 @@ class MailerViewsTestCase(MailerTestMixin, MailerViewTestMixin, GenericDocumentV
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_SEMICOLON
|
self.test_email_address = TEST_RECIPIENTS_MULTIPLE_SEMICOLON
|
||||||
|
|
||||||
response = self._request_test_document_send_view()
|
response = self._request_test_document_send_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ class UserMailerLogEntryListView(SingleObjectListView):
|
|||||||
'title': _('%s error log') % self.get_user_mailer(),
|
'title': _('%s error log') % self.get_user_mailer(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_user_mailer().error_log.all()
|
return self.get_user_mailer().error_log.all()
|
||||||
|
|
||||||
def get_user_mailer(self):
|
def get_user_mailer(self):
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class NamespaceListView(SingleObjectListView):
|
|||||||
template_name = 'appearance/generic_list.html'
|
template_name = 'appearance/generic_list.html'
|
||||||
view_permission = permission_statistics_view
|
view_permission = permission_statistics_view
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return StatisticNamespace.get_all()
|
return StatisticNamespace.get_all()
|
||||||
|
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ class NamespaceDetailView(SingleObjectListView):
|
|||||||
def get_namespace(self):
|
def get_namespace(self):
|
||||||
return StatisticNamespace.get(slug=self.kwargs['slug'])
|
return StatisticNamespace.get(slug=self.kwargs['slug'])
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_namespace().statistics
|
return self.get_namespace().statistics
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ from mayan.apps.rest_api.permissions import MayanPermission
|
|||||||
|
|
||||||
from .models import MetadataType
|
from .models import MetadataType
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_metadata_document_add, permission_metadata_document_remove,
|
permission_document_metadata_add, permission_document_metadata_remove,
|
||||||
permission_metadata_document_edit, permission_metadata_document_view,
|
permission_document_metadata_edit, permission_document_metadata_view,
|
||||||
permission_metadata_type_create, permission_metadata_type_delete,
|
permission_metadata_type_create, permission_metadata_type_delete,
|
||||||
permission_metadata_type_edit, permission_metadata_type_view
|
permission_metadata_type_edit, permission_metadata_type_view
|
||||||
)
|
)
|
||||||
@@ -34,9 +34,9 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView):
|
|||||||
"""
|
"""
|
||||||
def get_document(self):
|
def get_document(self):
|
||||||
if self.request.method == 'GET':
|
if self.request.method == 'GET':
|
||||||
permission_required = permission_metadata_document_view
|
permission_required = permission_document_metadata_view
|
||||||
else:
|
else:
|
||||||
permission_required = permission_metadata_document_add
|
permission_required = permission_document_metadata_add
|
||||||
|
|
||||||
document = get_object_or_404(
|
document = get_object_or_404(
|
||||||
klass=Document, pk=self.kwargs['document_pk']
|
klass=Document, pk=self.kwargs['document_pk']
|
||||||
@@ -90,13 +90,13 @@ class APIDocumentMetadataView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
|
|
||||||
def get_document(self):
|
def get_document(self):
|
||||||
if self.request.method == 'GET':
|
if self.request.method == 'GET':
|
||||||
permission_required = permission_metadata_document_view
|
permission_required = permission_document_metadata_view
|
||||||
elif self.request.method == 'PUT':
|
elif self.request.method == 'PUT':
|
||||||
permission_required = permission_metadata_document_edit
|
permission_required = permission_document_metadata_edit
|
||||||
elif self.request.method == 'PATCH':
|
elif self.request.method == 'PATCH':
|
||||||
permission_required = permission_metadata_document_edit
|
permission_required = permission_document_metadata_edit
|
||||||
elif self.request.method == 'DELETE':
|
elif self.request.method == 'DELETE':
|
||||||
permission_required = permission_metadata_document_remove
|
permission_required = permission_document_metadata_remove
|
||||||
|
|
||||||
document = get_object_or_404(
|
document = get_object_or_404(
|
||||||
klass=Document, pk=self.kwargs['document_pk']
|
klass=Document, pk=self.kwargs['document_pk']
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ from .links import (
|
|||||||
link_setup_metadata_type_edit, link_setup_metadata_type_list,
|
link_setup_metadata_type_edit, link_setup_metadata_type_list,
|
||||||
)
|
)
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_metadata_document_add, permission_metadata_document_edit,
|
permission_document_metadata_add, permission_document_metadata_edit,
|
||||||
permission_metadata_document_remove, permission_metadata_document_view,
|
permission_document_metadata_remove, permission_document_metadata_view,
|
||||||
permission_metadata_type_delete, permission_metadata_type_edit,
|
permission_metadata_type_delete, permission_metadata_type_edit,
|
||||||
permission_metadata_type_view
|
permission_metadata_type_view
|
||||||
)
|
)
|
||||||
@@ -139,10 +139,10 @@ class MetadataApp(MayanAppConfig):
|
|||||||
|
|
||||||
ModelPermission.register(
|
ModelPermission.register(
|
||||||
model=Document, permissions=(
|
model=Document, permissions=(
|
||||||
permission_metadata_document_add,
|
permission_document_metadata_add,
|
||||||
permission_metadata_document_edit,
|
permission_document_metadata_edit,
|
||||||
permission_metadata_document_remove,
|
permission_document_metadata_remove,
|
||||||
permission_metadata_document_view,
|
permission_document_metadata_view,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ModelPermission.register(
|
ModelPermission.register(
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ from mayan.apps.documents.permissions import permission_document_type_edit
|
|||||||
from mayan.apps.navigation.classes import Link
|
from mayan.apps.navigation.classes import Link
|
||||||
|
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_metadata_document_add, permission_metadata_document_edit,
|
permission_document_metadata_add, permission_document_metadata_edit,
|
||||||
permission_metadata_document_remove, permission_metadata_document_view,
|
permission_document_metadata_remove, permission_document_metadata_view,
|
||||||
permission_metadata_type_create, permission_metadata_type_delete,
|
permission_metadata_type_create, permission_metadata_type_delete,
|
||||||
permission_metadata_type_edit, permission_metadata_type_view
|
permission_metadata_type_edit, permission_metadata_type_view
|
||||||
)
|
)
|
||||||
@@ -15,13 +15,13 @@ from .permissions import (
|
|||||||
link_metadata_add = Link(
|
link_metadata_add = Link(
|
||||||
args='object.pk',
|
args='object.pk',
|
||||||
icon_class_path='mayan.apps.metadata.icons.icon_document_metadata_add',
|
icon_class_path='mayan.apps.metadata.icons.icon_document_metadata_add',
|
||||||
permissions=(permission_metadata_document_add,), text=_('Add metadata'),
|
permissions=(permission_document_metadata_add,), text=_('Add metadata'),
|
||||||
view='metadata:metadata_add',
|
view='metadata:metadata_add',
|
||||||
)
|
)
|
||||||
link_metadata_edit = Link(
|
link_metadata_edit = Link(
|
||||||
args='object.pk',
|
args='object.pk',
|
||||||
icon_class_path='mayan.apps.metadata.icons.icon_document_metadata_edit',
|
icon_class_path='mayan.apps.metadata.icons.icon_document_metadata_edit',
|
||||||
permissions=(permission_metadata_document_edit,),
|
permissions=(permission_document_metadata_edit,),
|
||||||
text=_('Edit metadata'), view='metadata:metadata_edit'
|
text=_('Edit metadata'), view='metadata:metadata_edit'
|
||||||
)
|
)
|
||||||
link_metadata_multiple_add = Link(
|
link_metadata_multiple_add = Link(
|
||||||
@@ -39,13 +39,13 @@ link_metadata_multiple_remove = Link(
|
|||||||
link_metadata_remove = Link(
|
link_metadata_remove = Link(
|
||||||
args='object.pk',
|
args='object.pk',
|
||||||
icon_class_path='mayan.apps.metadata.icons.icon_document_metadata_remove',
|
icon_class_path='mayan.apps.metadata.icons.icon_document_metadata_remove',
|
||||||
permissions=(permission_metadata_document_remove,),
|
permissions=(permission_document_metadata_remove,),
|
||||||
text=_('Remove metadata'), view='metadata:metadata_remove',
|
text=_('Remove metadata'), view='metadata:metadata_remove',
|
||||||
)
|
)
|
||||||
link_metadata_view = Link(
|
link_metadata_view = Link(
|
||||||
args='resolved_object.pk',
|
args='resolved_object.pk',
|
||||||
icon_class_path='mayan.apps.metadata.icons.icon_document_metadata_view',
|
icon_class_path='mayan.apps.metadata.icons.icon_document_metadata_view',
|
||||||
permissions=(permission_metadata_document_view,), text=_('Metadata'),
|
permissions=(permission_document_metadata_view,), text=_('Metadata'),
|
||||||
view='metadata:metadata_view',
|
view='metadata:metadata_view',
|
||||||
)
|
)
|
||||||
link_setup_document_type_metadata_types = Link(
|
link_setup_document_type_metadata_types = Link(
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ from mayan.apps.permissions import PermissionNamespace
|
|||||||
|
|
||||||
namespace = PermissionNamespace(label=_('Metadata'), name='metadata')
|
namespace = PermissionNamespace(label=_('Metadata'), name='metadata')
|
||||||
|
|
||||||
permission_metadata_document_edit = namespace.add_permission(
|
permission_document_metadata_add = namespace.add_permission(
|
||||||
label=_('Edit a document\'s metadata'), name='metadata_document_edit'
|
|
||||||
)
|
|
||||||
permission_metadata_document_add = namespace.add_permission(
|
|
||||||
label=_('Add metadata to a document'), name='metadata_document_add'
|
label=_('Add metadata to a document'), name='metadata_document_add'
|
||||||
)
|
)
|
||||||
permission_metadata_document_remove = namespace.add_permission(
|
permission_document_metadata_edit = namespace.add_permission(
|
||||||
|
label=_('Edit a document\'s metadata'), name='metadata_document_edit'
|
||||||
|
)
|
||||||
|
permission_document_metadata_remove = namespace.add_permission(
|
||||||
label=_('Remove metadata from a document'),
|
label=_('Remove metadata from a document'),
|
||||||
name='metadata_document_remove'
|
name='metadata_document_remove'
|
||||||
)
|
)
|
||||||
permission_metadata_document_view = namespace.add_permission(
|
permission_document_metadata_view = namespace.add_permission(
|
||||||
label=_('View metadata from a document'), name='metadata_document_view'
|
label=_('View metadata from a document'), name='metadata_document_view'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ from .literals import (
|
|||||||
class MetadataTypeTestMixin(object):
|
class MetadataTypeTestMixin(object):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(MetadataTypeTestMixin, self).setUp()
|
super(MetadataTypeTestMixin, self).setUp()
|
||||||
self.metadata_type = MetadataType.objects.create(
|
self.test_metadata_type = MetadataType.objects.create(
|
||||||
name=TEST_METADATA_TYPE_NAME, label=TEST_METADATA_TYPE_LABEL
|
name=TEST_METADATA_TYPE_NAME, label=TEST_METADATA_TYPE_LABEL
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class MetadataTestsMixin(object):
|
class MetadataTestsMixin(object):
|
||||||
def _create_metadata_type(self):
|
def _create_test_metadata_type(self):
|
||||||
self.metadata_type = MetadataType.objects.create(
|
self.test_metadata_type = MetadataType.objects.create(
|
||||||
label=TEST_METADATA_TYPE_LABEL,
|
label=TEST_METADATA_TYPE_LABEL,
|
||||||
name=TEST_METADATA_TYPE_NAME
|
name=TEST_METADATA_TYPE_NAME
|
||||||
)
|
)
|
||||||
|
|
||||||
def _request_metadata_type_create_view(self):
|
def _request_test_metadata_type_create_view(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='metadata:setup_metadata_type_create', data={
|
viewname='metadata:setup_metadata_type_create', data={
|
||||||
'label': TEST_METADATA_TYPE_LABEL,
|
'label': TEST_METADATA_TYPE_LABEL,
|
||||||
@@ -31,30 +31,30 @@ class MetadataTestsMixin(object):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def _request_metadata_type_delete_view(self):
|
def _request_test_metadata_type_delete_view(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='metadata:setup_metadata_type_delete', kwargs={
|
viewname='metadata:setup_metadata_type_delete', kwargs={
|
||||||
'pk': self.metadata_type.pk
|
'pk': self.test_metadata_type.pk
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def _request_metadata_type_edit_view(self):
|
def _request_test_metadata_type_edit_view(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='metadata:setup_metadata_type_edit', kwargs={
|
viewname='metadata:setup_metadata_type_edit', kwargs={
|
||||||
'pk': self.metadata_type.pk
|
'pk': self.test_metadata_type.pk
|
||||||
}, data={
|
}, data={
|
||||||
'label': TEST_METADATA_TYPE_LABEL_EDITED,
|
'label': TEST_METADATA_TYPE_LABEL_EDITED,
|
||||||
'name': TEST_METADATA_TYPE_NAME_EDITED
|
'name': TEST_METADATA_TYPE_NAME_EDITED
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def _request_metadata_type_relationship_edit_view(self):
|
def _request_test_metadata_type_relationship_edit_view(self):
|
||||||
# This request assumes there is only one document type and
|
# This request assumes there is only one document type and
|
||||||
# blindly sets the first form of the formset.
|
# blindly sets the first form of the formset.
|
||||||
|
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='metadata:setup_metadata_type_document_types',
|
viewname='metadata:setup_metadata_type_document_types',
|
||||||
kwargs={'pk': self.metadata_type.pk}, data={
|
kwargs={'pk': self.test_metadata_type.pk}, data={
|
||||||
'form-TOTAL_FORMS': '1',
|
'form-TOTAL_FORMS': '1',
|
||||||
'form-INITIAL_FORMS': '0',
|
'form-INITIAL_FORMS': '0',
|
||||||
'form-0-relationship_type': 'required'
|
'form-0-relationship_type': 'required'
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ from mayan.apps.rest_api.tests import BaseAPITestCase
|
|||||||
|
|
||||||
from ..models import DocumentTypeMetadataType, MetadataType
|
from ..models import DocumentTypeMetadataType, MetadataType
|
||||||
from ..permissions import (
|
from ..permissions import (
|
||||||
permission_metadata_document_add, permission_metadata_document_edit,
|
permission_document_metadata_add, permission_document_metadata_edit,
|
||||||
permission_metadata_document_remove, permission_metadata_document_view,
|
permission_document_metadata_remove, permission_document_metadata_view,
|
||||||
permission_metadata_type_create, permission_metadata_type_delete,
|
permission_metadata_type_create, permission_metadata_type_delete,
|
||||||
permission_metadata_type_edit, permission_metadata_type_view
|
permission_metadata_type_edit, permission_metadata_type_view
|
||||||
)
|
)
|
||||||
@@ -24,12 +24,12 @@ from .literals import (
|
|||||||
|
|
||||||
|
|
||||||
class MetadataTypeAPITestCase(BaseAPITestCase):
|
class MetadataTypeAPITestCase(BaseAPITestCase):
|
||||||
def _create_metadata_type(self):
|
def _create_test_metadata_type(self):
|
||||||
self.metadata_type = MetadataType.objects.create(
|
self.test_metadata_type = MetadataType.objects.create(
|
||||||
label=TEST_METADATA_TYPE_LABEL, name=TEST_METADATA_TYPE_NAME
|
label=TEST_METADATA_TYPE_LABEL, name=TEST_METADATA_TYPE_NAME
|
||||||
)
|
)
|
||||||
|
|
||||||
def _request_metadata_type_create_view(self):
|
def _request_test_metadata_type_create_view(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='rest_api:metadatatype-list', data={
|
viewname='rest_api:metadatatype-list', data={
|
||||||
'label': TEST_METADATA_TYPE_LABEL,
|
'label': TEST_METADATA_TYPE_LABEL,
|
||||||
@@ -38,13 +38,13 @@ class MetadataTypeAPITestCase(BaseAPITestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_metadata_type_create_no_permission(self):
|
def test_metadata_type_create_no_permission(self):
|
||||||
response = self._request_metadata_type_create_view()
|
response = self._request_test_metadata_type_create_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
self.assertEqual(MetadataType.objects.count(), 0)
|
self.assertEqual(MetadataType.objects.count(), 0)
|
||||||
|
|
||||||
def test_metadata_type_create_with_permission(self):
|
def test_metadata_type_create_with_permission(self):
|
||||||
self.grant_permission(permission=permission_metadata_type_create)
|
self.grant_permission(permission=permission_metadata_type_create)
|
||||||
response = self._request_metadata_type_create_view()
|
response = self._request_test_metadata_type_create_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
|
|
||||||
metadata_type = MetadataType.objects.first()
|
metadata_type = MetadataType.objects.first()
|
||||||
@@ -55,26 +55,26 @@ class MetadataTypeAPITestCase(BaseAPITestCase):
|
|||||||
self.assertEqual(metadata_type.label, TEST_METADATA_TYPE_LABEL)
|
self.assertEqual(metadata_type.label, TEST_METADATA_TYPE_LABEL)
|
||||||
self.assertEqual(metadata_type.name, TEST_METADATA_TYPE_NAME)
|
self.assertEqual(metadata_type.name, TEST_METADATA_TYPE_NAME)
|
||||||
|
|
||||||
def _request_metadata_type_delete_view(self):
|
def _request_test_metadata_type_delete_view(self):
|
||||||
return self.delete(
|
return self.delete(
|
||||||
viewname='rest_api:metadatatype-detail',
|
viewname='rest_api:metadatatype-detail',
|
||||||
kwargs={'metadata_type_pk': self.metadata_type.pk}
|
kwargs={'metadata_type_pk': self.test_metadata_type.pk}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_metadata_type_delete_no_access(self):
|
def test_metadata_type_delete_no_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
response = self._request_metadata_type_delete_view()
|
response = self._request_test_metadata_type_delete_view()
|
||||||
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
self.assertEqual(MetadataType.objects.count(), 1)
|
self.assertEqual(MetadataType.objects.count(), 1)
|
||||||
|
|
||||||
def test_metadata_type_delete_with_access(self):
|
def test_metadata_type_delete_with_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.metadata_type, permission=permission_metadata_type_delete
|
obj=self.test_metadata_type, permission=permission_metadata_type_delete
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_metadata_type_delete_view()
|
response = self._request_test_metadata_type_delete_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
self.assertEqual(MetadataType.objects.count(), 0)
|
self.assertEqual(MetadataType.objects.count(), 0)
|
||||||
@@ -82,19 +82,19 @@ class MetadataTypeAPITestCase(BaseAPITestCase):
|
|||||||
def _request_metadata_type_detail_view(self):
|
def _request_metadata_type_detail_view(self):
|
||||||
return self.get(
|
return self.get(
|
||||||
viewname='rest_api:metadatatype-detail',
|
viewname='rest_api:metadatatype-detail',
|
||||||
kwargs={'metadata_type_pk': self.metadata_type.pk}
|
kwargs={'metadata_type_pk': self.test_metadata_type.pk}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_metadata_type_detail_view_no_access(self):
|
def test_metadata_type_detail_view_no_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
|
|
||||||
response = self._request_metadata_type_detail_view()
|
response = self._request_metadata_type_detail_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
def test_metadata_type_detail_view_with_access(self):
|
def test_metadata_type_detail_view_with_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.metadata_type, permission=permission_metadata_type_view
|
obj=self.test_metadata_type, permission=permission_metadata_type_view
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_metadata_type_detail_view()
|
response = self._request_metadata_type_detail_view()
|
||||||
@@ -104,83 +104,83 @@ class MetadataTypeAPITestCase(BaseAPITestCase):
|
|||||||
response.data['label'], TEST_METADATA_TYPE_LABEL
|
response.data['label'], TEST_METADATA_TYPE_LABEL
|
||||||
)
|
)
|
||||||
|
|
||||||
def _request_metadata_type_edit_view_via_patch(self):
|
def _request_test_metadata_type_edit_view_via_patch(self):
|
||||||
return self.patch(
|
return self.patch(
|
||||||
viewname='rest_api:metadatatype-detail',
|
viewname='rest_api:metadatatype-detail',
|
||||||
kwargs={'metadata_type_pk': self.metadata_type.pk}, data={
|
kwargs={'metadata_type_pk': self.test_metadata_type.pk}, data={
|
||||||
'label': TEST_METADATA_TYPE_LABEL_2,
|
'label': TEST_METADATA_TYPE_LABEL_2,
|
||||||
'name': TEST_METADATA_TYPE_NAME_2
|
'name': TEST_METADATA_TYPE_NAME_2
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_metadata_type_patch_view_no_access(self):
|
def test_metadata_type_patch_view_no_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
|
|
||||||
response = self._request_metadata_type_edit_view_via_patch()
|
response = self._request_test_metadata_type_edit_view_via_patch()
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
self.metadata_type.refresh_from_db()
|
self.test_metadata_type.refresh_from_db()
|
||||||
self.assertEqual(self.metadata_type.label, TEST_METADATA_TYPE_LABEL)
|
self.assertEqual(self.test_metadata_type.label, TEST_METADATA_TYPE_LABEL)
|
||||||
self.assertEqual(self.metadata_type.name, TEST_METADATA_TYPE_NAME)
|
self.assertEqual(self.test_metadata_type.name, TEST_METADATA_TYPE_NAME)
|
||||||
|
|
||||||
def test_metadata_type_patch_view_with_access(self):
|
def test_metadata_type_patch_view_with_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.metadata_type, permission=permission_metadata_type_edit
|
obj=self.test_metadata_type, permission=permission_metadata_type_edit
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_metadata_type_edit_view_via_patch()
|
response = self._request_test_metadata_type_edit_view_via_patch()
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
self.metadata_type.refresh_from_db()
|
self.test_metadata_type.refresh_from_db()
|
||||||
self.assertEqual(self.metadata_type.label, TEST_METADATA_TYPE_LABEL_2)
|
self.assertEqual(self.test_metadata_type.label, TEST_METADATA_TYPE_LABEL_2)
|
||||||
self.assertEqual(self.metadata_type.name, TEST_METADATA_TYPE_NAME_2)
|
self.assertEqual(self.test_metadata_type.name, TEST_METADATA_TYPE_NAME_2)
|
||||||
|
|
||||||
def _request_metadata_type_edit_view_via_put(self):
|
def _request_test_metadata_type_edit_view_via_put(self):
|
||||||
return self.put(
|
return self.put(
|
||||||
viewname='rest_api:metadatatype-detail',
|
viewname='rest_api:metadatatype-detail',
|
||||||
kwargs={'metadata_type_pk': self.metadata_type.pk}, data={
|
kwargs={'metadata_type_pk': self.test_metadata_type.pk}, data={
|
||||||
'label': TEST_METADATA_TYPE_LABEL_2,
|
'label': TEST_METADATA_TYPE_LABEL_2,
|
||||||
'name': TEST_METADATA_TYPE_NAME_2
|
'name': TEST_METADATA_TYPE_NAME_2
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_metadata_type_put_view_no_access(self):
|
def test_metadata_type_put_view_no_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
response = self._request_metadata_type_edit_view_via_put()
|
response = self._request_test_metadata_type_edit_view_via_put()
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
self.metadata_type.refresh_from_db()
|
self.test_metadata_type.refresh_from_db()
|
||||||
self.assertEqual(self.metadata_type.label, TEST_METADATA_TYPE_LABEL)
|
self.assertEqual(self.test_metadata_type.label, TEST_METADATA_TYPE_LABEL)
|
||||||
self.assertEqual(self.metadata_type.name, TEST_METADATA_TYPE_NAME)
|
self.assertEqual(self.test_metadata_type.name, TEST_METADATA_TYPE_NAME)
|
||||||
|
|
||||||
def test_metadata_type_put_view_with_access(self):
|
def test_metadata_type_put_view_with_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.metadata_type, permission=permission_metadata_type_edit
|
obj=self.test_metadata_type, permission=permission_metadata_type_edit
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_metadata_type_edit_view_via_put()
|
response = self._request_test_metadata_type_edit_view_via_put()
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
self.metadata_type.refresh_from_db()
|
self.test_metadata_type.refresh_from_db()
|
||||||
self.assertEqual(self.metadata_type.label, TEST_METADATA_TYPE_LABEL_2)
|
self.assertEqual(self.test_metadata_type.label, TEST_METADATA_TYPE_LABEL_2)
|
||||||
self.assertEqual(self.metadata_type.name, TEST_METADATA_TYPE_NAME_2)
|
self.assertEqual(self.test_metadata_type.name, TEST_METADATA_TYPE_NAME_2)
|
||||||
|
|
||||||
def _request_metadata_type_list_view(self):
|
def _request_metadata_type_list_view(self):
|
||||||
return self.get(viewname='rest_api:metadatatype-list')
|
return self.get(viewname='rest_api:metadatatype-list')
|
||||||
|
|
||||||
def test_metadata_type_list_view_no_access(self):
|
def test_metadata_type_list_view_no_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
response = self._request_metadata_type_list_view()
|
response = self._request_metadata_type_list_view()
|
||||||
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
self.assertEqual(response.data['count'], 0)
|
self.assertEqual(response.data['count'], 0)
|
||||||
|
|
||||||
def test_metadata_type_list_view_with_access(self):
|
def test_metadata_type_list_view_with_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.metadata_type, permission=permission_metadata_type_view
|
obj=self.test_metadata_type, permission=permission_metadata_type_view
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_metadata_type_list_view()
|
response = self._request_metadata_type_list_view()
|
||||||
@@ -195,20 +195,20 @@ class DocumentTypeMetadataTypeAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(DocumentTypeMetadataTypeAPITestCase, self).setUp()
|
super(DocumentTypeMetadataTypeAPITestCase, self).setUp()
|
||||||
self.metadata_type = MetadataType.objects.create(
|
self.test_metadata_type = MetadataType.objects.create(
|
||||||
label=TEST_METADATA_TYPE_LABEL, name=TEST_METADATA_TYPE_NAME
|
label=TEST_METADATA_TYPE_LABEL, name=TEST_METADATA_TYPE_NAME
|
||||||
)
|
)
|
||||||
|
|
||||||
def _create_document_type_metadata_type(self):
|
def _create_document_type_metadata_type(self):
|
||||||
self.test_document_type_metadata_type = self.test_document_type.metadata.create(
|
self.test_document_type_metadata_type = self.test_document_type.metadata.create(
|
||||||
metadata_type=self.metadata_type, required=False
|
metadata_type=self.test_metadata_type, required=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def _request_document_type_metadata_type_create_view(self):
|
def _request_document_type_metadata_type_create_view(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='rest_api:documenttypemetadatatype-list',
|
viewname='rest_api:documenttypemetadatatype-list',
|
||||||
kwargs={'document_type_pk': self.test_document_type.pk}, data={
|
kwargs={'document_type_pk': self.test_document_type.pk}, data={
|
||||||
'metadata_type_pk': self.metadata_type.pk, 'required': False
|
'metadata_type_pk': self.test_metadata_type.pk, 'required': False
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -363,23 +363,23 @@ class DocumentTypeMetadataTypeAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
|||||||
class DocumentMetadataAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
class DocumentMetadataAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(DocumentMetadataAPITestCase, self).setUp()
|
super(DocumentMetadataAPITestCase, self).setUp()
|
||||||
self.metadata_type = MetadataType.objects.create(
|
self.test_metadata_type = MetadataType.objects.create(
|
||||||
label=TEST_METADATA_TYPE_LABEL, name=TEST_METADATA_TYPE_NAME
|
label=TEST_METADATA_TYPE_LABEL, name=TEST_METADATA_TYPE_NAME
|
||||||
)
|
)
|
||||||
self.test_document_type.metadata.create(
|
self.test_document_type.metadata.create(
|
||||||
metadata_type=self.metadata_type, required=False
|
metadata_type=self.test_metadata_type, required=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def _create_document_metadata(self):
|
def _create_document_metadata(self):
|
||||||
self.test_document_metadata = self.test_document.metadata.create(
|
self.test_document_metadata = self.test_document.metadata.create(
|
||||||
metadata_type=self.metadata_type, value=TEST_METADATA_VALUE
|
metadata_type=self.test_metadata_type, value=TEST_METADATA_VALUE
|
||||||
)
|
)
|
||||||
|
|
||||||
def _request_document_metadata_create_view(self):
|
def _request_document_metadata_create_view(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='rest_api:documentmetadata-list',
|
viewname='rest_api:documentmetadata-list',
|
||||||
kwargs={'document_pk': self.test_document.pk}, data={
|
kwargs={'document_pk': self.test_document.pk}, data={
|
||||||
'metadata_type_pk': self.metadata_type.pk,
|
'metadata_type_pk': self.test_metadata_type.pk,
|
||||||
'value': TEST_METADATA_VALUE
|
'value': TEST_METADATA_VALUE
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -392,7 +392,7 @@ class DocumentMetadataAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
|||||||
|
|
||||||
def test_document_metadata_create_view_with_access(self):
|
def test_document_metadata_create_view_with_access(self):
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.test_document, permission=permission_metadata_document_add
|
obj=self.test_document, permission=permission_document_metadata_add
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_metadata_create_view()
|
response = self._request_document_metadata_create_view()
|
||||||
@@ -400,21 +400,21 @@ class DocumentMetadataAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
|||||||
|
|
||||||
document_metadata = self.test_document.metadata.first()
|
document_metadata = self.test_document.metadata.first()
|
||||||
self.assertEqual(response.data['id'], document_metadata.pk)
|
self.assertEqual(response.data['id'], document_metadata.pk)
|
||||||
self.assertEqual(document_metadata.metadata_type, self.metadata_type)
|
self.assertEqual(document_metadata.metadata_type, self.test_metadata_type)
|
||||||
self.assertEqual(document_metadata.value, TEST_METADATA_VALUE)
|
self.assertEqual(document_metadata.value, TEST_METADATA_VALUE)
|
||||||
|
|
||||||
def test_document_metadata_create_duplicate_view(self):
|
def test_document_metadata_create_duplicate_view(self):
|
||||||
self._create_document_metadata()
|
self._create_document_metadata()
|
||||||
self.grant_permission(permission=permission_metadata_document_add)
|
self.grant_permission(permission=permission_document_metadata_add)
|
||||||
|
|
||||||
response = self._request_document_metadata_create_view()
|
response = self._request_document_metadata_create_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
self.assertEqual(list(response.data.keys())[0], 'non_field_errors')
|
self.assertEqual(list(response.data.keys())[0], 'non_field_errors')
|
||||||
|
|
||||||
def test_document_metadata_create_invalid_lookup_value_view(self):
|
def test_document_metadata_create_invalid_lookup_value_view(self):
|
||||||
self.metadata_type.lookup = 'invalid,lookup,values,on,purpose'
|
self.test_metadata_type.lookup = 'invalid,lookup,values,on,purpose'
|
||||||
self.metadata_type.save()
|
self.test_metadata_type.save()
|
||||||
self.grant_permission(permission=permission_metadata_document_add)
|
self.grant_permission(permission=permission_document_metadata_add)
|
||||||
|
|
||||||
response = self._request_document_metadata_create_view()
|
response = self._request_document_metadata_create_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||||
@@ -440,7 +440,7 @@ class DocumentMetadataAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
|||||||
self._create_document_metadata()
|
self._create_document_metadata()
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.test_document,
|
obj=self.test_document,
|
||||||
permission=permission_metadata_document_remove
|
permission=permission_document_metadata_remove
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_metadata_delete_view()
|
response = self._request_document_metadata_delete_view()
|
||||||
@@ -464,7 +464,7 @@ class DocumentMetadataAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
|||||||
self._create_document_metadata()
|
self._create_document_metadata()
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.test_document,
|
obj=self.test_document,
|
||||||
permission=permission_metadata_document_view
|
permission=permission_document_metadata_view
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_metadata_list_view()
|
response = self._request_document_metadata_list_view()
|
||||||
@@ -474,7 +474,7 @@ class DocumentMetadataAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.data['results'][0]['metadata_type']['id'],
|
response.data['results'][0]['metadata_type']['id'],
|
||||||
self.metadata_type.pk
|
self.test_metadata_type.pk
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.data['results'][0]['value'], TEST_METADATA_VALUE
|
response.data['results'][0]['value'], TEST_METADATA_VALUE
|
||||||
@@ -507,7 +507,7 @@ class DocumentMetadataAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
|||||||
self._create_document_metadata()
|
self._create_document_metadata()
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.test_document,
|
obj=self.test_document,
|
||||||
permission=permission_metadata_document_edit
|
permission=permission_document_metadata_edit
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_metadata_edit_view_via_patch()
|
response = self._request_document_metadata_edit_view_via_patch()
|
||||||
@@ -545,7 +545,7 @@ class DocumentMetadataAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
|||||||
self._create_document_metadata()
|
self._create_document_metadata()
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.test_document,
|
obj=self.test_document,
|
||||||
permission=permission_metadata_document_edit
|
permission=permission_document_metadata_edit
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_document_metadata_edit_view_via_put()
|
response = self._request_document_metadata_edit_view_via_put()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class MetadataTypeEventsTestCase(MetadataTestsMixin, GenericViewTestCase):
|
|||||||
def test_metadata_type_create_event_no_permissions(self):
|
def test_metadata_type_create_event_no_permissions(self):
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
response = self._request_metadata_type_create_view()
|
response = self._request_test_metadata_type_create_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
self.assertEqual(Action.objects.count(), 0)
|
self.assertEqual(Action.objects.count(), 0)
|
||||||
@@ -29,7 +29,7 @@ class MetadataTypeEventsTestCase(MetadataTestsMixin, GenericViewTestCase):
|
|||||||
|
|
||||||
self.grant_permission(permission=permission_metadata_type_create)
|
self.grant_permission(permission=permission_metadata_type_create)
|
||||||
|
|
||||||
response = self._request_metadata_type_create_view()
|
response = self._request_test_metadata_type_create_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
event = Action.objects.first()
|
event = Action.objects.first()
|
||||||
@@ -41,30 +41,30 @@ class MetadataTypeEventsTestCase(MetadataTestsMixin, GenericViewTestCase):
|
|||||||
self.assertEqual(event.verb, event_metadata_type_created.id)
|
self.assertEqual(event.verb, event_metadata_type_created.id)
|
||||||
|
|
||||||
def test_metadata_type_edit_event_no_permissions(self):
|
def test_metadata_type_edit_event_no_permissions(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
|
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
response = self._request_metadata_type_edit_view()
|
response = self._request_test_metadata_type_edit_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Action.objects.count(), 0)
|
self.assertEqual(Action.objects.count(), 0)
|
||||||
|
|
||||||
def test_metadata_type_edit_event_with_access(self):
|
def test_metadata_type_edit_event_with_access(self):
|
||||||
self._create_metadata_type()
|
self._create_test_metadata_type()
|
||||||
|
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.metadata_type, permission=permission_metadata_type_edit
|
obj=self.test_metadata_type, permission=permission_metadata_type_edit
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_metadata_type_edit_view()
|
response = self._request_test_metadata_type_edit_view()
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
event = Action.objects.first()
|
event = Action.objects.first()
|
||||||
|
|
||||||
self.assertEqual(event.actor, self._test_case_user)
|
self.assertEqual(event.actor, self._test_case_user)
|
||||||
self.assertEqual(event.target, self.metadata_type)
|
self.assertEqual(event.target, self.test_metadata_type)
|
||||||
self.assertEqual(event.verb, event_metadata_type_edited.id)
|
self.assertEqual(event.verb, event_metadata_type_edited.id)
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(MetadataTestCase, self).setUp()
|
super(MetadataTestCase, self).setUp()
|
||||||
self.test_document_type.metadata.create(
|
self.test_document_type.metadata.create(
|
||||||
metadata_type=self.metadata_type
|
metadata_type=self.test_metadata_type
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_no_default(self):
|
def test_no_default(self):
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type
|
document=self.test_document, metadata_type=self.test_metadata_type
|
||||||
)
|
)
|
||||||
|
|
||||||
document_metadata.full_clean()
|
document_metadata.full_clean()
|
||||||
@@ -35,11 +35,11 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
self.assertEqual(self.test_document.metadata_value_of.test, None)
|
self.assertEqual(self.test_document.metadata_value_of.test, None)
|
||||||
|
|
||||||
def test_default(self):
|
def test_default(self):
|
||||||
self.metadata_type.default = TEST_DEFAULT_VALUE
|
self.test_metadata_type.default = TEST_DEFAULT_VALUE
|
||||||
self.metadata_type.save()
|
self.test_metadata_type.save()
|
||||||
|
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type
|
document=self.test_document, metadata_type=self.test_metadata_type
|
||||||
)
|
)
|
||||||
|
|
||||||
document_metadata.full_clean()
|
document_metadata.full_clean()
|
||||||
@@ -50,11 +50,11 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_lookup_with_incorrect_value(self):
|
def test_lookup_with_incorrect_value(self):
|
||||||
self.metadata_type.lookup = TEST_LOOKUP_TEMPLATE
|
self.test_metadata_type.lookup = TEST_LOOKUP_TEMPLATE
|
||||||
self.metadata_type.save()
|
self.test_metadata_type.save()
|
||||||
|
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type,
|
document=self.test_document, metadata_type=self.test_metadata_type,
|
||||||
value=TEST_INCORRECT_LOOKUP_VALUE
|
value=TEST_INCORRECT_LOOKUP_VALUE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -64,11 +64,11 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
document_metadata.save()
|
document_metadata.save()
|
||||||
|
|
||||||
def test_lookup_with_correct_value(self):
|
def test_lookup_with_correct_value(self):
|
||||||
self.metadata_type.lookup = TEST_LOOKUP_TEMPLATE
|
self.test_metadata_type.lookup = TEST_LOOKUP_TEMPLATE
|
||||||
self.metadata_type.save()
|
self.test_metadata_type.save()
|
||||||
|
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type,
|
document=self.test_document, metadata_type=self.test_metadata_type,
|
||||||
value=TEST_CORRECT_LOOKUP_VALUE
|
value=TEST_CORRECT_LOOKUP_VALUE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -84,21 +84,21 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
Checks for GitLab issue #250
|
Checks for GitLab issue #250
|
||||||
Empty optional lookup metadata trigger validation error
|
Empty optional lookup metadata trigger validation error
|
||||||
"""
|
"""
|
||||||
self.metadata_type.lookup = TEST_LOOKUP_TEMPLATE
|
self.test_metadata_type.lookup = TEST_LOOKUP_TEMPLATE
|
||||||
self.metadata_type.save()
|
self.test_metadata_type.save()
|
||||||
|
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type
|
document=self.test_document, metadata_type=self.test_metadata_type
|
||||||
)
|
)
|
||||||
|
|
||||||
document_metadata.full_clean()
|
document_metadata.full_clean()
|
||||||
document_metadata.save()
|
document_metadata.save()
|
||||||
|
|
||||||
def test_validation(self):
|
def test_validation(self):
|
||||||
self.metadata_type.validation = TEST_DATE_VALIDATOR
|
self.test_metadata_type.validation = TEST_DATE_VALIDATOR
|
||||||
|
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type,
|
document=self.test_document, metadata_type=self.test_metadata_type,
|
||||||
value=TEST_INVALID_DATE
|
value=TEST_INVALID_DATE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -115,10 +115,10 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
self.assertEqual(self.test_document.metadata_value_of.test, TEST_VALID_DATE)
|
self.assertEqual(self.test_document.metadata_value_of.test, TEST_VALID_DATE)
|
||||||
|
|
||||||
def test_parsing(self):
|
def test_parsing(self):
|
||||||
self.metadata_type.parser = TEST_DATE_PARSER
|
self.test_metadata_type.parser = TEST_DATE_PARSER
|
||||||
|
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type,
|
document=self.test_document, metadata_type=self.test_metadata_type,
|
||||||
value=TEST_INVALID_DATE
|
value=TEST_INVALID_DATE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -140,53 +140,53 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
self.test_document_type.metadata.all().delete()
|
self.test_document_type.metadata.all().delete()
|
||||||
|
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
self.metadata_type.get_required_for(self.test_document_type)
|
self.test_metadata_type.get_required_for(self.test_document_type)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.test_document_type.metadata.create(
|
self.test_document_type.metadata.create(
|
||||||
metadata_type=self.metadata_type, required=False
|
metadata_type=self.test_metadata_type, required=False
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
self.metadata_type.get_required_for(self.test_document_type)
|
self.test_metadata_type.get_required_for(self.test_document_type)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.test_document_type.metadata.all().delete()
|
self.test_document_type.metadata.all().delete()
|
||||||
|
|
||||||
self.test_document_type.metadata.create(
|
self.test_document_type.metadata.create(
|
||||||
metadata_type=self.metadata_type, required=True
|
metadata_type=self.test_metadata_type, required=True
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
self.metadata_type.get_required_for(self.test_document_type)
|
self.test_metadata_type.get_required_for(self.test_document_type)
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_unicode_lookup(self):
|
def test_unicode_lookup(self):
|
||||||
# Should NOT return a ValidationError, otherwise test fails
|
# Should NOT return a ValidationError, otherwise test fails
|
||||||
self.metadata_type.lookup = '测试1,测试2,test1,test2'
|
self.test_metadata_type.lookup = '测试1,测试2,test1,test2'
|
||||||
self.metadata_type.save()
|
self.test_metadata_type.save()
|
||||||
self.metadata_type.validate_value(document_type=None, value='测试1')
|
self.test_metadata_type.validate_value(document_type=None, value='测试1')
|
||||||
|
|
||||||
def test_non_unicode_lookup(self):
|
def test_non_unicode_lookup(self):
|
||||||
# Should NOT return a ValidationError, otherwise test fails
|
# Should NOT return a ValidationError, otherwise test fails
|
||||||
self.metadata_type.lookup = 'test1,test2'
|
self.test_metadata_type.lookup = 'test1,test2'
|
||||||
self.metadata_type.save()
|
self.test_metadata_type.save()
|
||||||
self.metadata_type.validate_value(document_type=None, value='test1')
|
self.test_metadata_type.validate_value(document_type=None, value='test1')
|
||||||
|
|
||||||
def test_add_new_metadata_type_on_document_type_change(self):
|
def test_add_new_metadata_type_on_document_type_change(self):
|
||||||
"""
|
"""
|
||||||
When switching document types, add the required metadata of the new
|
When switching document types, add the required metadata of the new
|
||||||
document type, the value to the default of the metadata type.
|
document type, the value to the default of the metadata type.
|
||||||
"""
|
"""
|
||||||
self.metadata_type.default = TEST_DEFAULT_VALUE
|
self.test_metadata_type.default = TEST_DEFAULT_VALUE
|
||||||
self.metadata_type.save()
|
self.test_metadata_type.save()
|
||||||
|
|
||||||
self.test_document_type_2 = DocumentType.objects.create(
|
self.test_document_type_2 = DocumentType.objects.create(
|
||||||
label=TEST_DOCUMENT_TYPE_2_LABEL
|
label=TEST_DOCUMENT_TYPE_2_LABEL
|
||||||
)
|
)
|
||||||
|
|
||||||
self.test_document_type_2.metadata.create(
|
self.test_document_type_2.metadata.create(
|
||||||
metadata_type=self.metadata_type, required=True
|
metadata_type=self.test_metadata_type, required=True
|
||||||
)
|
)
|
||||||
|
|
||||||
self.test_document.set_document_type(document_type=self.test_document_type_2)
|
self.test_document.set_document_type(document_type=self.test_document_type_2)
|
||||||
@@ -202,7 +202,7 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
old and new document types
|
old and new document types
|
||||||
"""
|
"""
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type,
|
document=self.test_document, metadata_type=self.test_metadata_type,
|
||||||
value=TEST_DEFAULT_VALUE
|
value=TEST_DEFAULT_VALUE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
label=TEST_DOCUMENT_TYPE_2_LABEL
|
label=TEST_DOCUMENT_TYPE_2_LABEL
|
||||||
)
|
)
|
||||||
|
|
||||||
self.test_document_type_2.metadata.create(metadata_type=self.metadata_type)
|
self.test_document_type_2.metadata.create(metadata_type=self.test_metadata_type)
|
||||||
|
|
||||||
self.test_document.set_document_type(document_type=self.test_document_type_2)
|
self.test_document.set_document_type(document_type=self.test_document_type_2)
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
self.test_document.metadata.first().value, TEST_DEFAULT_VALUE
|
self.test_document.metadata.first().value, TEST_DEFAULT_VALUE
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.test_document.metadata.first().metadata_type, self.metadata_type
|
self.test_document.metadata.first().metadata_type, self.test_metadata_type
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_delete_metadata_value_on_document_type_change(self):
|
def test_delete_metadata_value_on_document_type_change(self):
|
||||||
@@ -231,7 +231,7 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
new document type
|
new document type
|
||||||
"""
|
"""
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type,
|
document=self.test_document, metadata_type=self.test_metadata_type,
|
||||||
value=TEST_DEFAULT_VALUE
|
value=TEST_DEFAULT_VALUE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -252,7 +252,7 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
new document type
|
new document type
|
||||||
"""
|
"""
|
||||||
document_metadata = DocumentMetadata(
|
document_metadata = DocumentMetadata(
|
||||||
document=self.test_document, metadata_type=self.metadata_type,
|
document=self.test_document, metadata_type=self.test_metadata_type,
|
||||||
value=TEST_DEFAULT_VALUE
|
value=TEST_DEFAULT_VALUE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.test_document_type_2.metadata.create(
|
self.test_document_type_2.metadata.create(
|
||||||
metadata_type=self.metadata_type, required=True
|
metadata_type=self.test_metadata_type, required=True
|
||||||
)
|
)
|
||||||
|
|
||||||
self.test_document.set_document_type(document_type=self.test_document_type_2)
|
self.test_document.set_document_type(document_type=self.test_document_type_2)
|
||||||
@@ -274,5 +274,5 @@ class MetadataTestCase(DocumentTestMixin, MetadataTypeTestMixin, BaseTestCase):
|
|||||||
self.test_document.metadata.first().value, TEST_DEFAULT_VALUE
|
self.test_document.metadata.first().value, TEST_DEFAULT_VALUE
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.test_document.metadata.first().metadata_type, self.metadata_type
|
self.test_document.metadata.first().metadata_type, self.test_metadata_type
|
||||||
)
|
)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -31,12 +31,12 @@ class DocumentUploadMetadataTestCase(MetadataTypeTestMixin, GenericDocumentViewT
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.test_document_type.metadata.create(
|
self.test_document_type.metadata.create(
|
||||||
metadata_type=self.metadata_type, required=True
|
metadata_type=self.test_metadata_type, required=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_upload_interactive_with_unicode_metadata(self):
|
def test_upload_interactive_with_unicode_metadata(self):
|
||||||
url = furl(reverse('sources:upload_interactive'))
|
url = furl(reverse('sources:upload_interactive'))
|
||||||
url.args['metadata0_id'] = self.metadata_type.pk
|
url.args['metadata0_id'] = self.test_metadata_type.pk
|
||||||
url.args['metadata0_value'] = TEST_METADATA_VALUE_UNICODE
|
url.args['metadata0_value'] = TEST_METADATA_VALUE_UNICODE
|
||||||
|
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
@@ -61,7 +61,7 @@ class DocumentUploadMetadataTestCase(MetadataTypeTestMixin, GenericDocumentViewT
|
|||||||
|
|
||||||
def test_upload_interactive_with_ampersand_metadata(self):
|
def test_upload_interactive_with_ampersand_metadata(self):
|
||||||
url = furl(reverse('sources:upload_interactive'))
|
url = furl(reverse('sources:upload_interactive'))
|
||||||
url.args['metadata0_id'] = self.metadata_type.pk
|
url.args['metadata0_id'] = self.test_metadata_type.pk
|
||||||
url.args['metadata0_value'] = TEST_METADATA_VALUE_WITH_AMPERSAND
|
url.args['metadata0_value'] = TEST_METADATA_VALUE_WITH_AMPERSAND
|
||||||
|
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ from .links import (
|
|||||||
)
|
)
|
||||||
from .models import DocumentMetadata, MetadataType
|
from .models import DocumentMetadata, MetadataType
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_metadata_document_add, permission_metadata_document_edit,
|
permission_document_metadata_add, permission_document_metadata_edit,
|
||||||
permission_metadata_document_remove, permission_metadata_document_view,
|
permission_document_metadata_remove, permission_document_metadata_view,
|
||||||
permission_metadata_type_create, permission_metadata_type_delete,
|
permission_metadata_type_create, permission_metadata_type_delete,
|
||||||
permission_metadata_type_edit, permission_metadata_type_view
|
permission_metadata_type_edit, permission_metadata_type_view
|
||||||
)
|
)
|
||||||
@@ -47,7 +47,7 @@ from .permissions import (
|
|||||||
class DocumentMetadataAddView(MultipleObjectFormActionView):
|
class DocumentMetadataAddView(MultipleObjectFormActionView):
|
||||||
form_class = DocumentAddMetadataForm
|
form_class = DocumentAddMetadataForm
|
||||||
model = Document
|
model = Document
|
||||||
object_permission = permission_metadata_document_add
|
object_permission = permission_document_metadata_add
|
||||||
success_message = _('Metadata add request performed on %(count)d document')
|
success_message = _('Metadata add request performed on %(count)d document')
|
||||||
success_message_plural = _(
|
success_message_plural = _(
|
||||||
'Metadata add request performed on %(count)d documents'
|
'Metadata add request performed on %(count)d documents'
|
||||||
@@ -213,7 +213,7 @@ class DocumentMetadataAddView(MultipleObjectFormActionView):
|
|||||||
class DocumentMetadataEditView(MultipleObjectFormActionView):
|
class DocumentMetadataEditView(MultipleObjectFormActionView):
|
||||||
form_class = DocumentMetadataFormSet
|
form_class = DocumentMetadataFormSet
|
||||||
model = Document
|
model = Document
|
||||||
object_permission = permission_metadata_document_edit
|
object_permission = permission_document_metadata_edit
|
||||||
success_message = _(
|
success_message = _(
|
||||||
'Metadata edit request performed on %(count)d document'
|
'Metadata edit request performed on %(count)d document'
|
||||||
)
|
)
|
||||||
@@ -398,7 +398,7 @@ class DocumentMetadataListView(SingleObjectListView):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_document(),
|
obj=self.get_document(),
|
||||||
permissions=(permission_metadata_document_view,),
|
permissions=(permission_document_metadata_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -431,14 +431,14 @@ class DocumentMetadataListView(SingleObjectListView):
|
|||||||
'title': _('Metadata for document: %s') % document,
|
'title': _('Metadata for document: %s') % document,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_document().metadata.all()
|
return self.get_document().metadata.all()
|
||||||
|
|
||||||
|
|
||||||
class DocumentMetadataRemoveView(MultipleObjectFormActionView):
|
class DocumentMetadataRemoveView(MultipleObjectFormActionView):
|
||||||
form_class = DocumentMetadataRemoveFormSet
|
form_class = DocumentMetadataRemoveFormSet
|
||||||
model = Document
|
model = Document
|
||||||
object_permission = permission_metadata_document_remove
|
object_permission = permission_document_metadata_remove
|
||||||
success_message = _(
|
success_message = _(
|
||||||
'Metadata remove request performed on %(count)d document'
|
'Metadata remove request performed on %(count)d document'
|
||||||
)
|
)
|
||||||
@@ -657,7 +657,7 @@ class MetadataTypeListView(SingleObjectListView):
|
|||||||
'title': _('Metadata types'),
|
'title': _('Metadata types'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return MetadataType.objects.all()
|
return MetadataType.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
self.test_document.submit_for_ocr()
|
self.test_document.submit_for_ocr()
|
||||||
|
|
||||||
response = self._request_document_content_view()
|
response = self._request_document_content_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_content_view_with_access(self):
|
def test_document_content_view_with_access(self):
|
||||||
self.test_document.submit_for_ocr()
|
self.test_document.submit_for_ocr()
|
||||||
@@ -51,7 +51,7 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
self.test_document.submit_for_ocr()
|
self.test_document.submit_for_ocr()
|
||||||
|
|
||||||
response = self._request_document_page_content_view()
|
response = self._request_document_page_content_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_page_content_view_with_access(self):
|
def test_document_page_content_view_with_access(self):
|
||||||
self.test_document.submit_for_ocr()
|
self.test_document.submit_for_ocr()
|
||||||
@@ -73,7 +73,7 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_document_submit_view_no_permission(self):
|
def test_document_submit_view_no_permission(self):
|
||||||
response = self._request_document_submit_view()
|
response = self._request_document_submit_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
''.join(self.test_document.latest_version.ocr_content()), ''
|
''.join(self.test_document.latest_version.ocr_content()), ''
|
||||||
@@ -102,7 +102,7 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_multiple_document_submit_view_no_permission(self):
|
def test_multiple_document_submit_view_no_permission(self):
|
||||||
response = self._request_multiple_document_submit_view()
|
response = self._request_multiple_document_submit_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
''.join(self.test_document.latest_version.ocr_content()), ''
|
''.join(self.test_document.latest_version.ocr_content()), ''
|
||||||
@@ -159,7 +159,7 @@ class OCRViewsTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_document_type_ocr_settings_view_no_permission(self):
|
def test_document_type_ocr_settings_view_no_permission(self):
|
||||||
response = self._request_document_type_ocr_settings_view()
|
response = self._request_document_type_ocr_settings_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
def test_document_type_ocr_settings_view_with_access(self):
|
def test_document_type_ocr_settings_view_with_access(self):
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from mayan.apps.common.generics import (
|
|||||||
FormView, MultipleObjectConfirmActionView, SingleObjectDetailView,
|
FormView, MultipleObjectConfirmActionView, SingleObjectDetailView,
|
||||||
SingleObjectDownloadView, SingleObjectEditView, SingleObjectListView
|
SingleObjectDownloadView, SingleObjectEditView, SingleObjectListView
|
||||||
)
|
)
|
||||||
|
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||||
from mayan.apps.documents.forms import DocumentTypeFilteredSelectForm
|
from mayan.apps.documents.forms import DocumentTypeFilteredSelectForm
|
||||||
from mayan.apps.documents.models import Document, DocumentPage, DocumentType
|
from mayan.apps.documents.models import Document, DocumentPage, DocumentType
|
||||||
|
|
||||||
@@ -126,21 +127,23 @@ class DocumentTypeSubmitView(FormView):
|
|||||||
return reverse(viewname='common:tools_list')
|
return reverse(viewname='common:tools_list')
|
||||||
|
|
||||||
|
|
||||||
class DocumentTypeSettingsEditView(SingleObjectEditView):
|
class DocumentTypeSettingsEditView(ExternalObjectMixin, SingleObjectEditView):
|
||||||
|
external_object_class = DocumentType
|
||||||
|
external_object_permission = permission_document_type_ocr_setup
|
||||||
|
external_object_pk_url_kwarg = 'pk'
|
||||||
fields = ('auto_ocr',)
|
fields = ('auto_ocr',)
|
||||||
object_permission = permission_document_type_ocr_setup
|
|
||||||
post_action_redirect = reverse_lazy(
|
post_action_redirect = reverse_lazy(
|
||||||
viewname='documents:document_type_list'
|
viewname='documents:document_type_list'
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_document_type(self):
|
def get_document_type(self):
|
||||||
return get_object_or_404(klass=DocumentType, pk=self.kwargs['pk'])
|
return self.external_object
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'object': self.get_document_type(),
|
'object': self.get_document_type(),
|
||||||
'title': _(
|
'title': _(
|
||||||
'Edit OCR settings for document type: %s'
|
'Edit OCR settings for document type: %s.'
|
||||||
) % self.get_document_type()
|
) % self.get_document_type()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +158,7 @@ class EntryListView(SingleObjectListView):
|
|||||||
}
|
}
|
||||||
view_permission = permission_document_type_ocr_setup
|
view_permission = permission_document_type_ocr_setup
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return DocumentVersionOCRError.objects.all()
|
return DocumentVersionOCRError.objects.all()
|
||||||
|
|
||||||
|
|
||||||
@@ -172,7 +175,7 @@ class DocumentOCRErrorsListView(SingleObjectListView):
|
|||||||
'title': _('OCR errors for document: %s') % self.get_document(),
|
'title': _('OCR errors for document: %s') % self.get_document(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_document().latest_version.ocr_errors.all()
|
return self.get_document().latest_version.ocr_errors.all()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,10 +30,9 @@ class PermissionAPIViewTestCase(PermissionAPIViewTestMixin, BaseAPITestCase):
|
|||||||
|
|
||||||
class RoleAPIViewTestCase(GroupTestMixin, PermissionTestMixin, RoleAPIViewTestMixin, RoleTestMixin, BaseAPITestCase):
|
class RoleAPIViewTestCase(GroupTestMixin, PermissionTestMixin, RoleAPIViewTestMixin, RoleTestMixin, BaseAPITestCase):
|
||||||
def test_role_create_api_view_no_permission(self):
|
def test_role_create_api_view_no_permission(self):
|
||||||
response = self._request_test_role_create_api_view()
|
|
||||||
|
|
||||||
role_count = Role.objects.count()
|
role_count = Role.objects.count()
|
||||||
|
|
||||||
|
response = self._request_test_role_create_api_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
self.assertEqual(Role.objects.count(), role_count)
|
self.assertEqual(Role.objects.count(), role_count)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class RoleEventsTestCase(RoleTestMixin, RoleViewTestMixin, GenericViewTestCase):
|
|||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
response = self._request_test_role_edit_view()
|
response = self._request_test_role_edit_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
self.assertEqual(Action.objects.count(), 0)
|
self.assertEqual(Action.objects.count(), 0)
|
||||||
|
|
||||||
def test_role_edited_event_with_access(self):
|
def test_role_edited_event_with_access(self):
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ class RoleViewsTestCase(RoleTestMixin, RoleViewTestMixin, GenericViewTestCase):
|
|||||||
|
|
||||||
self.assertEqual(Role.objects.count(), role_count + 1)
|
self.assertEqual(Role.objects.count(), role_count + 1)
|
||||||
|
|
||||||
def test_role_delete_view_no_access(self):
|
def test_role_delete_view_no_permission(self):
|
||||||
self._create_test_role()
|
self._create_test_role()
|
||||||
|
|
||||||
role_count = Role.objects.count()
|
role_count = Role.objects.count()
|
||||||
|
|
||||||
response = self._request_test_role_delete_view()
|
response = self._request_test_role_delete_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Role.objects.count(), role_count)
|
self.assertEqual(Role.objects.count(), role_count)
|
||||||
|
|
||||||
@@ -52,13 +52,13 @@ class RoleViewsTestCase(RoleTestMixin, RoleViewTestMixin, GenericViewTestCase):
|
|||||||
|
|
||||||
self.assertEqual(Role.objects.count(), role_count - 1)
|
self.assertEqual(Role.objects.count(), role_count - 1)
|
||||||
|
|
||||||
def test_role_edit_view_no_access(self):
|
def test_role_edit_view_no_permission(self):
|
||||||
self._create_test_role()
|
self._create_test_role()
|
||||||
role_label = self.test_role.label
|
role_label = self.test_role.label
|
||||||
|
|
||||||
response = self._request_test_role_edit_view()
|
response = self._request_test_role_edit_view()
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.test_role.refresh_from_db()
|
self.test_role.refresh_from_db()
|
||||||
self.assertEqual(self.test_role.label, role_label)
|
self.assertEqual(self.test_role.label, role_label)
|
||||||
@@ -75,7 +75,7 @@ class RoleViewsTestCase(RoleTestMixin, RoleViewTestMixin, GenericViewTestCase):
|
|||||||
self.test_role.refresh_from_db()
|
self.test_role.refresh_from_db()
|
||||||
self.assertNotEqual(self.test_role.label, role_label)
|
self.assertNotEqual(self.test_role.label, role_label)
|
||||||
|
|
||||||
def test_role_list_view_no_access(self):
|
def test_role_list_view_no_permission(self):
|
||||||
self._create_test_role()
|
self._create_test_role()
|
||||||
|
|
||||||
response = self._request_test_role_list_view()
|
response = self._request_test_role_list_view()
|
||||||
@@ -93,7 +93,7 @@ class RoleViewsTestCase(RoleTestMixin, RoleViewTestMixin, GenericViewTestCase):
|
|||||||
response=response, text=self.test_role.label, status_code=200
|
response=response, text=self.test_role.label, status_code=200
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_role_permissions_view_no_access(self):
|
def test_role_permissions_view_no_permission(self):
|
||||||
self._create_test_role()
|
self._create_test_role()
|
||||||
|
|
||||||
response = self._request_test_role_permissions_view()
|
response = self._request_test_role_permissions_view()
|
||||||
@@ -108,7 +108,7 @@ class RoleViewsTestCase(RoleTestMixin, RoleViewTestMixin, GenericViewTestCase):
|
|||||||
response = self._request_test_role_permissions_view()
|
response = self._request_test_role_permissions_view()
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_role_groups_view_no_access(self):
|
def test_role_groups_view_no_permission(self):
|
||||||
self._create_test_role()
|
self._create_test_role()
|
||||||
|
|
||||||
response = self._request_test_role_groups_view()
|
response = self._request_test_role_groups_view()
|
||||||
@@ -123,7 +123,7 @@ class RoleViewsTestCase(RoleTestMixin, RoleViewTestMixin, GenericViewTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class GroupRoleViewTestCase(GroupTestMixin, GroupRoleViewTestMixin, RoleTestMixin, GenericViewTestCase):
|
class GroupRoleViewTestCase(GroupTestMixin, GroupRoleViewTestMixin, RoleTestMixin, GenericViewTestCase):
|
||||||
def test_group_roles_view_no_access(self):
|
def test_group_roles_view_no_permission(self):
|
||||||
self._create_test_group()
|
self._create_test_group()
|
||||||
|
|
||||||
response = self._request_test_group_roles_view()
|
response = self._request_test_group_roles_view()
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class NamespaceDetailView(SingleObjectListView):
|
|||||||
_('Namespace: %s, not found') % self.kwargs['namespace_name']
|
_('Namespace: %s, not found') % self.kwargs['namespace_name']
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_namespace().settings
|
return self.get_namespace().settings
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ class NamespaceListView(SingleObjectListView):
|
|||||||
}
|
}
|
||||||
view_permission = permission_settings_view
|
view_permission = permission_settings_view
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return Namespace.get_all()
|
return Namespace.get_all()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ class SourceLogListView(SingleObjectListView):
|
|||||||
'title': _('Log entries for source: %s') % self.get_source(),
|
'title': _('Log entries for source: %s') % self.get_source(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_source().logs.all()
|
return self.get_source().logs.all()
|
||||||
|
|
||||||
def get_source(self):
|
def get_source(self):
|
||||||
@@ -592,7 +592,7 @@ class SetupSourceEditView(SingleObjectEditView):
|
|||||||
|
|
||||||
|
|
||||||
class SetupSourceListView(SingleObjectListView):
|
class SetupSourceListView(SingleObjectListView):
|
||||||
queryset = Source.objects.select_subclasses()
|
source_queryset = Source.objects.select_subclasses()
|
||||||
view_permission = permission_sources_setup_view
|
view_permission = permission_sources_setup_view
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class TagEventsTestCase(TagTestMixin, TagViewTestMixin, GenericViewTestCase):
|
|||||||
action_count = Action.objects.count()
|
action_count = Action.objects.count()
|
||||||
|
|
||||||
response = self._request_test_tag_edit_view()
|
response = self._request_test_tag_edit_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Action.objects.count(), action_count)
|
self.assertEqual(Action.objects.count(), action_count)
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class TagViewTestCase(TagTestMixin, TagViewTestMixin, GenericViewTestCase):
|
|||||||
tag_count = Tag.objects.count()
|
tag_count = Tag.objects.count()
|
||||||
|
|
||||||
response = self._request_test_tag_delete_view()
|
response = self._request_test_tag_delete_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Tag.objects.count(), tag_count)
|
self.assertEqual(Tag.objects.count(), tag_count)
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ class TagViewTestCase(TagTestMixin, TagViewTestMixin, GenericViewTestCase):
|
|||||||
tag_count = Tag.objects.count()
|
tag_count = Tag.objects.count()
|
||||||
|
|
||||||
response = self._request_test_tag_delete_multiple_view()
|
response = self._request_test_tag_delete_multiple_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Tag.objects.count(), tag_count)
|
self.assertEqual(Tag.objects.count(), tag_count)
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ class TagViewTestCase(TagTestMixin, TagViewTestMixin, GenericViewTestCase):
|
|||||||
tag_label = self.test_tag.label
|
tag_label = self.test_tag.label
|
||||||
|
|
||||||
response = self._request_test_tag_edit_view()
|
response = self._request_test_tag_edit_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.test_tag.refresh_from_db()
|
self.test_tag.refresh_from_db()
|
||||||
self.assertEqual(self.test_tag.label, tag_label)
|
self.assertEqual(self.test_tag.label, tag_label)
|
||||||
@@ -131,9 +131,7 @@ class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentVie
|
|||||||
self._create_test_tag()
|
self._create_test_tag()
|
||||||
|
|
||||||
response = self._request_test_document_tag_attach_view()
|
response = self._request_test_document_tag_attach_view()
|
||||||
# Show same view with a warning message that ID XX is not one of the
|
self.assertEqual(response.status_code, 404)
|
||||||
# available choices.
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
self.assertTrue(self.test_tag not in self.test_document.tags.all())
|
self.assertTrue(self.test_tag not in self.test_document.tags.all())
|
||||||
|
|
||||||
@@ -143,7 +141,7 @@ class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentVie
|
|||||||
self.grant_access(obj=self.test_tag, permission=permission_tag_attach)
|
self.grant_access(obj=self.test_tag, permission=permission_tag_attach)
|
||||||
|
|
||||||
response = self._request_test_document_tag_attach_view()
|
response = self._request_test_document_tag_attach_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(self.test_tag not in self.test_document.tags.all())
|
self.assertTrue(self.test_tag not in self.test_document.tags.all())
|
||||||
|
|
||||||
@@ -172,7 +170,7 @@ class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentVie
|
|||||||
self._create_test_tag()
|
self._create_test_tag()
|
||||||
|
|
||||||
response = self._request_test_document_multiple_tag_multiple_attach_view()
|
response = self._request_test_document_multiple_tag_multiple_attach_view()
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(self.test_tag not in self.test_document.tags.all())
|
self.assertTrue(self.test_tag not in self.test_document.tags.all())
|
||||||
|
|
||||||
@@ -182,7 +180,7 @@ class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentVie
|
|||||||
self.grant_access(obj=self.test_tag, permission=permission_tag_attach)
|
self.grant_access(obj=self.test_tag, permission=permission_tag_attach)
|
||||||
|
|
||||||
response = self._request_test_document_multiple_tag_multiple_attach_view()
|
response = self._request_test_document_multiple_tag_multiple_attach_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(self.test_tag not in self.test_document.tags.all())
|
self.assertTrue(self.test_tag not in self.test_document.tags.all())
|
||||||
|
|
||||||
@@ -212,7 +210,7 @@ class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentVie
|
|||||||
self.test_document.tags.add(self.test_tag)
|
self.test_document.tags.add(self.test_tag)
|
||||||
|
|
||||||
response = self._request_test_document_tag_multiple_remove_view()
|
response = self._request_test_document_tag_multiple_remove_view()
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(self.test_tag in self.test_document.tags.all())
|
self.assertTrue(self.test_tag in self.test_document.tags.all())
|
||||||
|
|
||||||
@@ -223,7 +221,7 @@ class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentVie
|
|||||||
self.grant_access(obj=self.test_tag, permission=permission_tag_remove)
|
self.grant_access(obj=self.test_tag, permission=permission_tag_remove)
|
||||||
|
|
||||||
response = self._request_test_document_tag_multiple_remove_view()
|
response = self._request_test_document_tag_multiple_remove_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(self.test_tag in self.test_document.tags.all())
|
self.assertTrue(self.test_tag in self.test_document.tags.all())
|
||||||
|
|
||||||
@@ -255,7 +253,7 @@ class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentVie
|
|||||||
self.test_document.tags.add(self.test_tag)
|
self.test_document.tags.add(self.test_tag)
|
||||||
|
|
||||||
response = self._request_test_document_multiple_tag_remove_view()
|
response = self._request_test_document_multiple_tag_remove_view()
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(self.test_tag in self.test_document.tags.all())
|
self.assertTrue(self.test_tag in self.test_document.tags.all())
|
||||||
|
|
||||||
@@ -266,7 +264,7 @@ class TagDocumentViewTestCase(TagTestMixin, TagViewTestMixin, GenericDocumentVie
|
|||||||
self.grant_access(obj=self.test_tag, permission=permission_tag_remove)
|
self.grant_access(obj=self.test_tag, permission=permission_tag_remove)
|
||||||
|
|
||||||
response = self._request_test_document_multiple_tag_remove_view()
|
response = self._request_test_document_multiple_tag_remove_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertTrue(self.test_tag in self.test_document.tags.all())
|
self.assertTrue(self.test_tag in self.test_document.tags.all())
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ class TagListView(SingleObjectListView):
|
|||||||
'title': _('Tags'),
|
'title': _('Tags'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return self.get_tag_queryset()
|
return self.get_tag_queryset()
|
||||||
|
|
||||||
def get_tag_queryset(self):
|
def get_tag_queryset(self):
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class QueueListView(SingleObjectListView):
|
|||||||
}
|
}
|
||||||
view_permission = permission_task_view
|
view_permission = permission_task_view
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return CeleryQueue.all()
|
return CeleryQueue.all()
|
||||||
|
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ class QueueActiveTaskListView(SingleObjectListView):
|
|||||||
def get_object(self):
|
def get_object(self):
|
||||||
return CeleryQueue.get(queue_name=self.kwargs['queue_name'])
|
return CeleryQueue.get(queue_name=self.kwargs['queue_name'])
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
try:
|
try:
|
||||||
return self.get_task_list()
|
return self.get_task_list()
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ class GroupEventsViewTestCase(GroupTestMixin, GroupViewTestMixin, UserTestMixin,
|
|||||||
)
|
)
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
self._request_test_group_create_view()
|
response = self._request_test_group_create_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
action = Action.objects.last()
|
action = Action.objects.last()
|
||||||
|
|
||||||
@@ -43,7 +44,8 @@ class GroupEventsViewTestCase(GroupTestMixin, GroupViewTestMixin, UserTestMixin,
|
|||||||
)
|
)
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
self._request_test_group_edit_view()
|
response = self._request_test_group_edit_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
action = Action.objects.last()
|
action = Action.objects.last()
|
||||||
|
|
||||||
@@ -58,7 +60,8 @@ class GroupEventsAPITestCase(GroupAPITestMixin, GroupTestMixin, GroupViewTestMix
|
|||||||
)
|
)
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
self._request_test_group_create_api_view()
|
response = self._request_test_group_create_api_view()
|
||||||
|
self.assertEqual(response.status_code, 201)
|
||||||
|
|
||||||
action = Action.objects.last()
|
action = Action.objects.last()
|
||||||
|
|
||||||
@@ -76,7 +79,8 @@ class GroupEventsAPITestCase(GroupAPITestMixin, GroupTestMixin, GroupViewTestMix
|
|||||||
)
|
)
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
self._request_test_group_edit_patch_api_view()
|
response = self._request_test_group_edit_patch_api_view()
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
action = Action.objects.last()
|
action = Action.objects.last()
|
||||||
|
|
||||||
@@ -133,7 +137,8 @@ class UserEventsViewTestCase(UserAPITestMixin, UserTestMixin, UserViewTestMixin,
|
|||||||
)
|
)
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
self._request_test_user_create_view()
|
response = self._request_test_user_create_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
action = Action.objects.last()
|
action = Action.objects.last()
|
||||||
|
|
||||||
@@ -149,7 +154,8 @@ class UserEventsViewTestCase(UserAPITestMixin, UserTestMixin, UserViewTestMixin,
|
|||||||
)
|
)
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
self._request_test_user_edit_view()
|
response = self._request_test_user_edit_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
action = Action.objects.last()
|
action = Action.objects.last()
|
||||||
|
|
||||||
@@ -165,7 +171,8 @@ class UserEventsAPITestCase(UserAPITestMixin, UserTestMixin, UserViewTestMixin,
|
|||||||
)
|
)
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
self._request_test_user_create_api_view()
|
response = self._request_test_user_create_api_view()
|
||||||
|
self.assertEqual(response.status_code, 201)
|
||||||
|
|
||||||
action = Action.objects.last()
|
action = Action.objects.last()
|
||||||
|
|
||||||
@@ -182,7 +189,8 @@ class UserEventsAPITestCase(UserAPITestMixin, UserTestMixin, UserViewTestMixin,
|
|||||||
)
|
)
|
||||||
Action.objects.all().delete()
|
Action.objects.all().delete()
|
||||||
|
|
||||||
self._request_test_user_edit_patch_api_view()
|
response = self._request_test_user_edit_patch_api_view()
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
action = Action.objects.last()
|
action = Action.objects.last()
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from django.contrib.auth.models import Group
|
|||||||
from mayan.apps.common.tests import GenericViewTestCase
|
from mayan.apps.common.tests import GenericViewTestCase
|
||||||
from mayan.apps.documents.tests import GenericDocumentViewTestCase
|
from mayan.apps.documents.tests import GenericDocumentViewTestCase
|
||||||
from mayan.apps.metadata.models import MetadataType
|
from mayan.apps.metadata.models import MetadataType
|
||||||
from mayan.apps.metadata.permissions import permission_metadata_document_edit
|
from mayan.apps.metadata.permissions import permission_document_metadata_edit
|
||||||
from mayan.apps.metadata.tests.literals import (
|
from mayan.apps.metadata.tests.literals import (
|
||||||
TEST_METADATA_TYPE_LABEL, TEST_METADATA_TYPE_NAME,
|
TEST_METADATA_TYPE_LABEL, TEST_METADATA_TYPE_NAME,
|
||||||
)
|
)
|
||||||
@@ -48,7 +48,7 @@ class GroupViewsTestCase(GroupTestMixin, GroupViewTestMixin, UserTestMixin, Gene
|
|||||||
group_count = Group.objects.count()
|
group_count = Group.objects.count()
|
||||||
|
|
||||||
response = self._request_test_group_delete_view()
|
response = self._request_test_group_delete_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(Group.objects.count(), group_count)
|
self.assertEqual(Group.objects.count(), group_count)
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ class GroupViewsTestCase(GroupTestMixin, GroupViewTestMixin, UserTestMixin, Gene
|
|||||||
group_name = self.test_group.name
|
group_name = self.test_group.name
|
||||||
|
|
||||||
response = self._request_test_group_edit_view()
|
response = self._request_test_group_edit_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.test_group.refresh_from_db()
|
self.test_group.refresh_from_db()
|
||||||
self.assertEqual(self.test_group.name, group_name)
|
self.assertEqual(self.test_group.name, group_name)
|
||||||
@@ -173,7 +173,7 @@ class SuperUserViewTestCase(UserTestMixin, UserViewTestMixin, GenericViewTestCas
|
|||||||
obj=self.test_superuser, permission=permission_user_delete
|
obj=self.test_superuser, permission=permission_user_delete
|
||||||
)
|
)
|
||||||
response = self._request_test_superuser_delete_view()
|
response = self._request_test_superuser_delete_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
get_user_model().objects.filter(is_superuser=True).count(),
|
get_user_model().objects.filter(is_superuser=True).count(),
|
||||||
superuser_count
|
superuser_count
|
||||||
@@ -228,7 +228,7 @@ class UserViewTestCase(UserTestMixin, UserViewTestMixin, GenericViewTestCase):
|
|||||||
user_count = get_user_model().objects.count()
|
user_count = get_user_model().objects.count()
|
||||||
|
|
||||||
response = self._request_test_user_delete_view()
|
response = self._request_test_user_delete_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(get_user_model().objects.count(), user_count)
|
self.assertEqual(get_user_model().objects.count(), user_count)
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ class UserViewTestCase(UserTestMixin, UserViewTestMixin, GenericViewTestCase):
|
|||||||
user_count = get_user_model().objects.count()
|
user_count = get_user_model().objects.count()
|
||||||
|
|
||||||
response = self._request_test_user_delete_multiple_view()
|
response = self._request_test_user_delete_multiple_view()
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(get_user_model().objects.count(), user_count)
|
self.assertEqual(get_user_model().objects.count(), user_count)
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ class UserViewTestCase(UserTestMixin, UserViewTestMixin, GenericViewTestCase):
|
|||||||
response = self._request_test_user_password_set_view(
|
response = self._request_test_user_password_set_view(
|
||||||
password=TEST_USER_PASSWORD_EDITED
|
password=TEST_USER_PASSWORD_EDITED
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.test_user.refresh_from_db()
|
self.test_user.refresh_from_db()
|
||||||
self.assertEqual(self.test_user.password, password_hash)
|
self.assertEqual(self.test_user.password, password_hash)
|
||||||
@@ -300,7 +300,7 @@ class UserViewTestCase(UserTestMixin, UserViewTestMixin, GenericViewTestCase):
|
|||||||
response = self._request_test_user_password_set_multiple_view(
|
response = self._request_test_user_password_set_multiple_view(
|
||||||
password=TEST_USER_PASSWORD_EDITED
|
password=TEST_USER_PASSWORD_EDITED
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.test_user.refresh_from_db()
|
self.test_user.refresh_from_db()
|
||||||
self.assertEqual(self.test_user.password, password_hash)
|
self.assertEqual(self.test_user.password, password_hash)
|
||||||
@@ -388,7 +388,7 @@ class MetadataLookupIntegrationTestCase(GenericDocumentViewTestCase):
|
|||||||
self.metadata_type.save()
|
self.metadata_type.save()
|
||||||
self.document.metadata.create(metadata_type=self.metadata_type)
|
self.document.metadata.create(metadata_type=self.metadata_type)
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.document, permission=permission_metadata_document_edit
|
obj=self.document, permission=permission_document_metadata_edit
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self.get(
|
response = self.get(
|
||||||
@@ -407,7 +407,7 @@ class MetadataLookupIntegrationTestCase(GenericDocumentViewTestCase):
|
|||||||
self.metadata_type.save()
|
self.metadata_type.save()
|
||||||
self.document.metadata.create(metadata_type=self.metadata_type)
|
self.document.metadata.create(metadata_type=self.metadata_type)
|
||||||
self.grant_access(
|
self.grant_access(
|
||||||
obj=self.document, permission=permission_metadata_document_edit
|
obj=self.document, permission=permission_document_metadata_edit
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self.get(
|
response = self.get(
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ class UserCreateView(SingleObjectCreateView):
|
|||||||
|
|
||||||
class UserDeleteView(MultipleObjectConfirmActionView):
|
class UserDeleteView(MultipleObjectConfirmActionView):
|
||||||
object_permission = permission_user_delete
|
object_permission = permission_user_delete
|
||||||
queryset = get_user_queryset()
|
source_queryset = get_user_queryset()
|
||||||
success_message = _('User delete request performed on %(count)d user')
|
success_message = _('User delete request performed on %(count)d user')
|
||||||
success_message_plural = _(
|
success_message_plural = _(
|
||||||
'User delete request performed on %(count)d users'
|
'User delete request performed on %(count)d users'
|
||||||
@@ -232,7 +232,7 @@ class UserDetailsView(SingleObjectDetailView):
|
|||||||
)
|
)
|
||||||
object_permission = permission_user_view
|
object_permission = permission_user_view
|
||||||
pk_url_kwarg = 'pk'
|
pk_url_kwarg = 'pk'
|
||||||
queryset = get_user_queryset()
|
source_queryset = get_user_queryset()
|
||||||
|
|
||||||
def get_extra_context(self, **kwargs):
|
def get_extra_context(self, **kwargs):
|
||||||
return {
|
return {
|
||||||
@@ -247,7 +247,7 @@ class UserEditView(SingleObjectEditView):
|
|||||||
post_action_redirect = reverse_lazy(
|
post_action_redirect = reverse_lazy(
|
||||||
viewname='user_management:user_list'
|
viewname='user_management:user_list'
|
||||||
)
|
)
|
||||||
queryset = get_user_queryset()
|
source_queryset = get_user_queryset()
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -306,7 +306,7 @@ class UserListView(SingleObjectListView):
|
|||||||
'title': _('Users'),
|
'title': _('Users'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object_list(self):
|
def get_source_queryset(self):
|
||||||
return get_user_queryset()
|
return get_user_queryset()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user