[Checkins] SVN: CMF/branches/2.0/C Merge from 1.6 branch:

Philipp von Weitershausen philikon at philikon.de
Thu Dec 7 18:45:11 EST 2006


Log message for revision 71505:
  Merge from 1.6 branch:
   Log message for revision 71493:
    CMFCore.DynamicType: Fixed behaviour regarding default view.
    DynamicType was making it impossible to use a Zope3-style
    default view for CMF content types.
    (http://www.zope.org/Collectors/CMF/459)
  

Changed:
  U   CMF/branches/2.0/CHANGES.txt
  U   CMF/branches/2.0/CMFCore/DynamicType.py
  U   CMF/branches/2.0/CMFCore/tests/test_DynamicType.py

-=-
Modified: CMF/branches/2.0/CHANGES.txt
===================================================================
--- CMF/branches/2.0/CHANGES.txt	2006-12-07 22:15:59 UTC (rev 71504)
+++ CMF/branches/2.0/CHANGES.txt	2006-12-07 23:45:11 UTC (rev 71505)
@@ -35,7 +35,12 @@
     - standard_error_message.pt was out of sync with Zope.
       (http://www.zope.org/Collectors/Zope/2133)
 
+    - CMFCore.DynamicType: Fixed behaviour regarding default view.
+      DynamicType was making it impossible to use a Zope3-style
+      default view for CMF content types.
+      (http://www.zope.org/Collectors/CMF/459)
 
+
 CMF 2.0.0 (2006/04/16)
 
   New Features

Modified: CMF/branches/2.0/CMFCore/DynamicType.py
===================================================================
--- CMF/branches/2.0/CMFCore/DynamicType.py	2006-12-07 22:15:59 UTC (rev 71504)
+++ CMF/branches/2.0/CMFCore/DynamicType.py	2006-12-07 23:45:11 UTC (rev 71505)
@@ -25,6 +25,8 @@
 from interfaces.Dynamic import DynamicType as z2IDynamicType
 from utils import getToolByName
 
+from zope.component import queryMultiAdapter
+from zope.app.publisher.browser import queryDefaultViewName
 
 class DynamicType:
 
@@ -121,6 +123,18 @@
 
         stack = REQUEST['TraversalRequestNameStack']
         key = stack and stack[-1] or '(Default)'
+
+        # if there's a Zope3-style default view name set and the
+        # corresponding view exists, take that in favour of the FTI's
+        # default view
+        if key == '(Default)':
+            viewname = queryDefaultViewName(self, REQUEST)
+            if (viewname and
+                queryMultiAdapter((self, REQUEST), name=viewname) is not None):
+                stack.append(viewname)
+                REQUEST._hacked_path = 1
+                return
+
         ti = self.getTypeInfo()
         method_id = ti and ti.queryMethodID(key, context=self)
         if method_id:

Modified: CMF/branches/2.0/CMFCore/tests/test_DynamicType.py
===================================================================
--- CMF/branches/2.0/CMFCore/tests/test_DynamicType.py	2006-12-07 22:15:59 UTC (rev 71504)
+++ CMF/branches/2.0/CMFCore/tests/test_DynamicType.py	2006-12-07 23:45:11 UTC (rev 71505)
@@ -33,23 +33,36 @@
 from Products.CMFCore.TypesTool import FactoryTypeInformation as FTI
 from Products.CMFCore.TypesTool import TypesTool
 
+import zope.component
+from zope.testing.cleanup import CleanUp
+from zope.component.interfaces import IDefaultViewName
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.app.publisher.interfaces.browser import IBrowserView
 
-class DummyContent(DynamicType, Implicit):
+from Products.Five.traversable import FiveTraversable
+from Products.Five.traversable import Traversable
+from Products.Five.browser import BrowserView
+from zope.app.traversing.adapters import Traverser
+from zope.app.traversing.interfaces import ITraverser, ITraversable
+
+def defineDefaultViewName(name, for_=None):
+    zope.component.provideAdapter(name, (for_, BaseRequest),
+                                  IDefaultViewName, '')
+
+
+class DummyContent(Traversable, DynamicType, Implicit):
     """ Basic dynamic content class.
     """
 
     portal_type = 'Dummy Content 15'
 
 
+class DummyView(BrowserView):
+    """This is a view"""
+
+
 class DynamicTypeTests(TestCase):
 
-    def setUp(self):
-        self.site = DummySite('site')
-        self.site._setObject( 'portal_types', TypesTool() )
-        fti = FTIDATA_CMF15[0].copy()
-        self.site.portal_types._setObject( 'Dummy Content 15', FTI(**fti) )
-        self.site._setObject( 'foo', DummyContent() )
-
     def test_z2interfaces(self):
         from Interface.Verify import verifyClass
         from Products.CMFCore.interfaces.Dynamic \
@@ -60,11 +73,22 @@
     def test_z3interfaces(self):
         from zope.interface.verify import verifyClass
         from Products.CMFCore.interfaces import IDynamicType
-
         verifyClass(IDynamicType, DynamicType)
 
-    def test___before_publishing_traverse__(self):
+class DynamicTypeDefaultTraversalTests(CleanUp, TestCase):
+
+    def setUp(self):
+        self.site = DummySite('site')
+        self.site._setObject( 'portal_types', TypesTool() )
+        fti = FTIDATA_CMF15[0].copy()
+        self.site.portal_types._setObject( 'Dummy Content 15', FTI(**fti) )
+        self.site._setObject( 'foo', DummyContent() )
         dummy_view = self.site._setObject( 'dummy_view', DummyObject() )
+
+        zope.component.provideAdapter(FiveTraversable, (None,), ITraversable)
+        zope.component.provideAdapter(Traverser, (None,), ITraverser)
+
+    def test_default_view_from_fti(self):
         response = HTTPResponse()
         environment = { 'URL': '',
                         'PARENTS': [self.site],
@@ -80,7 +104,50 @@
                           'CMF Collector issue #192 (wrong base): %s'
                           % (r.response.base or 'empty',) )
 
+    def test_default_viewname_but_no_view_doesnt_override_fti(self):
+        response = HTTPResponse()
+        environment = { 'URL': '',
+                        'PARENTS': [self.site],
+                        'REQUEST_METHOD': 'GET',
+                        'steps': [],
+                        '_hacked_path': 0,
+                        'response': response }
+        r = BaseRequest(environment)
 
+        # we define a Zope3-style default view name, but no
+        # corresponding view, no change in behaviour expected
+        defineDefaultViewName('index.html', DummyContent)
+        r.traverse('foo')
+        self.assertEqual( r.URL, '/foo/dummy_view' )
+        self.assertEqual( r.response.base, '/foo/' )
+
+    def test_default_viewname_overrides_fti(self):
+        response = HTTPResponse()
+        environment = { 'URL': '',
+                        'PARENTS': [self.site],
+                        'REQUEST_METHOD': 'GET',
+                        'steps': [],
+                        '_hacked_path': 0,
+                        'response': response }
+        r = BaseRequest(environment)
+
+        # we define a Zope3-style default view name for which a view
+        # actually exists (double registration needed because we test
+        # with BaseRequest, but Five checks for IBrowserRequest as
+        # well)
+        defineDefaultViewName('index.html', DummyContent)
+        zope.component.provideAdapter(
+            DummyView, (DummyContent, BaseRequest), IBrowserView,
+            'index.html')
+        zope.component.provideAdapter(
+            DummyView, (DummyContent, IBrowserRequest), IBrowserView,
+            'index.html')
+
+        r.traverse('foo')
+        self.assertEqual( r.URL, '/foo/index.html' )
+        self.assertEqual( r.response.base, '/foo/' )
+
+
 class DynamicTypeSecurityTests(SecurityRequestTest):
 
     def setUp(self):
@@ -115,6 +182,7 @@
 def test_suite():
     return TestSuite((
         makeSuite(DynamicTypeTests),
+        makeSuite(DynamicTypeDefaultTraversalTests),
         makeSuite(DynamicTypeSecurityTests),
         ))
 



More information about the Checkins mailing list