Fix a bug in the traversal code regarding IBrowserPublisher.browserDefault.

browserDefault implementations that were returning object_thats_not_self, ()
didnt' work.
parent 3420457b
......@@ -427,7 +427,7 @@ class BaseRequest:
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 @@ class BaseRequest:
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 @@ class BaseRequest:
# 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)
......
......@@ -264,11 +264,11 @@ import zope.interface
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 @@ class DummyView(Implicit):
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 @@ class TestBaseRequestZope3Views(TestCase):
# 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 @@ class TestBaseRequestZope3Views(TestCase):
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),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment