plone.resourceeditor/master: Merge pull request #19 from plone/add-move-api-endpoint-to-f

GitHub <jenkins-z4DKO/[email protected]>
Newsgroups gmane.comp.web.zope.plone.cvs
Message-ID <[email protected]>
Repository: plone.resourceeditor
Branch: refs/heads/master
Date: 2017-07-14T00:08:23+03:00
Author: Asko Soukka (datakurre) <[email protected]>
Commit: https://github.com/plone/plone.resourceeditor/commit/0d5554899c5cda5336f027588e375651057bd8b6

Merge pull request #19 from plone/add-move-api-endpoint-to-filemanageraction-class

Add the move API endpoint to the FileManagerActions class

Files changed:
A plone/resourceeditor/tests/__init__.py
A plone/resourceeditor/tests/test_file_manager.py
A plone/resourceeditor/tests/test_file_manager_action.py
M CHANGES.rst
M plone/resourceeditor/browser.py
M plone/resourceeditor/testing.py
D plone/resourceeditor/tests.py

diff --git a/CHANGES.rst b/CHANGES.rst
index 05bb122..3548e46 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -11,6 +11,10 @@ Breaking changes:
 New features:
 
 - *add item here*
+- Add the download and move endpoint to the FileManagerActions class
+  [b4oshany]
+- Add test cases for FileManagerAction
+  [b4oshany]
 
 Bug fixes:
 
@@ -24,8 +28,14 @@ Fixes:
 
 - Remove  unittest2 dependency
   [kakshay21]
+- Split the error message for the move API endpoint into two. One
+  is for the parent folder and the other is for the distination folder
+  [b4oshany]
+- Fix Jenkins flake8 errors
 
 
+[b4oshany]: https://github.com/b4oshany
+
 2.0.5 (2016-03-31)
 ------------------
 
diff --git a/plone/resourceeditor/browser.py b/plone/resourceeditor/browser.py
index 112ab07..d83a29a 100644
--- a/plone/resourceeditor/browser.py
+++ b/plone/resourceeditor/browser.py
@@ -36,6 +36,7 @@ def authorize(context, request):
     if authenticator is not None and not authenticator.verify():
         raise Unauthorized
 
+
 invalidFilenameChars = frozenset('\/:*?"<>|')
 
 
@@ -68,6 +69,43 @@ def getExtension(self, obj=None, path=None):
         ext = ext[1:].lower()
         return ext
 
+    def getFolder(self, path):
+        """Returns a dict of file and folder objects representing the
+        contents of the given directory (indicated by a "path" parameter). The
+        values are dicts as returned by getInfo().
+
+        A boolean parameter "getsizes" indicates whether image dimensions
+        should be returned for each item. Folders should always be returned
+        before files.
+
+        Optionally a "type" parameter can be specified to restrict returned
+        files (depending on the connector). If a "type" parameter is given for
+        the HTML document, the same parameter value is reused and passed
+        to getFolder(). This can be used for example to only show image files
+        in a file system tree.
+        """
+
+        path = path.encode('utf-8')
+
+        folders = []
+        files = []
+
+        path = self.normalizePath(path)
+        folder = self.getObject(path)
+
+        for name in folder.listDirectory():
+            if IResourceDirectory.providedBy(folder[name]):
+                folders.append(self.getInfo(
+                    folder[name],
+                    path='/{0}/{1}/'.format(path, name)
+                ))
+            else:
+                files.append(self.getInfo(
+                    folder[name],
+                    path='/{0}/{1}'.format(path, name)
+                ))
+        return folders + files
+
     def getFile(self, path):
         path = self.normalizePath(path.encode('utf-8'))
         ext = self.getExtension(path=path)
@@ -82,7 +120,7 @@ def getFile(self, path):
             return json.dumps(result)
         else:
             data = self.context.openFile(path)
-            if hasattr(data, 'read'):
+            try:
                 data = data.read()
 
                 result['contents'] = str(data)
@@ -96,6 +134,8 @@ def getFile(self, path):
                     info = self.getInfo(obj)
                     result['info'] = self.previewTemplate(info=info)
                     return json.dumps(result)
+            except AttributeError:
+                return None
 
     def normalizePath(self, path):
         if path.startswith('/'):
@@ -121,7 +161,6 @@ def getInfo(self, obj, path='/'):
         indicates whether the dimensions of the file (if an image) should be
         returned.
         """
-
         filename = obj.__name__
 
         properties = {
@@ -134,7 +173,12 @@ def getInfo(self, obj, path='/'):
             properties['dateModified'] = DateTime(obj._p_mtime).strftime('%c')
             size = obj.get_size() / 1024
 
-        fileType = self.getExtension(obj)
+        if IResourceDirectory.providedBy(obj):
+            fileType = 'dir'
+            is_folder = True
+        else:
+            fileType = self.getExtension(obj)
+            is_folder = False
         if isinstance(obj, FilesystemFile):
             stats = os.stat(obj.path)
             modified = localtime(stats.st_mtime)
@@ -163,7 +207,7 @@ def getInfo(self, obj, path='/'):
             'filesystem': isinstance(obj, FilesystemFile),
             'properties': properties,
             'path': path,
-            'folder': False
+            'folder': is_folder
         }
 
     def saveFile(self, path, value):
@@ -294,6 +338,7 @@ def addFile(self, path, name):
             'name': name,
             'error': error,
             'code': code,
+            'path': path
         })
 
     def delete(self, path):
@@ -375,8 +420,71 @@ def renameFile(self, path, newName):
             'code': code,
         })
 
-    def __call__(self):
-        action = self.request.get('action')
+    def move(self, path, directory):
+        """Move the item at the given path to a new directory
+        """
+
+        path = path.encode('utf-8')
+        directory = directory.encode('utf-8')
+
+        npath = self.normalizePath(path)
+        newParentPath = self.normalizePath(directory)
+
+        parentPath = self.parentPath(npath)
+        filename = npath.split('/')[-1]
+
+        code = 0
+        error = ''
+        newCanonicalPath = '{0}/{1}'.format(newParentPath, filename)
+
+        try:
+            parent = self.getObject(parentPath)
+        except KeyError:
+            error = translate(_(u'filemanager_invalid_parent',
+                              default=u'Parent folder not found.'),
+                              context=self.request)
+            code = 1
+            return json.dumps({
+                'code': code,
+                'error': error,
+                'newPath': self.normalizeReturnPath(newCanonicalPath),
+            })
+
+        try:
+            target = self.getObject(newParentPath)
+        except KeyError:
+            error = translate(_(u'filemanager_error_folder_exists',
+                              default=u'Destination folder not found.'),
+                              context=self.request)
+            code = 1
+            return json.dumps({
+                'code': code,
+                'error': error,
+                'newPath': self.normalizeReturnPath(newCanonicalPath),
+            })
+
+        if filename not in parent:
+            error = translate(_(u'filemanager_error_file_not_found',
+                              default=u'File not found.'),
+                              context=self.request)
+            code = 1
+        elif filename in target:
+            error = translate(_(u'filemanager_error_file_exists',
+                              default=u'File already exists.'),
+                              context=self.request)
+            code = 1
+        else:
+            obj = parent[filename]
+            del parent[filename]
+            target[filename] = obj
+
+        return json.dumps({
+            'code': code,
+            'error': error,
+            'newPath': self.normalizeReturnPath(newCanonicalPath),
+        })
+
+    def do_action(self, action):
         if action == 'dataTree':
 
             def getDirectory(folder, relpath=''):
@@ -429,6 +537,37 @@ def getDirectory(folder, relpath=''):
             path = self.request.get('path', '')
             return self.delete(path)
 
+        if action == 'move':
+            src_path = self.request.get('source', '')
+            des_path = self.request.get('destination', '')
+            return self.move(src_path, des_path)
+
+    def download(self, path):
+        """Serve the requested file to the user
+        """
+
+        path = path.encode('utf-8')
+
+        npath = self.normalizePath(path)
+        parentPath = '/'.join(npath.split('/')[:-1])
+        name = npath.split('/')[-1]
+
+        parent = self.getObject(parentPath)
+
+        self.request.response.setHeader('Content-Type',
+                                        'application/octet-stream')
+        self.request.response.setHeader(
+            'Content-Disposition',
+            'attachment; filename="{0}"'.format(name)
+        )
+
+        # TODO: Use streams here if we can
+        return parent.readFile(name)
+
+    def __call__(self):
+        action = self.request.get('action')
+        return self.do_action(action)
+
 
 class FileManager(BrowserView):
     """Render the file manager and support its AJAX requests.
@@ -465,6 +604,68 @@ def pattern_options(self):
             )
         })
 
+    def mode_selector(self, form):
+        # AJAX methods called by the file manager
+        mode = form['mode']
+
+        if mode in self.protectedActions:
+            authorize(self.context, self.request)
+
+        response = {'error:': 'Unknown request', 'code': -1}
+        textareaWrap = False
+
+        if mode == u'getfolder':
+            response = self.getFolder(
+                path=urllib.unquote(form['path']),
+                getSizes=form.get('getsizes', 'false') == 'true'
+            )
+        elif mode == u'getinfo':
+            response = self.getInfo(
+                path=urllib.unquote(form['path']),
+                getSize=form.get('getsize', 'false') == 'true'
+            )
+        elif mode == u'addfolder':
+            response = self.addFolder(
+                path=urllib.unquote(form['path']),
+                name=urllib.unquote(form['name'])
+            )
+        elif mode == u'add':
+            textareaWrap = True
+            response = self.add(
+                path=urllib.unquote(form['currentpath']),
+                newfile=form['newfile'],
+                replacepath=form.get('replacepath', None)
+            )
+        elif mode == u'addnew':
+            response = self.addNew(
+                path=urllib.unquote(form['path']),
+                name=urllib.unquote(form['name'])
+            )
+        elif mode == u'rename':
+            response = self.rename(
+                path=urllib.unquote(form['old']),
+                newName=urllib.unquote(form['new'])
+            )
+        elif mode == u'delete':
+            response = self.delete(
+                path=urllib.unquote(form['path'])
+            )
+        elif mode == 'move':
+            response = self.move(
+                path=urllib.unquote(form['path']),
+                directory=urllib.unquote(form['directory'])
+            )
+        elif mode == u'download':
+            return self.download(
+                path=urllib.unquote(form['path'])
+            )
+        if textareaWrap:
+            self.request.response.setHeader('Content-Type', 'text/html')
+            return '<textarea>{0}</textarea>'.format(json.dumps(response))
+        self.request.response.setHeader('Content-Type',
+                                        'application/json')
+        return json.dumps(response)
+
     def __call__(self):
         # make sure theme is disable for these requests
         self.request.response.setHeader('X-Theme-Disabled', 'True')
@@ -475,66 +676,7 @@ def __call__(self):
 
         # AJAX methods called by the file manager
         if 'mode' in form:
-            mode = form['mode']
-
-            if mode in self.protectedActions:
-                authorize(self.context, self.request)
-
-            response = {'error:': 'Unknown request', 'code': -1}
-            textareaWrap = False
-
-            if mode == u'getfolder':
-                response = self.getFolder(
-                    path=urllib.unquote(form['path']),
-                    getSizes=form.get('getsizes', 'false') == 'true'
-                )
-            elif mode == u'getinfo':
-                response = self.getInfo(
-                    path=urllib.unquote(form['path']),
-                    getSize=form.get('getsize', 'false') == 'true'
-                )
-            elif mode == u'addfolder':
-                response = self.addFolder(
-                    path=urllib.unquote(form['path']),
-                    name=urllib.unquote(form['name'])
-                )
-            elif mode == u'add':
-                textareaWrap = True
-                response = self.add(
-                    path=urllib.unquote(form['currentpath']),
-                    newfile=form['newfile'],
-                    replacepath=form.get('replacepath', None)
-                )
-            elif mode == u'addnew':
-                response = self.addNew(
-                    path=urllib.unquote(form['path']),
-                    name=urllib.unquote(form['name'])
-                )
-            elif mode == u'rename':
-                response = self.rename(
-                    path=urllib.unquote(form['old']),
-                    newName=urllib.unquote(form['new'])
-                )
-            elif mode == u'delete':
-                response = self.delete(
-                    path=urllib.unquote(form['path'])
-                )
-            elif mode == 'move':
-                response = self.move(
-                    path=urllib.unquote(form['path']),
-                    directory=urllib.unquote(form['directory'])
-                )
-            elif mode == u'download':
-                return self.download(
-                    path=urllib.unquote(form['path'])
-                )
-            if textareaWrap:
-                self.request.response.setHeader('Content-Type', 'text/html')
-                return '<textarea>{0}</textarea>'.format(json.dumps(response))
-            else:
-                self.request.response.setHeader('Content-Type',
-                                                'application/json')
-                return json.dumps(response)
+            return self.mode_selector(form)
 
         # Rendering the view
         else:
@@ -958,32 +1100,48 @@ def move(self, path, directory):
 
         code = 0
         error = ''
+        newCanonicalPath = '{0}/{1}'.format(newParentPath, filename)
 
         try:
             parent = self.getObject(parentPath)
-            target = self.getObject(newParentPath)
         except KeyError:
             error = translate(_(u'filemanager_invalid_parent',
                               default=u'Parent folder not found.'),
                               context=self.request)
             code = 1
-        else:
-            if filename not in parent:
-                error = translate(_(u'filemanager_error_file_not_found',
-                                  default=u'File not found.'),
-                                  context=self.request)
-                code = 1
-            elif filename in target:
-                error = translate(_(u'filemanager_error_file_exists',
-                                  default=u'File already exists.'),
-                                  context=self.request)
-                code = 1
-            else:
-                obj = parent[filename]
-                del parent[filename]
-                target[filename] = obj
+            return {
+                'code': code,
+                'error': error,
+                'newPath': self.normalizeReturnPath(newCanonicalPath),
+            }
 
-        newCanonicalPath = '{0}/{1}'.format(newParentPath, filename)
+        try:
+            target = self.getObject(newParentPath)
+        except KeyError:
+            error = translate(_(u'filemanager_error_folder_exists',
+                              default=u'Destination folder not found.'),
+                              context=self.request)
+            code = 1
+            return {
+                'code': code,
+                'error': error,
+                'newPath': self.normalizeReturnPath(newCanonicalPath),
+            }
+
+        if filename not in parent:
+            error = translate(_(u'filemanager_error_file_not_found',
+                              default=u'File not found.'),
+                              context=self.request)
+            code = 1
+        elif filename in target:
+            error = translate(_(u'filemanager_error_file_exists',
+                              default=u'File already exists.'),
+                              context=self.request)
+            code = 1
+        else:
+            obj = parent[filename]
+            del parent[filename]
+            target[filename] = obj
 
         return {
             'code': code,
diff --git a/plone/resourceeditor/testing.py b/plone/resourceeditor/testing.py
index b00a6bd..de5cbe1 100644
--- a/plone/resourceeditor/testing.py
+++ b/plone/resourceeditor/testing.py
@@ -3,7 +3,6 @@
 from plone.app.testing import IntegrationTesting
 from plone.app.testing import PLONE_FIXTURE
 from plone.app.testing import PloneSandboxLayer
-from zope.configuration import xmlconfig
 
 
 class PloneResourceEditor(PloneSandboxLayer):
@@ -12,9 +11,9 @@ class PloneResourceEditor(PloneSandboxLayer):
     def setUpZope(self, app, configurationContext):
         # Load ZCML
         import plone.resourceeditor
-        xmlconfig.file(
+        self.loadZCML(
             'configure.zcml',
-            plone.resourceeditor,
+            package=plone.resourceeditor,
             context=configurationContext
         )
 
@@ -22,6 +21,7 @@ def setUpPloneSite(self, portal):
         # install plone.resource
         applyProfile(portal, 'plone.resource:default')
 
+
 PLONE_RESOURCE_EDITOR_FIXTURE = PloneResourceEditor()
 PLONE_RESOURCE_EDITOR_INTEGRATION_TESTING = IntegrationTesting(
     bases=(PLONE_RESOURCE_EDITOR_FIXTURE, ),
diff --git a/plone/resourceeditor/tests/__init__.py b/plone/resourceeditor/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/plone/resourceeditor/tests.py b/plone/resourceeditor/tests/test_file_manager.py
similarity index 99%
rename from plone/resourceeditor/tests.py
rename to plone/resourceeditor/tests/test_file_manager.py
index 410cc3e..f71f123 100644
--- a/plone/resourceeditor/tests.py
+++ b/plone/resourceeditor/tests/test_file_manager.py
@@ -40,7 +40,7 @@ def test_getfolder(self):
         r.makeDirectory('alpha')
         r['alpha'].writeFile('beta.txt', 'Beta')
         r['alpha'].makeDirectory('delta')
-        r['alpha']['delta'].writeFile('gamma.css', 'body {}')
+        r['alpha']['delta'].writeFile('gamma.css', 'body')
 
         view = FileManager(r, self.layer['request'])
         info = view.getFolder('/alpha')
diff --git a/plone/resourceeditor/tests/test_file_manager_action.py b/plone/resourceeditor/tests/test_file_manager_action.py
new file mode 100644
index 0000000..99fd92a
--- /dev/null
+++ b/plone/resourceeditor/tests/test_file_manager_action.py
@@ -0,0 +1,349 @@
+# -*- coding: utf-8 -*-
+from plone.resourceeditor.testing import PLONE_RESOURCE_EDITOR_INTEGRATION_TESTING  # noqa
+import json
+import unittest
+
+
+class TestResourceEditorOperations(unittest.TestCase):
+
+    layer = PLONE_RESOURCE_EDITOR_INTEGRATION_TESTING
+
+    def _make_directory(self, resourcetype='theme', resourcename='mytheme'):
+        from plone.resource.interfaces import IResourceDirectory
+        from zope.component import getUtility
+
+        resources = getUtility(IResourceDirectory, name='persistent')
+        resources.makeDirectory(resourcetype)
+        resources[resourcetype].makeDirectory(resourcename)
+
+        return resources[resourcetype][resourcename]
+
+    def test_getinfo(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+
+        r.writeFile('test.txt', 'A text file')
+        view = FileManagerActions(r, self.layer['request'])
+        info = view.getInfo(r['test.txt'])
+
+        self.assertEqual(info['fileType'], 'txt')
+        self.assertEqual(info['filename'], 'test.txt')
+        self.assertEqual(info['path'], '/')
+
+    def test_getfolder(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+
+        r.makeDirectory('alpha')
+        r['alpha'].writeFile('beta.txt', 'Beta')
+        r['alpha'].makeDirectory('delta')
+        r['alpha']['delta'].writeFile('gamma.css', 'body')
+
+        view = FileManagerActions(r, self.layer['request'])
+        info = view.getFolder('/alpha')
+
+        self.assertEqual(len(info), 2)
+        self.assertEqual(info[0]['fileType'], 'dir')
+        self.assertEqual(info[0]['filename'], 'delta')
+        self.assertEqual(info[0]['path'], '/alpha/delta/')
+
+        self.assertEqual(info[1]['fileType'], 'txt')
+        self.assertEqual(info[1]['filename'], 'beta.txt')
+        self.assertEqual(info[1]['path'], '/alpha/beta.txt')
+
+    def test_addfolder(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info_str = view.addFolder('/', 'alpha')
+        info = json.loads(info_str)
+
+        self.assertEqual(info['code'], 0)
+        self.assertEqual(info['error'], '')
+        self.assertEqual(info['parent'], '/')
+        self.assertEqual(info['name'], 'alpha')
+
+        info_str = view.addFolder('/alpha', 'beta')
+        info = json.loads(info_str)
+
+        self.assertEqual(info['code'], 0)
+        self.assertEqual(info['error'], '')
+        self.assertEqual(info['parent'], '/alpha')
+        self.assertEqual(info['name'], 'beta')
+
+    def test_addfolder_exists(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.makeDirectory('alpha')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info_str = view.addFolder('/', 'alpha')
+        info = json.loads(info_str)
+
+        self.assertEqual(info['code'], 1)
+        self.assertNotEqual(info['error'], '')
+        self.assertEqual(info['parent'], '/')
+        self.assertEqual(info['name'], 'alpha')
+
+    def test_addfolder_invalid_name(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.makeDirectory('alpha')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        for char in '\\/:*?"<>':
+            info = view.addFolder('/', 'foo' + char)
+            info = json.loads(info)
+
+            self.assertEqual(info['code'], 1)
+            self.assertNotEqual(info['error'], '')
+            self.assertEqual(info['parent'], '/')
+            self.assertEqual(info['name'], 'foo' + char)
+
+    def test_addfolder_invalid_parent(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.addFolder('/alpha', 'beta')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 1)
+        self.assertNotEqual(info['error'], '')
+        self.assertEqual(info['parent'], '/alpha')
+        self.assertEqual(info['name'], 'beta')
+
+    def test_add(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        d = 'test.txt'
+
+        info = view.addFile('/', d)
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 0)
+        self.assertEqual(info['error'], '')
+        self.assertEqual(info['name'], 'test.txt')
+        self.assertEqual(info['path'], '/')
+        self.assertEqual(info['parent'], '/')
+
+    def test_add_subfolder(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.makeDirectory('alpha')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        d = 'test.txt'
+
+        info = view.addFile('/alpha', d)
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 0)
+        self.assertEqual(info['error'], '')
+        self.assertEqual(info['name'], 'test.txt')
+        self.assertEqual(info['path'], '/alpha')
+        self.assertEqual(info['parent'], '/alpha')
+
+    def test_add_exists(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.writeFile('test.txt', 'boo')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        d = 'test.txt'
+
+        info = view.addFile('/', d)
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 1)
+        self.assertNotEqual(info['error'], '')
+
+        self.assertEqual(r.readFile('test.txt'), 'boo')
+
+    def test_addnew_invalidname(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        for char in '\\/:*?"<>':
+            info = view.addFile('/', 'foo' + char)
+            info = json.loads(info)
+            self.assertEqual(info['code'], 1)
+            self.assertNotEqual(info['error'], '')
+
+    def test_rename(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.writeFile('test.txt', 'foo')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.renameFile('/test.txt', 'foo.txt')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 0)
+        self.assertEqual(info['error'], '')
+        self.assertEqual(info['oldName'], 'test.txt')
+        self.assertEqual(info['newName'], 'foo.txt')
+        self.assertEqual(info['oldParent'], '/')
+        self.assertEqual(info['newParent'], '/')
+
+        self.assertEqual(r.readFile('foo.txt'), 'foo')
+
+    def test_rename_subfolder(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.makeDirectory('alpha')
+        r['alpha'].writeFile('test.txt', 'foo')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.renameFile('/alpha/test.txt', 'foo.txt')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 0)
+        self.assertEqual(info['error'], '')
+        self.assertEqual(info['oldName'], 'test.txt')
+        self.assertEqual(info['newName'], 'foo.txt')
+        self.assertEqual(info['oldParent'], '/alpha')
+        self.assertEqual(info['newParent'], '/alpha')
+
+        self.assertEqual(r['alpha'].readFile('foo.txt'), 'foo')
+
+    def test_rename_exists(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.writeFile('test.txt', 'foo')
+        r.writeFile('foo.txt', 'bar')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.renameFile('/test.txt', 'foo.txt')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 1)
+        self.assertNotEqual(info['error'], '')
+        self.assertEqual(info['oldName'], 'test.txt')
+        self.assertEqual(info['newName'], 'foo.txt')
+        self.assertEqual(info['oldParent'], '/')
+        self.assertEqual(info['newParent'], '/')
+
+        self.assertEqual(r.readFile('foo.txt'), 'bar')
+
+    def test_delete(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.writeFile('test.txt', 'foo')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.delete('/test.txt')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 0)
+        self.assertEqual(info['error'], '')
+        self.assertEqual(info['path'], '/test.txt')
+
+        self.assertFalse('test.txt' in r)
+
+    def test_delete_subfolder(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.makeDirectory('alpha')
+        r['alpha'].writeFile('test.txt', 'foo')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.delete('/alpha/test.txt')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 0)
+        self.assertEqual(info['error'], '')
+        self.assertEqual(info['path'], '/alpha/test.txt')
+
+        self.assertFalse('test.txt' in r['alpha'])
+
+    def test_delete_notfound(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.delete('/test.txt')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 1)
+        self.assertNotEqual(info['error'], '')
+        self.assertEqual(info['path'], '/test.txt')
+
+    def test_move(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.makeDirectory('alpha')
+        r.writeFile('test.txt', 'foo')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.move('/test.txt', '/alpha')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 0)
+        self.assertEqual(info['error'], '')
+        self.assertEqual(info['newPath'], '/alpha/test.txt')
+
+        self.assertFalse('test.txt' in r)
+        self.assertEqual('foo', r['alpha'].readFile('test.txt'))
+
+    def test_move_exists(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.makeDirectory('alpha')
+        r['alpha'].writeFile('test.txt', 'bar')
+        r.writeFile('test.txt', 'foo')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.move('/test.txt', '/alpha')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 1)
+        self.assertNotEqual(info['error'], '')
+        self.assertEqual(info['newPath'], '/alpha/test.txt')
+
+        self.assertTrue('test.txt' in r)
+        self.assertEqual('bar', r['alpha'].readFile('test.txt'))
+
+    def test_move_invalid_parent(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.writeFile('test.txt', 'foo')
+
+        view = FileManagerActions(r, self.layer['request'])
+
+        info = view.move('/test.txt', '/alpha')
+        info = json.loads(info)
+
+        self.assertEqual(info['code'], 1)
+        self.assertNotEqual(info['error'], '')
+        self.assertEqual(info['newPath'], '/alpha/test.txt')
+
+        self.assertTrue('test.txt' in r)
+
+    def test_download(self):
+        from plone.resourceeditor.browser import FileManagerActions
+        r = self._make_directory()
+        r.writeFile('test.txt', 'foo')
+
+        view = FileManagerActions(r, self.layer['request'])
+        self.assertEqual('foo', view.download('/test.txt'))



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.