From: Rafael O. <svn...@pl...> - 2011-08-01 20:51:19
|
Author: rafaelbco Date: Mon Aug 1 20:49:57 2011 New Revision: 243034 Added: collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/skins/collective_cmfeditionsdexteritycompat/get_macros_wrapper.py Modified: collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/skins/collective_cmfeditionsdexteritycompat/versions_history_form.pt collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/testing.py collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/tests/test_functional.py Log: Corrected bug: Unauthorized error when content type has custom view set up with Grok. Added: collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/skins/collective_cmfeditionsdexteritycompat/get_macros_wrapper.py ============================================================================== --- (empty file) +++ collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/skins/collective_cmfeditionsdexteritycompat/get_macros_wrapper.py Mon Aug 1 20:49:57 2011 @@ -0,0 +1,17 @@ +## Script (Python) "get_macros_wrapper" +##bind container=container +##bind context=context +##bind namespace= +##bind script=script +##bind subpath=traverse_subpath +##title= +##parameters=vdata + +from ZODB.POSException import ConflictError + +try: + return context.get_macros(vdata) +except ConflictError: + raise +except: + return None Modified: collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/skins/collective_cmfeditionsdexteritycompat/versions_history_form.pt ============================================================================== --- collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/skins/collective_cmfeditionsdexteritycompat/versions_history_form.pt (original) +++ collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/skins/collective_cmfeditionsdexteritycompat/versions_history_form.pt Mon Aug 1 20:49:57 2011 @@ -201,7 +201,7 @@ <div style="border:solid 1px gray" tal:condition="version_id"> <tal:block define="vdata python:pr.retrieve(context, version_id); - version_view_macro python: context.get_macros(vdata); + version_view_macro python: context.get_macros_wrapper(vdata); context nocall:vdata/object; portal_type python:context.getPortalTypeName().lower().replace(' ', '_'); object_title context/Title; Modified: collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/testing.py ============================================================================== --- collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/testing.py (original) +++ collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/testing.py Mon Aug 1 20:49:57 2011 @@ -17,9 +17,10 @@ import collective.cmfeditionsdexteritycompat import plone.app.dexterity import plone.app.versioningbehavior - self.loadZCML(package=collective.cmfeditionsdexteritycompat) + self.loadZCML(package=collective.cmfeditionsdexteritycompat) self.loadZCML(package=plone.app.dexterity) self.loadZCML(package=plone.app.versioningbehavior) + def setUpPloneSite(self, portal): self.applyProfile(portal, '%s:default' % PACKAGE_NAME) Modified: collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/tests/test_functional.py ============================================================================== --- collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/tests/test_functional.py (original) +++ collective.cmfeditionsdexteritycompat/trunk/collective/cmfeditionsdexteritycompat/tests/test_functional.py Mon Aug 1 20:49:57 2011 @@ -1,13 +1,43 @@ #coding=utf8 from Products.CMFCore.utils import getToolByName +from Products.Five.browser import BrowserView, BrowserView +from collective.cmfeditionsdexteritycompat.testing import FUNCTIONAL_TESTING, TEST_CONTENT_TYPE_ID +from mechanize import LinkNotFoundError from plone.app.testing import setRoles from plone.app.testing.interfaces import (TEST_USER_ID, TEST_USER_PASSWORD, TEST_USER_ROLES, TEST_USER_NAME) from plone.testing.z2 import Browser -from collective.cmfeditionsdexteritycompat.testing import FUNCTIONAL_TESTING, TEST_CONTENT_TYPE_ID +from zExceptions import Unauthorized +from zope.configuration import xmlconfig import transaction import unittest2 as unittest -from mechanize import LinkNotFoundError + +class CustomView(BrowserView): + """ + A custom view. It raises an `Unauthorized` when one tries to access the `macros` attrbiute, + simulating what occurs with Grok based views. + """ + + def __call__(self): + return '<div id="content-core">Custom view</div>' + + def __getattr__(self, name): + if name == 'macros': + raise Unauthorized + + raise AttributeError + +VIEW_ZCML = """<configure + xmlns="http://namespaces.zope.org/zope" + xmlns:browser="http://namespaces.zope.org/browser"> + + <browser:page + for="*" + name="custom-view" + permission="zope2.Public" + class="collective.cmfeditionsdexteritycompat.tests.test_functional.CustomView" + /> +</configure>""" class FunctionalTestCase(unittest.TestCase): @@ -27,6 +57,7 @@ text=u'Object 1 some footext.', ) self.obj1 = self.portal['obj1'] + self.test_content_type_fti = self.layer['test_content_type_fti'] def _dump_to_file(self): f = open('/tmp/a.html', 'w') @@ -83,23 +114,6 @@ self._assert_versions_history_form(0, self.obj1.getId(), old_title, old_text) self._assert_versions_history_form(1, self.obj1.getId(), new_title, new_text) - - def _assert_versions_history_form(self, version_id, obj_id, title, text): - self.browser.open( - '%s/%s/versions_history_form?version_id=%s' % (self.portal_url, obj_id, version_id) - ) - self.assertTrue('Working Copy' in self.browser.contents) - self.assertTrue( - ('/%s/versions_history_form?version_id=%s' % (obj_id, version_id)) in self.browser.contents - ) - self.assertTrue('Working Copy' in self.browser.contents) - self.assertTrue('Revert to this revision' in self.browser.contents) - self.assertTrue(('/%s/version_diff?version_id1' % obj_id) in self.browser.contents) - self.assertTrue(('Preview of Revision %s' % version_id) in self.browser.contents) - self.assertTrue( - ('<h1 class="documentFirstHeading">%s</h1>' % str(title)) in self.browser.contents - ) - self.assertTrue(str(text) in self.browser.contents) def test_versions_history_form_should_work_with_archetypes_content(self): old_text = self.obj1.text @@ -126,4 +140,37 @@ self._assert_versions_history_form(0, page.getId(), old_title, old_text) self._assert_versions_history_form(1, page.getId(), new_title, new_text) + + def test_versions_history_form_should_work_with_dexterity_content_with_custom_view(self): + """ + This test reproduce the following situation: a Dexterity content type has a custom default + view set up using Grok. This set up makes the `get_macros` skin script raise an + `Unauthorized` error. + + To solve this we created a `get_macros_wrapper` script to handle the `Unauthorized`. This + test reproduce this situation to prevent regressions. + """ + xmlconfig.string(s=VIEW_ZCML, context=self.layer['configurationContext']) + old_default_view = self.test_content_type_fti.default_view + self.test_content_type_fti.default_view = '@@custom-view' + self.test_versions_history_form_should_work_with_dexterity_content() + + self.test_content_type_fti.default_view = old_default_view + + def _assert_versions_history_form(self, version_id, obj_id, title, text): + self.browser.open( + '%s/%s/versions_history_form?version_id=%s' % (self.portal_url, obj_id, version_id) + ) + self.assertTrue('Working Copy' in self.browser.contents) + self.assertTrue( + ('/%s/versions_history_form?version_id=%s' % (obj_id, version_id)) in self.browser.contents + ) + self.assertTrue('Working Copy' in self.browser.contents) + self.assertTrue('Revert to this revision' in self.browser.contents) + self.assertTrue(('/%s/version_diff?version_id1' % obj_id) in self.browser.contents) + self.assertTrue(('Preview of Revision %s' % version_id) in self.browser.contents) + self.assertTrue( + ('<h1 class="documentFirstHeading">%s</h1>' % str(title)) in self.browser.contents + ) + self.assertTrue(str(text) in self.browser.contents) \ No newline at end of file |