[Products.Silva][Sylvain Viollon] Test paste as ghost and fix it.

[email protected] Mon, 11 Nov 2013 18:21:17 +0100
Newsgroups gmane.comp.web.zope.silva.cvs
Message-ID <[email protected]>
author:    Sylvain Viollon
date:      Mon Nov 11 18:21:13 2013 +0100
revision:  11880:3cf45cddedcb in Products.Silva
branch:    2.4
details:   https://hg.infrae.com/Products.Silva?cmd=changeset;node=3cf45cddedcb
modified:  Products/Silva/Ghost/__init__.py Products/Silva/Ghost/base.py Products/Silva/Ghost/content.py Products/Silva/GhostAsset/content.py Products/Silva/GhostFolder/content.py Products/Silva/tests/test_folder_copy.py Products/Silva/tests/test_folder_ghoster.py
added:     Products/Silva/tests/test_folder_ghoster.py
removed:   
log:       Test paste as ghost and fix it.


diffstat:

 Products/Silva/Ghost/__init__.py            |    2 +-
 Products/Silva/Ghost/base.py                |    6 +-
 Products/Silva/Ghost/content.py             |    2 +-
 Products/Silva/GhostAsset/content.py        |    2 +-
 Products/Silva/GhostFolder/content.py       |    6 +-
 Products/Silva/tests/test_folder_copy.py    |   21 ++--
 Products/Silva/tests/test_folder_ghoster.py |  107 ++++++++++++++++++++++++++++
 7 files changed, 128 insertions(+), 18 deletions(-)

diffs (238 lines):

diff -r 01355a2a8b4e -r 3cf45cddedcb Products/Silva/Ghost/__init__.py
--- a/Products/Silva/Ghost/__init__.py	Mon Nov 11 16:55:32 2013 +0100
+++ b/Products/Silva/Ghost/__init__.py	Mon Nov 11 18:21:13 2013 +0100
@@ -23,5 +23,5 @@
         return None
 
     return lambda identifier: get_manager(
-        container=container).modify(target, identifier).create()
+        container=container).modify(target, identifier).create(recursive=True)
 
diff -r 01355a2a8b4e -r 3cf45cddedcb Products/Silva/Ghost/base.py
--- a/Products/Silva/Ghost/base.py	Mon Nov 11 16:55:32 2013 +0100
+++ b/Products/Silva/Ghost/base.py	Mon Nov 11 18:21:13 2013 +0100
@@ -44,7 +44,7 @@
         for reference in self.__references:
             reference.set_target(content)
 
-    def create(self):
+    def create(self, recursive=False):
         raise NotImplementedError
 
     def update(self):
@@ -67,10 +67,10 @@
         self.create()
         self.restore_references_to(self.manager.ghost)
 
-    def verify(self):
+    def verify(self, recursive=False):
         if self.manager.ghost is None:
             if self.target is not None:
-                return self.create()
+                return self.create(recursive=recursive)
         elif self.need_update():
             return self.update()
         return self.manager.ghost
diff -r 01355a2a8b4e -r 3cf45cddedcb Products/Silva/Ghost/content.py
--- a/Products/Silva/Ghost/content.py	Mon Nov 11 16:55:32 2013 +0100
+++ b/Products/Silva/Ghost/content.py	Mon Nov 11 18:21:13 2013 +0100
@@ -99,7 +99,7 @@
 
 class GhostManipulator(GhostBaseManipulator):
 
-    def create(self):
+    def create(self, recursive=False):
         assert self.manager.ghost is None
         ghost = None
         factory = self.manager.container.manage_addProduct['Silva']
diff -r 01355a2a8b4e -r 3cf45cddedcb Products/Silva/GhostAsset/content.py
--- a/Products/Silva/GhostAsset/content.py	Mon Nov 11 16:55:32 2013 +0100
+++ b/Products/Silva/GhostAsset/content.py	Mon Nov 11 18:21:13 2013 +0100
@@ -120,7 +120,7 @@
 
 class GhostAssetManipulator(GhostBaseManipulator):
 
-    def create(self):
+    def create(self, recursive=False):
         assert self.manager.ghost is None
         factory = self.manager.container.manage_addProduct['Silva']
         factory.manage_addGhostAsset(self.identifier, None)
diff -r 01355a2a8b4e -r 3cf45cddedcb Products/Silva/GhostFolder/content.py
--- a/Products/Silva/GhostFolder/content.py	Mon Nov 11 16:55:32 2013 +0100
+++ b/Products/Silva/GhostFolder/content.py	Mon Nov 11 18:21:13 2013 +0100
@@ -38,7 +38,7 @@
         # Publish if needed ?
         return self.manager.container._getOb(self.identifier)
 
-    def create(self):
+    def create(self, recursive=False):
         assert self.manager.ghost is None
         ghost = self.make_copy()
         self.manager.ghost = ghost
@@ -213,12 +213,14 @@
 
 class GhostFolderManipulator(GhostBaseManipulator):
 
-    def create(self):
+    def create(self, recursive=False):
         assert self.manager.ghost is None
         factory = self.manager.container.manage_addProduct['Silva']
         factory.manage_addGhostFolder(self.identifier, None)
         ghost = self.manager.container._getOb(self.identifier)
         ghost.set_haunted(self.target, auto_delete=self.manager.auto_delete)
+        if recursive:
+            ghost.haunt()
         self.manager.ghost = ghost
         return ghost
 
diff -r 01355a2a8b4e -r 3cf45cddedcb Products/Silva/tests/test_folder_copy.py
--- a/Products/Silva/tests/test_folder_copy.py	Mon Nov 11 16:55:32 2013 +0100
+++ b/Products/Silva/tests/test_folder_copy.py	Mon Nov 11 18:21:13 2013 +0100
@@ -9,7 +9,7 @@
 from silva.core.interfaces import IAutoTOC, ILink, IFolder
 from zope.interface.verify import verifyObject
 
-from Products.Silva.testing import FunctionalLayer
+from Products.Silva.testing import FunctionalLayer, Transaction
 from Products.Silva.testing import assertTriggersEvents, assertNotTriggersEvents
 
 
@@ -23,17 +23,18 @@
         self.root = self.layer.get_application()
         self.layer.login('editor')
 
-        factory = self.root.manage_addProduct['Silva']
-        factory.manage_addFolder('source', 'Source Folder')
-        factory.manage_addFolder('target', 'Target Folder')
+        with Transaction():
+            factory = self.root.manage_addProduct['Silva']
+            factory.manage_addFolder('source', 'Source Folder')
+            factory.manage_addFolder('target', 'Target Folder')
 
-        factory = self.root.source.manage_addProduct['Silva']
-        factory.manage_addAutoTOC('toc', 'AutoTOC')
-        factory.manage_addLink('link', 'Link')
-        factory.manage_addLink('published_link', 'Published Link')
-        factory.manage_addFolder('folder', 'Folder')
+            factory = self.root.source.manage_addProduct['Silva']
+            factory.manage_addAutoTOC('toc', 'AutoTOC')
+            factory.manage_addLink('link', 'Link')
+            factory.manage_addLink('published_link', 'Published Link')
+            factory.manage_addFolder('folder', 'Folder')
 
-        IPublicationWorkflow(self.root.source.published_link).publish()
+            IPublicationWorkflow(self.root.source.published_link).publish()
 
         self.layer.login(self.user)
 
diff -r 01355a2a8b4e -r 3cf45cddedcb Products/Silva/tests/test_folder_ghoster.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Products/Silva/tests/test_folder_ghoster.py	Mon Nov 11 18:21:13 2013 +0100
@@ -0,0 +1,107 @@
+
+import unittest
+
+from silva.core.interfaces import IContainerManager, IPublicationWorkflow
+from silva.core.interfaces import IGhost, IGhostVersion, IGhostAsset, IGhostFolder
+from zope.interface.verify import verifyObject
+
+from Products.Silva.testing import assertTriggersEvents
+from Products.Silva.testing import FunctionalLayer, Transaction
+
+
+class EditorFolderGhosterTestCase(unittest.TestCase):
+    """Test API to paste as a ghost inside a folder.
+    """
+    layer = FunctionalLayer
+
+    def setUp(self):
+        self.root = self.layer.get_application()
+        self.layer.login('editor')
+        with Transaction():
+            factory = self.root.manage_addProduct['Silva']
+            factory.manage_addFolder('source', 'Source Folder')
+            factory.manage_addFolder('target', 'Target Folder')
+            factory = self.root.source.manage_addProduct['Silva']
+            factory.manage_addAutoTOC('toc', 'AutoTOC')
+            factory.manage_addMockupVersionedContent('data', 'Data')
+            factory.manage_addFolder('folder', 'Folder')
+            with self.layer.open_fixture('silva.png') as stream:
+                factory.manage_addFile('logo', 'Silva Logo', stream)
+
+            IPublicationWorkflow(self.root.source.data).publish()
+
+    def test_asset(self):
+        """Pasting an asset as a ghost asset.
+        """
+        manager = IContainerManager(self.root.target)
+        with assertTriggersEvents('ObjectWillBeAddedEvent',
+                                  'ObjectAddedEvent',
+                                  'ContainerModifiedEvent'):
+            with manager.ghoster() as ghoster:
+                ghost = ghoster(self.root.source.logo)
+
+        self.assertTrue(verifyObject(IGhostAsset, ghost))
+        self.assertIn('logo', self.root.target.objectIds())
+        self.assertEqual(ghost.get_link_status(), None)
+        self.assertEqual(ghost.get_haunted(), self.root.source.logo)
+
+    def test_content(self):
+        """When pasting a content as a regular ghost, it doesn't get
+        published.
+        """
+        manager = IContainerManager(self.root.target)
+        with assertTriggersEvents('ObjectWillBeAddedEvent',
+                                  'ObjectAddedEvent',
+                                  'ContainerModifiedEvent'):
+            with manager.ghoster() as ghoster:
+                ghost = ghoster(self.root.source.data)
+
+        self.assertTrue(verifyObject(IGhost, ghost))
+        self.assertIn('data', self.root.target.objectIds())
+        self.assertEqual(ghost.get_haunted(), self.root.source.data)
+        self.assertEqual(ghost.is_published(), False)
+        self.assertEqual(ghost.get_viewable(), None)
+
+        version = ghost.get_editable()
+        self.assertTrue(verifyObject(IGhostVersion, version))
+        self.assertEqual(version.get_link_status(), None)
+        self.assertEqual(version.get_haunted(), self.root.source.data)
+
+    def test_folder(self):
+        """When pasting a folder as a ghost, its content is ghosted
+        and any versioned content (ghost) in it are published.
+        """
+        manager = IContainerManager(self.root.target)
+        with assertTriggersEvents('ObjectWillBeAddedEvent',
+                                  'ObjectAddedEvent',
+                                  'ContainerModifiedEvent'):
+            with manager.ghoster() as ghoster:
+                ghost = ghoster(self.root.source)
+
+        self.assertTrue(verifyObject(IGhostFolder, ghost))
+        self.assertEqual(ghost.get_link_status(), None)
+        self.assertEqual(ghost.get_haunted(), self.root.source)
+        self.assertIn('source', self.root.target.objectIds())
+
+        # The ghost folder is created inside the target folder and is
+        # already haunting the source.
+        ghost = self.root.target.source
+        self.assertTrue(verifyObject(IGhostFolder, ghost))
+        self.assertEqual(ghost.get_link_status(), None)
+        self.assertEqual(ghost.get_haunted(), self.root.source)
+        self.assertItemsEqual(
+            ghost.objectIds(),
+            ['toc', 'data', 'folder', 'logo'])
+        self.assertTrue(verifyObject(IGhost, ghost.toc))
+        self.assertEqual(ghost.toc.get_haunted(), self.root.source.toc)
+        self.assertTrue(verifyObject(IGhost, ghost.data))
+        self.assertEqual(ghost.data.get_haunted(), self.root.source.data)
+        self.assertEqual(ghost.data.is_published(), True)
+        self.assertTrue(verifyObject(IGhostFolder, ghost.folder))
+        self.assertEqual(ghost.folder.get_haunted(), self.root.source.folder)
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(EditorFolderGhosterTestCase))
+    return suite