From 1982c9920fd78e118ab0be9cde26acda694a4cd1 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 14 May 2019 21:03:15 -0400 Subject: [PATCH] Add cabinet created and edited events Signed-off-by: Roberto Rosario --- HISTORY.rst | 1 + docs/releases/3.2.rst | 1 + mayan/apps/cabinets/apps.py | 25 +++++++- mayan/apps/cabinets/events.py | 11 +++- mayan/apps/cabinets/models.py | 24 ++++++- mayan/apps/cabinets/tests/test_events.py | 80 +++++++++++++++++++++--- mayan/apps/cabinets/views.py | 14 ++++- 7 files changed, 141 insertions(+), 15 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index d2fec5c6a9..031c06a095 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -261,6 +261,7 @@ * Allow setting the Docker user UID and GUID. * Add task path validation. * Increase dropzone upload file size limit to 2GB. +* Add cabinet created and edited events. 3.1.11 (2019-04-XX) =================== diff --git a/docs/releases/3.2.rst b/docs/releases/3.2.rst index a8997a29d2..cc748e59ac 100644 --- a/docs/releases/3.2.rst +++ b/docs/releases/3.2.rst @@ -571,6 +571,7 @@ Other changes * Allow setting the Docker user UID and GUID. * Add task path validation. * Increase dropzone upload file size limit to 2GB +* Add cabinet created and edited events. Removals diff --git a/mayan/apps/cabinets/apps.py b/mayan/apps/cabinets/apps.py index 3944655b8b..6011bd4874 100644 --- a/mayan/apps/cabinets/apps.py +++ b/mayan/apps/cabinets/apps.py @@ -10,10 +10,19 @@ from mayan.apps.common.menus import ( menu_facet, menu_list_facet, menu_main, menu_multi_item, menu_object, menu_secondary ) +from mayan.apps.events.classes import ModelEventType +from mayan.apps.events.links import ( + link_events_for_object, link_object_event_types_user_subcriptions_list, +) +from mayan.apps.events.permissions import permission_events_view from mayan.apps.documents.search import document_page_search, document_search from mayan.apps.navigation.classes import SourceColumn from .dependencies import * # NOQA +from .events import ( + event_cabinet_edited, event_cabinet_add_document, + event_cabinet_remove_document +) from .links import ( link_cabinet_list, link_document_cabinet_list, link_document_cabinet_remove, link_document_cabinet_add, @@ -58,10 +67,18 @@ class CabinetsApp(MayanAppConfig): name='document_cabinets', value=method_get_document_cabinets ) + ModelEventType.register( + model=Cabinet, event_types=( + event_cabinet_edited, event_cabinet_add_document, + event_cabinet_remove_document + ) + ) + ModelPermission.register( model=Document, permissions=( permission_cabinet_add_document, - permission_cabinet_remove_document + permission_cabinet_remove_document, + permission_events_view ) ) @@ -115,7 +132,11 @@ class CabinetsApp(MayanAppConfig): ) ) menu_list_facet.bind_links( - links=(link_cabinet_view, link_custom_acl_list), + links=( + link_cabinet_view, link_custom_acl_list, + link_events_for_object, + link_object_event_types_user_subcriptions_list, + ), sources=(Cabinet,) ) diff --git a/mayan/apps/cabinets/events.py b/mayan/apps/cabinets/events.py index 82f7e2115c..60b34358ba 100644 --- a/mayan/apps/cabinets/events.py +++ b/mayan/apps/cabinets/events.py @@ -6,9 +6,16 @@ from mayan.apps.events.classes import EventTypeNamespace namespace = EventTypeNamespace(label=_('Cabinets'), name='cabinets') -event_cabinets_add_document = namespace.add_event_type( + +event_cabinet_created = namespace.add_event_type( + label=_('Cabinet created'), name='cabinet_created' +) +event_cabinet_edited = namespace.add_event_type( + label=_('Cabinet edited'), name='cabinet_edited' +) +event_cabinet_add_document = namespace.add_event_type( label=_('Document added to cabinet'), name='add_document' ) -event_cabinets_remove_document = namespace.add_event_type( +event_cabinet_remove_document = namespace.add_event_type( label=_('Document removed from cabinet'), name='remove_document' ) diff --git a/mayan/apps/cabinets/models.py b/mayan/apps/cabinets/models.py index d1f07bb01c..8db6f827b6 100644 --- a/mayan/apps/cabinets/models.py +++ b/mayan/apps/cabinets/models.py @@ -13,7 +13,10 @@ from mayan.apps.acls.models import AccessControlList from mayan.apps.documents.models import Document from mayan.apps.documents.permissions import permission_document_view -from .events import event_cabinets_add_document, event_cabinets_remove_document +from .events import ( + event_cabinet_created, event_cabinet_edited, event_cabinet_add_document, + event_cabinet_remove_document +) from .search import cabinet_search # NOQA @@ -52,7 +55,7 @@ class Cabinet(MPTTModel): method but this method provides the event commit already coded. """ self.documents.add(document) - event_cabinets_add_document.commit( + event_cabinet_add_document.commit( action_object=self, actor=user, target=document ) @@ -93,10 +96,25 @@ class Cabinet(MPTTModel): corresponding event commit. """ self.documents.remove(document) - event_cabinets_remove_document.commit( + event_cabinet_remove_document.commit( action_object=self, actor=user, target=document ) + def save(self, *args, **kwargs): + _user = kwargs.pop('_user', None) + + with transaction.atomic(): + is_new = not self.pk + super(Cabinet, self).save(*args, **kwargs) + if is_new: + event_cabinet_created.commit( + actor=_user, target=self + ) + else: + event_cabinet_edited.commit( + actor=_user, target=self + ) + def validate_unique(self, exclude=None): """ Explicit validation of uniqueness of parent+label as the provided diff --git a/mayan/apps/cabinets/tests/test_events.py b/mayan/apps/cabinets/tests/test_events.py index 5f0b22add5..d131291abd 100644 --- a/mayan/apps/cabinets/tests/test_events.py +++ b/mayan/apps/cabinets/tests/test_events.py @@ -2,31 +2,97 @@ from __future__ import unicode_literals from actstream.models import Action +from mayan.apps.common.tests import GenericViewTestCase from mayan.apps.documents.tests.test_models import GenericDocumentTestCase from ..events import ( - event_cabinets_add_document, event_cabinets_remove_document + event_cabinet_created, event_cabinet_edited, event_cabinet_add_document, + event_cabinet_remove_document ) +from ..models import Cabinet +from ..permissions import permission_cabinet_create, permission_cabinet_edit -from .mixins import CabinetTestMixin +from .mixins import CabinetTestMixin, CabinetViewTestMixin -class CabinetsEventsTestCase(CabinetTestMixin, GenericDocumentTestCase): - def setUp(self): - super(CabinetsEventsTestCase, self).setUp() +class CabinetsEventsTestCase( + CabinetTestMixin, CabinetViewTestMixin, GenericViewTestCase +): + def test_cabinet_create_event_no_permissions(self): + action_count = Action.objects.count() + + response = self._request_test_cabinet_create_view() + self.assertEqual(response.status_code, 403) + + self.assertEqual(Action.objects.count(), action_count) + + def test_cabinet_create_event_with_permissions(self): + self.grant_permission(permission=permission_cabinet_create) + + action_count = Action.objects.count() + + response = self._request_test_cabinet_create_view() + self.assertEqual(response.status_code, 302) + + self.assertEqual(Action.objects.count(), action_count + 1) + + event = Action.objects.first() + + cabinet = Cabinet.objects.first() + + self.assertEqual(event.verb, event_cabinet_created.id) + self.assertEqual(event.target, cabinet) + self.assertEqual(event.actor, self._test_case_user) + + def test_cabinet_edit_event_no_permissions(self): self._create_test_cabinet() + action_count = Action.objects.count() + + response = self._request_test_cabinet_edit_view() + self.assertEqual(response.status_code, 404) + + self.assertEqual(Action.objects.count(), action_count) + + def test_cabinet_edit_event_with_access(self): + self._create_test_cabinet() + + self.grant_access( + obj=self.test_cabinet, permission=permission_cabinet_edit + ) + + action_count = Action.objects.count() + + response = self._request_test_cabinet_edit_view() + self.assertEqual(response.status_code, 302) + + self.assertEqual(Action.objects.count(), action_count + 1) + + event = Action.objects.first() + + self.assertEqual(event.verb, event_cabinet_edited.id) + self.assertEqual(event.target, self.test_cabinet) + self.assertEqual(event.actor, self._test_case_user) + + +class CabinetDocumentsEventsTestCase( + CabinetTestMixin, CabinetViewTestMixin, GenericDocumentTestCase +): def test_document_cabinet_add_event(self): + self._create_test_cabinet() + Action.objects.all().delete() self.test_cabinet.add_document(document=self.test_document) self.assertEqual(Action.objects.last().target, self.test_document) self.assertEqual( Action.objects.last().verb, - event_cabinets_add_document.id + event_cabinet_add_document.id ) def test_document_cabinet_remove_event(self): + self._create_test_cabinet() + self.test_cabinet.add_document(document=self.test_document) Action.objects.all().delete() self.test_cabinet.remove_document(document=self.test_document) @@ -34,5 +100,5 @@ class CabinetsEventsTestCase(CabinetTestMixin, GenericDocumentTestCase): self.assertEqual(Action.objects.first().target, self.test_document) self.assertEqual( Action.objects.first().verb, - event_cabinets_remove_document.id + event_cabinet_remove_document.id ) diff --git a/mayan/apps/cabinets/views.py b/mayan/apps/cabinets/views.py index d0e8d3e21a..7d095ba795 100644 --- a/mayan/apps/cabinets/views.py +++ b/mayan/apps/cabinets/views.py @@ -45,6 +45,9 @@ class CabinetCreateView(SingleObjectCreateView): 'title': _('Create cabinet'), } + def get_save_extra_data(self): + return {'_user': self.request.user} + class CabinetChildAddView(ExternalObjectMixin, SingleObjectCreateView): fields = ('label',) @@ -63,7 +66,10 @@ class CabinetChildAddView(ExternalObjectMixin, SingleObjectCreateView): return self.external_object.get_descendants() def get_save_extra_data(self): - return {'parent': self.external_object} + return { + 'parent': self.external_object, + '_user': self.request.user + } class CabinetDeleteView(SingleObjectDeleteView): @@ -123,6 +129,9 @@ class CabinetDetailView(ExternalObjectMixin, DocumentListView): return context + def get_save_extra_data(self): + return {'_user': self.request.user} + class CabinetEditView(SingleObjectEditView): fields = ('label',) @@ -136,6 +145,9 @@ class CabinetEditView(SingleObjectEditView): 'title': _('Edit cabinet: %s') % self.get_object(), } + def get_save_extra_data(self): + return {'_user': self.request.user} + class CabinetListView(SingleObjectListView): object_permission = permission_cabinet_view