Skip to content

Commit

Permalink
Merge pull request #70 from plone/fix-cut-copy-locked-errors-fc
Browse files Browse the repository at this point in the history
do not throw exceptions for cutting locked objects in folder contents
  • Loading branch information
vangheem committed Jan 26, 2016
2 parents bac6dfd + a3ff084 commit 5ac6fea
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 13 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ New:

Fixes:

- *add item here*
- Fix errors when cutting and copying objects in folder contents
[vangheem]


3.0.16 (2016-01-08)
Expand Down
7 changes: 3 additions & 4 deletions plone/app/content/browser/contents/copy.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# -*- coding: utf-8 -*-
from cgi import escape
from OFS.CopySupport import _cb_encode
from OFS.CopySupport import cookie_path
from OFS.CopySupport import CopyError
from OFS.CopySupport import eNotSupported
from OFS.Moniker import Moniker
from plone.app.content.browser.contents import ContentsBaseAction
from plone.app.content.interfaces import IStructureAction
Expand Down Expand Up @@ -41,7 +38,9 @@ def finish(self):
oblist = []
for ob in self.oblist:
if not ob.cb_isCopyable():
raise CopyError(eNotSupported % escape(id))
self.errors.append(_(u'${title} cannot be copied.',
mapping={u'title': self.objectTitle(ob)}))
continue
m = Moniker(ob)
oblist.append(m.dump())
cp = (0, oblist)
Expand Down
14 changes: 6 additions & 8 deletions plone/app/content/browser/contents/cut.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
# -*- coding: utf-8 -*-
from cgi import escape
from OFS.CopySupport import _cb_encode
from OFS.CopySupport import cookie_path
from OFS.CopySupport import CopyError
from OFS.CopySupport import eNotSupported
from OFS.Moniker import Moniker
from plone.app.content.browser.contents import ContentsBaseAction
from plone.app.content.interfaces import IStructureAction
from Products.CMFPlone import PloneMessageFactory as _
from webdav.Lockable import ResourceLockedError
from zope.i18n import translate
from zope.interface import implementer

Expand Down Expand Up @@ -42,11 +38,13 @@ def finish(self):
oblist = []
for ob in self.oblist:
if ob.wl_isLocked():
raise ResourceLockedError('Object "%s" is locked via WebDAV'
% ob.getId())

self.errors.append(_(u'${title} is being edited and cannot be cut.',
mapping={u'title': self.objectTitle(ob)}))
continue
if not ob.cb_isMoveable():
raise CopyError(eNotSupported % escape(id))
self.errors.append(_(u'${title} is being edited and can not be cut.',
mapping={u'title': self.objectTitle(ob)}))
continue
m = Moniker(ob)
oblist.append(m.dump())
cp = (1, oblist)
Expand Down
41 changes: 41 additions & 0 deletions plone/app/content/tests/test_folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from zope.publisher.browser import TestRequest
import json
import unittest
from plone.locking.interfaces import IRefreshableLockable


class BaseTest(unittest.TestCase):
Expand Down Expand Up @@ -220,6 +221,38 @@ def testStateChange(self):
self.assertTrue(len(result['breadcrumbs']) > 0)


class CutCopyLockedTest(BaseTest):
"""in folder contents """

layer = PLONE_APP_CONTENT_DX_INTEGRATION_TESTING

def setUp(self):
self.portal = self.layer['portal']
login(self.portal, TEST_USER_NAME)
setRoles(self.portal, TEST_USER_ID, ['Manager'])

self.portal.invokeFactory('Document', id="page", title="page")
self.portal.page.reindexObject()

self.env = {'HTTP_ACCEPT_LANGUAGE': 'en', 'REQUEST_METHOD': 'POST'}
self.request = makerequest(self.layer['app']).REQUEST
self.request.environ.update(self.env)
self.request.form = {
'selection': '["' + IUUID(self.portal.page) + '"]',
'_authenticator': createToken(),
'folder': '/'
}
self.request.REQUEST_METHOD = 'POST'

def test_cut_object_when_locked(self):
from plone.app.content.browser.contents.cut import CutActionView
lockable = IRefreshableLockable(self.portal.page)
lockable.lock()
view = CutActionView(self.portal, self.request)
view()
self.assertEquals(len(view.errors), 1)


class DeleteDXTest(BaseTest):
"""Verify delete behavior from the folder contents view"""

Expand Down Expand Up @@ -257,6 +290,14 @@ def test_delete_object(self):
view()
self.assertTrue(page_id not in self.portal)

def test_delete_object_when_locked(self):
from plone.app.content.browser.contents.delete import DeleteActionView
lockable = IRefreshableLockable(self.portal.page)
lockable.lock()
view = DeleteActionView(self.portal, self.request)
view()
self.assertEquals(len(view.errors), 1)

def test_delete_wrong_object_by_acquisition(self):
page_id = self.portal.page.id
f1 = self.portal.invokeFactory('Folder', id="f1", title="folder one")
Expand Down

0 comments on commit 5ac6fea

Please sign in to comment.