Log message for revision 78460:
  Fix a bug in the traversal code regarding IBrowserPublisher.browserDefault.
  browserDefault implementations that were returning object_thats_not_self, ()
  didnt' work.
  

Changed:
  U   Zope/branches/philikon-aq/lib/python/ZPublisher/BaseRequest.py
  U   Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testBaseRequest.py

-=-
Modified: Zope/branches/philikon-aq/lib/python/ZPublisher/BaseRequest.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/ZPublisher/BaseRequest.py      
2007-07-29 12:05:30 UTC (rev 78459)
+++ Zope/branches/philikon-aq/lib/python/ZPublisher/BaseRequest.py      
2007-07-29 14:57:38 UTC (rev 78460)
@@ -427,7 +427,7 @@
                 else:
                     # If we have reached the end of the path, we look to see
                     # if we can find IBrowserPublisher.browserDefault. If so,
-                    # we call it to let the object tell us how to publish it
+                    # we call it to let the object tell us how to publish it.
                     # BrowserDefault returns the object to be published
                     # (usually self) and a sequence of names to traverse to
                     # find the method to be published.
@@ -440,7 +440,8 @@
                         not hasattr(object,'__bobo_traverse__')):
                         if object.aq_parent is not object.aq_inner.aq_parent:
                             from webdav.NullResource import NullResource
-                            object = NullResource(parents[-2], object.getId(), 
self).__of__(parents[-2])
+                            object = NullResource(parents[-2], object.getId(),
+                                                  self).__of__(parents[-2])
                     
                     if IBrowserPublisher.providedBy(object):
                         adapter = object
@@ -451,10 +452,9 @@
                             # Zope2 doesn't set up its own adapters in a lot
                             # of cases so we will just use a default adapter.
                             adapter = DefaultPublishTraverse(object, self)
-                    
-                    newobject, default_path = adapter.browserDefault(self)
-                    if default_path or newobject is not object:
-                        object = newobject
+
+                    object, default_path = adapter.browserDefault(self)
+                    if default_path:
                         request._hacked_path=1
                         if len(default_path) > 1:
                             path = list(default_path)

Modified: 
Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testBaseRequest.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testBaseRequest.py    
2007-07-29 12:05:30 UTC (rev 78459)
+++ Zope/branches/philikon-aq/lib/python/ZPublisher/tests/testBaseRequest.py    
2007-07-29 14:57:38 UTC (rev 78460)
@@ -264,11 +264,11 @@
 import zope.component
 import zope.testing.cleanup
 import zope.traversing.namespace
+import zope.publisher.browser
 from zope.publisher.browser import IBrowserRequest
 from zope.publisher.browser import IDefaultBrowserLayer
 from zope.traversing.interfaces import ITraversable
 
-
 class IDummy(zope.interface.Interface):
     """IDummy"""
 
@@ -292,6 +292,33 @@
     def __call__(self):
         return 'view on %s' % (self.content.name)
 
+class DummyPage(zope.publisher.browser.BrowserPage):
+
+    # BrowserPage is an IBrowserPublisher with a browserDefault that
+    # returns self, () so that __call__ is invoked by the publisher.
+
+    def __call__(self):
+        return 'Test page'
+
+class DummyPage2(zope.publisher.browser.BrowserPage):
+
+    def browserDefault(self, request):
+        # intentionally return something that's not self
+        return DummyPage(self.context, request), ()
+
+    # __call__ remains unimplemented, baseclass raises NotImplementedError
+
+class DummyPage3(zope.publisher.browser.BrowserPage):
+
+    def browserDefault(self, request):
+        # intentionally return a method here
+        return self.foo, ()
+
+    def foo(self):
+        return 'Test page'
+
+    # __call__ remains unimplemented, baseclass raises NotImplementedError
+
 class TestBaseRequestZope3Views(TestCase):
 
     def setUp(self):
@@ -309,9 +336,15 @@
         # The request needs to implement the proper interface
         zope.interface.classImplements(BaseRequest, IDefaultBrowserLayer)
 
-        # Define our 'meth' view
-        gsm.registerAdapter(DummyView, (IDummy, IDefaultBrowserLayer), None,
-                            'meth')
+        # Define the views
+        gsm.registerAdapter(DummyView, (IDummy, IDefaultBrowserLayer),
+                            zope.interface.Interface, 'meth')
+        gsm.registerAdapter(DummyPage, (IDummy, IDefaultBrowserLayer),
+                            zope.interface.Interface, 'page')
+        gsm.registerAdapter(DummyPage2, (IDummy, IDefaultBrowserLayer),
+                            zope.interface.Interface, 'page2')
+        gsm.registerAdapter(DummyPage3, (IDummy, IDefaultBrowserLayer),
+                            zope.interface.Interface, 'page3')
 
         # Bind the 'view' namespace (for @@ traversal)
         gsm.registerAdapter(zope.traversing.namespace.view,
@@ -407,6 +440,16 @@
         r.traverse('folder/obj/++view++meth')
         self.assertEqual(r['URL'], '/folder/obj/++view++meth')
 
+    def test_browserDefault(self):
+        # Test that browserDefault returning self, () works
+        r = self.makeBaseRequest()
+        ob = r.traverse('folder/obj/page')
+        self.assertEqual(ob(), 'Test page')
+
+        r = self.makeBaseRequest()
+        ob = r.traverse('folder/obj/page2')
+        self.assertEqual(ob(), 'Test page')
+
 def test_suite():
     return TestSuite( ( makeSuite(TestBaseRequest),
                         makeSuite(TestBaseRequestZope3Views),

_______________________________________________
Zope-Checkins maillist  -  Zope-Checkins@zope.org
http://mail.zope.org/mailman/listinfo/zope-checkins

Reply via email to