Compare commits

...

10 Commits

Author SHA1 Message Date
Roberto Rosario
9e2ef57e00 Fix document view test mixin
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-13 16:09:54 -04:00
Roberto Rosario
756765ce4a Fix layer imports
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-13 15:40:50 -04:00
Roberto Rosario
53096b8bdd Allow "Execute document tools" permission via ACL
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-13 15:34:32 -04:00
Roberto Rosario
8aa2567a56 Document tests layout tweaks
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-13 15:28:41 -04:00
Roberto Rosario
ce6e568001 Sort documents models methods
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-13 15:21:37 -04:00
Roberto Rosario
d1f0e23c53 Test layout updates
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-11 11:21:05 -04:00
Roberto Rosario
3f33bdd9c2 Sources apps test updates
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-11 10:57:51 -04:00
Roberto Rosario
b2390843ab Update changelog
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-10 17:18:39 -04:00
Roberto Rosario
fc14341d40 Update document version upload to use dropzone
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-10 17:17:09 -04:00
Roberto Rosario
57dd5b1bca Split source multiform template
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
2019-10-10 17:17:01 -04:00
21 changed files with 371 additions and 311 deletions

View File

@@ -78,6 +78,11 @@
Support Docker networks and make it the default. Support Docker networks and make it the default.
Delete the containers to allow the script to be idempotent. Delete the containers to allow the script to be idempotent.
Deploy a Redis container. Deploy a Redis container.
- Improve document version upload form.
- Use dropzone for document version upload form.
- Allow the "Execute document tools" permission to be
granted via ACL.
3.2.8 (2019-10-01) 3.2.8 (2019-10-01)
================== ==================

View File

@@ -87,10 +87,10 @@ from .permissions import (
permission_document_download, permission_document_edit, permission_document_download, permission_document_edit,
permission_document_new_version, permission_document_print, permission_document_new_version, permission_document_print,
permission_document_properties_edit, permission_document_restore, permission_document_properties_edit, permission_document_restore,
permission_document_trash, permission_document_type_delete, permission_document_tools, permission_document_trash,
permission_document_type_edit, permission_document_type_view, permission_document_type_delete, permission_document_type_edit,
permission_document_version_revert, permission_document_version_view, permission_document_type_view, permission_document_version_revert,
permission_document_view permission_document_version_view, permission_document_view
) )
# Just import to initialize the search models # Just import to initialize the search models
from .search import document_search, document_page_search # NOQA from .search import document_search, document_page_search # NOQA
@@ -191,8 +191,8 @@ class DocumentsApp(MayanAppConfig):
permission_document_delete, permission_document_download, permission_document_delete, permission_document_download,
permission_document_edit, permission_document_new_version, permission_document_edit, permission_document_new_version,
permission_document_print, permission_document_properties_edit, permission_document_print, permission_document_properties_edit,
permission_document_restore, permission_document_trash, permission_document_restore, permission_document_tools,
permission_document_version_revert, permission_document_trash, permission_document_version_revert,
permission_document_version_view, permission_document_view, permission_document_version_view, permission_document_view,
permission_events_view, permission_transformation_create, permission_events_view, permission_transformation_create,
permission_transformation_delete, permission_transformation_delete,

View File

@@ -102,6 +102,14 @@ class Document(models.Model):
) )
return RecentDocument.objects.add_document_for_user(user, self) return RecentDocument.objects.add_document_for_user(user, self)
@property
def checksum(self):
return self.latest_version.checksum
@property
def date_updated(self):
return self.latest_version.timestamp
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
to_trash = kwargs.pop('to_trash', True) to_trash = kwargs.pop('to_trash', True)
@@ -126,6 +134,14 @@ class Document(models.Model):
else: else:
return False return False
@property
def file_mime_encoding(self):
return self.latest_version.encoding
@property
def file_mimetype(self):
return self.latest_version.mimetype
def get_absolute_url(self): def get_absolute_url(self):
return reverse( return reverse(
viewname='documents:document_preview', kwargs={'pk': self.pk} viewname='documents:document_preview', kwargs={'pk': self.pk}
@@ -140,6 +156,10 @@ class Document(models.Model):
def is_in_trash(self): def is_in_trash(self):
return self.in_trash return self.in_trash
@property
def latest_version(self):
return self.versions.order_by('timestamp').last()
def natural_key(self): def natural_key(self):
return (self.uuid,) return (self.uuid,)
natural_key.dependencies = ['documents.DocumentType'] natural_key.dependencies = ['documents.DocumentType']
@@ -165,6 +185,34 @@ class Document(models.Model):
""" """
return self.latest_version.open(*args, **kwargs) return self.latest_version.open(*args, **kwargs)
@property
def page_count(self):
return self.latest_version.page_count
@property
def pages(self):
try:
return self.latest_version.pages
except AttributeError:
# Document has no version yet
DocumentPage = apps.get_model(
app_label='documents', model_name='DocumentPage'
)
return DocumentPage.objects.none()
@property
def pages_all(self):
try:
return self.latest_version.pages_all
except AttributeError:
# Document has no version yet
DocumentPage = apps.get_model(
app_label='documents', model_name='DocumentPage'
)
return DocumentPage.objects.none()
def restore(self): def restore(self):
self.in_trash = False self.in_trash = False
self.save() self.save()
@@ -209,53 +257,3 @@ class Document(models.Model):
@property @property
def size(self): def size(self):
return self.latest_version.size return self.latest_version.size
# Compatibility methods
@property
def checksum(self):
return self.latest_version.checksum
@property
def date_updated(self):
return self.latest_version.timestamp
@property
def file_mime_encoding(self):
return self.latest_version.encoding
@property
def file_mimetype(self):
return self.latest_version.mimetype
@property
def latest_version(self):
return self.versions.order_by('timestamp').last()
@property
def page_count(self):
return self.latest_version.page_count
@property
def pages_all(self):
try:
return self.latest_version.pages_all
except AttributeError:
# Document has no version yet
DocumentPage = apps.get_model(
app_label='documents', model_name='DocumentPage'
)
return DocumentPage.objects.none()
@property
def pages(self):
try:
return self.latest_version.pages
except AttributeError:
# Document has no version yet
DocumentPage = apps.get_model(
app_label='documents', model_name='DocumentPage'
)
return DocumentPage.objects.none()

View File

@@ -253,10 +253,6 @@ class DocumentVersion(models.Model):
) )
return DocumentPage.passthrough.filter(document_version=self) return DocumentPage.passthrough.filter(document_version=self)
@property
def pages(self):
return self.version_pages.all()
@property @property
def page_count(self): def page_count(self):
""" """
@@ -264,6 +260,10 @@ class DocumentVersion(models.Model):
""" """
return self.pages.count() return self.pages.count()
@property
def pages(self):
return self.version_pages.all()
def revert(self, _user=None): def revert(self, _user=None):
""" """
Delete the subsequent versions after this one Delete the subsequent versions after this one

View File

@@ -5,6 +5,7 @@ import os
from django.conf import settings from django.conf import settings
from mayan.apps.converter.classes import Layer from mayan.apps.converter.classes import Layer
from mayan.apps.converter.layers import layer_saved_transformations
from ..literals import PAGE_RANGE_ALL from ..literals import PAGE_RANGE_ALL
from ..models import DocumentType from ..models import DocumentType
@@ -14,6 +15,7 @@ from .literals import (
TEST_DOCUMENT_TYPE_LABEL, TEST_DOCUMENT_TYPE_LABEL_EDITED, TEST_DOCUMENT_TYPE_LABEL, TEST_DOCUMENT_TYPE_LABEL_EDITED,
TEST_DOCUMENT_TYPE_QUICK_LABEL, TEST_DOCUMENT_TYPE_QUICK_LABEL_EDITED, TEST_DOCUMENT_TYPE_QUICK_LABEL, TEST_DOCUMENT_TYPE_QUICK_LABEL_EDITED,
TEST_SMALL_DOCUMENT_FILENAME, TEST_SMALL_DOCUMENT_PATH, TEST_SMALL_DOCUMENT_FILENAME, TEST_SMALL_DOCUMENT_PATH,
TEST_TRANSFORMATION_ARGUMENT, TEST_TRANSFORMATION_CLASS,
TEST_VERSION_COMMENT TEST_VERSION_COMMENT
) )
@@ -69,6 +71,8 @@ class DocumentTestMixin(object):
self.test_document = document self.test_document = document
self.test_documents.append(document) self.test_documents.append(document)
self.test_document_page = document.latest_version.pages.first()
self.test_document_version = document.latest_version
class DocumentTypeViewTestMixin(object): class DocumentTypeViewTestMixin(object):
@@ -149,6 +153,13 @@ class DocumentVersionTestMixin(object):
class DocumentViewTestMixin(object): class DocumentViewTestMixin(object):
def _create_document_transformation(self):
layer_saved_transformations.add_transformation_to(
obj=self.test_document.pages.first(),
transformation_class=TEST_TRANSFORMATION_CLASS,
arguments=TEST_TRANSFORMATION_ARGUMENT
)
def _request_document_properties_view(self): def _request_document_properties_view(self):
return self.get( return self.get(
viewname='documents:document_properties', viewname='documents:document_properties',

View File

@@ -9,10 +9,10 @@ from ..permissions import (
from .base import GenericDocumentViewTestCase from .base import GenericDocumentViewTestCase
class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase): class DocumentPageDisableViewTestMixin(object):
def setUp(self): def _disable_test_document_page(self):
super(DocumentPageDisableViewTestCase, self).setUp() self.test_document_page.enabled = False
self.test_document_page = self.test_document.pages_all.first() self.test_document_page.save()
def _request_test_document_page_disable_view(self): def _request_test_document_page_disable_view(self):
return self.post( return self.post(
@@ -21,6 +21,31 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
} }
) )
def _request_test_document_page_enable_view(self):
return self.post(
viewname='documents:document_page_enable', kwargs={
'pk': self.test_document_page.pk
}
)
def _request_test_document_page_multiple_disable_view(self):
return self.post(
viewname='documents:document_page_multiple_disable', data={
'id_list': self.test_document_page.pk
}
)
def _request_test_document_page_multiple_enable_view(self):
return self.post(
viewname='documents:document_page_multiple_enable', data={
'id_list': self.test_document_page.pk
}
)
class DocumentPageDisableViewTestCase(
DocumentPageDisableViewTestMixin, GenericDocumentViewTestCase
):
def test_document_page_disable_view_no_permission(self): def test_document_page_disable_view_no_permission(self):
test_document_page_count = self.test_document.pages.count() test_document_page_count = self.test_document.pages.count()
@@ -45,13 +70,6 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
test_document_page_count, self.test_document.pages.count() test_document_page_count, self.test_document.pages.count()
) )
def _request_test_document_page_multiple_disable_view(self):
return self.post(
viewname='documents:document_page_multiple_disable', data={
'id_list': self.test_document_page.pk
}
)
def test_document_page_multiple_disable_view_no_permission(self): def test_document_page_multiple_disable_view_no_permission(self):
test_document_page_count = self.test_document.pages.count() test_document_page_count = self.test_document.pages.count()
@@ -76,17 +94,6 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
test_document_page_count, self.test_document.pages.count() test_document_page_count, self.test_document.pages.count()
) )
def _disable_test_document_page(self):
self.test_document_page.enabled = False
self.test_document_page.save()
def _request_test_document_page_enable_view(self):
return self.post(
viewname='documents:document_page_enable', kwargs={
'pk': self.test_document_page.pk
}
)
def test_document_page_enable_view_no_permission(self): def test_document_page_enable_view_no_permission(self):
self._disable_test_document_page() self._disable_test_document_page()
@@ -114,13 +121,6 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
test_document_page_count, self.test_document.pages.count() test_document_page_count, self.test_document.pages.count()
) )
def _request_test_document_page_multiple_enable_view(self):
return self.post(
viewname='documents:document_page_multiple_enable', data={
'id_list': self.test_document_page.pk
}
)
def test_document_page_multiple_enable_view_no_permission(self): def test_document_page_multiple_enable_view_no_permission(self):
self._disable_test_document_page() self._disable_test_document_page()
test_document_page_count = self.test_document.pages.count() test_document_page_count = self.test_document.pages.count()
@@ -148,7 +148,7 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
) )
class DocumentPageViewTestCase(GenericDocumentViewTestCase): class DocumentPageViewTestMixin(object):
def _request_test_document_page_list_view(self): def _request_test_document_page_list_view(self):
return self.get( return self.get(
viewname='documents:document_pages', kwargs={ viewname='documents:document_pages', kwargs={
@@ -156,6 +156,17 @@ class DocumentPageViewTestCase(GenericDocumentViewTestCase):
} }
) )
def _request_test_document_page_view(self, document_page):
return self.get(
viewname='documents:document_page_view', kwargs={
'pk': document_page.pk,
}
)
class DocumentPageViewTestCase(
DocumentPageViewTestMixin, GenericDocumentViewTestCase
):
def test_document_page_list_view_no_permission(self): def test_document_page_list_view_no_permission(self):
response = self._request_test_document_page_list_view() response = self._request_test_document_page_list_view()
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
@@ -170,13 +181,6 @@ class DocumentPageViewTestCase(GenericDocumentViewTestCase):
response=response, text=self.test_document.label, status_code=200 response=response, text=self.test_document.label, status_code=200
) )
def _request_test_document_page_view(self, document_page):
return self.get(
viewname='documents:document_page_view', kwargs={
'pk': document_page.pk,
}
)
def test_document_page_view_no_permissions(self): def test_document_page_view_no_permissions(self):
response = self._request_test_document_page_view( response = self._request_test_document_page_view(
document_page=self.test_document.pages.first() document_page=self.test_document.pages.first()

View File

@@ -203,7 +203,7 @@ class DocumentTypeQuickLabelViewsTestCase(
) )
class DocumentsQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericDocumentViewTestCase): class DocumentsQuickLabelViewTestMixin(object):
def _request_document_quick_label_edit_view(self, extra_data=None): def _request_document_quick_label_edit_view(self, extra_data=None):
data = { data = {
'document_type_available_filenames': self.test_document_type_filename.pk, 'document_type_available_filenames': self.test_document_type_filename.pk,
@@ -219,6 +219,11 @@ class DocumentsQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericD
}, data=data }, data=data
) )
class DocumentsQuickLabelViewTestCase(
DocumentsQuickLabelViewTestMixin, DocumentTypeQuickLabelTestMixin,
GenericDocumentViewTestCase
):
def test_document_quick_label_no_permission(self): def test_document_quick_label_no_permission(self):
self._create_test_quick_label() self._create_test_quick_label()

View File

@@ -9,13 +9,24 @@ from .literals import TEST_VERSION_COMMENT
from .mixins import DocumentVersionTestMixin from .mixins import DocumentVersionTestMixin
class DocumentVersionTestCase(DocumentVersionTestMixin, GenericDocumentViewTestCase): class DocumentVersionViewTestMixin(object):
def _request_document_version_list_view(self): def _request_document_version_list_view(self):
return self.get( return self.get(
viewname='documents:document_version_list', viewname='documents:document_version_list',
kwargs={'pk': self.test_document.pk} kwargs={'pk': self.test_document.pk}
) )
def _request_document_version_revert_view(self, document_version):
return self.post(
viewname='documents:document_version_revert',
kwargs={'pk': document_version.pk}
)
class DocumentVersionViewTestCase(
DocumentVersionTestMixin, DocumentVersionViewTestMixin,
GenericDocumentViewTestCase
):
def test_document_version_list_no_permission(self): def test_document_version_list_no_permission(self):
self._upload_new_version() self._upload_new_version()
@@ -33,12 +44,6 @@ class DocumentVersionTestCase(DocumentVersionTestMixin, GenericDocumentViewTestC
response=response, text=TEST_VERSION_COMMENT, status_code=200 response=response, text=TEST_VERSION_COMMENT, status_code=200
) )
def _request_document_version_revert_view(self, document_version):
return self.post(
viewname='documents:document_version_revert',
kwargs={'pk': document_version.pk}
)
def test_document_version_revert_no_permission(self): def test_document_version_revert_no_permission(self):
first_version = self.test_document.latest_version first_version = self.test_document.latest_version
self._upload_new_version() self._upload_new_version()

View File

@@ -16,22 +16,14 @@ from ..permissions import (
from .base import GenericDocumentViewTestCase from .base import GenericDocumentViewTestCase
from .literals import ( from .literals import (
TEST_DOCUMENT_TYPE_2_LABEL, TEST_SMALL_DOCUMENT_FILENAME, TEST_DOCUMENT_TYPE_2_LABEL, TEST_SMALL_DOCUMENT_FILENAME
TEST_TRANSFORMATION_ARGUMENT, TEST_TRANSFORMATION_CLASS
) )
from .mixins import DocumentViewTestMixin from .mixins import DocumentViewTestMixin
class DocumentsViewsTestCase( class DocumentViewTestCase(
LayerTestMixin, DocumentViewTestMixin, GenericDocumentViewTestCase LayerTestMixin, DocumentViewTestMixin, GenericDocumentViewTestCase
): ):
def _create_document_transformation(self):
layer_saved_transformations.add_transformation_to(
obj=self.test_document.pages.first(),
transformation_class=TEST_TRANSFORMATION_CLASS,
arguments=TEST_TRANSFORMATION_ARGUMENT
)
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, 404) self.assertEqual(response.status_code, 404)
@@ -302,13 +294,13 @@ class DocumentsViewsTestCase(
self.assertEqual(self.test_document.pages.count(), 0) self.assertEqual(self.test_document.pages.count(), 0)
def test_document_update_page_count_view_with_permission(self): def test_document_update_page_count_view_with_permission(self):
# TODO: Revise permission association
page_count = self.test_document.pages.count() page_count = self.test_document.pages.count()
self.test_document.pages.all().delete() self.test_document.pages.all().delete()
self.assertEqual(self.test_document.pages.count(), 0) self.assertEqual(self.test_document.pages.count(), 0)
self.grant_permission(permission=permission_document_tools) self.grant_access(
obj=self.test_document, permission=permission_document_tools
)
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, 302)
@@ -329,7 +321,9 @@ class DocumentsViewsTestCase(
self.test_document.pages.all().delete() self.test_document.pages.all().delete()
self.assertEqual(self.test_document.pages.count(), 0) self.assertEqual(self.test_document.pages.count(), 0)
self.grant_permission(permission=permission_document_tools) self.grant_access(
obj=self.test_document, permission=permission_document_tools
)
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, 302)

View File

@@ -5,7 +5,7 @@ from ..permissions import permission_document_view
from .base import GenericDocumentViewTestCase from .base import GenericDocumentViewTestCase
class DuplicatedDocumentsViewsTestCase(GenericDocumentViewTestCase): class DuplicatedDocumentsViewsTestMixin(object):
def _upload_duplicate_document(self): def _upload_duplicate_document(self):
self.upload_document() self.upload_document()
@@ -18,6 +18,10 @@ class DuplicatedDocumentsViewsTestCase(GenericDocumentViewTestCase):
kwargs={'pk': self.test_documents[0].pk} kwargs={'pk': self.test_documents[0].pk}
) )
class DuplicatedDocumentsViewsTestCase(
DuplicatedDocumentsViewsTestMixin, GenericDocumentViewTestCase
):
def test_duplicated_document_list_no_permissions(self): def test_duplicated_document_list_no_permissions(self):
self._upload_duplicate_document() self._upload_duplicate_document()

View File

@@ -17,12 +17,23 @@ TEST_TRANSFORMATION_NAME = 'rotate'
TEST_TRANSFORMATION_ARGUMENT = 'degrees: 180' TEST_TRANSFORMATION_ARGUMENT = 'degrees: 180'
class DocumentEventsTestCase(GenericDocumentViewTestCase): class DocumentEventsTestMixin(object):
def _request_test_document_download_view(self): def _request_test_document_download_view(self):
return self.get( return self.get(
'documents:document_download', kwargs={'pk': self.test_document.pk} 'documents:document_download', kwargs={'pk': self.test_document.pk}
) )
def _request_test_document_preview_view(self):
return self.get(
viewname='documents:document_preview', kwargs={
'pk': self.test_document.pk
}
)
class DocumentEventsTestCase(
DocumentEventsTestMixin, GenericDocumentViewTestCase
):
def test_document_download_event_no_permissions(self): def test_document_download_event_no_permissions(self):
Action.objects.all().delete() Action.objects.all().delete()
@@ -55,13 +66,6 @@ class DocumentEventsTestCase(GenericDocumentViewTestCase):
self.assertEqual(event.target, self.test_document) self.assertEqual(event.target, self.test_document)
self.assertEqual(event.verb, event_document_download.id) self.assertEqual(event.verb, event_document_download.id)
def _request_test_document_preview_view(self):
return self.get(
viewname='documents:document_preview', kwargs={
'pk': self.test_document.pk
}
)
def test_document_view_event_no_permissions(self): def test_document_view_event_no_permissions(self):
Action.objects.all().delete() Action.objects.all().delete()

View File

@@ -6,13 +6,34 @@ from ..permissions import permission_document_view
from .base import GenericDocumentViewTestCase from .base import GenericDocumentViewTestCase
class FavoriteDocumentsTestCase(GenericDocumentViewTestCase): class FavoriteDocumentsTestMixin(object):
def _request_document_add_to_favorites_view(self): def _request_document_add_to_favorites_view(self):
return self.post( return self.post(
viewname='documents:document_add_to_favorites', viewname='documents:document_add_to_favorites',
kwargs={'pk': self.test_document.pk} kwargs={'pk': self.test_document.pk}
) )
def _document_add_to_favorites(self):
FavoriteDocument.objects.add_for_user(
document=self.test_document, user=self._test_case_user
)
def _request_document_list_favorites(self):
return self.get(
viewname='documents:document_list_favorites',
)
def _request_document_remove_from_favorites(self):
return self.post(
viewname='documents:document_remove_from_favorites',
kwargs={'pk': self.test_document.pk}
)
class FavoriteDocumentsTestCase(
FavoriteDocumentsTestMixin, 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, 404) self.assertEqual(response.status_code, 404)
@@ -26,16 +47,6 @@ class FavoriteDocumentsTestCase(GenericDocumentViewTestCase):
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(FavoriteDocument.objects.count(), 1) self.assertEqual(FavoriteDocument.objects.count(), 1)
def _document_add_to_favorites(self):
FavoriteDocument.objects.add_for_user(
document=self.test_document, user=self._test_case_user
)
def _request_document_list_favorites(self):
return self.get(
viewname='documents:document_list_favorites',
)
def test_document_list_favorites_view_no_permission(self): def test_document_list_favorites_view_no_permission(self):
self._document_add_to_favorites() self._document_add_to_favorites()
response = self._request_document_list_favorites() response = self._request_document_list_favorites()
@@ -53,12 +64,6 @@ class FavoriteDocumentsTestCase(GenericDocumentViewTestCase):
response=response, text=self.test_document.label, status_code=200 response=response, text=self.test_document.label, status_code=200
) )
def _request_document_remove_from_favorites(self):
return self.post(
viewname='documents:document_remove_from_favorites',
kwargs={'pk': self.test_document.pk}
)
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()

View File

@@ -89,7 +89,6 @@ class DocumentsLinksTestCase(GenericDocumentViewTestCase):
class DeletedDocumentsLinksTestCase(GenericDocumentViewTestCase): class DeletedDocumentsLinksTestCase(GenericDocumentViewTestCase):
def setUp(self): def setUp(self):
super(DeletedDocumentsLinksTestCase, self).setUp() super(DeletedDocumentsLinksTestCase, self).setUp()
self.login_user()
self.test_document.delete() self.test_document.delete()
self.test_deleted_document = DeletedDocument.objects.get( self.test_deleted_document = DeletedDocument.objects.get(
pk=self.test_document.pk pk=self.test_document.pk

View File

@@ -1,12 +1,12 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from mayan.apps.common.tests.base import BaseTestCase
from mayan.apps.documents.permissions import permission_document_view from mayan.apps.documents.permissions import permission_document_view
from mayan.apps.documents.search import document_search, document_page_search from mayan.apps.documents.search import document_search, document_page_search
from mayan.apps.documents.tests.mixins import DocumentTestMixin
from .base import GenericDocumentViewTestCase
class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase): class DocumentSearchTestMixin(object):
def _perform_document_page_search(self): def _perform_document_page_search(self):
return document_page_search.search( return document_page_search.search(
query_string={'q': self.test_document.label}, user=self._test_case_user query_string={'q': self.test_document.label}, user=self._test_case_user
@@ -17,6 +17,10 @@ class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase):
query_string={'q': self.test_document.label}, user=self._test_case_user query_string={'q': self.test_document.label}, user=self._test_case_user
) )
class DocumentSearchTestCase(
DocumentSearchTestMixin, GenericDocumentViewTestCase
):
def test_document_page_search_no_access(self): def test_document_page_search_no_access(self):
queryset = self._perform_document_page_search() queryset = self._perform_document_page_search()
self.assertFalse(self.test_document.pages.first() in queryset) self.assertFalse(self.test_document.pages.first() in queryset)

View File

@@ -9,7 +9,7 @@ from ..permissions import (
from .base import GenericDocumentViewTestCase from .base import GenericDocumentViewTestCase
class TrashedDocumentTestCase(GenericDocumentViewTestCase): class TrashedDocumentTestMixin(object):
def _request_document_restore_get_view(self): def _request_document_restore_get_view(self):
return self.get( return self.get(
viewname='documents:document_restore', kwargs={ viewname='documents:document_restore', kwargs={
@@ -17,6 +17,49 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
} }
) )
def _request_document_restore_post_view(self):
return self.post(
viewname='documents:document_restore', kwargs={
'pk': self.test_document.pk
}
)
def _request_document_trash_get_view(self):
return self.get(
viewname='documents:document_trash', kwargs={
'pk': self.test_document.pk
}
)
def _request_document_trash_post_view(self):
return self.post(
viewname='documents:document_trash', kwargs={
'pk': self.test_document.pk
}
)
def _request_document_delete_get_view(self):
return self.get(
viewname='documents:document_delete', kwargs={
'pk': self.test_document.pk
}
)
def _request_document_delete_post_view(self):
return self.post(
viewname='documents:document_delete', kwargs={
'pk': self.test_document.pk
}
)
def _request_document_list_deleted_view(self):
return self.get(viewname='documents:document_list_deleted')
class TrashedDocumentTestCase(
TrashedDocumentTestMixin, GenericDocumentViewTestCase
):
def test_document_restore_get_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)
@@ -43,13 +86,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
self.assertEqual(Document.objects.count(), document_count) 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): def test_document_restore_post_view_no_permission(self):
self.test_document.delete() self.test_document.delete()
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
@@ -74,13 +110,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
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_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): def test_document_trash_get_view_no_permissions(self):
document_count = Document.objects.count() document_count = Document.objects.count()
@@ -101,13 +130,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
self.assertEqual(Document.objects.count(), document_count) self.assertEqual(Document.objects.count(), document_count)
def _request_document_trash_post_view(self):
return self.post(
viewname='documents:document_trash', kwargs={
'pk': self.test_document.pk
}
)
def test_document_trash_post_view_no_permissions(self): def test_document_trash_post_view_no_permissions(self):
response = self._request_document_trash_post_view() response = self._request_document_trash_post_view()
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
@@ -126,13 +148,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
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_get_view(self):
return self.get(
viewname='documents:document_delete', kwargs={
'pk': self.test_document.pk
}
)
def test_document_delete_get_view_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)
@@ -165,13 +180,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
DeletedDocument.objects.count(), trashed_document_count 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): def test_document_delete_post_view_no_permissions(self):
self.test_document.delete() self.test_document.delete()
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
@@ -198,9 +206,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
self.assertEqual(DeletedDocument.objects.count(), 0) self.assertEqual(DeletedDocument.objects.count(), 0)
self.assertEqual(Document.objects.count(), 0) self.assertEqual(Document.objects.count(), 0)
def _request_document_list_deleted_view(self):
return self.get(viewname='documents:document_list_deleted')
def test_deleted_document_list_view_no_permissions(self): def test_deleted_document_list_view_no_permissions(self):
self.test_document.delete() self.test_document.delete()

View File

@@ -0,0 +1,115 @@
{% load i18n %}
{% load static %}
<link href="{% static 'sources/node_modules/dropzone/dist/dropzone.css' %}" media="screen" rel="stylesheet" type="text/css" />
<style>
.dropzone .dz-preview .dz-details {
top: 25px;
}
.dropzone .dz-preview .dz-progress {
top: 60%;
}
.dropzone .dz-preview .dz-error-message {
top: 130px;
}
.dropzone-previews, .dropzone .dz-message {
border: 2px solid rgba(0, 0, 0, 0.3);
padding: 40px 20px;
}
.dropzone .dz-preview .dz-error-message {
overflow-wrap: break-word;
padding: 1.2em;
top: 180px;
}
.dropzone .dz-preview .dz-details .dz-filename span,
.dropzone .dz-preview .dz-details .dz-size span {
padding: 0px;
}
.dropzone {
min-height: 150px;
border: inherit;
background: inherit;
padding: 0px;
}
.dropzone-previews, .dropzone .dz-message {
background: white;
}
}
</style>
<script type="text/x-template" id="previewTemplate">
<div class="dz-preview dz-file-preview">
<i class="far fa-file fa-10x"></i>
<div class="dz-details">
<div class="dz-filename"><span data-dz-name></span></div>
<div class="dz-size" data-dz-size></div>
<img data-dz-thumbnail />
</div>
<div class="dz-progress">
<span class="dz-upload" data-dz-uploadprogress>
<div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" style="width: 100%">
</div>
</span>
</div>
<div class="dz-success-mark">
<span>
<i class="text-success fa fa-4x fa-check-circle"></i>
</span>
</div>
<div class="dz-error-mark">
<span>
<i class="text-danger fa fa-4x fa-times-circle"></i>
</span>
</div>
<div class="dz-error-message">
<span data-dz-errormessage>
</span>
</div>
</div>
</script>
<script>
var messageCancelUpload = "{% trans 'Cancel upload' %}";
var messageCancelUploadConfirmation = "{% trans 'Are you sure you want to cancel this upload?' %}";
var messageDefaultMessage = "{% trans 'Drop files or click here to upload files' %}";
var messageFallbackMessage = "{% trans 'Your browser does not support drag and drop file uploads.' %}";
var messageFallbackText = "{% trans 'Please use the fallback form below to upload your files.' %}";
var messageRemoveFile = "{% trans 'Clear' %}";
var messageResponseError = "{% trans 'Server responded with {{statusCode}} code.' %}";
$.getScript( "{% static 'sources/node_modules/dropzone/dist/dropzone.js' %}" )
.done(function( script, textStatus ) {
Dropzone.autoDiscover = false;
jQuery(document).ready(function() {
var previewTemplate = document.querySelector('#previewTemplate').innerHTML;
{% verbatim %}
$('.dropzone').dropzone({
addRemoveLinks: true,
createImageThumbnails: false,
dictCancelUpload: messageCancelUpload,
dictCancelUploadConfirmation: messageCancelUploadConfirmation,
dictDefaultMessage: '<i class="fa fa-cloud-upload-alt"></i> ' + messageDefaultMessage,
dictFallbackMessage: messageFallbackMessage,
dictFallbackText: messageFallbackText,
dictRemoveFile: messageRemoveFile,
dictResponseError: messageResponseError,
maxFilesize: 2048,
paramName: 'source-file',
previewTemplate: previewTemplate,
timeout: 1200000
});
{% endverbatim %}
});
});
</script>

View File

@@ -1,118 +1,2 @@
{% load i18n %}
{% load static %}
<link href="{% static 'sources/node_modules/dropzone/dist/dropzone.css' %}" media="screen" rel="stylesheet" type="text/css" />
<style>
.dropzone .dz-preview .dz-details {
top: 25px;
}
.dropzone .dz-preview .dz-progress {
top: 60%;
}
.dropzone .dz-preview .dz-error-message {
top: 130px;
}
.dropzone-previews, .dropzone .dz-message {
border: 2px solid rgba(0, 0, 0, 0.3);
padding: 40px 20px;
}
.dropzone .dz-preview .dz-error-message {
overflow-wrap: break-word;
padding: 1.2em;
top: 180px;
}
.dropzone .dz-preview .dz-details .dz-filename span,
.dropzone .dz-preview .dz-details .dz-size span {
padding: 0px;
}
.dropzone {
min-height: 150px;
border: inherit;
background: inherit;
padding: 0px;
}
.dropzone-previews, .dropzone .dz-message {
background: white;
}
}
</style>
{% include 'appearance/generic_multiform_subtemplate.html' %} {% include 'appearance/generic_multiform_subtemplate.html' %}
{% include 'sources/dropzone.html' %}
<script type="text/x-template" id="previewTemplate">
<div class="dz-preview dz-file-preview">
<i class="far fa-file fa-10x"></i>
<div class="dz-details">
<div class="dz-filename"><span data-dz-name></span></div>
<div class="dz-size" data-dz-size></div>
<img data-dz-thumbnail />
</div>
<div class="dz-progress">
<span class="dz-upload" data-dz-uploadprogress>
<div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" style="width: 100%">
</div>
</span>
</div>
<div class="dz-success-mark">
<span>
<i class="text-success fa fa-4x fa-check-circle"></i>
</span>
</div>
<div class="dz-error-mark">
<span>
<i class="text-danger fa fa-4x fa-times-circle"></i>
</span>
</div>
<div class="dz-error-message">
<span data-dz-errormessage>
</span>
</div>
</div>
</script>
<script>
var messageCancelUpload = "{% trans 'Cancel upload' %}";
var messageCancelUploadConfirmation = "{% trans 'Are you sure you want to cancel this upload?' %}";
var messageDefaultMessage = "{% trans 'Drop files or click here to upload files' %}";
var messageFallbackMessage = "{% trans 'Your browser does not support drag and drop file uploads.' %}";
var messageFallbackText = "{% trans 'Please use the fallback form below to upload your files.' %}";
var messageRemoveFile = "{% trans 'Clear' %}";
var messageResponseError = "{% trans 'Server responded with {{statusCode}} code.' %}";
$.getScript( "{% static 'sources/node_modules/dropzone/dist/dropzone.js' %}" )
.done(function( script, textStatus ) {
Dropzone.autoDiscover = false;
jQuery(document).ready(function() {
var previewTemplate = document.querySelector('#previewTemplate').innerHTML;
{% verbatim %}
$('.dropzone').dropzone({
addRemoveLinks: true,
createImageThumbnails: false,
dictCancelUpload: messageCancelUpload,
dictCancelUploadConfirmation: messageCancelUploadConfirmation,
dictDefaultMessage: '<i class="fa fa-cloud-upload-alt"></i> ' + messageDefaultMessage,
dictFallbackMessage: messageFallbackMessage,
dictFallbackText: messageFallbackText,
dictRemoveFile: messageRemoveFile,
dictResponseError: messageResponseError,
maxFilesize: 2048,
paramName: 'source-file',
previewTemplate: previewTemplate,
timeout: 1200000
});
{% endverbatim %}
});
});
</script>

View File

@@ -7,6 +7,13 @@ from .literals import TEST_SOURCE_LABEL, TEST_SOURCE_UNCOMPRESS_N
class SourceTestMixin(object): class SourceTestMixin(object):
auto_create_test_source = True
def setUp(self):
super(SourceTestMixin, self).setUp()
if self.auto_create_test_source:
self._create_test_source()
def _create_test_source(self): def _create_test_source(self):
self.test_source = WebFormSource.objects.create( self.test_source = WebFormSource.objects.create(
enabled=True, label=TEST_SOURCE_LABEL, enabled=True, label=TEST_SOURCE_LABEL,

View File

@@ -39,7 +39,6 @@ class CompressedUploadsTestCase(SourceTestMixin, GenericDocumentTestCase):
auto_upload_document = False auto_upload_document = False
def test_upload_compressed_file(self): def test_upload_compressed_file(self):
self._create_test_source()
self.test_source.uncompress = SOURCE_UNCOMPRESS_CHOICE_Y self.test_source.uncompress = SOURCE_UNCOMPRESS_CHOICE_Y
self.test_source.save() self.test_source.save()

View File

@@ -54,10 +54,6 @@ class DocumentUploadWizardViewTestCase(
): ):
auto_upload_document = False auto_upload_document = False
def setUp(self):
super(DocumentUploadWizardViewTestCase, self).setUp()
self._create_test_source()
def test_upload_compressed_file(self): def test_upload_compressed_file(self):
self.test_source.uncompress = SOURCE_UNCOMPRESS_CHOICE_Y self.test_source.uncompress = SOURCE_UNCOMPRESS_CHOICE_Y
self.test_source.save() self.test_source.save()
@@ -300,6 +296,8 @@ class StagingFolderViewTestCase(
class SourcesViewTestCase( class SourcesViewTestCase(
SourceTestMixin, SourceViewTestMixin, GenericViewTestCase SourceTestMixin, SourceViewTestMixin, GenericViewTestCase
): ):
auto_create_test_source = False
def test_source_create_view_no_permission(self): def test_source_create_view_no_permission(self):
response = self._request_setup_source_create_view() response = self._request_setup_source_create_view()
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 403)

View File

@@ -449,9 +449,15 @@ class DocumentVersionUploadInteractiveView(UploadBaseView):
) )
def get_form_classes(self): def get_form_classes(self):
source_form_class = get_upload_form_class(self.source.source_type)
# Override source form class to enable the HTML5 file uploader
if source_form_class == WebFormUploadForm:
source_form_class = WebFormUploadFormHTML5
return { return {
'document_form': NewVersionForm, 'document_form': NewVersionForm,
'source_form': get_upload_form_class(self.source.source_type) 'source_form': source_form_class
} }
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@@ -464,6 +470,14 @@ class DocumentVersionUploadInteractiveView(UploadBaseView):
'from source: %(source)s' 'from source: %(source)s'
) % {'document': self.document, 'source': self.source.label} ) % {'document': self.document, 'source': self.source.label}
context['submit_label'] = _('Submit') context['submit_label'] = _('Submit')
context['form_css_classes'] = 'dropzone'
context['form_disable_submit'] = True
context['form_action'] = '{}?{}'.format(
reverse(
viewname=self.request.resolver_match.view_name,
kwargs=self.request.resolver_match.kwargs
), self.request.META['QUERY_STRING']
)
return context return context