Add keyword arguments to the cabinet app

Modernize tests. Use the FilteredSelectionForm in the view
to add new cabinets to documents. Add missing icons.
Rename some view names to be more consistent.

Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
Roberto Rosario
2019-01-02 13:54:58 -04:00
parent 39689e2a4f
commit 3e53ce0c43
15 changed files with 254 additions and 193 deletions

View File

@@ -33,7 +33,7 @@ class APIDocumentCabinetListView(generics.ListAPIView):
mayan_object_permissions = {'GET': (permission_cabinet_view,)}
def get_queryset(self):
document = get_object_or_404(Document, pk=self.kwargs['pk'])
document = get_object_or_404(Document, pk=self.kwargs['document_pk'])
AccessControlList.objects.check_access(
permissions=permission_document_view, user=self.request.user,
obj=document
@@ -135,7 +135,7 @@ class APICabinetDocumentListView(generics.ListCreateAPIView):
return context
def get_cabinet(self):
return get_object_or_404(klass=Cabinet, pk=self.kwargs['pk'])
return get_object_or_404(klass=Cabinet, pk=self.kwargs['cabinet_pk'])
def get_queryset(self):
cabinet = self.get_cabinet()
@@ -163,7 +163,7 @@ class APICabinetDocumentView(generics.RetrieveDestroyAPIView):
serializer_class = CabinetDocumentSerializer
def get_cabinet(self):
return get_object_or_404(klass=Cabinet, pk=self.kwargs['pk'])
return get_object_or_404(klass=Cabinet, pk=self.kwargs['cabinet_pk'])
def get_queryset(self):
return self.get_cabinet().documents.all()

View File

@@ -16,11 +16,11 @@ from mayan.apps.documents.search import document_page_search, document_search
from mayan.apps.navigation import SourceColumn
from .links import (
link_cabinet_add_document, link_cabinet_add_multiple_documents,
link_cabinet_child_add, link_cabinet_create, link_cabinet_delete,
link_cabinet_edit, link_cabinet_list, link_cabinet_view,
link_custom_acl_list, link_document_cabinet_list,
link_document_cabinet_remove, link_multiple_document_cabinet_remove
link_custom_acl_list, link_document_cabinet_add,
link_document_cabinet_list, link_document_cabinet_remove,
link_document_multiple_cabinet_add, link_document_multiple_cabinet_remove
)
from .menus import menu_cabinets
from .methods import method_get_document_cabinets
@@ -49,8 +49,8 @@ class CabinetsApp(MayanAppConfig):
app_label='documents', model_name='Document'
)
DocumentCabinet = self.get_model('DocumentCabinet')
Cabinet = self.get_model('Cabinet')
DocumentCabinet = self.get_model(model_name='DocumentCabinet')
Cabinet = self.get_model(model_name='Cabinet')
# Add explicit order_by as DocumentCabinet ordering Meta option has no
# effect.
@@ -80,18 +80,17 @@ class CabinetsApp(MayanAppConfig):
)
SourceColumn(
source=Document, label=_('Cabinets'),
func=lambda context: widget_document_cabinets(
document=context['object'], user=context['request'].user
), order=1
), order=1, label=_('Cabinets'), source=Document
)
document_page_search.add_model_field(
field='document_version__document__cabinets__label',
label=_('Cabinets')
label=_('Cabinets'),
field='document_version__document__cabinets__label'
)
document_search.add_model_field(
field='cabinets__label', label=_('Cabinets')
label=_('Cabinets'), field='cabinets__label'
)
menu_facet.bind_links(
@@ -108,8 +107,8 @@ class CabinetsApp(MayanAppConfig):
menu_multi_item.bind_links(
links=(
link_cabinet_add_multiple_documents,
link_multiple_document_cabinet_remove
link_document_multiple_cabinet_add,
link_document_multiple_cabinet_remove
), sources=(Document,)
)
menu_object.bind_links(
@@ -125,10 +124,10 @@ class CabinetsApp(MayanAppConfig):
), sources=(Cabinet,)
)
menu_sidebar.bind_links(
links=(link_cabinet_add_document, link_document_cabinet_remove),
links=(link_document_cabinet_add, link_document_cabinet_remove),
sources=(
'cabinets:document_cabinet_list',
'cabinets:cabinet_add_document',
'cabinets:document_cabinet_add',
'cabinets:document_cabinet_remove'
)
)

View File

@@ -4,7 +4,7 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.events import EventTypeNamespace
namespace = EventTypeNamespace(name='cabinets', label=_('Cabinets'))
namespace = EventTypeNamespace(label=_('Cabinets'), name='cabinets')
event_cabinets_add_document = namespace.add_event_type(
label=_('Document added to cabinet'), name='add_document'

View File

@@ -1,33 +1,12 @@
from __future__ import absolute_import, unicode_literals
import logging
from django import forms
from django.utils.translation import ugettext_lazy as _
from mayan.apps.acls.models import AccessControlList
from .models import Cabinet
logger = logging.getLogger(__name__)
from mayan.apps.common.forms import FilteredSelectionForm
class CabinetListForm(forms.Form):
def __init__(self, *args, **kwargs):
help_text = kwargs.pop('help_text', None)
permission = kwargs.pop('permission', None)
queryset = kwargs.pop('queryset', Cabinet.objects.all())
user = kwargs.pop('user', None)
logger.debug('user: %s', user)
super(CabinetListForm, self).__init__(*args, **kwargs)
queryset = AccessControlList.objects.filter_by_access(
permission=permission, user=user, queryset=queryset
)
self.fields['cabinets'] = forms.ModelMultipleChoiceField(
label=_('Cabinets'), help_text=help_text,
queryset=queryset, required=False,
widget=forms.SelectMultiple(attrs={'class': 'select2'})
)
class CabinetListForm(FilteredSelectionForm):
_field_name = 'cabinets'
_label = _('Cabinets')
_widget_attributes = {'class': 'select2'}
_allow_multiple = True

View File

@@ -3,7 +3,25 @@ from __future__ import absolute_import, unicode_literals
from mayan.apps.appearance.classes import Icon
icon_cabinet = Icon(driver_name='fontawesome', symbol='columns')
icon_cabinet_add = Icon(driver_name='fontawesome', symbol='plus')
icon_cabinet_child_add = Icon(driver_name='fontawesome', symbol='plus')
icon_cabinet_create = Icon(driver_name='fontawesome', symbol='plus')
icon_cabinet_delete = Icon(driver_name='fontawesome', symbol='times')
icon_cabinet_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
icon_cabinet_list = Icon(driver_name='fontawesome', symbol='columns')
icon_cabinet_view = Icon(driver_name='fontawesome', symbol='columns')
icon_document_cabinet_add = Icon(
driver_name='fontawesome-dual', primary_symbol='columns',
secondary_symbol='arrow-right'
)
icon_document_multiple_cabinet_add = Icon(
driver_name='fontawesome-dual', primary_symbol='columns',
secondary_symbol='arrow-right'
)
icon_document_cabinet_remove = Icon(
driver_name='fontawesome-dual', primary_symbol='columns',
secondary_symbol='minus'
)
icon_document_multiple_cabinet_remove = Icon(
driver_name='fontawesome-dual', primary_symbol='columns',
secondary_symbol='minus'
)

View File

@@ -9,8 +9,10 @@ from mayan.apps.documents.permissions import permission_document_view
from mayan.apps.navigation import Link, get_cascade_condition
from .icons import (
icon_cabinet_add, icon_cabinet_child_add, icon_cabinet_create,
icon_cabinet_list
icon_cabinet_child_add, icon_cabinet_create, icon_cabinet_delete,
icon_cabinet_edit, icon_cabinet_list, icon_cabinet_view,
icon_document_cabinet_add, icon_document_cabinet_remove,
icon_document_multiple_cabinet_add, icon_document_multiple_cabinet_remove
)
from .permissions import (
permission_cabinet_add_document, permission_cabinet_create,
@@ -26,21 +28,23 @@ link_document_cabinet_list = Link(
text=_('Cabinets'), view='cabinets:document_cabinet_list',
)
link_document_cabinet_remove = Link(
args='resolved_object.pk',
args='resolved_object.pk', icon_class=icon_document_cabinet_remove,
permissions=(permission_cabinet_remove_document,),
text=_('Remove from cabinets'), view='cabinets:document_cabinet_remove'
)
link_cabinet_add_document = Link(
args='object.pk', icon_class=icon_cabinet_add,
link_document_cabinet_add = Link(
args='object.pk', icon_class=icon_document_cabinet_add,
permissions=(permission_cabinet_add_document,), text=_('Add to cabinets'),
view='cabinets:cabinet_add_document',
view='cabinets:document_cabinet_add',
)
link_cabinet_add_multiple_documents = Link(
text=_('Add to cabinets'), view='cabinets:cabinet_add_multiple_documents'
link_document_multiple_cabinet_add = Link(
icon_class=icon_document_multiple_cabinet_add, text=_('Add to cabinets'),
view='cabinets:document_multiple_cabinet_add'
)
link_multiple_document_cabinet_remove = Link(
link_document_multiple_cabinet_remove = Link(
icon_class=icon_document_multiple_cabinet_remove,
text=_('Remove from cabinets'),
view='cabinets:multiple_document_cabinet_remove'
view='cabinets:document_multiple_cabinet_remove'
)
# Cabinet links
@@ -65,11 +69,13 @@ link_cabinet_create = Link(
text=_('Create cabinet'), view='cabinets:cabinet_create'
)
link_cabinet_delete = Link(
args='object.pk', permissions=(permission_cabinet_delete,),
tags='dangerous', text=_('Delete'), view='cabinets:cabinet_delete'
args='object.pk', icon_class=icon_cabinet_delete,
permissions=(permission_cabinet_delete,), tags='dangerous',
text=_('Delete'), view='cabinets:cabinet_delete'
)
link_cabinet_edit = Link(
args='object.pk', permissions=(permission_cabinet_edit,), text=_('Edit'),
args='object.pk', icon_class=icon_cabinet_edit,
permissions=(permission_cabinet_edit,), text=_('Edit'),
view='cabinets:cabinet_edit'
)
link_cabinet_list = Link(
@@ -80,6 +86,7 @@ link_cabinet_list = Link(
view='cabinets:cabinet_list'
)
link_cabinet_view = Link(
args='object.pk', permissions=(permission_cabinet_view,), text=_('Details'),
args='object.pk', icon_class=icon_cabinet_view,
permissions=(permission_cabinet_view,), text=_('Details'),
view='cabinets:cabinet_view'
)

View File

@@ -53,11 +53,13 @@ class Cabinet(MPTTModel):
"""
self.documents.add(document)
event_cabinets_add_document.commit(
action_object=self, actor=user, target=document
actor=user, action_object=self, target=document
)
def get_absolute_url(self):
return reverse('cabinets:cabinet_view', args=(self.pk,))
return reverse(
viewname='cabinets:cabinet_view', kwargs={'cabinet_pk': self.pk}
)
def get_document_count(self, user):
"""
@@ -72,7 +74,8 @@ class Cabinet(MPTTModel):
filtered by access.
"""
return AccessControlList.objects.filter_by_access(
permission_document_view, user, queryset=self.documents
permission=permission_document_view, queryset=self.documents,
user=user
)
def get_full_path(self):
@@ -93,7 +96,7 @@ class Cabinet(MPTTModel):
"""
self.documents.remove(document)
event_cabinets_remove_document.commit(
action_object=self, actor=user, target=document
actor=user, action_object=self, target=document
)
def validate_unique(self, exclude=None):
@@ -105,9 +108,13 @@ class Cabinet(MPTTModel):
"""
with transaction.atomic():
if connection.vendor == 'oracle':
queryset = Cabinet.objects.filter(parent=self.parent, label=self.label)
queryset = Cabinet.objects.filter(
parent=self.parent, label=self.label
)
else:
queryset = Cabinet.objects.select_for_update().filter(parent=self.parent, label=self.label)
queryset = Cabinet.objects.select_for_update().filter(
parent=self.parent, label=self.label
)
if queryset.exists():
params = {

View File

@@ -9,20 +9,20 @@ namespace = PermissionNamespace(label=_('Cabinets'), name='cabinets')
# Translators: this refers to the permission that will allow users to add
# documents to cabinets.
permission_cabinet_add_document = namespace.add_permission(
name='cabinet_add_document', label=_('Add documents to cabinets')
label=_('Add documents to cabinets'), name='cabinet_add_document'
)
permission_cabinet_create = namespace.add_permission(
name='cabinet_create', label=_('Create cabinets')
label=_('Create cabinets'), name='cabinet_create'
)
permission_cabinet_delete = namespace.add_permission(
name='cabinet_delete', label=_('Delete cabinets')
label=_('Delete cabinets'), name='cabinet_delete'
)
permission_cabinet_edit = namespace.add_permission(
name='cabinet_edit', label=_('Edit cabinets')
label=_('Edit cabinets'), name='cabinet_edit'
)
permission_cabinet_remove_document = namespace.add_permission(
name='cabinet_remove_document', label=_('Remove documents from cabinets')
label=_('Remove documents from cabinets'), name='cabinet_remove_document'
)
permission_cabinet_view = namespace.add_permission(
name='cabinet_view', label=_('View cabinets')
label=_('View cabinets'), name='cabinet_view'
)

View File

@@ -54,7 +54,7 @@ class CabinetSerializer(serializers.ModelSerializer):
def get_parent_url(self, obj):
if obj.parent:
return reverse(
'rest_api:cabinet-detail', args=(obj.parent.pk,),
viewname='rest_api:cabinet-detail', kwargs={'cabinet_pk': obj.parent.pk},
format=self.context['format'],
request=self.context.get('request')
)
@@ -167,9 +167,10 @@ class CabinetDocumentSerializer(DocumentSerializer):
def get_cabinet_document_url(self, instance):
return reverse(
'rest_api:cabinet-document', args=(
self.context['cabinet'].pk, instance.pk
), request=self.context['request'], format=self.context['format']
viewname='rest_api:cabinet-document', kwargs={
'cabinet_pk': self.context['cabinet'].pk,
'document_pk': instance.pk
}, request=self.context['request'], format=self.context['format']
)

View File

@@ -1,7 +1,6 @@
from __future__ import unicode_literals
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.utils.encoding import force_text
from rest_framework import status
@@ -39,8 +38,9 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
self.document_2 = self.upload_document()
def test_cabinet_create(self):
response = self.client.post(
reverse('rest_api:cabinet-list'), {'label': TEST_CABINET_LABEL}
response = self.post(
viewname='rest_api:cabinet-list',
data={'label': TEST_CABINET_LABEL}
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
@@ -53,8 +53,8 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
self.assertEqual(cabinet.label, TEST_CABINET_LABEL)
def test_cabinet_create_with_single_document(self):
response = self.client.post(
reverse('rest_api:cabinet-list'), {
response = self.post(
viewname='rest_api:cabinet-list', data={
'label': TEST_CABINET_LABEL, 'documents_pk_list': '{}'.format(
self.document.pk
)
@@ -73,8 +73,8 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
self.assertEqual(cabinet.label, TEST_CABINET_LABEL)
def test_cabinet_create_with_multiple_documents(self):
response = self.client.post(
reverse('rest_api:cabinet-list'), {
response = self.post(
viewname='rest_api:cabinet-list', data={
'label': TEST_CABINET_LABEL,
'documents_pk_list': '{},{}'.format(
self.document.pk, self.document_2.pk
@@ -102,11 +102,9 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
cabinet = Cabinet.objects.create(label=TEST_CABINET_LABEL)
cabinet.documents.add(self.document)
response = self.client.delete(
reverse(
'rest_api:cabinet-document',
args=(cabinet.pk, self.document.pk)
)
response = self.delete(
viewname='rest_api:cabinet-document',
kwargs={'cabinet_pk': cabinet.pk, 'document_pk': self.document.pk}
)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
@@ -116,11 +114,9 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
cabinet = Cabinet.objects.create(label=TEST_CABINET_LABEL)
cabinet.documents.add(self.document)
response = self.client.get(
reverse(
'rest_api:cabinet-document',
args=(cabinet.pk, self.document.pk)
)
response = self.get(
viewname='rest_api:cabinet-document',
kwargs={'cabinet_pk': cabinet.pk, 'document_pk': self.document.pk}
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -132,8 +128,9 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
cabinet = Cabinet.objects.create(label=TEST_CABINET_LABEL)
cabinet.documents.add(self.document)
response = self.client.get(
reverse('rest_api:cabinet-document-list', args=(cabinet.pk,))
response = self.get(
viewname='rest_api:cabinet-document-list',
kwargs={'cabinet_pk': cabinet.pk}
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -144,8 +141,9 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
def test_cabinet_delete(self):
cabinet = Cabinet.objects.create(label=TEST_CABINET_LABEL)
response = self.client.delete(
reverse('rest_api:cabinet-detail', args=(cabinet.pk,))
response = self.delete(
viewname='rest_api:cabinet-detail',
kwargs={'cabinet_pk': cabinet.pk}
)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
@@ -154,9 +152,10 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
def test_cabinet_edit_via_patch(self):
cabinet = Cabinet.objects.create(label=TEST_CABINET_LABEL)
response = self.client.patch(
reverse('rest_api:cabinet-detail', args=(cabinet.pk,)),
{'label': TEST_CABINET_EDITED_LABEL}
response = self.patch(
viewname='rest_api:cabinet-detail',
kwargs={'cabinet_pk': cabinet.pk},
data={'label': TEST_CABINET_EDITED_LABEL}
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -167,9 +166,10 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
def test_cabinet_edit_via_put(self):
cabinet = Cabinet.objects.create(label=TEST_CABINET_LABEL)
response = self.client.put(
reverse('rest_api:cabinet-detail', args=(cabinet.pk,)),
{'label': TEST_CABINET_EDITED_LABEL}
response = self.put(
viewname='rest_api:cabinet-detail',
kwargs={'cabinet_pk': cabinet.pk},
data={'label': TEST_CABINET_EDITED_LABEL}
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -180,8 +180,9 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
def test_cabinet_add_document(self):
cabinet = Cabinet.objects.create(label=TEST_CABINET_LABEL)
response = self.client.post(
reverse('rest_api:cabinet-document-list', args=(cabinet.pk,)), {
response = self.post(
viewname='rest_api:cabinet-document-list',
kwargs={'cabinet_pk': cabinet.pk}, data={
'documents_pk_list': '{}'.format(self.document.pk)
}
)
@@ -194,8 +195,10 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
def test_cabinet_add_multiple_documents(self):
cabinet = Cabinet.objects.create(label=TEST_CABINET_LABEL)
response = self.client.post(
reverse('rest_api:cabinet-document-list', args=(cabinet.pk,)), {
response = self.post(
viewname='rest_api:cabinet-document-list',
kwargs={'cabinet_pk': cabinet.pk},
data={
'documents_pk_list': '{},{}'.format(
self.document.pk, self.document_2.pk
)
@@ -215,8 +218,8 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
label=TEST_CABINET_LABEL, parent=cabinet
)
response = self.client.get(
reverse('rest_api:cabinet-list')
response = self.get(
viewname='rest_api:cabinet-list'
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['results'][0]['label'], cabinet.label)
@@ -226,12 +229,10 @@ class CabinetAPITestCase(DocumentTestMixin, APITestCase):
cabinet.documents.add(self.document)
response = self.client.delete(
reverse(
'rest_api:cabinet-document', args=(
cabinet.pk, self.document.pk
)
),
response = self.delete(
viewname='rest_api:cabinet-document', kwargs={
'cabinet_pk': cabinet.pk, 'document_pk': self.document.pk
}
)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(cabinet.documents.count(), 0)

View File

@@ -53,14 +53,15 @@ class CabinetViewTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
def _request_delete_cabinet(self):
return self.post(
viewname='cabinets:cabinet_delete', args=(self.cabinet.pk,)
viewname='cabinets:cabinet_delete',
kwargs={'cabinet_pk': self.cabinet.pk}
)
def test_cabinet_delete_view_no_permission(self):
self._create_cabinet()
response = self._request_delete_cabinet()
self.assertEqual(response.status_code, 403)
self.assertEqual(response.status_code, 404)
self.assertEqual(Cabinet.objects.count(), 1)
def test_cabinet_delete_view_with_access(self):
@@ -74,7 +75,7 @@ class CabinetViewTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
def _request_edit_cabinet(self):
return self.post(
viewname='cabinets:cabinet_edit', args=(self.cabinet.pk,), data={
viewname='cabinets:cabinet_edit', kwargs={'cabinet_pk': self.cabinet.pk}, data={
'label': TEST_CABINET_EDITED_LABEL
}
)
@@ -83,7 +84,7 @@ class CabinetViewTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
self._create_cabinet()
response = self._request_edit_cabinet()
self.assertEqual(response.status_code, 403)
self.assertEqual(response.status_code, 404)
self.cabinet.refresh_from_db()
self.assertEqual(self.cabinet.label, TEST_CABINET_LABEL)
@@ -125,16 +126,14 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
def _add_document_to_cabinet(self):
return self.post(
viewname='cabinets:cabinet_add_document', args=(
self.document.pk,
), data={'cabinets': self.cabinet.pk}
viewname='cabinets:document_cabinet_add', kwargs={
'document_pk': self.document.pk
}, data={'cabinets': self.cabinet.pk}
)
def test_cabinet_add_document_view_no_permission(self):
self._create_cabinet()
self.grant_permission(permission=permission_cabinet_view)
response = self._add_document_to_cabinet()
self.assertContains(
@@ -143,10 +142,37 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
self.cabinet.refresh_from_db()
self.assertEqual(self.cabinet.documents.count(), 0)
def test_cabinet_add_document_view_with_access(self):
def test_cabinet_add_document_view_with_cabinet_access(self):
self._create_cabinet()
self.grant_access(
obj=self.cabinet, permission=permission_cabinet_add_document
)
response = self._add_document_to_cabinet()
self.assertContains(
response, text='Select a valid choice.', status_code=404
)
self.cabinet.refresh_from_db()
self.assertEqual(self.cabinet.documents.count(), 0)
def test_cabinet_add_document_view_with_document_access(self):
self._create_cabinet()
self.grant_access(
obj=self.cabinet, permission=permission_cabinet_add_document
)
response = self._add_document_to_cabinet()
self.assertContains(
response, text='Select a valid choice.', status_code=404
)
self.cabinet.refresh_from_db()
self.assertEqual(self.cabinet.documents.count(), 0)
def test_cabinet_add_document_view_with_full_access(self):
self._create_cabinet()
self.grant_access(obj=self.cabinet, permission=permission_cabinet_view)
self.grant_access(
obj=self.cabinet, permission=permission_cabinet_add_document
)
@@ -166,7 +192,7 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
def _request_add_multiple_documents_to_cabinet(self):
return self.post(
viewname='cabinets:cabinet_add_multiple_documents', data={
viewname='cabinets:document_multiple_cabinet_add', data={
'id_list': (self.document.pk,), 'cabinets': self.cabinet.pk
}
)
@@ -174,8 +200,6 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
def test_cabinet_add_multiple_documents_view_no_permission(self):
self._create_cabinet()
self.grant_permission(permission=permission_cabinet_view)
response = self._request_add_multiple_documents_to_cabinet()
self.assertContains(
@@ -184,7 +208,7 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
self.cabinet.refresh_from_db()
self.assertEqual(self.cabinet.documents.count(), 0)
def test_cabinet_add_multiple_documents_view_with_access(self):
def test_cabinet_add_multiple_documents_view_with_full_access(self):
self._create_cabinet()
self.grant_access(
@@ -206,7 +230,7 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
def _request_remove_document_from_cabinet(self):
return self.post(
viewname='cabinets:document_cabinet_remove',
args=(self.document.pk,), data={
kwargs={'document_pk': self.document.pk}, data={
'cabinets': (self.cabinet.pk,),
}
)
@@ -225,7 +249,7 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
self.cabinet.refresh_from_db()
self.assertEqual(self.cabinet.documents.count(), 1)
def test_cabinet_remove_document_view_with_access(self):
def test_cabinet_remove_document_view_with_full_access(self):
self._create_cabinet()
self.cabinet.documents.add(self.document)
@@ -245,7 +269,8 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
def _request_document_cabinet_list(self):
return self.get(
viewname='cabinets:document_cabinet_list', args=(self.document.pk,)
viewname='cabinets:document_cabinet_list',
kwargs={'document_pk': self.document.pk}
)
def test_document_cabinet_list_view_no_permission(self):
@@ -253,10 +278,10 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
self.cabinet.documents.add(self.document)
response = self._request_document_cabinet_list()
self.assertNotContains(
response=response, text=self.document.label, status_code=403
response=response, text=self.document.label, status_code=404
)
self.assertNotContains(
response=response, text=self.cabinet.label, status_code=403
response=response, text=self.cabinet.label, status_code=404
)
def test_document_cabinet_list_view_with_cabinet_access(self):
@@ -265,10 +290,10 @@ class DocumentViewsTestCase(CabinetTestMixin, GenericDocumentViewTestCase):
self.grant_access(obj=self.cabinet, permission=permission_cabinet_view)
response = self._request_document_cabinet_list()
self.assertNotContains(
response=response, text=self.document.label, status_code=403
response=response, text=self.document.label, status_code=404
)
self.assertNotContains(
response=response, text=self.cabinet.label, status_code=403
response=response, text=self.cabinet.label, status_code=404
)
def test_document_cabinet_list_view_with_document_access(self):

View File

@@ -35,7 +35,7 @@ class CabinetDocumentUploadTestCase(GenericDocumentViewTestCase):
def _request_upload_interactive_document_create_view(self):
with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object:
return self.post(
viewname='sources:upload_interactive', args=(self.source.pk,),
viewname='sources:upload_interactive', kwargs={'source_pk': self.source.pk},
data={
'document_type_id': self.document_type.pk,
'source-file': file_object,

View File

@@ -14,61 +14,74 @@ from .views import (
)
urlpatterns = [
url(r'^list/$', CabinetListView.as_view(), name='cabinet_list'),
url(
r'^(?P<pk>\d+)/child/add/$', CabinetChildAddView.as_view(),
name='cabinet_child_add'
),
url(r'^create/$', CabinetCreateView.as_view(), name='cabinet_create'),
url(
r'^(?P<pk>\d+)/edit/$', CabinetEditView.as_view(), name='cabinet_edit'
regex=r'^cabinets/$', name='cabinet_list',
view=CabinetListView.as_view()
),
url(
r'^(?P<pk>\d+)/delete/$', CabinetDeleteView.as_view(),
name='cabinet_delete'
),
url(r'^(?P<pk>\d+)/$', CabinetDetailView.as_view(), name='cabinet_view'),
url(
r'^document/(?P<pk>\d+)/cabinet/add/$',
DocumentAddToCabinetView.as_view(), name='cabinet_add_document'
regex=r'^cabinets/create/$', name='cabinet_create',
view=CabinetCreateView.as_view()
),
url(
r'^document/multiple/cabinet/add/$',
DocumentAddToCabinetView.as_view(),
name='cabinet_add_multiple_documents'
regex=r'^cabinets/(?P<cabinet_pk>\d+)/$', name='cabinet_view',
view=CabinetDetailView.as_view()
),
url(
r'^document/(?P<pk>\d+)/cabinet/remove/$',
DocumentRemoveFromCabinetView.as_view(), name='document_cabinet_remove'
regex=r'^cabinets/(?P<cabinet_pk>\d+)/delete/$', name='cabinet_delete',
view=CabinetDeleteView.as_view()
),
url(
r'^document/multiple/cabinet/remove/$',
DocumentRemoveFromCabinetView.as_view(),
name='multiple_document_cabinet_remove'
regex=r'^cabinets/(?P<cabinet_pk>\d+)/edit/$', name='cabinet_edit',
view=CabinetEditView.as_view()
),
url(
r'^document/(?P<pk>\d+)/cabinet/list/$',
DocumentCabinetListView.as_view(), name='document_cabinet_list'
regex=r'^cabinets/(?P<cabinet_pk>\d+)/child/add/$',
name='cabinet_child_add', view=CabinetChildAddView.as_view()
),
url(
regex=r'^documents/(?P<document_pk>\d+)/cabinets/add/$',
name='document_cabinet_add', view=DocumentAddToCabinetView.as_view()
),
url(
regex=r'^documents/multiple/cabinets/add/$',
name='document_multiple_cabinet_add',
view=DocumentAddToCabinetView.as_view()
),
url(
regex=r'^documents/(?P<document_pk>\d+)/cabinets/remove/$',
name='document_cabinet_remove',
view=DocumentRemoveFromCabinetView.as_view()
),
url(
regex=r'^documents/multiple/cabinets/remove/$',
name='document_multiple_cabinet_remove',
view=DocumentRemoveFromCabinetView.as_view()
),
url(
regex=r'^documents/(?P<document_pk>\d+)/cabinets/list/$',
name='document_cabinet_list', view=DocumentCabinetListView.as_view()
),
]
api_urls = [
url(
r'^cabinets/(?P<pk>[0-9]+)/documents/(?P<document_pk>[0-9]+)/$',
APICabinetDocumentView.as_view(), name='cabinet-document'
regex=r'^cabinets/(?P<cabinet_pk>\d+)/documents/(?P<document_pk>\d+)/$',
name='cabinet-document', view=APICabinetDocumentView.as_view()
),
url(
r'^cabinets/(?P<pk>[0-9]+)/documents/$',
APICabinetDocumentListView.as_view(), name='cabinet-document-list'
regex=r'^cabinets/(?P<cabinet_pk>\d+)/documents/$',
name='cabinet-document-list', view=APICabinetDocumentListView.as_view()
),
url(
r'^cabinets/(?P<pk>[0-9]+)/$', APICabinetView.as_view(),
name='cabinet-detail'
regex=r'^cabinets/(?P<cabinet_pk>\d+)/$', name='cabinet-detail',
view=APICabinetView.as_view()
),
url(r'^cabinets/$', APICabinetListView.as_view(), name='cabinet-list'),
url(
r'^documents/(?P<pk>[0-9]+)/cabinets/$',
APIDocumentCabinetListView.as_view(), name='document-cabinet-list'
regex=r'^cabinets/$', name='cabinet-list',
view=APICabinetListView.as_view()
),
url(
regex=r'^documents/(?P<document_pk>\d+)/cabinets/$',
name='document-cabinet-list', view=APIDocumentCabinetListView.as_view()
),
]

View File

@@ -21,7 +21,7 @@ from mayan.apps.documents.views import DocumentListView
from .forms import CabinetListForm
from .icons import icon_cabinet
from .links import (
link_cabinet_add_document, link_cabinet_child_add, link_cabinet_create
link_cabinet_child_add, link_cabinet_create, link_document_cabinet_add
)
from .models import Cabinet
from .permissions import (
@@ -37,7 +37,7 @@ logger = logging.getLogger(__name__)
class CabinetCreateView(SingleObjectCreateView):
fields = ('label',)
model = Cabinet
post_action_redirect = reverse_lazy('cabinets:cabinet_list')
post_action_redirect = reverse_lazy(viewname='cabinets:cabinet_list')
view_permission = permission_cabinet_create
def get_extra_context(self):
@@ -64,8 +64,8 @@ class CabinetChildAddView(SingleObjectCreateView):
cabinet = super(CabinetChildAddView, self).get_object(*args, **kwargs)
AccessControlList.objects.check_access(
permissions=permission_cabinet_edit, user=self.request.user,
obj=cabinet.get_root()
permissions=permission_cabinet_edit, obj=cabinet.get_root(),
user=self.request.user, raise_404=True
)
return cabinet
@@ -81,7 +81,9 @@ class CabinetChildAddView(SingleObjectCreateView):
class CabinetDeleteView(SingleObjectDeleteView):
model = Cabinet
object_permission = permission_cabinet_delete
post_action_redirect = reverse_lazy('cabinets:cabinet_list')
object_permission_raise_404 = True
pk_url_kwarg = 'cabinet_pk'
post_action_redirect = reverse_lazy(viewname='cabinets:cabinet_list')
def get_extra_context(self):
return {
@@ -95,8 +97,9 @@ class CabinetDetailView(DocumentListView):
def get_document_queryset(self):
queryset = AccessControlList.objects.filter_by_access(
permission=permission_document_view, user=self.request.user,
queryset=self.get_object().documents.all()
permission=permission_document_view,
queryset=self.get_object().documents.all(),
user=self.request.user
)
return queryset
@@ -133,7 +136,9 @@ class CabinetDetailView(DocumentListView):
return context
def get_object(self):
cabinet = get_object_or_404(klass=Cabinet, pk=self.kwargs['pk'])
cabinet = get_object_or_404(
klass=Cabinet, pk=self.kwargs['cabinet_pk']
)
if cabinet.is_root_node():
permission_object = cabinet
@@ -141,8 +146,8 @@ class CabinetDetailView(DocumentListView):
permission_object = cabinet.get_root()
AccessControlList.objects.check_access(
permissions=permission_cabinet_view, user=self.request.user,
obj=permission_object
permissions=permission_cabinet_view, obj=permission_object,
user=self.request.user, raise_404=True
)
return cabinet
@@ -152,7 +157,9 @@ class CabinetEditView(SingleObjectEditView):
fields = ('label',)
model = Cabinet
object_permission = permission_cabinet_edit
post_action_redirect = reverse_lazy('cabinets:cabinet_list')
object_permission_raise_404 = True
pk_url_kwarg = 'cabinet_pk'
post_action_redirect = reverse_lazy(viewname='cabinets:cabinet_list')
def get_extra_context(self):
return {
@@ -188,11 +195,13 @@ class CabinetListView(SingleObjectListView):
class DocumentCabinetListView(CabinetListView):
def dispatch(self, request, *args, **kwargs):
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
self.document = get_object_or_404(
klass=Document, pk=self.kwargs['document_pk']
)
AccessControlList.objects.check_access(
permissions=permission_document_view, user=request.user,
obj=self.document
obj=self.document, raise_404=True
)
return super(DocumentCabinetListView, self).dispatch(
@@ -203,7 +212,7 @@ class DocumentCabinetListView(CabinetListView):
return {
'hide_link': True,
'no_results_icon': icon_cabinet,
'no_results_main_link': link_cabinet_add_document.resolve(
'no_results_main_link': link_document_cabinet_add.resolve(
context=RequestContext(
request=self.request, dict_={'object': self.document}
)
@@ -226,6 +235,7 @@ class DocumentAddToCabinetView(MultipleObjectFormActionView):
form_class = CabinetListForm
model = Document
object_permission = permission_cabinet_add_document
pk_url_kwarg = 'document_pk'
success_message = _(
'Add to cabinet request performed on %(count)d document'
)
@@ -286,11 +296,11 @@ class DocumentAddToCabinetView(MultipleObjectFormActionView):
for cabinet in form.cleaned_data['cabinets']:
AccessControlList.objects.check_access(
obj=cabinet, permissions=permission_cabinet_add_document,
user=self.request.user
user=self.request.user, raise_404=True
)
if cabinet in cabinet_membership:
messages.warning(
self.request, _(
request=self.request, message=_(
'Document: %(document)s is already in '
'cabinet: %(cabinet)s.'
) % {
@@ -302,7 +312,7 @@ class DocumentAddToCabinetView(MultipleObjectFormActionView):
document=instance, user=self.request.user
)
messages.success(
self.request, _(
request=self.request, message=_(
'Document: %(document)s added to cabinet: '
'%(cabinet)s successfully.'
) % {
@@ -315,6 +325,7 @@ class DocumentRemoveFromCabinetView(MultipleObjectFormActionView):
form_class = CabinetListForm
model = Document
object_permission = permission_cabinet_remove_document
pk_url_kwarg = 'document_pk'
success_message = _(
'Remove from cabinet request performed on %(count)d document'
)
@@ -373,12 +384,12 @@ class DocumentRemoveFromCabinetView(MultipleObjectFormActionView):
for cabinet in form.cleaned_data['cabinets']:
AccessControlList.objects.check_access(
obj=cabinet, permissions=permission_cabinet_remove_document,
user=self.request.user
user=self.request.user, raise_404=True
)
if cabinet not in cabinet_membership:
messages.warning(
self.request, _(
request=self.request, message=_(
'Document: %(document)s is not in cabinet: '
'%(cabinet)s.'
) % {
@@ -390,7 +401,7 @@ class DocumentRemoveFromCabinetView(MultipleObjectFormActionView):
document=instance, user=self.request.user
)
messages.success(
self.request, _(
request=self.request, message=_(
'Document: %(document)s removed from cabinet: '
'%(cabinet)s.'
) % {

View File

@@ -28,7 +28,7 @@ class WizardStepCabinets(WizardStep):
@classmethod
def done(cls, wizard):
result = {}
cleaned_data = wizard.get_cleaned_data_for_step(cls.name)
cleaned_data = wizard.get_cleaned_data_for_step(step=cls.name)
if cleaned_data:
result['cabinets'] = [
force_text(cabinet.pk) for cabinet in cleaned_data['cabinets']