Compare commits
10 Commits
features/d
...
versions/m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e2ef57e00 | ||
|
|
756765ce4a | ||
|
|
53096b8bdd | ||
|
|
8aa2567a56 | ||
|
|
ce6e568001 | ||
|
|
d1f0e23c53 | ||
|
|
3f33bdd9c2 | ||
|
|
b2390843ab | ||
|
|
fc14341d40 | ||
|
|
57dd5b1bca |
@@ -78,6 +78,11 @@
|
||||
Support Docker networks and make it the default.
|
||||
Delete the containers to allow the script to be idempotent.
|
||||
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)
|
||||
==================
|
||||
|
||||
@@ -87,10 +87,10 @@ from .permissions import (
|
||||
permission_document_download, permission_document_edit,
|
||||
permission_document_new_version, permission_document_print,
|
||||
permission_document_properties_edit, permission_document_restore,
|
||||
permission_document_trash, permission_document_type_delete,
|
||||
permission_document_type_edit, permission_document_type_view,
|
||||
permission_document_version_revert, permission_document_version_view,
|
||||
permission_document_view
|
||||
permission_document_tools, permission_document_trash,
|
||||
permission_document_type_delete, permission_document_type_edit,
|
||||
permission_document_type_view, permission_document_version_revert,
|
||||
permission_document_version_view, permission_document_view
|
||||
)
|
||||
# Just import to initialize the search models
|
||||
from .search import document_search, document_page_search # NOQA
|
||||
@@ -191,8 +191,8 @@ class DocumentsApp(MayanAppConfig):
|
||||
permission_document_delete, permission_document_download,
|
||||
permission_document_edit, permission_document_new_version,
|
||||
permission_document_print, permission_document_properties_edit,
|
||||
permission_document_restore, permission_document_trash,
|
||||
permission_document_version_revert,
|
||||
permission_document_restore, permission_document_tools,
|
||||
permission_document_trash, permission_document_version_revert,
|
||||
permission_document_version_view, permission_document_view,
|
||||
permission_events_view, permission_transformation_create,
|
||||
permission_transformation_delete,
|
||||
|
||||
@@ -102,6 +102,14 @@ class Document(models.Model):
|
||||
)
|
||||
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):
|
||||
to_trash = kwargs.pop('to_trash', True)
|
||||
|
||||
@@ -126,6 +134,14 @@ class Document(models.Model):
|
||||
else:
|
||||
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):
|
||||
return reverse(
|
||||
viewname='documents:document_preview', kwargs={'pk': self.pk}
|
||||
@@ -140,6 +156,10 @@ class Document(models.Model):
|
||||
def is_in_trash(self):
|
||||
return self.in_trash
|
||||
|
||||
@property
|
||||
def latest_version(self):
|
||||
return self.versions.order_by('timestamp').last()
|
||||
|
||||
def natural_key(self):
|
||||
return (self.uuid,)
|
||||
natural_key.dependencies = ['documents.DocumentType']
|
||||
@@ -165,6 +185,34 @@ class Document(models.Model):
|
||||
"""
|
||||
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):
|
||||
self.in_trash = False
|
||||
self.save()
|
||||
@@ -209,53 +257,3 @@ class Document(models.Model):
|
||||
@property
|
||||
def size(self):
|
||||
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()
|
||||
|
||||
@@ -253,10 +253,6 @@ class DocumentVersion(models.Model):
|
||||
)
|
||||
return DocumentPage.passthrough.filter(document_version=self)
|
||||
|
||||
@property
|
||||
def pages(self):
|
||||
return self.version_pages.all()
|
||||
|
||||
@property
|
||||
def page_count(self):
|
||||
"""
|
||||
@@ -264,6 +260,10 @@ class DocumentVersion(models.Model):
|
||||
"""
|
||||
return self.pages.count()
|
||||
|
||||
@property
|
||||
def pages(self):
|
||||
return self.version_pages.all()
|
||||
|
||||
def revert(self, _user=None):
|
||||
"""
|
||||
Delete the subsequent versions after this one
|
||||
|
||||
@@ -5,6 +5,7 @@ import os
|
||||
from django.conf import settings
|
||||
|
||||
from mayan.apps.converter.classes import Layer
|
||||
from mayan.apps.converter.layers import layer_saved_transformations
|
||||
|
||||
from ..literals import PAGE_RANGE_ALL
|
||||
from ..models import DocumentType
|
||||
@@ -14,6 +15,7 @@ from .literals import (
|
||||
TEST_DOCUMENT_TYPE_LABEL, TEST_DOCUMENT_TYPE_LABEL_EDITED,
|
||||
TEST_DOCUMENT_TYPE_QUICK_LABEL, TEST_DOCUMENT_TYPE_QUICK_LABEL_EDITED,
|
||||
TEST_SMALL_DOCUMENT_FILENAME, TEST_SMALL_DOCUMENT_PATH,
|
||||
TEST_TRANSFORMATION_ARGUMENT, TEST_TRANSFORMATION_CLASS,
|
||||
TEST_VERSION_COMMENT
|
||||
)
|
||||
|
||||
@@ -69,6 +71,8 @@ class DocumentTestMixin(object):
|
||||
|
||||
self.test_document = 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):
|
||||
@@ -149,6 +153,13 @@ class DocumentVersionTestMixin(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):
|
||||
return self.get(
|
||||
viewname='documents:document_properties',
|
||||
|
||||
@@ -9,10 +9,10 @@ from ..permissions import (
|
||||
from .base import GenericDocumentViewTestCase
|
||||
|
||||
|
||||
class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
|
||||
def setUp(self):
|
||||
super(DocumentPageDisableViewTestCase, self).setUp()
|
||||
self.test_document_page = self.test_document.pages_all.first()
|
||||
class DocumentPageDisableViewTestMixin(object):
|
||||
def _disable_test_document_page(self):
|
||||
self.test_document_page.enabled = False
|
||||
self.test_document_page.save()
|
||||
|
||||
def _request_test_document_page_disable_view(self):
|
||||
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):
|
||||
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()
|
||||
)
|
||||
|
||||
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):
|
||||
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()
|
||||
)
|
||||
|
||||
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):
|
||||
self._disable_test_document_page()
|
||||
|
||||
@@ -114,13 +121,6 @@ class DocumentPageDisableViewTestCase(GenericDocumentViewTestCase):
|
||||
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):
|
||||
self._disable_test_document_page()
|
||||
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):
|
||||
return self.get(
|
||||
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):
|
||||
response = self._request_test_document_page_list_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
@@ -170,13 +181,6 @@ class DocumentPageViewTestCase(GenericDocumentViewTestCase):
|
||||
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):
|
||||
response = self._request_test_document_page_view(
|
||||
document_page=self.test_document.pages.first()
|
||||
|
||||
@@ -203,7 +203,7 @@ class DocumentTypeQuickLabelViewsTestCase(
|
||||
)
|
||||
|
||||
|
||||
class DocumentsQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericDocumentViewTestCase):
|
||||
class DocumentsQuickLabelViewTestMixin(object):
|
||||
def _request_document_quick_label_edit_view(self, extra_data=None):
|
||||
data = {
|
||||
'document_type_available_filenames': self.test_document_type_filename.pk,
|
||||
@@ -219,6 +219,11 @@ class DocumentsQuickLabelViewsTestCase(DocumentTypeQuickLabelTestMixin, GenericD
|
||||
}, data=data
|
||||
)
|
||||
|
||||
|
||||
class DocumentsQuickLabelViewTestCase(
|
||||
DocumentsQuickLabelViewTestMixin, DocumentTypeQuickLabelTestMixin,
|
||||
GenericDocumentViewTestCase
|
||||
):
|
||||
def test_document_quick_label_no_permission(self):
|
||||
self._create_test_quick_label()
|
||||
|
||||
|
||||
@@ -9,13 +9,24 @@ from .literals import TEST_VERSION_COMMENT
|
||||
from .mixins import DocumentVersionTestMixin
|
||||
|
||||
|
||||
class DocumentVersionTestCase(DocumentVersionTestMixin, GenericDocumentViewTestCase):
|
||||
class DocumentVersionViewTestMixin(object):
|
||||
def _request_document_version_list_view(self):
|
||||
return self.get(
|
||||
viewname='documents:document_version_list',
|
||||
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):
|
||||
self._upload_new_version()
|
||||
|
||||
@@ -33,12 +44,6 @@ class DocumentVersionTestCase(DocumentVersionTestMixin, GenericDocumentViewTestC
|
||||
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):
|
||||
first_version = self.test_document.latest_version
|
||||
self._upload_new_version()
|
||||
|
||||
@@ -16,22 +16,14 @@ from ..permissions import (
|
||||
|
||||
from .base import GenericDocumentViewTestCase
|
||||
from .literals import (
|
||||
TEST_DOCUMENT_TYPE_2_LABEL, TEST_SMALL_DOCUMENT_FILENAME,
|
||||
TEST_TRANSFORMATION_ARGUMENT, TEST_TRANSFORMATION_CLASS
|
||||
TEST_DOCUMENT_TYPE_2_LABEL, TEST_SMALL_DOCUMENT_FILENAME
|
||||
)
|
||||
from .mixins import DocumentViewTestMixin
|
||||
|
||||
|
||||
class DocumentsViewsTestCase(
|
||||
class DocumentViewTestCase(
|
||||
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):
|
||||
response = self._request_document_properties_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
@@ -302,13 +294,13 @@ class DocumentsViewsTestCase(
|
||||
self.assertEqual(self.test_document.pages.count(), 0)
|
||||
|
||||
def test_document_update_page_count_view_with_permission(self):
|
||||
# TODO: Revise permission association
|
||||
|
||||
page_count = self.test_document.pages.count()
|
||||
self.test_document.pages.all().delete()
|
||||
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()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
@@ -329,7 +321,9 @@ class DocumentsViewsTestCase(
|
||||
self.test_document.pages.all().delete()
|
||||
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()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
@@ -5,7 +5,7 @@ from ..permissions import permission_document_view
|
||||
from .base import GenericDocumentViewTestCase
|
||||
|
||||
|
||||
class DuplicatedDocumentsViewsTestCase(GenericDocumentViewTestCase):
|
||||
class DuplicatedDocumentsViewsTestMixin(object):
|
||||
def _upload_duplicate_document(self):
|
||||
self.upload_document()
|
||||
|
||||
@@ -18,6 +18,10 @@ class DuplicatedDocumentsViewsTestCase(GenericDocumentViewTestCase):
|
||||
kwargs={'pk': self.test_documents[0].pk}
|
||||
)
|
||||
|
||||
|
||||
class DuplicatedDocumentsViewsTestCase(
|
||||
DuplicatedDocumentsViewsTestMixin, GenericDocumentViewTestCase
|
||||
):
|
||||
def test_duplicated_document_list_no_permissions(self):
|
||||
self._upload_duplicate_document()
|
||||
|
||||
|
||||
@@ -17,12 +17,23 @@ TEST_TRANSFORMATION_NAME = 'rotate'
|
||||
TEST_TRANSFORMATION_ARGUMENT = 'degrees: 180'
|
||||
|
||||
|
||||
class DocumentEventsTestCase(GenericDocumentViewTestCase):
|
||||
class DocumentEventsTestMixin(object):
|
||||
def _request_test_document_download_view(self):
|
||||
return self.get(
|
||||
'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):
|
||||
Action.objects.all().delete()
|
||||
|
||||
@@ -55,13 +66,6 @@ class DocumentEventsTestCase(GenericDocumentViewTestCase):
|
||||
self.assertEqual(event.target, self.test_document)
|
||||
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):
|
||||
Action.objects.all().delete()
|
||||
|
||||
|
||||
@@ -6,13 +6,34 @@ from ..permissions import permission_document_view
|
||||
from .base import GenericDocumentViewTestCase
|
||||
|
||||
|
||||
class FavoriteDocumentsTestCase(GenericDocumentViewTestCase):
|
||||
class FavoriteDocumentsTestMixin(object):
|
||||
def _request_document_add_to_favorites_view(self):
|
||||
return self.post(
|
||||
viewname='documents:document_add_to_favorites',
|
||||
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):
|
||||
response = self._request_document_add_to_favorites_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
@@ -26,16 +47,6 @@ class FavoriteDocumentsTestCase(GenericDocumentViewTestCase):
|
||||
self.assertEqual(response.status_code, 302)
|
||||
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):
|
||||
self._document_add_to_favorites()
|
||||
response = self._request_document_list_favorites()
|
||||
@@ -53,12 +64,6 @@ class FavoriteDocumentsTestCase(GenericDocumentViewTestCase):
|
||||
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):
|
||||
self._document_add_to_favorites()
|
||||
response = self._request_document_remove_from_favorites()
|
||||
|
||||
@@ -89,7 +89,6 @@ class DocumentsLinksTestCase(GenericDocumentViewTestCase):
|
||||
class DeletedDocumentsLinksTestCase(GenericDocumentViewTestCase):
|
||||
def setUp(self):
|
||||
super(DeletedDocumentsLinksTestCase, self).setUp()
|
||||
self.login_user()
|
||||
self.test_document.delete()
|
||||
self.test_deleted_document = DeletedDocument.objects.get(
|
||||
pk=self.test_document.pk
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
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.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):
|
||||
return document_page_search.search(
|
||||
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
|
||||
)
|
||||
|
||||
|
||||
class DocumentSearchTestCase(
|
||||
DocumentSearchTestMixin, GenericDocumentViewTestCase
|
||||
):
|
||||
def test_document_page_search_no_access(self):
|
||||
queryset = self._perform_document_page_search()
|
||||
self.assertFalse(self.test_document.pages.first() in queryset)
|
||||
|
||||
@@ -9,7 +9,7 @@ from ..permissions import (
|
||||
from .base import GenericDocumentViewTestCase
|
||||
|
||||
|
||||
class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
||||
class TrashedDocumentTestMixin(object):
|
||||
def _request_document_restore_get_view(self):
|
||||
return self.get(
|
||||
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):
|
||||
self.test_document.delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
@@ -43,13 +86,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
||||
|
||||
self.assertEqual(Document.objects.count(), document_count)
|
||||
|
||||
def _request_document_restore_post_view(self):
|
||||
return self.post(
|
||||
viewname='documents:document_restore', kwargs={
|
||||
'pk': self.test_document.pk
|
||||
}
|
||||
)
|
||||
|
||||
def test_document_restore_post_view_no_permission(self):
|
||||
self.test_document.delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
@@ -74,13 +110,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
||||
self.assertEqual(DeletedDocument.objects.count(), 0)
|
||||
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):
|
||||
document_count = Document.objects.count()
|
||||
|
||||
@@ -101,13 +130,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
||||
|
||||
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):
|
||||
response = self._request_document_trash_post_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
@@ -126,13 +148,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
||||
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||
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):
|
||||
self.test_document.delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
@@ -165,13 +180,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
||||
DeletedDocument.objects.count(), trashed_document_count
|
||||
)
|
||||
|
||||
def _request_document_delete_post_view(self):
|
||||
return self.post(
|
||||
viewname='documents:document_delete', kwargs={
|
||||
'pk': self.test_document.pk
|
||||
}
|
||||
)
|
||||
|
||||
def test_document_delete_post_view_no_permissions(self):
|
||||
self.test_document.delete()
|
||||
self.assertEqual(Document.objects.count(), 0)
|
||||
@@ -198,9 +206,6 @@ class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
||||
self.assertEqual(DeletedDocument.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):
|
||||
self.test_document.delete()
|
||||
|
||||
|
||||
115
mayan/apps/sources/templates/sources/dropzone.html
Normal file
115
mayan/apps/sources/templates/sources/dropzone.html
Normal 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>
|
||||
@@ -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' %}
|
||||
|
||||
<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>
|
||||
|
||||
{% include 'sources/dropzone.html' %}
|
||||
|
||||
@@ -7,6 +7,13 @@ from .literals import TEST_SOURCE_LABEL, TEST_SOURCE_UNCOMPRESS_N
|
||||
|
||||
|
||||
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):
|
||||
self.test_source = WebFormSource.objects.create(
|
||||
enabled=True, label=TEST_SOURCE_LABEL,
|
||||
|
||||
@@ -39,7 +39,6 @@ class CompressedUploadsTestCase(SourceTestMixin, GenericDocumentTestCase):
|
||||
auto_upload_document = False
|
||||
|
||||
def test_upload_compressed_file(self):
|
||||
self._create_test_source()
|
||||
self.test_source.uncompress = SOURCE_UNCOMPRESS_CHOICE_Y
|
||||
self.test_source.save()
|
||||
|
||||
|
||||
@@ -54,10 +54,6 @@ class DocumentUploadWizardViewTestCase(
|
||||
):
|
||||
auto_upload_document = False
|
||||
|
||||
def setUp(self):
|
||||
super(DocumentUploadWizardViewTestCase, self).setUp()
|
||||
self._create_test_source()
|
||||
|
||||
def test_upload_compressed_file(self):
|
||||
self.test_source.uncompress = SOURCE_UNCOMPRESS_CHOICE_Y
|
||||
self.test_source.save()
|
||||
@@ -300,6 +296,8 @@ class StagingFolderViewTestCase(
|
||||
class SourcesViewTestCase(
|
||||
SourceTestMixin, SourceViewTestMixin, GenericViewTestCase
|
||||
):
|
||||
auto_create_test_source = False
|
||||
|
||||
def test_source_create_view_no_permission(self):
|
||||
response = self._request_setup_source_create_view()
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
@@ -449,9 +449,15 @@ class DocumentVersionUploadInteractiveView(UploadBaseView):
|
||||
)
|
||||
|
||||
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 {
|
||||
'document_form': NewVersionForm,
|
||||
'source_form': get_upload_form_class(self.source.source_type)
|
||||
'source_form': source_form_class
|
||||
}
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
@@ -464,6 +470,14 @@ class DocumentVersionUploadInteractiveView(UploadBaseView):
|
||||
'from source: %(source)s'
|
||||
) % {'document': self.document, 'source': self.source.label}
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user