diff --git a/CHANGES.rst b/CHANGES.rst index 5b2068c2..03a3b572 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,7 +10,7 @@ Breaking changes: New features: -- Add ``@@allowed_types_in_context`` JSON view in ``plone.app.content.browser.allowed_types_in_context``, which returns a list of all FTI ids, which can be added in the current container. +- Add ``@@allow_upload`` view, which returns a JSON string to indicate if File or Image uploads are allowed in the current container. [thet] - Factor out the available columns ignored list which can be used to narrow down the available columns list to a user friendly set. diff --git a/plone/app/content/browser/__init__.py b/plone/app/content/browser/__init__.py index 1d4d0add..40a96afc 100644 --- a/plone/app/content/browser/__init__.py +++ b/plone/app/content/browser/__init__.py @@ -1,17 +1 @@ # -*- coding: utf-8 -*- -from Products.Five.browser import BrowserView -import json - - -class AllowedTypesInContext(BrowserView): - - def __call__(self): - """Return JSON structure with all allowed content type ids from the - current container. - """ - - self.request.response.setHeader( - 'Content-Type', 'application/json; charset=utf-8' - ) - allowed_types = [t.getId() for t in self.context.allowedContentTypes()] - return json.dumps({'allowed_types': allowed_types}) diff --git a/plone/app/content/browser/configure.zcml b/plone/app/content/browser/configure.zcml index 2f251b3f..9a9faf27 100644 --- a/plone/app/content/browser/configure.zcml +++ b/plone/app/content/browser/configure.zcml @@ -180,11 +180,10 @@ permission="zope2.View" /> - diff --git a/plone/app/content/browser/file.py b/plone/app/content/browser/file.py index e6491fe2..d79f4e1a 100644 --- a/plone/app/content/browser/file.py +++ b/plone/app/content/browser/file.py @@ -194,3 +194,22 @@ def __call__(self): 'Content-Type', 'application/json; charset=utf-8' ) return json.dumps(result) + + +class AllowUploadView(BrowserView): + + def __call__(self): + """Return JSON structure to indicate if File or Image uploads are + allowed in the current container. + """ + self.request.response.setHeader( + 'Content-Type', 'application/json; charset=utf-8' + ) + allowed_types = [t.getId() for t in self.context.allowedContentTypes()] + allow_images = u'Image' in allowed_types + allow_files = u'File' in allowed_types + return json.dumps({ + 'allowUpload': allow_images or allow_files, + 'allowImages': allow_images, + 'allowFiles': allow_files + }) diff --git a/plone/app/content/tests/test_contents.py b/plone/app/content/tests/test_contents.py index 4e405085..3a90c492 100644 --- a/plone/app/content/tests/test_contents.py +++ b/plone/app/content/tests/test_contents.py @@ -155,7 +155,7 @@ def test_paste_fail_constraint(self): self.assertEqual(len(self.portal.it1.contentIds()), 0) -class AllowedTypesInContextTests(unittest.TestCase): +class AllowUploadViewTests(unittest.TestCase): layer = PLONE_APP_CONTENT_DX_INTEGRATION_TESTING def setUp(self): @@ -166,9 +166,8 @@ def setUp(self): type1_fti = DexterityFTI('type1') type1_fti.klass = 'plone.dexterity.content.Container' type1_fti.filter_content_types = True - type1_fti.allowed_content_types = ['type1'] + type1_fti.allowed_content_types = [] type1_fti.behaviors = ( - 'Products.CMFPlone.interfaces.constrains.ISelectableConstrainTypes', # noqa 'plone.app.dexterity.behaviors.metadata.IBasic' ) self.portal.portal_types._setObject('type1', type1_fti) @@ -179,22 +178,43 @@ def setUp(self): self.portal.invokeFactory('type1', id='it1', title='Item 1') - def test_allowed_types_in_context_view(self): - - # Test root object - allowed_types = self.portal.restrictedTraverse('@@allowed_types_in_context') # noqa - allowed_types = json.loads(allowed_types()) - - self.assertEqual( - sorted(allowed_types['allowed_types']), - [u'Collection', u'Document', u'Event', u'File', u'Folder', u'Image', u'Link', u'News Item', u'type1'] # noqa - ) - - # Test subfolder - allowed_types = self.portal.it1.restrictedTraverse('@@allowed_types_in_context') # noqa - allowed_types = json.loads(allowed_types()) + def test_allow_upload(self): + """Test, if file or images are allowed in a container in different FTI + configurations. + """ - self.assertEqual( - sorted(allowed_types['allowed_types']), - [u'type1'] - ) + # Test none allowed + self.type1_fti.allowed_content_types = [] + allow_upload = self.portal.it1.restrictedTraverse('@@allow_upload') + allow_upload = json.loads(allow_upload()) + + self.assertEqual(allow_upload['allowUpload'], False) + self.assertEqual(allow_upload['allowImages'], False) + self.assertEqual(allow_upload['allowFiles'], False) + + # Test images allowed + self.type1_fti.allowed_content_types = ['Image'] + allow_upload = self.portal.it1.restrictedTraverse('@@allow_upload') + allow_upload = json.loads(allow_upload()) + + self.assertEqual(allow_upload['allowUpload'], True) + self.assertEqual(allow_upload['allowImages'], True) + self.assertEqual(allow_upload['allowFiles'], False) + + # Test files allowed + self.type1_fti.allowed_content_types = ['File'] + allow_upload = self.portal.it1.restrictedTraverse('@@allow_upload') + allow_upload = json.loads(allow_upload()) + + self.assertEqual(allow_upload['allowUpload'], True) + self.assertEqual(allow_upload['allowImages'], False) + self.assertEqual(allow_upload['allowFiles'], True) + + # Test images and files allowed + self.type1_fti.allowed_content_types = ['Image', 'File'] + allow_upload = self.portal.it1.restrictedTraverse('@@allow_upload') + allow_upload = json.loads(allow_upload()) + + self.assertEqual(allow_upload['allowUpload'], True) + self.assertEqual(allow_upload['allowImages'], True) + self.assertEqual(allow_upload['allowFiles'], True)