[Testbot] Plone 5.0 - Python 2.7 - Build # 2481 - Fixed! - 0 failure(s)

jenkins at plone.org jenkins at plone.org
Tue May 13 05:56:08 UTC 2014


-------------------------------------------------------------------------------
Plone 5.0 - Python 2.7 - Build # 2481 - Fixed!
-------------------------------------------------------------------------------

http://jenkins.plone.org/job/plone-5.0-python-2.7/2481/


-------------------------------------------------------------------------------
CHANGES
-------------------------------------------------------------------------------

Repository: plone.app.discussion
Branch: refs/heads/master
Date: 2014-05-13T07:07:37+02:00
Author: Timo Stollenwerk () <contact at timostollenwerk.net>
Commit: https://github.com/plone/plone.app.discussion/commit/2b18d5a2e4e65ceddd551697b1ae73713e0ffab4

Revert "Merge pull request #38 from delib/evilbungle-comment-acquisition"

This reverts commit e18598e316e824795e752e7bb1c90ee37dc1cc6f, reversing
changes made to fd6ac0788bf3ade982e60ede7ceda26b0c0e598e.

This pull request introduces two test failures. See http://jenkins.plone.org/job/plone-5.0-python-2.7/lastCompletedBuild/testReport/ for details.

Files changed:
M plone/app/discussion/conversation.py
M plone/app/discussion/testing.py
D plone/app/discussion/tests/configure.zcml
D plone/app/discussion/tests/profile/types.xml
D plone/app/discussion/tests/profile/types/sample_content_type.xml
D plone/app/discussion/tests/profile/workflows.xml
D plone/app/discussion/tests/profile/workflows/comment_workflow_acquired_view/definition.xml
D plone/app/discussion/tests/test_acquisition.py

diff --git a/plone/app/discussion/conversation.py b/plone/app/discussion/conversation.py
index ca22c05..ba27c0f 100644
--- a/plone/app/discussion/conversation.py
+++ b/plone/app/discussion/conversation.py
@@ -50,14 +50,8 @@
 
 from AccessControl.SpecialUsers import nobody as user_nobody
 
-from ComputedAttribute import ComputedAttribute
-
 ANNOTATION_KEY = 'plone.app.discussion:conversation'
 
-def computed_attribute_decorator(level=0):
-    def computed_attribute_wrapper(func):
-        return ComputedAttribute(func, level)
-    return computed_attribute_wrapper
 
 class Conversation(Traversable, Persistent, Explicit):
     """A conversation is a container for all comments on a content object.
@@ -93,21 +87,21 @@ def enabled(self):
         parent = aq_inner(self.__parent__)
         return parent.restrictedTraverse('@@conversation_view').enabled()
 
-    @computed_attribute_decorator(level=1)
+    @property
     def total_comments(self):
         public_comments = [
-            x for x in self.values()
+            x for x in self._comments.values()
             if user_nobody.has_permission('View', x)
         ]
         return len(public_comments)
 
-    @computed_attribute_decorator(level=1)
+    @property
     def last_comment_date(self):
         # self._comments is an Instance of a btree. The keys
         # are always ordered
         comment_keys = self._comments.keys()
         for comment_key in reversed(comment_keys):
-            comment = self[comment_key]
+            comment = self._comments[comment_key]
             if user_nobody.has_permission('View', comment):
                 return comment.creation_date
         return None
@@ -116,10 +110,10 @@ def last_comment_date(self):
     def commentators(self):
         return self._commentators
 
-    @computed_attribute_decorator(level=1)
+    @property
     def public_commentators(self):
         retval = set()
-        for comment in self.values():
+        for comment in self._comments.values():
             if not user_nobody.has_permission('View', comment):
                 continue
             retval.add(comment.author_username)
diff --git a/plone/app/discussion/testing.py b/plone/app/discussion/testing.py
index e47026f..e7a397d 100644
--- a/plone/app/discussion/testing.py
+++ b/plone/app/discussion/testing.py
@@ -41,14 +41,10 @@ def setUpZope(self, app, configurationContext):
         xmlconfig.file('configure.zcml',
                        plone.app.discussion,
                        context=configurationContext)
-        xmlconfig.file('configure.zcml',
-                       plone.app.discussion.tests,
-                       context=configurationContext)
 
     def setUpPloneSite(self, portal):
         # Install into Plone site using portal_setup
         applyProfile(portal, 'plone.app.discussion:default')
-        applyProfile(portal, 'plone.app.discussion.tests:testing')
 
         # Creates some users
         acl_users = getToolByName(portal, 'acl_users')
diff --git a/plone/app/discussion/tests/configure.zcml b/plone/app/discussion/tests/configure.zcml
deleted file mode 100644
index ee79b95..0000000
--- a/plone/app/discussion/tests/configure.zcml
+++ /dev/null
@@ -1,16 +0,0 @@
-<configure
-  xmlns="http://namespaces.zope.org/zope"
-  xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
-  i18n_domain="freitag.discussion">
-
-  <include package="plone.app.dexterity" />
-
-  <genericsetup:registerProfile
-    name="testing"
-    title="plone.app.discussion.testing"
-    directory="profile"
-    description="Testing profile for plone.app.discussion"
-    provides="Products.GenericSetup.interfaces.EXTENSION"
-    />
-
-</configure>
diff --git a/plone/app/discussion/tests/profile/types.xml b/plone/app/discussion/tests/profile/types.xml
deleted file mode 100644
index 0aec569..0000000
--- a/plone/app/discussion/tests/profile/types.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0"?>
-<object name="portal_types" meta_type="Plone Types Tool">
-  <object name="sample_content_type" meta_type="Dexterity FTI" />
-</object>
diff --git a/plone/app/discussion/tests/profile/types/sample_content_type.xml b/plone/app/discussion/tests/profile/types/sample_content_type.xml
deleted file mode 100644
index 7869638..0000000
--- a/plone/app/discussion/tests/profile/types/sample_content_type.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0"?>
-<object name="sample_content_type"
-   meta_type="Dexterity FTI"
-   i18n:domain="freitag.discussion" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
-
-  <!-- Basic metadata -->
-  <property name="title" i18n:translate="">sample_content_type</property>
-  <property name="description"
-    i18n:translate="">Sample Content</property>
-  <property name="content_icon">document_icon.png</property>
-  <property name="global_allow">True</property>
-  <property name="filter_content_types">True</property>
-  <property name="allowed_content_types">
-  </property>
-  <property name="allow_discussion">True</property>
-
-  <property name="klass">plone.dexterity.content.Item</property>
-
-  <property name="add_permission">cmf.AddPortalContent</property>
-  <property name="behaviors">
-    <element value="plone.app.content.interfaces.INameFromTitle" />
-  </property>
-
-  <!-- View information -->
-  <property name="default_view">view</property>
-  <property name="default_view_fallback">False</property>
-  <property name="view_methods">
-    <element value="view" />
-  </property>
-
-  <!-- Method aliases -->
-  <alias from="(Default)" to="(selected layout)" />
-  <alias from="edit" to="@@edit" />
-  <alias from="sharing" to="@@sharing" />
-  <alias from="view" to="@@view" />
-
-  <!-- Actions -->
-  <action title="View" action_id="view" category="object" condition_expr=""
-    url_expr="string:${object_url}/" visible="True">
-    <permission value="View" />
-  </action>
-
-  <action title="Edit" action_id="edit" category="object" condition_expr=""
-    url_expr="string:${object_url}/edit" visible="True">
-    <permission value="Modify portal content" />
-  </action>
-</object>
diff --git a/plone/app/discussion/tests/profile/workflows.xml b/plone/app/discussion/tests/profile/workflows.xml
deleted file mode 100644
index 500f444..0000000
--- a/plone/app/discussion/tests/profile/workflows.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0"?>
-<object name="portal_workflow" meta_type="CMF Workflow Tool">
- <object name="comment_workflow_acquired_view" meta_type="Workflow"/>
-</object>
diff --git a/plone/app/discussion/tests/profile/workflows/comment_workflow_acquired_view/definition.xml b/plone/app/discussion/tests/profile/workflows/comment_workflow_acquired_view/definition.xml
deleted file mode 100644
index 89a9fb2..0000000
--- a/plone/app/discussion/tests/profile/workflows/comment_workflow_acquired_view/definition.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0"?>
-<dc-workflow
-    workflow_id="comment_workflow_acquired_view"
-    title="Single State Workflow"
-    description="- Essentially a workflow with no transitions, but has a Published state, so portlets and applications that expect that state will continue to work."
-    state_variable="review_state"
-    initial_state="published"
-    manager_bypass="False">
- <permission>Access contents information</permission>
- <permission>Change portal events</permission>
- <permission>Modify portal content</permission>
- <permission>View</permission>
- <state state_id="published" title="Published">
-  <description>Visible to everyone, editable by the owner.</description>
-  <permission-map name="Access contents information" acquired="False">
-   <permission-role>Anonymous</permission-role>
-  </permission-map>
-  <permission-map name="Change portal events" acquired="False">
-   <permission-role>Editor</permission-role>
-   <permission-role>Manager</permission-role>
-   <permission-role>Owner</permission-role>
-   <permission-role>Site Administrator</permission-role>
-  </permission-map>
-  <permission-map name="Modify portal content" acquired="False">
-   <permission-role>Editor</permission-role>
-   <permission-role>Manager</permission-role>
-   <permission-role>Owner</permission-role>
-   <permission-role>Site Administrator</permission-role>
-  </permission-map>
-  <permission-map name="View" acquired="True">
-  </permission-map>
- </state>
- <variable variable_id="action" for_catalog="False" for_status="True" update_always="True">
-  <description>Previous transition</description>
-  <default>
-   <expression>transition/getId|nothing</expression>
-  </default>
-  <guard>
-  </guard>
- </variable>
- <variable variable_id="actor" for_catalog="False" for_status="True" update_always="True">
-  <description>The ID of the user who performed the previous transition</description>
-  <default>
-   <expression>user/getId</expression>
-  </default>
-  <guard>
-  </guard>
- </variable>
- <variable variable_id="comments" for_catalog="False" for_status="True" update_always="True">
-  <description>Comment about the last transition</description>
-  <default>
-   <expression>python:state_change.kwargs.get('comment', '')</expression>
-  </default>
-  <guard>
-  </guard>
- </variable>
- <variable variable_id="review_history" for_catalog="False" for_status="False" update_always="False">
-  <description>Provides access to workflow history</description>
-  <default>
-   <expression>state_change/getHistory</expression>
-  </default>
-  <guard>
-   <guard-permission>Request review</guard-permission>
-   <guard-permission>Review portal content</guard-permission>
-  </guard>
- </variable>
- <variable variable_id="time" for_catalog="False" for_status="True" update_always="True">
-  <description>When the previous transition was performed</description>
-  <default>
-   <expression>state_change/getDateTime</expression>
-  </default>
-  <guard>
-  </guard>
- </variable>
-</dc-workflow>
diff --git a/plone/app/discussion/tests/test_acquisition.py b/plone/app/discussion/tests/test_acquisition.py
deleted file mode 100644
index c6a96db..0000000
--- a/plone/app/discussion/tests/test_acquisition.py
+++ /dev/null
@@ -1,243 +0,0 @@
-# -*- coding: utf-8 -*-
-from AccessControl.User import User  # before SpecialUsers
-from AccessControl.SpecialUsers import nobody as user_nobody
-from AccessControl.PermissionRole import rolesForPermissionOn
-from Acquisition import aq_chain, aq_base
-from plone.app.discussion.testing import \
-    PLONE_APP_DISCUSSION_INTEGRATION_TESTING
-from plone.app.discussion.interfaces import IConversation
-from plone.app.testing import TEST_USER_ID, setRoles
-from Products.CMFCore.utils import getToolByName
-from zope.component import createObject
-
-import unittest2 as unittest
-
-
-dexterity_type_name = 'sample_content_type'
-dexterity_object_id = 'instance-of-dexterity-type'
-archetypes_object_id = 'instance-of-archetypes-type'
-one_state_workflow = 'one_state_workflow'
-comment_workflow_acquired_view = 'comment_workflow_acquired_view'
-
-class AcquisitionTest(unittest.TestCase):
-    """ Define the expected behaviour of wrapped and unwrapped comments. """
-
-    layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
-
-    def setUp(self):
-        self.portal = self.layer['portal']
-        self.request = self.layer['request']
-        setRoles(self.portal, TEST_USER_ID, ['Manager'])
-        self.wftool = getToolByName(self.portal, 'portal_workflow')
-
-        # Use customized workflow for comments.
-        self.wftool.setChainForPortalTypes(
-            ['Discussion Item'],
-            (comment_workflow_acquired_view,),
-        )
-
-        # Use one_state_workflow for Document and sample_content_type,
-        # so they're always published.
-        self.wftool.setChainForPortalTypes(
-            ['Document', dexterity_type_name],
-            (one_state_workflow,),
-        )
-
-        # Create a dexterity item and add a comment.
-        self.portal.invokeFactory(
-            id=dexterity_object_id,
-            title='Instance Of Dexterity Type',
-            type_name=dexterity_type_name,
-        )
-        
-        self.dexterity_object = self.portal.get(dexterity_object_id)
-        dx_conversation = IConversation(self.dexterity_object)
-        self.dexterity_conversation = dx_conversation
-        dx_comment = createObject('plone.Comment')
-        dx_conversation.addComment(dx_comment)
-        self.unwrapped_dexterity_comment = dx_comment
-        self.wrapped_dexterity_comment = dx_conversation[dx_comment.id]
-
-        # Create an Archetypes item and add a comment.
-        self.portal.invokeFactory(
-            id=archetypes_object_id,
-            title='Instance Of Archetypes Type',
-            type_name='Document',
-        )
-        
-        self.archetypes_object = self.portal.get(archetypes_object_id)
-        at_conversation = IConversation(self.archetypes_object)
-        self.archetypes_conversation = at_conversation
-        at_comment = createObject('plone.Comment')
-        at_conversation.addComment(at_comment)
-        self.unwrapped_archetypes_comment = at_comment
-        self.wrapped_archetypes_comment = at_conversation[at_comment.id]
-        
-
-    def test_workflows_installed(self):
-        """Check that the new comment workflow has been installed properly.
-        (Just a test to check our test setup.)
-        """
-        workflows = self.wftool.objectIds()
-        self.assertTrue('comment_workflow_acquired_view' in workflows)
-
-    def test_workflows_applied(self):
-        """Check that all objects have the workflow that we expect.
-        (Just a test to check our test setup.)"""
-        self.assertEqual(
-            self.wftool.getChainFor(self.archetypes_object),
-            (one_state_workflow,)
-        )
-        self.assertEqual(
-            self.wftool.getChainFor(self.dexterity_object),
-            (one_state_workflow,)
-        )
-        self.assertEqual(
-            self.wftool.getChainFor(self.unwrapped_archetypes_comment),
-            (comment_workflow_acquired_view,)
-        )
-        self.assertEqual(
-            self.wftool.getChainFor(self.unwrapped_dexterity_comment),
-            (comment_workflow_acquired_view,)
-        )
-
-    def test_comment_acquisition_chain(self):
-        """ Test that the acquisition chains for wrapped and unwrapped
-            comments are as expected. """
-        
-        # Unwrapped comments rely on __parent__ attributes to determine 
-        # parentage.  Frustratingly there is no guarantee that __parent__
-        # is always set, so the computed acquisition chain may be short.
-        # In this case the unwrapped AT and DX objects stored as the 
-        # conversation parents don't have a __parent__, preventing the portal
-        # from being included in the chain.
-        self.assertNotIn(self.portal,
-                         aq_chain(self.unwrapped_archetypes_comment))
-        self.assertNotIn(self.portal,
-                         aq_chain(self.unwrapped_dexterity_comment))
-
-        # Wrapped comments however have a complete chain and thus can find the
-        # portal object reliably.
-        self.assertIn(self.portal,aq_chain(self.wrapped_archetypes_comment))
-        self.assertIn(self.portal,aq_chain(self.wrapped_dexterity_comment))
-
-    
-    def test_acquiring_comment_permissions(self):
-        """ Unwrapped comments should not be able to acquire permissions
-            controlled by unreachable objects """
-        
-        # We use the "Allow sendto" permission as by default it is
-        # controlled by the portal, which is unreachable via __parent__
-        # attributes on the comments.
-        permission = "Allow sendto"
-
-        # Unwrapped comments can't find the portal so just return manager
-        self.assertNotIn("Anonymous",
-             rolesForPermissionOn(permission,
-                                  self.unwrapped_archetypes_comment))
-        self.assertNotIn("Anonymous",
-             rolesForPermissionOn(permission,
-                                  self.unwrapped_dexterity_comment))
-        
-        # Wrapped objects can find the portal and correctly return the
-        # anonymous role.
-        self.assertIn("Anonymous",
-             rolesForPermissionOn(permission,
-                                  self.wrapped_archetypes_comment))
-        self.assertIn("Anonymous",
-             rolesForPermissionOn(permission,
-                                  self.wrapped_dexterity_comment))
-    
-    def test_acquiring_comment_permissions_via_user_nobody(self):
-        """ The current implementation uses user_nobody.has_permission to
-            check whether anonymous can view comments.  This confirms it also
-            works. """        
-        
-        # Again we want to use a permission that's not managed by any of our
-        # content objects so it must be acquired from the portal.
-        permission = "Allow sendto"
-    
-        self.assertFalse(
-             user_nobody.has_permission(permission,
-                                        self.unwrapped_archetypes_comment))
-        
-        self.assertFalse(
-             user_nobody.has_permission(permission,
-                                        self.unwrapped_dexterity_comment))
-
-        self.assertTrue(
-             user_nobody.has_permission(permission,
-                                        self.wrapped_archetypes_comment))
-
-        self.assertTrue(
-             user_nobody.has_permission(permission,
-                                        self.wrapped_dexterity_comment))
-
-class AcquiredPermissionTest(unittest.TestCase):
-    """ Test methods of a conversation which rely on acquired permissions """
-
-    layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
-
-    def setUp(self):
-        self.portal = self.layer['portal']
-        self.request = self.layer['request']
-        setRoles(self.portal, TEST_USER_ID, ['Manager'])
-        self.wftool = getToolByName(self.portal, 'portal_workflow')
-
-        # Disable workflow for comments and content.
-        self.wftool.setChainForPortalTypes(["Discussion Item"],[])
-        self.wftool.setChainForPortalTypes([dexterity_type_name],[])
-
-        # Create a dexterity item.
-        self.portal.invokeFactory(
-            id=dexterity_object_id,
-            title='Instance Of Dexterity Type',
-            type_name=dexterity_type_name,
-        )
-        
-        self.content = self.portal.get(dexterity_object_id)
-
-        # Absolutely make sure that we're replicating the case of an 
-        # incomplete chain correctly.
-        aq_base(self.content).__parent__ = None
-        
-        self.conversation = IConversation(self.content)
-        
-        # Add a comment
-        comment = createObject('plone.Comment')
-        self.conversation.addComment(comment)
-        self.comment = comment
-    
-    def test_view_permission_is_only_available_on_portal(self):
-        """ Check that the test setup is correct """
-        
-        content_roles = rolesForPermissionOn("View",aq_base(self.content))
-        self.assertNotIn("Anonymous",content_roles)
-        
-        comment_roles = rolesForPermissionOn("View",aq_base(self.comment))
-        self.assertNotIn("Anonymous",comment_roles)
-        
-        # This actually acquires view from the app root, but we don't really
-        # care, we just need to confirm that something above our content
-        # object will give us View.
-        portal_roles = rolesForPermissionOn("View",self.portal)
-        self.assertIn("Anonymous",portal_roles)
-
-    # The following tests fail when the conversation uses unwrapped comment
-    # objects to determine whether an anonymous user has the view permission.
-        
-    def test_total_comments(self):
-        self.assertEqual(self.conversation.total_comments,1)
-    
-    def test_last_comment_date(self):
-        self.assertEqual(self.conversation.last_comment_date,
-                         self.comment.creation_date)
-    
-    def test_public_commentators(self):
-        self.assertEqual(self.conversation.public_commentators,
-                         (self.comment.author_username,))
-
-
-
-def test_suite():
-    return unittest.defaultTestLoader.loadTestsFromName(__name__)




-------------------------------------------------------------------------------


More information about the Testbot mailing list