Add support for editing document comments
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -250,6 +250,7 @@
|
|||||||
* Update tag document list and the document tag list
|
* Update tag document list and the document tag list
|
||||||
views to require the view permissions for both objects.
|
views to require the view permissions for both objects.
|
||||||
* Install and server static content to and from the image.
|
* Install and server static content to and from the image.
|
||||||
|
* Add support for editing document comments.
|
||||||
|
|
||||||
3.1.11 (2019-04-XX)
|
3.1.11 (2019-04-XX)
|
||||||
===================
|
===================
|
||||||
|
|||||||
@@ -560,7 +560,7 @@ Other changes
|
|||||||
* Install and server static content to and from the image.
|
* Install and server static content to and from the image.
|
||||||
Remove installation of static content from the setup
|
Remove installation of static content from the setup
|
||||||
and upgrade stages.
|
and upgrade stages.
|
||||||
|
* Add support for editing document comments.
|
||||||
|
|
||||||
|
|
||||||
Removals
|
Removals
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from mayan.apps.documents.models import Document
|
|||||||
|
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_document_comment_create, permission_document_comment_delete,
|
permission_document_comment_create, permission_document_comment_delete,
|
||||||
permission_document_comment_view
|
permission_document_comment_edit, permission_document_comment_view
|
||||||
)
|
)
|
||||||
from .serializers import CommentSerializer, WritableCommentSerializer
|
from .serializers import CommentSerializer, WritableCommentSerializer
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ class APICommentListView(generics.ListCreateAPIView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class APICommentView(generics.RetrieveDestroyAPIView):
|
class APICommentView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
"""
|
"""
|
||||||
delete: Delete the selected document comment.
|
delete: Delete the selected document comment.
|
||||||
get: Returns the details of the selected document comment.
|
get: Returns the details of the selected document comment.
|
||||||
@@ -75,10 +75,12 @@ class APICommentView(generics.RetrieveDestroyAPIView):
|
|||||||
serializer_class = CommentSerializer
|
serializer_class = CommentSerializer
|
||||||
|
|
||||||
def get_document(self):
|
def get_document(self):
|
||||||
if self.request.method == 'GET':
|
if self.request.method == 'DELETE':
|
||||||
permission_required = permission_document_comment_view
|
|
||||||
else:
|
|
||||||
permission_required = permission_document_comment_delete
|
permission_required = permission_document_comment_delete
|
||||||
|
elif self.request.method in ('PATCH', 'PUT'):
|
||||||
|
permission_required = permission_document_comment_edit
|
||||||
|
else:
|
||||||
|
permission_required = permission_document_comment_view
|
||||||
|
|
||||||
document = get_object_or_404(
|
document = get_object_or_404(
|
||||||
klass=Document, pk=self.kwargs['document_pk']
|
klass=Document, pk=self.kwargs['document_pk']
|
||||||
|
|||||||
@@ -11,20 +11,22 @@ from mayan.apps.common.menus import (
|
|||||||
from mayan.apps.documents.search import document_page_search, document_search
|
from mayan.apps.documents.search import document_page_search, document_search
|
||||||
from mayan.apps.events.classes import ModelEventType
|
from mayan.apps.events.classes import ModelEventType
|
||||||
from mayan.apps.events.links import (
|
from mayan.apps.events.links import (
|
||||||
link_events_for_object,
|
link_events_for_object, link_object_event_types_user_subcriptions_list
|
||||||
)
|
)
|
||||||
from mayan.apps.events.permissions import permission_events_view
|
from mayan.apps.events.permissions import permission_events_view
|
||||||
from mayan.apps.navigation.classes import SourceColumn
|
from mayan.apps.navigation.classes import SourceColumn
|
||||||
|
|
||||||
from .events import (
|
from .events import (
|
||||||
event_document_comment_created, event_document_comment_deleted
|
event_document_comment_created, event_document_comment_deleted,
|
||||||
|
event_document_comment_edited
|
||||||
)
|
)
|
||||||
from .links import (
|
from .links import (
|
||||||
link_comment_add, link_comment_delete, link_comments_for_document
|
link_comment_add, link_comment_delete, link_comment_edit,
|
||||||
|
link_comments_for_document
|
||||||
)
|
)
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_document_comment_create, permission_document_comment_delete,
|
permission_document_comment_create, permission_document_comment_delete,
|
||||||
permission_document_comment_view
|
permission_document_comment_edit, permission_document_comment_view
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -46,9 +48,15 @@ class DocumentCommentsApp(MayanAppConfig):
|
|||||||
|
|
||||||
Comment = self.get_model(model_name='Comment')
|
Comment = self.get_model(model_name='Comment')
|
||||||
|
|
||||||
|
ModelEventType.register(
|
||||||
|
model=Comment, event_types=(
|
||||||
|
event_document_comment_edited,
|
||||||
|
)
|
||||||
|
)
|
||||||
ModelEventType.register(
|
ModelEventType.register(
|
||||||
model=Document, event_types=(
|
model=Document, event_types=(
|
||||||
event_document_comment_created, event_document_comment_deleted
|
event_document_comment_created, event_document_comment_deleted,
|
||||||
|
event_document_comment_edited
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -60,7 +68,9 @@ class DocumentCommentsApp(MayanAppConfig):
|
|||||||
)
|
)
|
||||||
ModelPermission.register(
|
ModelPermission.register(
|
||||||
model=Document, permissions=(
|
model=Document, permissions=(
|
||||||
permission_document_comment_create, permission_document_comment_delete,
|
permission_document_comment_create,
|
||||||
|
permission_document_comment_delete,
|
||||||
|
permission_document_comment_edit,
|
||||||
permission_document_comment_view
|
permission_document_comment_view
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -88,6 +98,7 @@ class DocumentCommentsApp(MayanAppConfig):
|
|||||||
menu_list_facet.bind_links(
|
menu_list_facet.bind_links(
|
||||||
links=(
|
links=(
|
||||||
link_events_for_object,
|
link_events_for_object,
|
||||||
|
link_object_event_types_user_subcriptions_list
|
||||||
), sources=(Comment,)
|
), sources=(Comment,)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -95,12 +106,13 @@ class DocumentCommentsApp(MayanAppConfig):
|
|||||||
links=(link_comment_add,),
|
links=(link_comment_add,),
|
||||||
sources=(
|
sources=(
|
||||||
'comments:comments_for_document', 'comments:comment_add',
|
'comments:comments_for_document', 'comments:comment_add',
|
||||||
'comments:comment_delete', 'comments:comment_multiple_delete'
|
'comments:comment_delete', 'comments:comment_details',
|
||||||
|
'comments:comment_edit', 'comments:comment_multiple_delete'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
menu_object.bind_links(
|
menu_object.bind_links(
|
||||||
links=(link_comment_delete,), sources=(Comment,)
|
links=(link_comment_delete, link_comment_edit), sources=(Comment,)
|
||||||
)
|
)
|
||||||
|
|
||||||
registry.register(Comment)
|
registry.register(Comment)
|
||||||
|
|||||||
@@ -14,3 +14,6 @@ event_document_comment_created = namespace.add_event_type(
|
|||||||
event_document_comment_deleted = namespace.add_event_type(
|
event_document_comment_deleted = namespace.add_event_type(
|
||||||
label=_('Document comment deleted'), name='delete'
|
label=_('Document comment deleted'), name='delete'
|
||||||
)
|
)
|
||||||
|
event_document_comment_edited = namespace.add_event_type(
|
||||||
|
label=_('Document comment edited'), name='edited'
|
||||||
|
)
|
||||||
|
|||||||
18
mayan/apps/document_comments/forms.py
Normal file
18
mayan/apps/document_comments/forms.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
from mayan.apps.common.forms import DetailForm
|
||||||
|
|
||||||
|
from .models import Comment
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentCommentDetailForm(DetailForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
fields = ('comment',)
|
||||||
|
extra_fields = (
|
||||||
|
{'field': 'submit_date', 'widget': forms.widgets.DateTimeInput},
|
||||||
|
{'field': 'user'},
|
||||||
|
)
|
||||||
|
model = Comment
|
||||||
@@ -7,4 +7,5 @@ icon_comment_add = Icon(
|
|||||||
secondary_symbol='plus'
|
secondary_symbol='plus'
|
||||||
)
|
)
|
||||||
icon_comment_delete = Icon(driver_name='fontawesome', symbol='times')
|
icon_comment_delete = Icon(driver_name='fontawesome', symbol='times')
|
||||||
|
icon_comment_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
|
||||||
icon_comments_for_document = Icon(driver_name='fontawesome', symbol='comment')
|
icon_comments_for_document = Icon(driver_name='fontawesome', symbol='comment')
|
||||||
|
|||||||
@@ -4,10 +4,13 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
|
|
||||||
from mayan.apps.navigation.classes import Link
|
from mayan.apps.navigation.classes import Link
|
||||||
|
|
||||||
from .icons import icon_comment_add, icon_comment_delete, icon_comments_for_document
|
from .icons import (
|
||||||
|
icon_comment_add, icon_comment_delete, icon_comment_edit,
|
||||||
|
icon_comments_for_document
|
||||||
|
)
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_document_comment_create, permission_document_comment_delete,
|
permission_document_comment_create, permission_document_comment_delete,
|
||||||
permission_document_comment_view
|
permission_document_comment_edit, permission_document_comment_view
|
||||||
)
|
)
|
||||||
|
|
||||||
link_comment_add = Link(
|
link_comment_add = Link(
|
||||||
@@ -20,6 +23,11 @@ link_comment_delete = Link(
|
|||||||
permissions=(permission_document_comment_delete,), tags='dangerous',
|
permissions=(permission_document_comment_delete,), tags='dangerous',
|
||||||
text=_('Delete'), view='comments:comment_delete',
|
text=_('Delete'), view='comments:comment_delete',
|
||||||
)
|
)
|
||||||
|
link_comment_edit = Link(
|
||||||
|
args='object.pk', icon_class=icon_comment_edit,
|
||||||
|
permissions=(permission_document_comment_edit,),
|
||||||
|
text=_('Edit'), view='comments:comment_edit',
|
||||||
|
)
|
||||||
link_comments_for_document = Link(
|
link_comments_for_document = Link(
|
||||||
args='resolved_object.pk', icon_class=icon_comments_for_document,
|
args='resolved_object.pk', icon_class=icon_comments_for_document,
|
||||||
permissions=(permission_document_comment_view,), text=_('Comments'),
|
permissions=(permission_document_comment_view,), text=_('Comments'),
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ import logging
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
|
from django.urls import reverse
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from mayan.apps.documents.models import Document
|
from mayan.apps.documents.models import Document
|
||||||
|
|
||||||
from .events import (
|
from .events import (
|
||||||
event_document_comment_created, event_document_comment_deleted
|
event_document_comment_created, event_document_comment_deleted,
|
||||||
|
event_document_comment_edited
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -53,6 +55,11 @@ class Comment(models.Model):
|
|||||||
actor=_user, target=self.document
|
actor=_user, target=self.document
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse(
|
||||||
|
viewname='comments:comment_details', kwargs={'pk': self.pk}
|
||||||
|
)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
_user = kwargs.pop('_user', None) or self.user
|
_user = kwargs.pop('_user', None) or self.user
|
||||||
created = not self.pk
|
created = not self.pk
|
||||||
@@ -61,5 +68,9 @@ class Comment(models.Model):
|
|||||||
super(Comment, self).save(*args, **kwargs)
|
super(Comment, self).save(*args, **kwargs)
|
||||||
if created:
|
if created:
|
||||||
event_document_comment_created.commit(
|
event_document_comment_created.commit(
|
||||||
action_object=self, actor=_user, target=self.document,
|
action_object=self.document, actor=_user, target=self,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
event_document_comment_edited.commit(
|
||||||
|
action_object=self.document, actor=_user, target=self,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ permission_document_comment_create = namespace.add_permission(
|
|||||||
permission_document_comment_delete = namespace.add_permission(
|
permission_document_comment_delete = namespace.add_permission(
|
||||||
label=_('Delete comments'), name='comment_delete'
|
label=_('Delete comments'), name='comment_delete'
|
||||||
)
|
)
|
||||||
|
permission_document_comment_edit = namespace.add_permission(
|
||||||
|
label=_('Edit comments'), name='comment_edit'
|
||||||
|
)
|
||||||
permission_document_comment_view = namespace.add_permission(
|
permission_document_comment_view = namespace.add_permission(
|
||||||
label=_('View comments'), name='comment_view'
|
label=_('View comments'), name='comment_view'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
TEST_COMMENT_TEXT = 'test comment text'
|
TEST_COMMENT_TEXT = 'test comment text'
|
||||||
|
TEST_COMMENT_TEXT_EDITED = 'test comment text edited'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .literals import TEST_COMMENT_TEXT
|
from .literals import TEST_COMMENT_TEXT, TEST_COMMENT_TEXT_EDITED
|
||||||
|
|
||||||
|
|
||||||
class DocumentCommentTestMixin(object):
|
class DocumentCommentTestMixin(object):
|
||||||
@@ -24,3 +24,19 @@ class DocumentCommentViewTestMixin(object):
|
|||||||
'pk': self.test_document_comment.pk
|
'pk': self.test_document_comment.pk
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _request_test_comment_edit_view(self):
|
||||||
|
return self.post(
|
||||||
|
viewname='comments:comment_edit', kwargs={
|
||||||
|
'pk': self.test_document_comment.pk,
|
||||||
|
}, data={
|
||||||
|
'comment': TEST_COMMENT_TEXT_EDITED
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def _request_test_comment_list_view(self):
|
||||||
|
return self.get(
|
||||||
|
viewname='comments:comments_for_document', kwargs={
|
||||||
|
'pk': self.test_document.pk,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ from mayan.apps.rest_api.tests import BaseAPITestCase
|
|||||||
from ..models import Comment
|
from ..models import Comment
|
||||||
from ..permissions import (
|
from ..permissions import (
|
||||||
permission_document_comment_create, permission_document_comment_delete,
|
permission_document_comment_create, permission_document_comment_delete,
|
||||||
permission_document_comment_view
|
permission_document_comment_edit, permission_document_comment_view
|
||||||
)
|
)
|
||||||
|
|
||||||
from .literals import TEST_COMMENT_TEXT
|
from .literals import TEST_COMMENT_TEXT, TEST_COMMENT_TEXT_EDITED
|
||||||
from .mixins import DocumentCommentTestMixin
|
from .mixins import DocumentCommentTestMixin
|
||||||
|
|
||||||
|
|
||||||
class CommentAPITestCase(
|
class CommentAPITestCase(
|
||||||
DocumentCommentTestMixin, DocumentTestMixin, BaseAPITestCase
|
DocumentCommentTestMixin, DocumentTestMixin, BaseAPITestCase
|
||||||
):
|
):
|
||||||
def _request_comment_create_view(self):
|
def _request_test_comment_create_api_view(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='rest_api:comment-list', kwargs={
|
viewname='rest_api:comment-list', kwargs={
|
||||||
'document_pk': self.test_document.pk
|
'document_pk': self.test_document.pk
|
||||||
@@ -28,7 +28,7 @@ class CommentAPITestCase(
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_comment_create_view_no_access(self):
|
def test_comment_create_view_no_access(self):
|
||||||
response = self._request_comment_create_view()
|
response = self._request_test_comment_create_api_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
self.assertEqual(Comment.objects.count(), 0)
|
self.assertEqual(Comment.objects.count(), 0)
|
||||||
@@ -38,14 +38,14 @@ class CommentAPITestCase(
|
|||||||
obj=self.test_document, permission=permission_document_comment_create
|
obj=self.test_document, permission=permission_document_comment_create
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_comment_create_view()
|
response = self._request_test_comment_create_api_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
|
|
||||||
comment = Comment.objects.first()
|
comment = Comment.objects.first()
|
||||||
self.assertEqual(Comment.objects.count(), 1)
|
self.assertEqual(Comment.objects.count(), 1)
|
||||||
self.assertEqual(response.data['id'], comment.pk)
|
self.assertEqual(response.data['id'], comment.pk)
|
||||||
|
|
||||||
def _request_comment_delete_view(self):
|
def _request_test_comment_delete_api_view(self):
|
||||||
return self.delete(
|
return self.delete(
|
||||||
viewname='rest_api:comment-detail', kwargs={
|
viewname='rest_api:comment-detail', kwargs={
|
||||||
'document_pk': self.test_document.pk,
|
'document_pk': self.test_document.pk,
|
||||||
@@ -56,7 +56,7 @@ class CommentAPITestCase(
|
|||||||
def test_comment_delete_view_no_access(self):
|
def test_comment_delete_view_no_access(self):
|
||||||
self._create_test_comment()
|
self._create_test_comment()
|
||||||
|
|
||||||
response = self._request_comment_delete_view()
|
response = self._request_test_comment_delete_api_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
self.assertTrue(self.test_document_comment in Comment.objects.all())
|
self.assertTrue(self.test_document_comment in Comment.objects.all())
|
||||||
@@ -67,12 +67,43 @@ class CommentAPITestCase(
|
|||||||
obj=self.test_document, permission=permission_document_comment_delete
|
obj=self.test_document, permission=permission_document_comment_delete
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_comment_delete_view()
|
response = self._request_test_comment_delete_api_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||||
|
|
||||||
self.assertFalse(self.test_document_comment in Comment.objects.all())
|
self.assertFalse(self.test_document_comment in Comment.objects.all())
|
||||||
|
|
||||||
def _request_comment_view(self):
|
def _request_comment_edit_patch_api_view(self):
|
||||||
|
return self.patch(
|
||||||
|
viewname='rest_api:comment-detail', kwargs={
|
||||||
|
'document_pk': self.test_document.pk,
|
||||||
|
'comment_pk': self.test_document_comment.pk,
|
||||||
|
}, data={'comment': TEST_COMMENT_TEXT_EDITED}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_comment_edit_view_no_access(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
comment_text = self.test_document_comment.comment
|
||||||
|
|
||||||
|
response = self._request_comment_edit_patch_api_view()
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
|
self.test_document_comment.refresh_from_db()
|
||||||
|
self.assertEqual(self.test_document_comment.comment, comment_text)
|
||||||
|
|
||||||
|
def test_comment_edit_view_with_access(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document, permission=permission_document_comment_edit
|
||||||
|
)
|
||||||
|
comment_text = self.test_document_comment.comment
|
||||||
|
|
||||||
|
response = self._request_comment_edit_patch_api_view()
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
self.test_document_comment.refresh_from_db()
|
||||||
|
self.assertNotEqual(self.test_document_comment.comment, comment_text)
|
||||||
|
|
||||||
|
def _request_test_comment_api_view(self):
|
||||||
return self.get(
|
return self.get(
|
||||||
viewname='rest_api:comment-detail', kwargs={
|
viewname='rest_api:comment-detail', kwargs={
|
||||||
'document_pk': self.test_document.pk,
|
'document_pk': self.test_document.pk,
|
||||||
@@ -83,7 +114,7 @@ class CommentAPITestCase(
|
|||||||
def test_comment_detail_view_no_access(self):
|
def test_comment_detail_view_no_access(self):
|
||||||
self._create_test_comment()
|
self._create_test_comment()
|
||||||
|
|
||||||
response = self._request_comment_view()
|
response = self._request_test_comment_api_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
def test_comment_detail_view_with_access(self):
|
def test_comment_detail_view_with_access(self):
|
||||||
@@ -92,12 +123,12 @@ class CommentAPITestCase(
|
|||||||
obj=self.test_document, permission=permission_document_comment_view
|
obj=self.test_document, permission=permission_document_comment_view
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_comment_view()
|
response = self._request_test_comment_api_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
self.assertEqual(response.data['comment'], self.test_document_comment.comment)
|
self.assertEqual(response.data['comment'], self.test_document_comment.comment)
|
||||||
|
|
||||||
def _request_comment_list_view(self):
|
def _request_test_comment_list_api_view(self):
|
||||||
return self.get(
|
return self.get(
|
||||||
viewname='rest_api:comment-list', kwargs={
|
viewname='rest_api:comment-list', kwargs={
|
||||||
'document_pk': self.test_document.pk
|
'document_pk': self.test_document.pk
|
||||||
@@ -107,7 +138,7 @@ class CommentAPITestCase(
|
|||||||
def test_comment_list_view_no_access(self):
|
def test_comment_list_view_no_access(self):
|
||||||
self._create_test_comment()
|
self._create_test_comment()
|
||||||
|
|
||||||
response = self._request_comment_list_view()
|
response = self._request_test_comment_list_api_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
def test_comment_list_view_with_access(self):
|
def test_comment_list_view_with_access(self):
|
||||||
@@ -116,7 +147,7 @@ class CommentAPITestCase(
|
|||||||
obj=self.test_document, permission=permission_document_comment_view
|
obj=self.test_document, permission=permission_document_comment_view
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self._request_comment_list_view()
|
response = self._request_test_comment_list_api_view()
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response.data['results'][0]['comment'], self.test_document_comment.comment
|
response.data['results'][0]['comment'], self.test_document_comment.comment
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ from actstream.models import Action
|
|||||||
from mayan.apps.documents.tests import GenericDocumentViewTestCase
|
from mayan.apps.documents.tests import GenericDocumentViewTestCase
|
||||||
|
|
||||||
from ..events import (
|
from ..events import (
|
||||||
event_document_comment_created, event_document_comment_deleted
|
event_document_comment_created, event_document_comment_deleted,
|
||||||
|
event_document_comment_edited
|
||||||
)
|
)
|
||||||
from ..models import Comment
|
from ..models import Comment
|
||||||
from ..permissions import (
|
from ..permissions import (
|
||||||
permission_document_comment_create, permission_document_comment_delete
|
permission_document_comment_create, permission_document_comment_delete,
|
||||||
|
permission_document_comment_edit
|
||||||
)
|
)
|
||||||
|
|
||||||
from .mixins import DocumentCommentTestMixin, DocumentCommentViewTestMixin
|
from .mixins import DocumentCommentTestMixin, DocumentCommentViewTestMixin
|
||||||
@@ -41,9 +43,9 @@ class CommentEventsTestCase(
|
|||||||
|
|
||||||
comment = Comment.objects.first()
|
comment = Comment.objects.first()
|
||||||
|
|
||||||
self.assertEqual(event.action_object, comment)
|
self.assertEqual(event.action_object, self.test_document)
|
||||||
self.assertEqual(event.actor, self._test_case_user)
|
self.assertEqual(event.actor, self._test_case_user)
|
||||||
self.assertEqual(event.target, self.test_document)
|
self.assertEqual(event.target, comment)
|
||||||
self.assertEqual(event.verb, event_document_comment_created.id)
|
self.assertEqual(event.verb, event_document_comment_created.id)
|
||||||
|
|
||||||
def test_comment_delete_event_no_permissions(self):
|
def test_comment_delete_event_no_permissions(self):
|
||||||
@@ -77,3 +79,34 @@ class CommentEventsTestCase(
|
|||||||
self.assertEqual(event.actor, self._test_case_user)
|
self.assertEqual(event.actor, self._test_case_user)
|
||||||
self.assertEqual(event.target, self.test_document)
|
self.assertEqual(event.target, self.test_document)
|
||||||
self.assertEqual(event.verb, event_document_comment_deleted.id)
|
self.assertEqual(event.verb, event_document_comment_deleted.id)
|
||||||
|
|
||||||
|
def test_comment_edit_event_no_permissions(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
|
||||||
|
action_count = Action.objects.count()
|
||||||
|
|
||||||
|
response = self._request_test_comment_edit_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
self.assertEqual(Action.objects.count(), action_count)
|
||||||
|
|
||||||
|
def test_comment_edit_event_with_access(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document,
|
||||||
|
permission=permission_document_comment_edit
|
||||||
|
)
|
||||||
|
|
||||||
|
action_count = Action.objects.count()
|
||||||
|
|
||||||
|
response = self._request_test_comment_edit_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
self.assertEqual(Action.objects.count(), action_count + 1)
|
||||||
|
|
||||||
|
event = Action.objects.first()
|
||||||
|
|
||||||
|
self.assertEqual(event.action_object, self.test_document)
|
||||||
|
self.assertEqual(event.actor, self._test_case_user)
|
||||||
|
self.assertEqual(event.target, self.test_document_comment)
|
||||||
|
self.assertEqual(event.verb, event_document_comment_edited.id)
|
||||||
|
|||||||
110
mayan/apps/document_comments/tests/test_views.py
Normal file
110
mayan/apps/document_comments/tests/test_views.py
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from mayan.apps.documents.tests import GenericDocumentViewTestCase
|
||||||
|
|
||||||
|
from ..models import Comment
|
||||||
|
from ..permissions import (
|
||||||
|
permission_document_comment_create, permission_document_comment_delete,
|
||||||
|
permission_document_comment_edit, permission_document_comment_view
|
||||||
|
)
|
||||||
|
|
||||||
|
from .mixins import DocumentCommentTestMixin, DocumentCommentViewTestMixin
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentCommentViewTestCase(
|
||||||
|
DocumentCommentViewTestMixin, DocumentCommentTestMixin,
|
||||||
|
GenericDocumentViewTestCase
|
||||||
|
):
|
||||||
|
def test_comment_create_view_no_permissions(self):
|
||||||
|
comment_count = Comment.objects.count()
|
||||||
|
|
||||||
|
response = self._request_test_comment_create_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
self.assertEqual(comment_count, Comment.objects.count())
|
||||||
|
|
||||||
|
def test_comment_create_view_with_permissions(self):
|
||||||
|
comment_count = Comment.objects.count()
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document,
|
||||||
|
permission=permission_document_comment_create
|
||||||
|
)
|
||||||
|
response = self._request_test_comment_create_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
self.assertEqual(comment_count + 1, Comment.objects.count())
|
||||||
|
|
||||||
|
def test_comment_delete_view_no_permissions(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
|
||||||
|
comment_count = Comment.objects.count()
|
||||||
|
|
||||||
|
response = self._request_test_comment_delete_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
self.assertEqual(Comment.objects.count(), comment_count)
|
||||||
|
|
||||||
|
def test_comment_delete_view_with_access(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document,
|
||||||
|
permission=permission_document_comment_delete
|
||||||
|
)
|
||||||
|
|
||||||
|
comment_count = Comment.objects.count()
|
||||||
|
|
||||||
|
response = self._request_test_comment_delete_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
self.assertEqual(Comment.objects.count(), comment_count - 1)
|
||||||
|
|
||||||
|
def test_comment_edit_view_no_permissions(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
|
||||||
|
comment_text = self.test_document_comment.comment
|
||||||
|
|
||||||
|
response = self._request_test_comment_edit_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
self.test_document_comment.refresh_from_db()
|
||||||
|
self.assertEqual(self.test_document_comment.comment, comment_text)
|
||||||
|
|
||||||
|
def test_comment_edit_view_with_access(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document, permission=permission_document_comment_edit
|
||||||
|
)
|
||||||
|
|
||||||
|
comment_text = self.test_document_comment.comment
|
||||||
|
|
||||||
|
response = self._request_test_comment_edit_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
self.test_document_comment.refresh_from_db()
|
||||||
|
self.assertNotEqual(self.test_document_comment.comment, comment_text)
|
||||||
|
|
||||||
|
def test_comment_list_view_with_no_permission(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
|
||||||
|
response = self._request_test_comment_list_view()
|
||||||
|
self.assertNotContains(
|
||||||
|
response=response, text=self.test_document_comment.comment,
|
||||||
|
status_code=404
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_comment_list_view_with_access(self):
|
||||||
|
self._create_test_comment()
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_document,
|
||||||
|
permission=permission_document_comment_view
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self._request_test_comment_list_view()
|
||||||
|
self.assertContains(
|
||||||
|
response=response, text=self.test_document_comment.comment,
|
||||||
|
status_code=200
|
||||||
|
)
|
||||||
@@ -5,17 +5,26 @@ from django.conf.urls import url
|
|||||||
from .api_views import APICommentListView, APICommentView
|
from .api_views import APICommentListView, APICommentView
|
||||||
from .views import (
|
from .views import (
|
||||||
DocumentCommentCreateView, DocumentCommentDeleteView,
|
DocumentCommentCreateView, DocumentCommentDeleteView,
|
||||||
|
DocumentCommentDetailView, DocumentCommentEditView,
|
||||||
DocumentCommentListView
|
DocumentCommentListView
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
url(
|
||||||
|
regex=r'^(?P<pk>\d+)/comment/add/$',
|
||||||
|
view=DocumentCommentCreateView.as_view(), name='comment_add'
|
||||||
|
),
|
||||||
url(
|
url(
|
||||||
regex=r'^comment/(?P<pk>\d+)/delete/$',
|
regex=r'^comment/(?P<pk>\d+)/delete/$',
|
||||||
view=DocumentCommentDeleteView.as_view(), name='comment_delete'
|
view=DocumentCommentDeleteView.as_view(), name='comment_delete'
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
regex=r'^(?P<pk>\d+)/comment/add/$',
|
regex=r'^comment/(?P<pk>\d+)/$',
|
||||||
view=DocumentCommentCreateView.as_view(), name='comment_add'
|
view=DocumentCommentDetailView.as_view(), name='comment_details'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^comment/(?P<pk>\d+)/edit/$',
|
||||||
|
view=DocumentCommentEditView.as_view(), name='comment_edit'
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
regex=r'^(?P<pk>\d+)/comment/list/$',
|
regex=r'^(?P<pk>\d+)/comment/list/$',
|
||||||
|
|||||||
@@ -5,17 +5,19 @@ from django.urls import reverse
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from mayan.apps.common.generics import (
|
from mayan.apps.common.generics import (
|
||||||
SingleObjectCreateView, SingleObjectDeleteView, SingleObjectListView
|
SingleObjectCreateView, SingleObjectDeleteView, SingleObjectDetailView,
|
||||||
|
SingleObjectEditView, SingleObjectListView
|
||||||
)
|
)
|
||||||
from mayan.apps.common.mixins import ExternalObjectMixin
|
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||||
from mayan.apps.documents.models import Document
|
from mayan.apps.documents.models import Document
|
||||||
|
|
||||||
|
from .forms import DocumentCommentDetailForm
|
||||||
from .icons import icon_comments_for_document
|
from .icons import icon_comments_for_document
|
||||||
from .links import link_comment_add
|
from .links import link_comment_add
|
||||||
from .models import Comment
|
from .models import Comment
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_document_comment_create, permission_document_comment_delete,
|
permission_document_comment_create, permission_document_comment_delete,
|
||||||
permission_document_comment_view
|
permission_document_comment_edit, permission_document_comment_view
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -24,7 +26,6 @@ class DocumentCommentCreateView(ExternalObjectMixin, SingleObjectCreateView):
|
|||||||
external_object_permission = permission_document_comment_create
|
external_object_permission = permission_document_comment_create
|
||||||
external_object_pk_url_kwarg = 'pk'
|
external_object_pk_url_kwarg = 'pk'
|
||||||
fields = ('comment',)
|
fields = ('comment',)
|
||||||
model = Comment
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -44,6 +45,9 @@ class DocumentCommentCreateView(ExternalObjectMixin, SingleObjectCreateView):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return self.external_object.comments.all()
|
||||||
|
|
||||||
def get_save_extra_data(self):
|
def get_save_extra_data(self):
|
||||||
return {
|
return {
|
||||||
'_user': self.request.user,
|
'_user': self.request.user,
|
||||||
@@ -60,7 +64,9 @@ class DocumentCommentDeleteView(SingleObjectDeleteView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'object': self.object.document,
|
'comment': self.object,
|
||||||
|
'document': self.object.document,
|
||||||
|
'navigation_object_list': ('document', 'comment'),
|
||||||
'title': _('Delete comment: %s?') % self.object,
|
'title': _('Delete comment: %s?') % self.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +78,46 @@ class DocumentCommentDeleteView(SingleObjectDeleteView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentCommentDetailView(SingleObjectDetailView):
|
||||||
|
form_class = DocumentCommentDetailForm
|
||||||
|
model = Comment
|
||||||
|
pk_url_kwarg = 'pk'
|
||||||
|
object_permission = permission_document_comment_view
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
return {
|
||||||
|
'comment': self.object,
|
||||||
|
'document': self.object.document,
|
||||||
|
'navigation_object_list': ('document', 'comment'),
|
||||||
|
'title': _('Details for comment: %s?') % self.object,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentCommentEditView(SingleObjectEditView):
|
||||||
|
fields = ('comment',)
|
||||||
|
model = Comment
|
||||||
|
pk_url_kwarg = 'pk'
|
||||||
|
object_permission = permission_document_comment_edit
|
||||||
|
|
||||||
|
def get_save_extra_data(self):
|
||||||
|
return {'_user': self.request.user}
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
return {
|
||||||
|
'comment': self.object,
|
||||||
|
'document': self.object.document,
|
||||||
|
'navigation_object_list': ('document', 'comment'),
|
||||||
|
'title': _('Edit comment: %s?') % self.object,
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_post_action_redirect(self):
|
||||||
|
return reverse(
|
||||||
|
viewname='comments:comments_for_document', kwargs={
|
||||||
|
'pk': self.object.document.pk
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DocumentCommentListView(ExternalObjectMixin, SingleObjectListView):
|
class DocumentCommentListView(ExternalObjectMixin, SingleObjectListView):
|
||||||
external_object_class = Document
|
external_object_class = Document
|
||||||
external_object_permission = permission_document_comment_view
|
external_object_permission = permission_document_comment_view
|
||||||
|
|||||||
Reference in New Issue
Block a user