summaryrefslogtreecommitdiff
path: root/repoze/bfg/tests
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2010-04-14 02:49:19 +0000
committerChris McDonough <chrism@agendaless.com>2010-04-14 02:49:19 +0000
commitff1213e8f2aed987108ba57aed517c033491b1aa (patch)
treef531544c3373ae7d5b51746987cb373326277a9c /repoze/bfg/tests
parent2b6bc8adfa294f7133680f64df411251afb67dfc (diff)
downloadpyramid-ff1213e8f2aed987108ba57aed517c033491b1aa.tar.gz
pyramid-ff1213e8f2aed987108ba57aed517c033491b1aa.tar.bz2
pyramid-ff1213e8f2aed987108ba57aed517c033491b1aa.zip
Add "exception views" work contributed primarily by Andrey Popp by merging the "phash" branch.
Diffstat (limited to 'repoze/bfg/tests')
-rw-r--r--repoze/bfg/tests/exceptionviewapp/__init__.py1
-rw-r--r--repoze/bfg/tests/exceptionviewapp/configure.zcml44
-rw-r--r--repoze/bfg/tests/exceptionviewapp/models.py18
-rw-r--r--repoze/bfg/tests/exceptionviewapp/views.py17
-rw-r--r--repoze/bfg/tests/fixtureapp/configure.zcml15
-rw-r--r--repoze/bfg/tests/fixtureapp/views.py14
-rw-r--r--repoze/bfg/tests/hybridapp/configure.zcml56
-rw-r--r--repoze/bfg/tests/hybridapp/views.py22
-rw-r--r--repoze/bfg/tests/test_configuration.py743
-rw-r--r--repoze/bfg/tests/test_integration.py59
-rw-r--r--repoze/bfg/tests/test_request.py2
-rw-r--r--repoze/bfg/tests/test_router.py578
-rw-r--r--repoze/bfg/tests/test_security.py3
-rw-r--r--repoze/bfg/tests/test_view.py3
-rw-r--r--repoze/bfg/tests/test_zcml.py193
15 files changed, 1462 insertions, 306 deletions
diff --git a/repoze/bfg/tests/exceptionviewapp/__init__.py b/repoze/bfg/tests/exceptionviewapp/__init__.py
new file mode 100644
index 000000000..ef5fe8b12
--- /dev/null
+++ b/repoze/bfg/tests/exceptionviewapp/__init__.py
@@ -0,0 +1 @@
+# a package
diff --git a/repoze/bfg/tests/exceptionviewapp/configure.zcml b/repoze/bfg/tests/exceptionviewapp/configure.zcml
new file mode 100644
index 000000000..680e065a6
--- /dev/null
+++ b/repoze/bfg/tests/exceptionviewapp/configure.zcml
@@ -0,0 +1,44 @@
+<configure xmlns="http://namespaces.repoze.org/bfg">
+
+ <include package="repoze.bfg.includes" />
+
+ <view view=".views.maybe"/>
+
+ <view context=".models.NotAnException"
+ view=".views.no"/>
+
+ <view context=".models.AnException"
+ view=".views.yes"/>
+
+ <view name="raise_exception"
+ view=".views.raise_exception"/>
+
+ <route name="route_raise_exception"
+ path="route_raise_exception"
+ view=".views.raise_exception"/>
+
+ <route name="route_raise_exception2"
+ path="route_raise_exception2"
+ view=".views.raise_exception"
+ factory=".models.route_factory"/>
+
+ <route name="route_raise_exception3"
+ path="route_raise_exception3"
+ view=".views.raise_exception"
+ factory=".models.route_factory2"/>
+
+ <view context=".models.AnException"
+ route_name="route_raise_exception3"
+ view=".views.whoa"/>
+
+ <route name="route_raise_exception4"
+ path="route_raise_exception4"
+ view=".views.raise_exception"/>
+
+ <view context=".models.AnException"
+ route_name="route_raise_exception4"
+ view=".views.whoa"/>
+
+</configure>
+
+
diff --git a/repoze/bfg/tests/exceptionviewapp/models.py b/repoze/bfg/tests/exceptionviewapp/models.py
new file mode 100644
index 000000000..fe407badc
--- /dev/null
+++ b/repoze/bfg/tests/exceptionviewapp/models.py
@@ -0,0 +1,18 @@
+
+class NotAnException(object):
+ pass
+
+class AnException(Exception):
+ pass
+
+class RouteContext(object):
+ pass
+
+class RouteContext2(object):
+ pass
+
+def route_factory(*arg):
+ return RouteContext()
+
+def route_factory2(*arg):
+ return RouteContext2()
diff --git a/repoze/bfg/tests/exceptionviewapp/views.py b/repoze/bfg/tests/exceptionviewapp/views.py
new file mode 100644
index 000000000..1432618cf
--- /dev/null
+++ b/repoze/bfg/tests/exceptionviewapp/views.py
@@ -0,0 +1,17 @@
+from webob import Response
+from models import AnException
+
+def no(request):
+ return Response('no')
+
+def yes(request):
+ return Response('yes')
+
+def maybe(request):
+ return Response('maybe')
+
+def whoa(request):
+ return Response('whoa')
+
+def raise_exception(request):
+ raise AnException()
diff --git a/repoze/bfg/tests/fixtureapp/configure.zcml b/repoze/bfg/tests/fixtureapp/configure.zcml
index b936b158e..e3470d47a 100644
--- a/repoze/bfg/tests/fixtureapp/configure.zcml
+++ b/repoze/bfg/tests/fixtureapp/configure.zcml
@@ -7,6 +7,21 @@
/>
<view
+ view=".views.exception_view"
+ for="RuntimeError"
+ />
+
+ <view
+ view=".views.protected_view"
+ name="protected.html"
+ />
+
+ <view
+ view=".views.erroneous_view"
+ name="error.html"
+ />
+
+ <view
view=".views.fixture_view"
name="dummyskin.html"
request_type=".views.IDummy"
diff --git a/repoze/bfg/tests/fixtureapp/views.py b/repoze/bfg/tests/fixtureapp/views.py
index d9bc0bb6e..862046d43 100644
--- a/repoze/bfg/tests/fixtureapp/views.py
+++ b/repoze/bfg/tests/fixtureapp/views.py
@@ -1,10 +1,22 @@
from zope.interface import Interface
from webob import Response
+from repoze.bfg.exceptions import Forbidden
def fixture_view(context, request):
""" """
return Response('fixture')
+def erroneous_view(context, request):
+ """ """
+ raise RuntimeError()
+
+def exception_view(context, request):
+ """ """
+ return Response('supressed')
+
+def protected_view(context, request):
+ """ """
+ raise Forbidden()
+
class IDummy(Interface):
pass
-
diff --git a/repoze/bfg/tests/hybridapp/configure.zcml b/repoze/bfg/tests/hybridapp/configure.zcml
index 56c6ea8db..a94409e26 100644
--- a/repoze/bfg/tests/hybridapp/configure.zcml
+++ b/repoze/bfg/tests/hybridapp/configure.zcml
@@ -58,4 +58,60 @@
use_global_views="True"
/>
+ <route
+ path="error"
+ name="route7"
+ />
+
+ <view
+ route_name="route7"
+ view=".views.erroneous_view"
+ />
+
+ <route
+ path="error2"
+ name="route8"
+ />
+
+ <view
+ route_name="route8"
+ view=".views.erroneous_view"
+ />
+
+ <!-- we want this view to "win" for route7 as exception view -->
+ <view
+ view=".views.exception_view"
+ for="RuntimeError"
+ />
+
+ <!-- we want this view to "win" for route8 as exception view-->
+ <view
+ route_name="route8"
+ view=".views.exception2_view"
+ for="RuntimeError"
+ />
+
+ <route
+ path="error_sub"
+ name="route9"
+ />
+
+ <view
+ route_name="route9"
+ view=".views.erroneous_sub_view"
+ />
+
+ <!-- we want this view to "win" for route9 as exception view... -->
+ <view
+ route_name="route9"
+ view=".views.exception2_view"
+ for=".views.SuperException"
+ />
+
+ <!-- ...even if we have more context-specialized view for raised exception -->
+ <view
+ view=".views.exception_view"
+ for=".views.SubException"
+ />
+
</configure>
diff --git a/repoze/bfg/tests/hybridapp/views.py b/repoze/bfg/tests/hybridapp/views.py
index 7f60ddbfe..135ef8290 100644
--- a/repoze/bfg/tests/hybridapp/views.py
+++ b/repoze/bfg/tests/hybridapp/views.py
@@ -15,3 +15,25 @@ def global2_view(request):
def route2_view(request):
""" """
return Response('route2')
+
+def exception_view(request):
+ """ """
+ return Response('supressed')
+
+def exception2_view(request):
+ """ """
+ return Response('supressed2')
+
+def erroneous_view(request):
+ """ """
+ raise RuntimeError()
+
+def erroneous_sub_view(request):
+ """ """
+ raise SubException()
+
+class SuperException(Exception):
+ """ """
+
+class SubException(SuperException):
+ """ """
diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py
index 90413f1d6..99d564b91 100644
--- a/repoze/bfg/tests/test_configuration.py
+++ b/repoze/bfg/tests/test_configuration.py
@@ -21,16 +21,22 @@ class ConfiguratorTests(unittest.TestCase):
return Renderer
def _getViewCallable(self, config, ctx_iface=None, request_iface=None,
- name=''):
+ name='', exception_view=False):
from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ if exception_view:
+ classifier = IExceptionViewClassifier
+ else:
+ classifier = IViewClassifier
if ctx_iface is None:
ctx_iface = Interface
if request_iface is None:
request_iface = IRequest
return config.registry.adapters.lookup(
- (request_iface, ctx_iface), IView, name=name,
+ (classifier, request_iface, ctx_iface), IView, name=name,
default=None)
def _getRouteRequestIface(self, config, name):
@@ -182,6 +188,8 @@ class ConfiguratorTests(unittest.TestCase):
pass
reg = DummyRegistry()
config = self._makeOne(reg)
+ config.set_notfound_view = lambda *arg, **kw: None
+ config.set_forbidden_view = lambda *arg, **kw: None
config.setup_registry()
self.assertEqual(reg.has_listeners, True)
self.assertEqual(reg.notify(1), None)
@@ -558,54 +566,260 @@ class ConfiguratorTests(unittest.TestCase):
from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import ISecuredView
+ from repoze.bfg.interfaces import IViewClassifier
view = lambda *arg: 'OK'
view.__call_permissive__ = view
config = self._makeOne()
config.add_view(view=view)
wrapper = config.registry.adapters.lookup(
- (IRequest, Interface), ISecuredView, name='', default=None)
+ (IViewClassifier, IRequest, Interface),
+ ISecuredView, name='', default=None)
self.assertEqual(wrapper, view)
+ def test_add_view_exception_register_secured_view(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ view = lambda *arg: 'OK'
+ view.__call_permissive__ = view
+ config = self._makeOne()
+ config.add_view(view=view, context=RuntimeError)
+ wrapper = config.registry.adapters.lookup(
+ (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='', default=None)
+ self.assertEqual(wrapper, view)
+
+ def test_add_view_same_phash_overrides_existing_single_view(self):
+ from repoze.bfg.compat import md5
+ from zope.interface import Interface
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IMultiView
+ phash = md5()
+ phash.update('xhr:True')
+ view = lambda *arg: 'NOT OK'
+ view.__phash__ = phash.hexdigest()
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view, (IViewClassifier, IRequest, Interface), IView, name='')
+ def newview(context, request):
+ return 'OK'
+ config.add_view(view=newview, xhr=True)
+ wrapper = self._getViewCallable(config)
+ self.failIf(IMultiView.providedBy(wrapper))
+ request = DummyRequest()
+ request.is_xhr = True
+ self.assertEqual(wrapper(None, request), 'OK')
+
+ def test_add_view_exc_same_phash_overrides_existing_single_view(self):
+ from repoze.bfg.compat import md5
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IMultiView
+ phash = md5()
+ phash.update('xhr:True')
+ view = lambda *arg: 'NOT OK'
+ view.__phash__ = phash.hexdigest()
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view,
+ (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='')
+ def newview(context, request):
+ return 'OK'
+ config.add_view(view=newview, xhr=True,
+ context=RuntimeError)
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError), exception_view=True)
+ self.failIf(IMultiView.providedBy(wrapper))
+ request = DummyRequest()
+ request.is_xhr = True
+ self.assertEqual(wrapper(None, request), 'OK')
+
+ def test_add_view_default_phash_overrides_no_phash(self):
+ from zope.interface import Interface
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IMultiView
+ view = lambda *arg: 'NOT OK'
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view, (IViewClassifier, IRequest, Interface), IView, name='')
+ def newview(context, request):
+ return 'OK'
+ config.add_view(view=newview)
+ wrapper = self._getViewCallable(config)
+ self.failIf(IMultiView.providedBy(wrapper))
+ request = DummyRequest()
+ request.is_xhr = True
+ self.assertEqual(wrapper(None, request), 'OK')
+
+ def test_add_view_exc_default_phash_overrides_no_phash(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IMultiView
+ view = lambda *arg: 'NOT OK'
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view,
+ (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='')
+ def newview(context, request):
+ return 'OK'
+ config.add_view(view=newview, context=RuntimeError)
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError), exception_view=True)
+ self.failIf(IMultiView.providedBy(wrapper))
+ request = DummyRequest()
+ request.is_xhr = True
+ self.assertEqual(wrapper(None, request), 'OK')
+
+ def test_add_view_default_phash_overrides_default_phash(self):
+ from repoze.bfg.configuration import DEFAULT_PHASH
+ from zope.interface import Interface
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IMultiView
+ view = lambda *arg: 'NOT OK'
+ view.__phash__ = DEFAULT_PHASH
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view, (IViewClassifier, IRequest, Interface), IView, name='')
+ def newview(context, request):
+ return 'OK'
+ config.add_view(view=newview)
+ wrapper = self._getViewCallable(config)
+ self.failIf(IMultiView.providedBy(wrapper))
+ request = DummyRequest()
+ request.is_xhr = True
+ self.assertEqual(wrapper(None, request), 'OK')
+
+ def test_add_view_exc_default_phash_overrides_default_phash(self):
+ from repoze.bfg.configuration import DEFAULT_PHASH
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IMultiView
+ view = lambda *arg: 'NOT OK'
+ view.__phash__ = DEFAULT_PHASH
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view,
+ (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='')
+ def newview(context, request):
+ return 'OK'
+ config.add_view(view=newview, context=RuntimeError)
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError), exception_view=True)
+ self.failIf(IMultiView.providedBy(wrapper))
+ request = DummyRequest()
+ request.is_xhr = True
+ self.assertEqual(wrapper(None, request), 'OK')
+
def test_add_view_multiview_replaces_existing_view(self):
from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IMultiView
view = lambda *arg: 'OK'
+ view.__phash__ = 'abc'
config = self._makeOne()
config.registry.registerAdapter(
- view, (IRequest, Interface), IView, name='')
+ view, (IViewClassifier, IRequest, Interface), IView, name='')
config.add_view(view=view)
wrapper = self._getViewCallable(config)
self.failUnless(IMultiView.providedBy(wrapper))
self.assertEqual(wrapper(None, None), 'OK')
+ def test_add_view_exc_multiview_replaces_existing_view(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IMultiView
+ view = lambda *arg: 'OK'
+ view.__phash__ = 'abc'
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view,
+ (IViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='')
+ config.registry.registerAdapter(
+ view,
+ (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='')
+ config.add_view(view=view, context=RuntimeError)
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError), exception_view=True)
+ self.failUnless(IMultiView.providedBy(wrapper))
+ self.assertEqual(wrapper(None, None), 'OK')
+
def test_add_view_multiview_replaces_existing_securedview(self):
from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import ISecuredView
from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
view = lambda *arg: 'OK'
+ view.__phash__ = 'abc'
config = self._makeOne()
config.registry.registerAdapter(
- view, (IRequest, Interface), ISecuredView, name='')
+ view, (IViewClassifier, IRequest, Interface),
+ ISecuredView, name='')
config.add_view(view=view)
wrapper = self._getViewCallable(config)
self.failUnless(IMultiView.providedBy(wrapper))
self.assertEqual(wrapper(None, None), 'OK')
+ def test_add_view_exc_multiview_replaces_existing_securedview(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import ISecuredView
+ from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ view = lambda *arg: 'OK'
+ view.__phash__ = 'abc'
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view,
+ (IViewClassifier, IRequest, implementedBy(RuntimeError)),
+ ISecuredView, name='')
+ config.registry.registerAdapter(
+ view,
+ (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),
+ ISecuredView, name='')
+ config.add_view(view=view, context=RuntimeError)
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError), exception_view=True)
+ self.failUnless(IMultiView.providedBy(wrapper))
+ self.assertEqual(wrapper(None, None), 'OK')
+
def test_add_view_with_accept_multiview_replaces_existing_view(self):
from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import IView
from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
def view(context, request):
return 'OK'
def view2(context, request):
return 'OK2'
config = self._makeOne()
config.registry.registerAdapter(
- view, (IRequest, Interface), IView, name='')
+ view, (IViewClassifier, IRequest, Interface), IView, name='')
config.add_view(view=view2, accept='text/html')
wrapper = self._getViewCallable(config)
self.failUnless(IMultiView.providedBy(wrapper))
@@ -616,19 +830,52 @@ class ConfiguratorTests(unittest.TestCase):
request.accept = DummyAccept('text/html', 'text/html')
self.assertEqual(wrapper(None, request), 'OK2')
+ def test_add_view_exc_with_accept_multiview_replaces_existing_view(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ def view(context, request):
+ return 'OK'
+ def view2(context, request):
+ return 'OK2'
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view,
+ (IViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='')
+ config.registry.registerAdapter(
+ view,
+ (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='')
+ config.add_view(view=view2, accept='text/html', context=RuntimeError)
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError), exception_view=True)
+ self.failUnless(IMultiView.providedBy(wrapper))
+ self.assertEqual(len(wrapper.views), 1)
+ self.assertEqual(len(wrapper.media_views), 1)
+ self.assertEqual(wrapper(None, None), 'OK')
+ request = DummyRequest()
+ request.accept = DummyAccept('text/html', 'text/html')
+ self.assertEqual(wrapper(None, request), 'OK2')
+
def test_add_view_multiview_replaces_existing_view_with___accept__(self):
from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import IView
from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
def view(context, request):
return 'OK'
def view2(context, request):
return 'OK2'
view.__accept__ = 'text/html'
+ view.__phash__ = 'abc'
config = self._makeOne()
config.registry.registerAdapter(
- view, (IRequest, Interface), IView, name='')
+ view, (IViewClassifier, IRequest, Interface), IView, name='')
config.add_view(view=view2)
wrapper = self._getViewCallable(config)
self.failUnless(IMultiView.providedBy(wrapper))
@@ -639,19 +886,78 @@ class ConfiguratorTests(unittest.TestCase):
request.accept = DummyAccept('text/html')
self.assertEqual(wrapper(None, request), 'OK')
+ def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ def view(context, request):
+ return 'OK'
+ def view2(context, request):
+ return 'OK2'
+ view.__accept__ = 'text/html'
+ view.__phash__ = 'abc'
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view,
+ (IViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='')
+ config.registry.registerAdapter(
+ view,
+ (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IView, name='')
+ config.add_view(view=view2, context=RuntimeError)
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError), exception_view=True)
+ self.failUnless(IMultiView.providedBy(wrapper))
+ self.assertEqual(len(wrapper.views), 1)
+ self.assertEqual(len(wrapper.media_views), 1)
+ self.assertEqual(wrapper(None, None), 'OK2')
+ request = DummyRequest()
+ request.accept = DummyAccept('text/html')
+ self.assertEqual(wrapper(None, request), 'OK')
+
def test_add_view_multiview_replaces_multiview(self):
from zope.interface import Interface
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
view = DummyMultiView()
config = self._makeOne()
- config.registry.registerAdapter(view, (IRequest, Interface),
- IMultiView, name='')
+ config.registry.registerAdapter(
+ view, (IViewClassifier, IRequest, Interface),
+ IMultiView, name='')
view2 = lambda *arg: 'OK2'
config.add_view(view=view2)
wrapper = self._getViewCallable(config)
self.failUnless(IMultiView.providedBy(wrapper))
- self.assertEqual(wrapper.views, [(view2, None)])
+ self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])
+ self.assertEqual(wrapper(None, None), 'OK1')
+
+ def test_add_view_exc_multiview_replaces_multiview(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ view = DummyMultiView()
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view,
+ (IViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IMultiView, name='')
+ config.registry.registerAdapter(
+ view,
+ (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)),
+ IMultiView, name='')
+ view2 = lambda *arg: 'OK2'
+ config.add_view(view=view2, context=RuntimeError)
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError), exception_view=True)
+ self.failUnless(IMultiView.providedBy(wrapper))
+ self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])
self.assertEqual(wrapper(None, None), 'OK1')
def test_add_view_multiview_context_superclass_then_subclass(self):
@@ -659,6 +965,7 @@ class ConfiguratorTests(unittest.TestCase):
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import IView
from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
class ISuper(Interface):
pass
class ISub(ISuper):
@@ -667,7 +974,7 @@ class ConfiguratorTests(unittest.TestCase):
view2 = lambda *arg: 'OK2'
config = self._makeOne()
config.registry.registerAdapter(
- view, (IRequest, ISuper), IView, name='')
+ view, (IViewClassifier, IRequest, ISuper), IView, name='')
config.add_view(view=view2, for_=ISub)
wrapper = self._getViewCallable(config, ISuper, IRequest)
self.failIf(IMultiView.providedBy(wrapper))
@@ -676,6 +983,40 @@ class ConfiguratorTests(unittest.TestCase):
self.failIf(IMultiView.providedBy(wrapper))
self.assertEqual(wrapper(None, None), 'OK2')
+ def test_add_view_multiview_exception_superclass_then_subclass(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IMultiView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ class Super(Exception):
+ pass
+ class Sub(Super):
+ pass
+ view = lambda *arg: 'OK'
+ view2 = lambda *arg: 'OK2'
+ config = self._makeOne()
+ config.registry.registerAdapter(
+ view, (IViewClassifier, IRequest, Super), IView, name='')
+ config.registry.registerAdapter(
+ view, (IExceptionViewClassifier, IRequest, Super), IView, name='')
+ config.add_view(view=view2, for_=Sub)
+ wrapper = self._getViewCallable(
+ config, implementedBy(Super), IRequest)
+ wrapper_exc_view = self._getViewCallable(
+ config, implementedBy(Super), IRequest, exception_view=True)
+ self.assertEqual(wrapper_exc_view, wrapper)
+ self.failIf(IMultiView.providedBy(wrapper_exc_view))
+ self.assertEqual(wrapper_exc_view(None, None), 'OK')
+ wrapper = self._getViewCallable(
+ config, implementedBy(Sub), IRequest)
+ wrapper_exc_view = self._getViewCallable(
+ config, implementedBy(Sub), IRequest, exception_view=True)
+ self.assertEqual(wrapper_exc_view, wrapper)
+ self.failIf(IMultiView.providedBy(wrapper_exc_view))
+ self.assertEqual(wrapper_exc_view(None, None), 'OK2')
+
def test_add_view_multiview_call_ordering(self):
from zope.interface import directlyProvides
def view1(context, request): return 'view1'
@@ -821,6 +1162,37 @@ class ConfiguratorTests(unittest.TestCase):
self.failIfEqual(wrapper, None)
self.assertEqual(wrapper(None, None), 'OK')
+ def test_add_view_with_route_name_exception(self):
+ from zope.interface import implementedBy
+ from zope.component import ComponentLookupError
+ view = lambda *arg: 'OK'
+ config = self._makeOne()
+ config.add_view(view=view, route_name='foo', context=RuntimeError)
+ self.assertEqual(len(config.registry.deferred_route_views), 1)
+ infos = config.registry.deferred_route_views['foo']
+ self.assertEqual(len(infos), 1)
+ info = infos[0]
+ self.assertEqual(info['route_name'], 'foo')
+ self.assertEqual(info['view'], view)
+ self.assertRaises(ComponentLookupError,
+ self._getRouteRequestIface, config, 'foo')
+ wrapper_exc_view = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError),
+ exception_view=True)
+ self.assertEqual(wrapper_exc_view, None)
+ config.add_route('foo', '/a/b')
+ request_iface = self._getRouteRequestIface(config, 'foo')
+ self.failIfEqual(request_iface, None)
+ wrapper_exc_view = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError),
+ request_iface=request_iface, exception_view=True)
+ self.failIfEqual(wrapper_exc_view, None)
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError),
+ request_iface=request_iface)
+ self.assertEqual(wrapper_exc_view, wrapper)
+ self.assertEqual(wrapper_exc_view(None, None), 'OK')
+
def test_add_view_with_request_method_true(self):
view = lambda *arg: 'OK'
config = self._makeOne()
@@ -1048,6 +1420,16 @@ class ConfiguratorTests(unittest.TestCase):
request.is_xhr = True
self.assertEqual(wrapper(None, request), 'OK')
+ def test_add_view_same_predicates(self):
+ view2 = lambda *arg: 'second'
+ view1 = lambda *arg: 'first'
+ config = self._makeOne()
+ config.add_view(view=view1)
+ config.add_view(view=view2)
+ view = self._getViewCallable(config)
+ request = self._makeRequest(config)
+ self.assertEqual(view(None, request), 'second')
+
def _assertRoute(self, config, name, path, num_predicates=0):
from repoze.bfg.interfaces import IRoutesMapper
mapper = config.registry.getUtility(IRoutesMapper)
@@ -1164,6 +1546,22 @@ class ConfiguratorTests(unittest.TestCase):
wrapper = self._getViewCallable(config, IOther, request_type)
self.assertEqual(wrapper, None)
+ def test_add_route_with_view_exception(self):
+ from zope.interface import implementedBy
+ config = self._makeOne()
+ view = lambda *arg: 'OK'
+ config.add_route('name', 'path', view=view, view_context=RuntimeError)
+ request_type = self._getRouteRequestIface(config, 'name')
+ wrapper = self._getViewCallable(
+ config, ctx_iface=implementedBy(RuntimeError),
+ request_iface=request_type, exception_view=True)
+ self.assertEqual(wrapper(None, None), 'OK')
+ self._assertRoute(config, 'name', 'path')
+ wrapper = self._getViewCallable(
+ config, ctx_iface=IOther,
+ request_iface=request_type, exception_view=True)
+ self.assertEqual(wrapper, None)
+
def test_add_route_with_view_for(self):
config = self._makeOne()
view = lambda *arg: 'OK'
@@ -1280,6 +1678,7 @@ class ConfiguratorTests(unittest.TestCase):
from zope.interface import implementedBy
from repoze.bfg.static import StaticRootFactory
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
config = self._makeOne()
config.add_static_view('static', 'fixtures/static')
request_type = self._getRouteRequestIface(config, 'static')
@@ -1287,7 +1686,7 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(route.factory.__class__, StaticRootFactory)
iface = implementedBy(StaticRootFactory)
wrapped = config.registry.adapters.lookup(
- (request_type, iface), IView, name='')
+ (IViewClassifier, request_type, iface), IView, name='')
request = self._makeRequest(config)
self.assertEqual(wrapped(None, request).__class__, PackageURLParser)
@@ -1296,6 +1695,7 @@ class ConfiguratorTests(unittest.TestCase):
from zope.interface import implementedBy
from repoze.bfg.static import StaticRootFactory
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
config = self._makeOne()
config.add_static_view('static', 'repoze.bfg.tests:fixtures/static')
request_type = self._getRouteRequestIface(config, 'static')
@@ -1303,7 +1703,7 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(route.factory.__class__, StaticRootFactory)
iface = implementedBy(StaticRootFactory)
wrapped = config.registry.adapters.lookup(
- (request_type, iface), IView, name='')
+ (IViewClassifier, request_type, iface), IView, name='')
request = self._makeRequest(config)
self.assertEqual(wrapped(None, request).__class__, PackageURLParser)
@@ -1313,6 +1713,7 @@ class ConfiguratorTests(unittest.TestCase):
from zope.interface import implementedBy
from repoze.bfg.static import StaticRootFactory
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
config = self._makeOne()
here = os.path.dirname(__file__)
static_path = os.path.join(here, 'fixtures', 'static')
@@ -1322,76 +1723,63 @@ class ConfiguratorTests(unittest.TestCase):
self.assertEqual(route.factory.__class__, StaticRootFactory)
iface = implementedBy(StaticRootFactory)
wrapped = config.registry.adapters.lookup(
- (request_type, iface), IView, name='')
+ (IViewClassifier, request_type, iface), IView, name='')
request = self._makeRequest(config)
self.assertEqual(wrapped(None, request).__class__, StaticURLParser)
- def test__system_view_no_view_no_renderer(self):
- from repoze.bfg.exceptions import ConfigurationError
- config = self._makeOne()
- self.assertRaises(ConfigurationError, config._system_view, IDummy)
-
- def test__system_view_no_view_with_renderer(self):
+ def test_set_notfound_view(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.exceptions import NotFound
config = self._makeOne()
- self._registerRenderer(config, name='.pt')
- config._system_view(IDummy,
- renderer='repoze.bfg.tests:fixtures/minimal.pt')
+ view = lambda *arg: arg
+ config.set_notfound_view(view)
request = self._makeRequest(config)
- view = config.registry.getUtility(IDummy)
+ view = self._getViewCallable(config, ctx_iface=implementedBy(NotFound),
+ request_iface=IRequest)
result = view(None, request)
- self.assertEqual(result.body, 'Hello!')
+ self.assertEqual(result, (None, request))
- def test__system_view_with_attr(self):
+ def test_set_notfound_view_request_has_context(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.exceptions import NotFound
config = self._makeOne()
- class view(object):
- def __init__(self, context, request):
- pass
- def index(self):
- return 'OK'
- config._system_view(IDummy, view=view, attr='index')
- view = config.registry.getUtility(IDummy)
+ view = lambda *arg: arg
+ config.set_notfound_view(view)
request = self._makeRequest(config)
+ request.context = 'abc'
+ view = self._getViewCallable(config, ctx_iface=implementedBy(NotFound),
+ request_iface=IRequest)
result = view(None, request)
- self.assertEqual(result, 'OK')
+ self.assertEqual(result, ('abc', request))
- def test__system_view_with_wrapper(self):
- from zope.interface import Interface
- from zope.interface import directlyProvides
+ def test_set_forbidden_view(self):
+ from zope.interface import implementedBy
from repoze.bfg.interfaces import IRequest
- from repoze.bfg.interfaces import IView
- config = self._makeOne()
- view = lambda *arg: DummyResponse()
- wrapper = lambda *arg: 'OK2'
- config.registry.registerAdapter(wrapper, (Interface, Interface),
- IView, name='wrapper')
- config._system_view(IDummy, view=view, wrapper='wrapper')
- view = config.registry.getUtility(IDummy)
- request = self._makeRequest(config)
- directlyProvides(request, IRequest)
- request.registry = config.registry
- context = DummyContext()
- result = view(context, request)
- self.assertEqual(result, 'OK2')
-
- def test_set_notfound_view(self):
- from repoze.bfg.interfaces import INotFoundView
+ from repoze.bfg.exceptions import Forbidden
config = self._makeOne()
view = lambda *arg: 'OK'
- config.set_notfound_view(view)
+ config.set_forbidden_view(view)
request = self._makeRequest(config)
- view = config.registry.getUtility(INotFoundView)
+ view = self._getViewCallable(config, ctx_iface=implementedBy(Forbidden),
+ request_iface=IRequest)
result = view(None, request)
self.assertEqual(result, 'OK')
- def test_set_forbidden_view(self):
- from repoze.bfg.interfaces import IForbiddenView
+ def test_set_forbidden_view_request_has_context(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.exceptions import Forbidden
config = self._makeOne()
- view = lambda *arg: 'OK'
+ view = lambda *arg: arg
config.set_forbidden_view(view)
request = self._makeRequest(config)
- view = config.registry.getUtility(IForbiddenView)
+ request.context = 'abc'
+ view = self._getViewCallable(config, ctx_iface=implementedBy(Forbidden),
+ request_iface=IRequest)
result = view(None, request)
- self.assertEqual(result, 'OK')
+ self.assertEqual(result, ('abc', request))
def test__set_authentication_policy(self):
from repoze.bfg.interfaces import IAuthenticationPolicy
@@ -1680,6 +2068,7 @@ class ConfiguratorTests(unittest.TestCase):
def test__derive_view_with_wrapper_viewname(self):
from webob import Response
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
inner_response = Response('OK')
def inner_view(context, request):
return inner_response
@@ -1690,7 +2079,7 @@ class ConfiguratorTests(unittest.TestCase):
return Response('outer ' + request.wrapped_body)
config = self._makeOne()
config.registry.registerAdapter(
- outer_view, (None, None), IView, 'owrap')
+ outer_view, (IViewClassifier, None, None), IView, 'owrap')
result = config._derive_view(inner_view, viewname='inner',
wrapper_viewname='owrap')
self.failIf(result is inner_view)
@@ -2396,6 +2785,183 @@ class Test_decorate_view(unittest.TestCase):
self.failUnless(view1.__predicated__.im_func is
view2.__predicated__.im_func)
+class Test__make_predicates(unittest.TestCase):
+ def _callFUT(self, **kw):
+ from repoze.bfg.configuration import _make_predicates
+ return _make_predicates(**kw)
+
+ def test_ordering_xhr_and_request_method_trump_only_containment(self):
+ order1, _, _ = self._callFUT(xhr=True, request_method='GET')
+ order2, _, _ = self._callFUT(containment=True)
+ self.failUnless(order1 < order2)
+
+ def test_ordering_number_of_predicates(self):
+ order1, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ request_param='param',
+ header='header',
+ accept='accept',
+ containment='containment',
+ request_type='request_type',
+ custom=('a',)
+ )
+ order2, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ request_param='param',
+ header='header',
+ accept='accept',
+ containment='containment',
+ request_type='request_type',
+ custom=('a',)
+ )
+ order3, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ request_param='param',
+ header='header',
+ accept='accept',
+ containment='containment',
+ request_type='request_type',
+ )
+ order4, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ request_param='param',
+ header='header',
+ accept='accept',
+ containment='containment',
+ )
+ order5, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ request_param='param',
+ header='header',
+ accept='accept',
+ )
+ order6, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ request_param='param',
+ header='header',
+ )
+ order7, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ request_param='param',
+ )
+ order8, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ )
+ order9, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ )
+ order10, _, _ = self._callFUT(
+ xhr='xhr',
+ )
+ order11, _, _ = self._callFUT(
+ )
+ self.assertEqual(order1, order2)
+ self.failUnless(order3 > order2)
+ self.failUnless(order4 > order3)
+ self.failUnless(order5 > order4)
+ self.failUnless(order6 > order5)
+ self.failUnless(order7 > order6)
+ self.failUnless(order8 > order7)
+ self.failUnless(order9 > order8)
+ self.failUnless(order10 > order9)
+ self.failUnless(order11 > order10)
+
+ def test_ordering_importance_of_predicates(self):
+ order1, _, _ = self._callFUT(
+ xhr='xhr',
+ )
+ order2, _, _ = self._callFUT(
+ request_method='request_method',
+ )
+ order3, _, _ = self._callFUT(
+ path_info='path_info',
+ )
+ order4, _, _ = self._callFUT(
+ request_param='param',
+ )
+ order5, _, _ = self._callFUT(
+ header='header',
+ )
+ order6, _, _ = self._callFUT(
+ accept='accept',
+ )
+ order7, _, _ = self._callFUT(
+ containment='containment',
+ )
+ order8, _, _ = self._callFUT(
+ request_type='request_type',
+ )
+ order9, _, _ = self._callFUT(
+ custom=('a',),
+ )
+ self.failUnless(order1 > order2)
+ self.failUnless(order2 > order3)
+ self.failUnless(order3 > order4)
+ self.failUnless(order4 > order5)
+ self.failUnless(order5 > order6)
+ self.failUnless(order6 > order7)
+ self.failUnless(order7 > order8)
+ self.failUnless(order8 > order9)
+
+ def test_ordering_importance_and_number(self):
+ order1, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ )
+ order2, _, _ = self._callFUT(
+ custom=('a',),
+ )
+ self.failUnless(order1 < order2)
+
+ order1, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ )
+ order2, _, _ = self._callFUT(
+ request_method='request_method',
+ custom=('a',),
+ )
+ self.failUnless(order1 > order2)
+
+ order1, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ )
+ order2, _, _ = self._callFUT(
+ request_method='request_method',
+ custom=('a',),
+ )
+ self.failUnless(order1 < order2)
+
+ order1, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ )
+ order2, _, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ custom=('a',),
+ )
+ self.failUnless(order1 > order2)
class TestMultiView(unittest.TestCase):
def _getTargetClass(self):
@@ -2418,20 +2984,33 @@ class TestMultiView(unittest.TestCase):
def test_add(self):
mv = self._makeOne()
mv.add('view', 100)
- self.assertEqual(mv.views, [(100, 'view')])
+ self.assertEqual(mv.views, [(100, 'view', None)])
mv.add('view2', 99)
- self.assertEqual(mv.views, [(99, 'view2'), (100, 'view')])
+ self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])
mv.add('view3', 100, 'text/html')
- self.assertEqual(mv.media_views['text/html'], [(100, 'view3')])
+ self.assertEqual(mv.media_views['text/html'], [(100, 'view3', None)])
mv.add('view4', 99, 'text/html')
self.assertEqual(mv.media_views['text/html'],
- [(99, 'view4'), (100, 'view3')])
+ [(99, 'view4', None), (100, 'view3', None)])
mv.add('view5', 100, 'text/xml')
- self.assertEqual(mv.media_views['text/xml'], [(100, 'view5')])
+ self.assertEqual(mv.media_views['text/xml'], [(100, 'view5', None)])
self.assertEqual(set(mv.accepts), set(['text/xml', 'text/html']))
- self.assertEqual(mv.views, [(99, 'view2'), (100, 'view')])
+ self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])
mv.add('view6', 98, 'text/*')
- self.assertEqual(mv.views, [(98, 'view6'),(99, 'view2'), (100, 'view')])
+ self.assertEqual(mv.views, [(98, 'view6', None),
+ (99, 'view2', None),
+ (100, 'view', None)])
+
+ def test_add_with_phash(self):
+ mv = self._makeOne()
+ mv.add('view', 100, phash='abc')
+ self.assertEqual(mv.views, [(100, 'view', 'abc')])
+ mv.add('view', 100, phash='abc')
+ self.assertEqual(mv.views, [(100, 'view', 'abc')])
+ mv.add('view', 100, phash='def')
+ self.assertEqual(mv.views, [(100, 'view', 'abc'), (100, 'view', 'def')])
+ mv.add('view', 100, phash='abc')
+ self.assertEqual(mv.views, [(100, 'view', 'abc'), (100, 'view', 'def')])
def test_get_views_request_has_no_accept(self):
request = DummyRequest()
@@ -2478,7 +3057,7 @@ class TestMultiView(unittest.TestCase):
def view(context, request):
""" """
view.__predicated__ = lambda *arg: False
- mv.views = [(100, view)]
+ mv.views = [(100, view, None)]
context = DummyContext()
request = DummyRequest()
self.assertRaises(NotFound, mv.match, context, request)
@@ -2488,7 +3067,7 @@ class TestMultiView(unittest.TestCase):
def view(context, request):
""" """
view.__predicated__ = lambda *arg: True
- mv.views = [(100, view)]
+ mv.views = [(100, view, None)]
context = DummyContext()
request = DummyRequest()
result = mv.match(context, request)
@@ -2505,7 +3084,7 @@ class TestMultiView(unittest.TestCase):
mv = self._makeOne()
def view(context, request):
""" """
- mv.views = [(100, view)]
+ mv.views = [(100, view, None)]
self.assertEqual(mv.__permitted__(None, None), True)
def test_permitted(self):
@@ -2515,7 +3094,7 @@ class TestMultiView(unittest.TestCase):
def permitted(context, request):
return False
view.__permitted__ = permitted
- mv.views = [(100, view)]
+ mv.views = [(100, view, None)]
context = DummyContext()
request = DummyRequest()
result = mv.__permitted__(context, request)
@@ -2539,7 +3118,7 @@ class TestMultiView(unittest.TestCase):
raise NotFound
def view2(context, request):
return expected_response
- mv.views = [(100, view1), (99, view2)]
+ mv.views = [(100, view1, None), (99, view2, None)]
response = mv(context, request)
self.assertEqual(response, expected_response)
@@ -2551,7 +3130,7 @@ class TestMultiView(unittest.TestCase):
expected_response = DummyResponse()
def view(context, request):
return expected_response
- mv.views = [(100, view)]
+ mv.views = [(100, view, None)]
response = mv(context, request)
self.assertEqual(response, expected_response)
@@ -2573,7 +3152,7 @@ class TestMultiView(unittest.TestCase):
def permissive(context, request):
return expected_response
view.__call_permissive__ = permissive
- mv.views = [(100, view)]
+ mv.views = [(100, view, None)]
response = mv.__call_permissive__(context, request)
self.assertEqual(response, expected_response)
@@ -2585,7 +3164,7 @@ class TestMultiView(unittest.TestCase):
expected_response = DummyResponse()
def view(context, request):
return expected_response
- mv.views = [(100, view)]
+ mv.views = [(100, view, None)]
response = mv.__call_permissive__(context, request)
self.assertEqual(response, expected_response)
@@ -2598,7 +3177,7 @@ class TestMultiView(unittest.TestCase):
def view(context, request):
return expected_response
mv.views = [(100, None)]
- mv.media_views['text/xml'] = [(100, view)]
+ mv.media_views['text/xml'] = [(100, view, None)]
mv.accepts = ['text/xml']
response = mv(context, request)
self.assertEqual(response, expected_response)
@@ -2611,8 +3190,8 @@ class TestMultiView(unittest.TestCase):
expected_response = DummyResponse()
def view(context, request):
return expected_response
- mv.views = [(100, view)]
- mv.media_views['text/xml'] = [(100, None)]
+ mv.views = [(100, view, None)]
+ mv.media_views['text/xml'] = [(100, None, None)]
mv.accepts = ['text/xml']
response = mv(context, request)
self.assertEqual(response, expected_response)
@@ -2932,8 +3511,8 @@ class DummyMultiView:
def __init__(self):
self.views = []
self.name = 'name'
- def add(self, view, score, accept=None):
- self.views.append((view, accept))
+ def add(self, view, order, accept=None, phash=None):
+ self.views.append((view, accept, phash))
def __call__(self, context, request):
return 'OK1'
def __permitted__(self, context, request):
diff --git a/repoze/bfg/tests/test_integration.py b/repoze/bfg/tests/test_integration.py
index 41144f7c3..c54509378 100644
--- a/repoze/bfg/tests/test_integration.py
+++ b/repoze/bfg/tests/test_integration.py
@@ -31,12 +31,14 @@ class WGSIAppPlusBFGViewTests(unittest.TestCase):
def test_scanned(self):
from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.configuration import Configurator
from repoze.bfg.tests import test_integration
config = Configurator()
config.scan(test_integration)
reg = config.registry
- view = reg.adapters.lookup((IRequest, INothing), IView, name='')
+ view = reg.adapters.lookup(
+ (IViewClassifier, IRequest, INothing), IView, name='')
self.assertEqual(view, wsgiapptest)
here = os.path.dirname(__file__)
@@ -63,11 +65,12 @@ class TestStaticApp(unittest.TestCase):
open(os.path.join(here, 'fixtures/minimal.pt'), 'r').read())
class TwillBase(unittest.TestCase):
+ root_factory = None
def setUp(self):
import sys
import twill
from repoze.bfg.configuration import Configurator
- config = Configurator()
+ config = Configurator(root_factory=self.root_factory)
config.load_zcml(self.config)
twill.add_wsgi_intercept('localhost', 6543, config.make_wsgi_app)
if sys.platform is 'win32': # pragma: no cover
@@ -98,6 +101,11 @@ class TestFixtureApp(TwillBase):
self.assertEqual(browser.get_html(), 'fixture')
browser.go('http://localhost:6543/dummyskin.html')
self.assertEqual(browser.get_code(), 404)
+ browser.go('http://localhost:6543/error.html')
+ self.assertEqual(browser.get_code(), 200)
+ self.assertEqual(browser.get_html(), 'supressed')
+ browser.go('http://localhost:6543/protected.html')
+ self.assertEqual(browser.get_code(), 401)
class TestCCBug(TwillBase):
# "unordered" as reported in IRC by author of
@@ -140,6 +148,15 @@ class TestHybridApp(TwillBase):
browser.go('http://localhost:6543/pqr/global2')
self.assertEqual(browser.get_code(), 200)
self.assertEqual(browser.get_html(), 'global2')
+ browser.go('http://localhost:6543/error')
+ self.assertEqual(browser.get_code(), 200)
+ self.assertEqual(browser.get_html(), 'supressed')
+ browser.go('http://localhost:6543/error2')
+ self.assertEqual(browser.get_code(), 200)
+ self.assertEqual(browser.get_html(), 'supressed2')
+ browser.go('http://localhost:6543/error_sub')
+ self.assertEqual(browser.get_code(), 200)
+ self.assertEqual(browser.get_html(), 'supressed2')
class TestRestBugApp(TwillBase):
# test bug reported by delijati 2010/2/3 (http://pastebin.com/d4cc15515)
@@ -168,6 +185,44 @@ class TestViewDecoratorApp(TwillBase):
self.assertEqual(browser.get_code(), 200)
self.failUnless('OK3' in browser.get_html())
+from repoze.bfg.tests.exceptionviewapp.models import AnException, NotAnException
+excroot = {'anexception':AnException(),
+ 'notanexception':NotAnException()}
+
+class TestExceptionViewsApp(TwillBase):
+ config = 'repoze.bfg.tests.exceptionviewapp:configure.zcml'
+ root_factory = lambda *arg: excroot
+ def test_it(self):
+ import twill.commands
+ browser = twill.commands.get_browser()
+ browser.go('http://localhost:6543/')
+ self.assertEqual(browser.get_code(), 200)
+ self.failUnless('maybe' in browser.get_html())
+
+ browser.go('http://localhost:6543/notanexception')
+ self.assertEqual(browser.get_code(), 200)
+ self.failUnless('no' in browser.get_html())
+
+ browser.go('http://localhost:6543/anexception')
+ self.assertEqual(browser.get_code(), 200)
+ self.failUnless('yes' in browser.get_html())
+
+ browser.go('http://localhost:6543/route_raise_exception')
+ self.assertEqual(browser.get_code(), 200)
+ self.failUnless('yes' in browser.get_html())
+
+ browser.go('http://localhost:6543/route_raise_exception2')
+ self.assertEqual(browser.get_code(), 200)
+ self.failUnless('yes' in browser.get_html())
+
+ browser.go('http://localhost:6543/route_raise_exception3')
+ self.assertEqual(browser.get_code(), 200)
+ self.failUnless('whoa' in browser.get_html())
+
+ browser.go('http://localhost:6543/route_raise_exception4')
+ self.assertEqual(browser.get_code(), 200)
+ self.failUnless('whoa' in browser.get_html())
+
class DummyContext(object):
pass
diff --git a/repoze/bfg/tests/test_request.py b/repoze/bfg/tests/test_request.py
index 06255721e..7b3d0ce7b 100644
--- a/repoze/bfg/tests/test_request.py
+++ b/repoze/bfg/tests/test_request.py
@@ -165,6 +165,8 @@ class Test_route_request_iface(unittest.TestCase):
def test_it(self):
iface = self._callFUT('routename')
self.assertEqual(iface.__name__, 'routename_IRequest')
+ self.assertTrue(hasattr(iface, 'combined'))
+ self.assertEqual(iface.combined.__name__, 'routename_combined_IRequest')
class Test_add_global_response_headers(unittest.TestCase):
def _callFUT(self, request, headerlist):
diff --git a/repoze/bfg/tests/test_router.py b/repoze/bfg/tests/test_router.py
index 0d7bee720..8702b9317 100644
--- a/repoze/bfg/tests/test_router.py
+++ b/repoze/bfg/tests/test_router.py
@@ -13,11 +13,10 @@ class TestRouter(unittest.TestCase):
def _registerRouteRequest(self, name):
from repoze.bfg.interfaces import IRouteRequest
- from zope.interface import Interface
- class IRequest(Interface):
- """ """
- self.registry.registerUtility(IRequest, IRouteRequest, name=name)
- return IRequest
+ from repoze.bfg.request import route_request_iface
+ iface = route_request_iface(name)
+ self.registry.registerUtility(iface, IRouteRequest, name=name)
+ return iface
def _connectRoute(self, path, name, factory=None):
from repoze.bfg.interfaces import IRoutesMapper
@@ -75,9 +74,10 @@ class TestRouter(unittest.TestCase):
self.registry.registerAdapter(DummyTraverserFactory, (None,),
ITraverser, name='')
- def _registerView(self, app, name, *for_):
+ def _registerView(self, app, name, classifier, req_iface, ctx_iface):
from repoze.bfg.interfaces import IView
- self.registry.registerAdapter(app, for_, IView, name)
+ self.registry.registerAdapter(
+ app, (classifier, req_iface, ctx_iface), IView, name)
def _registerEventListener(self, iface):
L = []
@@ -118,44 +118,15 @@ class TestRouter(unittest.TestCase):
router = self._makeOne()
self.assertEqual(router.root_policy, rootfactory)
- def test_iforbiddenview_override(self):
- from repoze.bfg.interfaces import IForbiddenView
- def app():
- """ """
- self.registry.registerUtility(app, IForbiddenView)
- router = self._makeOne()
- self.assertEqual(router.forbidden_view, app)
-
- def test_iforbiddenview_nooverride(self):
- router = self._makeOne()
- from repoze.bfg.view import default_forbidden_view
- self.assertEqual(router.forbidden_view, default_forbidden_view)
-
- def test_inotfoundview_override(self):
- from repoze.bfg.interfaces import INotFoundView
- def app():
- """ """
- self.registry.registerUtility(app, INotFoundView)
- router = self._makeOne()
- self.assertEqual(router.notfound_view, app)
-
- def test_inotfoundview_nooverride(self):
- router = self._makeOne()
- from repoze.bfg.view import default_notfound_view
- self.assertEqual(router.notfound_view, default_notfound_view)
-
def test_call_traverser_default(self):
+ from repoze.bfg.exceptions import NotFound
environ = self._makeEnviron()
logger = self._registerLogger()
router = self._makeOne()
start_response = DummyStartResponse()
- result = router(environ, start_response)
- headers = start_response.headers
- self.assertEqual(len(headers), 2)
- status = start_response.status
- self.assertEqual(status, '404 Not Found')
- self.failUnless('<code>/</code>' in result[0], result)
- self.failIf('debug_notfound' in result[0])
+ why = exc_raised(NotFound, router, environ, start_response)
+ self.failUnless('/' in why[0], why)
+ self.failIf('debug_notfound' in why[0])
self.assertEqual(len(logger.messages), 0)
def test_traverser_raises_notfound_class(self):
@@ -165,12 +136,7 @@ class TestRouter(unittest.TestCase):
self._registerTraverserFactory(context, raise_error=NotFound)
router = self._makeOne()
start_response = DummyStartResponse()
- result = router(environ, start_response)
- headers = start_response.headers
- self.assertEqual(len(headers), 2)
- status = start_response.status
- self.assertEqual(status, '404 Not Found')
- self.failUnless('<code></code>' in result[0], result)
+ self.assertRaises(NotFound, router, environ, start_response)
def test_traverser_raises_notfound_instance(self):
from repoze.bfg.exceptions import NotFound
@@ -179,12 +145,8 @@ class TestRouter(unittest.TestCase):
self._registerTraverserFactory(context, raise_error=NotFound('foo'))
router = self._makeOne()
start_response = DummyStartResponse()
- result = router(environ, start_response)
- headers = start_response.headers
- self.assertEqual(len(headers), 2)
- status = start_response.status
- self.assertEqual(status, '404 Not Found')
- self.failUnless('<code>foo</code>' in result[0], result)
+ why = exc_raised(NotFound, router, environ, start_response)
+ self.failUnless('foo' in why[0], why)
def test_traverser_raises_forbidden_class(self):
from repoze.bfg.exceptions import Forbidden
@@ -193,12 +155,7 @@ class TestRouter(unittest.TestCase):
self._registerTraverserFactory(context, raise_error=Forbidden)
router = self._makeOne()
start_response = DummyStartResponse()
- result = router(environ, start_response)
- headers = start_response.headers
- self.assertEqual(len(headers), 2)
- status = start_response.status
- self.assertEqual(status, '401 Unauthorized')
- self.failUnless('<code></code>' in result[0], result)
+ self.assertRaises(Forbidden, router, environ, start_response)
def test_traverser_raises_forbidden_instance(self):
from repoze.bfg.exceptions import Forbidden
@@ -207,30 +164,24 @@ class TestRouter(unittest.TestCase):
self._registerTraverserFactory(context, raise_error=Forbidden('foo'))
router = self._makeOne()
start_response = DummyStartResponse()
- result = router(environ, start_response)
- headers = start_response.headers
- self.assertEqual(len(headers), 2)
- status = start_response.status
- self.assertEqual(status, '401 Unauthorized')
- self.failUnless('<code>foo</code>' in result[0], result)
+ why = exc_raised(Forbidden, router, environ, start_response)
+ self.failUnless('foo' in why[0], why)
def test_call_no_view_registered_no_isettings(self):
+ from repoze.bfg.exceptions import NotFound
environ = self._makeEnviron()
context = DummyContext()
self._registerTraverserFactory(context)
logger = self._registerLogger()
router = self._makeOne()
start_response = DummyStartResponse()
- result = router(environ, start_response)
- headers = start_response.headers
- self.assertEqual(len(headers), 2)
- status = start_response.status
- self.assertEqual(status, '404 Not Found')
- self.failUnless('<code>/</code>' in result[0], result)
- self.failIf('debug_notfound' in result[0])
+ why = exc_raised(NotFound, router, environ, start_response)
+ self.failUnless('/' in why[0], why)
+ self.failIf('debug_notfound' in why[0])
self.assertEqual(len(logger.messages), 0)
def test_call_no_view_registered_debug_notfound_false(self):
+ from repoze.bfg.exceptions import NotFound
environ = self._makeEnviron()
context = DummyContext()
self._registerTraverserFactory(context)
@@ -238,16 +189,13 @@ class TestRouter(unittest.TestCase):
self._registerSettings(debug_notfound=False)
router = self._makeOne()
start_response = DummyStartResponse()
- result = router(environ, start_response)
- headers = start_response.headers
- self.assertEqual(len(headers), 2)
- status = start_response.status
- self.assertEqual(status, '404 Not Found')
- self.failUnless('<code>/</code>' in result[0], result)
- self.failIf('debug_notfound' in result[0])
+ why = exc_raised(NotFound, router, environ, start_response)
+ self.failUnless('/' in why[0], why)
+ self.failIf('debug_notfound' in why[0])
self.assertEqual(len(logger.messages), 0)
def test_call_no_view_registered_debug_notfound_true(self):
+ from repoze.bfg.exceptions import NotFound
environ = self._makeEnviron()
context = DummyContext()
self._registerTraverserFactory(context)
@@ -255,17 +203,13 @@ class TestRouter(unittest.TestCase):
logger = self._registerLogger()
router = self._makeOne()
start_response = DummyStartResponse()
- result = router(environ, start_response)
- headers = start_response.headers
- self.assertEqual(len(headers), 2)
- status = start_response.status
- self.assertEqual(status, '404 Not Found')
+ why = exc_raised(NotFound, router, environ, start_response)
self.failUnless(
"debug_notfound of url http://localhost:8080/; path_info: '/', "
- "context:" in result[0])
- self.failUnless(
- "view_name: '', subpath: []" in result[0])
- self.failUnless('http://localhost:8080' in result[0], result)
+ "context:" in why[0])
+ self.failUnless("view_name: '', subpath: []" in why[0])
+ self.failUnless('http://localhost:8080' in why[0], why)
+
self.assertEqual(len(logger.messages), 1)
message = logger.messages[0]
self.failUnless('of url http://localhost:8080' in message)
@@ -275,35 +219,25 @@ class TestRouter(unittest.TestCase):
self.failUnless("subpath: []" in message)
def test_call_view_returns_nonresponse(self):
+ from repoze.bfg.interfaces import IViewClassifier
context = DummyContext()
self._registerTraverserFactory(context)
environ = self._makeEnviron()
view = DummyView('abc')
- self._registerView(view, '', None, None)
- router = self._makeOne()
- start_response = DummyStartResponse()
- self.assertRaises(ValueError, router, environ, start_response)
-
- def test_inotfoundview_returns_nonresponse(self):
- from repoze.bfg.interfaces import INotFoundView
- context = DummyContext()
- environ = self._makeEnviron()
- self._registerTraverserFactory(context)
- def app(context, request):
- """ """
- self.registry.registerUtility(app, INotFoundView)
+ self._registerView(view, '', IViewClassifier, None, None)
router = self._makeOne()
start_response = DummyStartResponse()
self.assertRaises(ValueError, router, environ, start_response)
def test_call_view_registered_nonspecific_default_path(self):
+ from repoze.bfg.interfaces import IViewClassifier
context = DummyContext()
self._registerTraverserFactory(context)
response = DummyResponse()
response.app_iter = ['Hello world']
view = DummyView(response)
environ = self._makeEnviron()
- self._registerView(view, '', None, None)
+ self._registerView(view, '', IViewClassifier, None, None)
self._registerRootFactory(context)
router = self._makeOne()
start_response = DummyStartResponse()
@@ -318,6 +252,7 @@ class TestRouter(unittest.TestCase):
self.assertEqual(request.root, context)
def test_call_view_registered_nonspecific_nondefault_path_and_subpath(self):
+ from repoze.bfg.interfaces import IViewClassifier
context = DummyContext()
self._registerTraverserFactory(context, view_name='foo',
subpath=['bar'],
@@ -327,7 +262,7 @@ class TestRouter(unittest.TestCase):
response.app_iter = ['Hello world']
view = DummyView(response)
environ = self._makeEnviron()
- self._registerView(view, 'foo', None, None)
+ self._registerView(view, 'foo', IViewClassifier, None, None)
router = self._makeOne()
start_response = DummyStartResponse()
result = router(environ, start_response)
@@ -346,6 +281,7 @@ class TestRouter(unittest.TestCase):
class IContext(Interface):
pass
from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IViewClassifier
context = DummyContext()
directlyProvides(context, IContext)
self._registerTraverserFactory(context)
@@ -354,7 +290,7 @@ class TestRouter(unittest.TestCase):
response.app_iter = ['Hello world']
view = DummyView(response)
environ = self._makeEnviron()
- self._registerView(view, '', IRequest, IContext)
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
router = self._makeOne()
start_response = DummyStartResponse()
result = router(environ, start_response)
@@ -370,6 +306,8 @@ class TestRouter(unittest.TestCase):
def test_call_view_registered_specific_fail(self):
from zope.interface import Interface
from zope.interface import directlyProvides
+ from repoze.bfg.exceptions import NotFound
+ from repoze.bfg.interfaces import IViewClassifier
class IContext(Interface):
pass
class INotContext(Interface):
@@ -381,31 +319,30 @@ class TestRouter(unittest.TestCase):
response = DummyResponse()
view = DummyView(response)
environ = self._makeEnviron()
- self._registerView(view, '', IRequest, IContext)
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
router = self._makeOne()
start_response = DummyStartResponse()
- result = router(environ, start_response)
- self.assertEqual(start_response.status, '404 Not Found')
- self.failUnless('404' in result[0])
+ self.assertRaises(NotFound, router, environ, start_response)
def test_call_view_raises_forbidden(self):
from zope.interface import Interface
from zope.interface import directlyProvides
+ from repoze.bfg.exceptions import Forbidden
class IContext(Interface):
pass
from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IViewClassifier
context = DummyContext()
directlyProvides(context, IContext)
self._registerTraverserFactory(context, subpath=[''])
response = DummyResponse()
- view = DummyView(response, raise_unauthorized=True)
+ view = DummyView(response, raise_exception=Forbidden("unauthorized"))
environ = self._makeEnviron()
- self._registerView(view, '', IRequest, IContext)
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
router = self._makeOne()
start_response = DummyStartResponse()
- response = router(environ, start_response)
- self.assertEqual(start_response.status, '401 Unauthorized')
- self.assertEqual(environ['repoze.bfg.message'], 'unauthorized')
+ why = exc_raised(Forbidden, router, environ, start_response)
+ self.assertEqual(why[0], 'unauthorized')
def test_call_view_raises_notfound(self):
from zope.interface import Interface
@@ -413,18 +350,19 @@ class TestRouter(unittest.TestCase):
class IContext(Interface):
pass
from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.exceptions import NotFound
context = DummyContext()
directlyProvides(context, IContext)
self._registerTraverserFactory(context, subpath=[''])
response = DummyResponse()
- view = DummyView(response, raise_notfound=True)
+ view = DummyView(response, raise_exception=NotFound("notfound"))
environ = self._makeEnviron()
- self._registerView(view, '', IRequest, IContext)
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
router = self._makeOne()
start_response = DummyStartResponse()
- response = router(environ, start_response)
- self.assertEqual(start_response.status, '404 Not Found')
- self.assertEqual(environ['repoze.bfg.message'], 'notfound')
+ why = exc_raised(NotFound, router, environ, start_response)
+ self.assertEqual(why[0], 'notfound')
def test_call_request_has_global_response_headers(self):
from zope.interface import Interface
@@ -432,6 +370,7 @@ class TestRouter(unittest.TestCase):
class IContext(Interface):
pass
from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IViewClassifier
context = DummyContext()
directlyProvides(context, IContext)
self._registerTraverserFactory(context, subpath=[''])
@@ -441,7 +380,7 @@ class TestRouter(unittest.TestCase):
request.global_response_headers = [('b', 2)]
return response
environ = self._makeEnviron()
- self._registerView(view, '', IRequest, IContext)
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
router = self._makeOne()
start_response = DummyStartResponse()
router(environ, start_response)
@@ -452,13 +391,14 @@ class TestRouter(unittest.TestCase):
from repoze.bfg.interfaces import INewRequest
from repoze.bfg.interfaces import INewResponse
from repoze.bfg.interfaces import IAfterTraversal
+ from repoze.bfg.interfaces import IViewClassifier
context = DummyContext()
self._registerTraverserFactory(context)
response = DummyResponse()
response.app_iter = ['Hello world']
view = DummyView(response)
environ = self._makeEnviron()
- self._registerView(view, '', None, None)
+ self._registerView(view, '', IViewClassifier, None, None)
request_events = self._registerEventListener(INewRequest)
aftertraversal_events = self._registerEventListener(IAfterTraversal)
response_events = self._registerEventListener(INewResponse)
@@ -474,13 +414,14 @@ class TestRouter(unittest.TestCase):
self.assertEqual(result, response.app_iter)
def test_call_pushes_and_pops_threadlocal_manager(self):
+ from repoze.bfg.interfaces import IViewClassifier
context = DummyContext()
self._registerTraverserFactory(context)
response = DummyResponse()
response.app_iter = ['Hello world']
view = DummyView(response)
environ = self._makeEnviron()
- self._registerView(view, '', None, None)
+ self._registerView(view, '', IViewClassifier, None, None)
router = self._makeOne()
start_response = DummyStartResponse()
router.threadlocal_manager = DummyThreadLocalManager()
@@ -489,7 +430,8 @@ class TestRouter(unittest.TestCase):
self.assertEqual(len(router.threadlocal_manager.popped), 1)
def test_call_route_matches_and_has_factory(self):
- req_iface = self._registerRouteRequest('foo')
+ from repoze.bfg.interfaces import IViewClassifier
+ self._registerRouteRequest('foo')
root = object()
def factory(request):
return root
@@ -500,7 +442,7 @@ class TestRouter(unittest.TestCase):
response.app_iter = ['Hello world']
view = DummyView(response)
environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
- self._registerView(view, '', None, None)
+ self._registerView(view, '', IViewClassifier, None, None)
self._registerRootFactory(context)
router = self._makeOne()
start_response = DummyStartResponse()
@@ -522,9 +464,10 @@ class TestRouter(unittest.TestCase):
def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):
from repoze.bfg.interfaces import INewRequest
+ from repoze.bfg.interfaces import IViewClassifier
from zope.interface import alsoProvides
from zope.interface import Interface
- req_iface = self._registerRouteRequest('foo')
+ self._registerRouteRequest('foo')
class IFoo(Interface):
pass
def listener(event):
@@ -540,7 +483,7 @@ class TestRouter(unittest.TestCase):
response.app_iter = ['Hello world']
view = DummyView(response)
environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
- self._registerView(view, '', None, None)
+ self._registerView(view, '', IViewClassifier, None, None)
self._registerRootFactory(context)
router = self._makeOne()
start_response = DummyStartResponse()
@@ -576,9 +519,8 @@ class TestRouter(unittest.TestCase):
environ = self._makeEnviron()
router = self._makeOne()
start_response = DummyStartResponse()
- app_iter = router(environ, start_response)
- self.assertEqual(start_response.status, '404 Not Found')
- self.failUnless('from root factory' in app_iter[0])
+ why = exc_raised(NotFound, router, environ, start_response)
+ self.failUnless('from root factory' in why[0])
def test_root_factory_raises_forbidden(self):
from repoze.bfg.interfaces import IRootFactory
@@ -595,29 +537,378 @@ class TestRouter(unittest.TestCase):
environ = self._makeEnviron()
router = self._makeOne()
start_response = DummyStartResponse()
+ why = exc_raised(Forbidden, router, environ, start_response)
+ self.failUnless('from root factory' in why[0])
+
+ def test_root_factory_exception_propagating(self):
+ from repoze.bfg.interfaces import IRootFactory
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ def rootfactory(request):
+ raise RuntimeError()
+ self.registry.registerUtility(rootfactory, IRootFactory)
+ class IContext(Interface):
+ pass
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ environ = self._makeEnviron()
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(RuntimeError, router, environ, start_response)
+
+ def test_traverser_exception_propagating(self):
+ environ = self._makeEnviron()
+ context = DummyContext()
+ self._registerTraverserFactory(context, raise_error=RuntimeError())
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(RuntimeError, router, environ, start_response)
+
+ def test_call_view_exception_propagating(self):
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ class IContext(Interface):
+ pass
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IViewClassifier
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ self._registerTraverserFactory(context, subpath=[''])
+ response = DummyResponse()
+ view = DummyView(response, raise_exception=RuntimeError)
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(RuntimeError, router, environ, start_response)
+
+ def test_call_view_raises_exception_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ response = DummyResponse()
+ exception_response = DummyResponse()
+ exception_response.app_iter = ["Hello, world"]
+ view = DummyView(response, raise_exception=RuntimeError)
+ exception_view = DummyView(exception_response)
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, None)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, RuntimeError)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, ["Hello, world"])
+ self.assertEqual(view.request.exception.__class__, RuntimeError)
+
+ def test_call_view_raises_super_exception_sub_exception_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ class SuperException(Exception):
+ pass
+ class SubException(SuperException):
+ pass
+ response = DummyResponse()
+ exception_response = DummyResponse()
+ exception_response.app_iter = ["Hello, world"]
+ view = DummyView(response, raise_exception=SuperException)
+ exception_view = DummyView(exception_response)
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, None)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, SubException)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(SuperException, router, environ, start_response)
+
+ def test_call_view_raises_sub_exception_super_exception_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ class SuperException(Exception):
+ pass
+ class SubException(SuperException):
+ pass
+ response = DummyResponse()
+ exception_response = DummyResponse()
+ exception_response.app_iter = ["Hello, world"]
+ view = DummyView(response, raise_exception=SubException)
+ exception_view = DummyView(exception_response)
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, None)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, SuperException)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, ["Hello, world"])
+
+ def test_call_view_raises_exception_another_exception_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ class MyException(Exception):
+ pass
+ class AnotherException(Exception):
+ pass
+ response = DummyResponse()
+ exception_response = DummyResponse()
+ exception_response.app_iter = ["Hello, world"]
+ view = DummyView(response, raise_exception=MyException)
+ exception_view = DummyView(exception_response)
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, None)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, AnotherException)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(MyException, router, environ, start_response)
+
+ def test_root_factory_raises_exception_view(self):
+ from repoze.bfg.interfaces import IRootFactory
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ def rootfactory(request):
+ raise RuntimeError()
+ self.registry.registerUtility(rootfactory, IRootFactory)
+ exception_response = DummyResponse()
+ exception_response.app_iter = ["Hello, world"]
+ exception_view = DummyView(exception_response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, RuntimeError)
+ environ = self._makeEnviron()
+ router = self._makeOne()
+ start_response = DummyStartResponse()
app_iter = router(environ, start_response)
- self.assertEqual(start_response.status, '401 Unauthorized')
- self.failUnless('from root factory' in app_iter[0])
+ self.assertEqual(app_iter, ["Hello, world"])
+
+ def test_traverser_raises_exception_view(self):
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ environ = self._makeEnviron()
+ context = DummyContext()
+ self._registerTraverserFactory(context, raise_error=RuntimeError())
+ exception_response = DummyResponse()
+ exception_response.app_iter = ["Hello, world"]
+ exception_view = DummyView(exception_response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, RuntimeError)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, ["Hello, world"])
+
+ def test_exception_view_returns_non_response(self):
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ environ = self._makeEnviron()
+ response = DummyResponse()
+ view = DummyView(response, raise_exception=RuntimeError)
+ self._registerView(view, '', IViewClassifier, IRequest, None)
+ exception_view = DummyView(None)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, RuntimeError)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(ValueError, router, environ, start_response)
+
+ def test_call_route_raises_route_exception_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('archives/:action/:article', 'foo', None)
+ view = DummyView(DummyResponse(), raise_exception=RuntimeError)
+ self._registerView(view, '', IViewClassifier, req_iface, None)
+ response = DummyResponse()
+ response.app_iter = ["Hello, world"]
+ exception_view = DummyView(response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ req_iface, RuntimeError)
+ environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
+ start_response = DummyStartResponse()
+ router = self._makeOne()
+ result = router(environ, start_response)
+ self.assertEqual(result, ["Hello, world"])
+
+ def test_call_view_raises_exception_route_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('archives/:action/:article', 'foo', None)
+ view = DummyView(DummyResponse(), raise_exception=RuntimeError)
+ self._registerView(view, '', IViewClassifier, IRequest, None)
+ response = DummyResponse()
+ response.app_iter = ["Hello, world"]
+ exception_view = DummyView(response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ req_iface, RuntimeError)
+ environ = self._makeEnviron()
+ start_response = DummyStartResponse()
+ router = self._makeOne()
+ self.assertRaises(RuntimeError, router, environ, start_response)
+
+ def test_call_route_raises_exception_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('archives/:action/:article', 'foo', None)
+ view = DummyView(DummyResponse(), raise_exception=RuntimeError)
+ self._registerView(view, '', IViewClassifier, req_iface, None)
+ response = DummyResponse()
+ response.app_iter = ["Hello, world"]
+ exception_view = DummyView(response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, RuntimeError)
+ environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
+ start_response = DummyStartResponse()
+ router = self._makeOne()
+ result = router(environ, start_response)
+ self.assertEqual(result, ["Hello, world"])
+
+ def test_call_route_raises_super_exception_sub_exception_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ class SuperException(Exception):
+ pass
+ class SubException(SuperException):
+ pass
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('archives/:action/:article', 'foo', None)
+ view = DummyView(DummyResponse(), raise_exception=SuperException)
+ self._registerView(view, '', IViewClassifier, req_iface, None)
+ response = DummyResponse()
+ response.app_iter = ["Hello, world"]
+ exception_view = DummyView(response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, SubException)
+ environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
+ start_response = DummyStartResponse()
+ router = self._makeOne()
+ self.assertRaises(SuperException, router, environ, start_response)
+
+ def test_call_route_raises_sub_exception_super_exception_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ class SuperException(Exception):
+ pass
+ class SubException(SuperException):
+ pass
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('archives/:action/:article', 'foo', None)
+ view = DummyView(DummyResponse(), raise_exception=SubException)
+ self._registerView(view, '', IViewClassifier, req_iface, None)
+ response = DummyResponse()
+ response.app_iter = ["Hello, world"]
+ exception_view = DummyView(response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, SuperException)
+ environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
+ start_response = DummyStartResponse()
+ router = self._makeOne()
+ result = router(environ, start_response)
+ self.assertEqual(result, ["Hello, world"])
+
+ def test_call_route_raises_exception_another_exception_view(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ class MyException(Exception):
+ pass
+ class AnotherException(Exception):
+ pass
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('archives/:action/:article', 'foo', None)
+ view = DummyView(DummyResponse(), raise_exception=MyException)
+ self._registerView(view, '', IViewClassifier, req_iface, None)
+ response = DummyResponse()
+ response.app_iter = ["Hello, world"]
+ exception_view = DummyView(response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, AnotherException)
+ environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
+ start_response = DummyStartResponse()
+ router = self._makeOne()
+ self.assertRaises(MyException, router, environ, start_response)
+
+ def test_call_route_raises_exception_view_specializing(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ from repoze.bfg.interfaces import IRequest
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('archives/:action/:article', 'foo', None)
+ view = DummyView(DummyResponse(), raise_exception=RuntimeError)
+ self._registerView(view, '', IViewClassifier, req_iface, None)
+ response = DummyResponse()
+ response.app_iter = ["Hello, world"]
+ exception_view = DummyView(response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, RuntimeError)
+ response_spec = DummyResponse()
+ response_spec.app_iter = ["Hello, special world"]
+ exception_view_spec = DummyView(response_spec)
+ self._registerView(exception_view_spec, '', IExceptionViewClassifier,
+ req_iface, RuntimeError)
+ environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
+ start_response = DummyStartResponse()
+ router = self._makeOne()
+ result = router(environ, start_response)
+ self.assertEqual(result, ["Hello, special world"])
+
+ def test_call_route_raises_exception_view_another_route(self):
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ req_iface = self._registerRouteRequest('foo')
+ another_req_iface = self._registerRouteRequest('bar')
+ self._connectRoute('archives/:action/:article', 'foo', None)
+ view = DummyView(DummyResponse(), raise_exception=RuntimeError)
+ self._registerView(view, '', IViewClassifier, req_iface, None)
+ response = DummyResponse()
+ response.app_iter = ["Hello, world"]
+ exception_view = DummyView(response)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ another_req_iface, RuntimeError)
+ environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
+ start_response = DummyStartResponse()
+ router = self._makeOne()
+ self.assertRaises(RuntimeError, router, environ, start_response)
+
+ def test_call_view_raises_exception_view_route(self):
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.interfaces import IExceptionViewClassifier
+ req_iface = self._registerRouteRequest('foo')
+ response = DummyResponse()
+ exception_response = DummyResponse()
+ exception_response.app_iter = ["Hello, world"]
+ view = DummyView(response, raise_exception=RuntimeError)
+ exception_view = DummyView(exception_response)
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, None)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ req_iface, RuntimeError)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(RuntimeError, router, environ, start_response)
class DummyContext:
pass
class DummyView:
- def __init__(self, response, raise_unauthorized=False,
- raise_notfound=False):
+ def __init__(self, response, raise_exception=None):
self.response = response
- self.raise_unauthorized = raise_unauthorized
- self.raise_notfound = raise_notfound
+ self.raise_exception = raise_exception
def __call__(self, context, request):
self.context = context
self.request = request
- if self.raise_unauthorized:
- from repoze.bfg.exceptions import Forbidden
- raise Forbidden('unauthorized')
- if self.raise_notfound:
- from repoze.bfg.exceptions import NotFound
- raise NotFound('notfound')
+ if not self.raise_exception is None:
+ raise self.raise_exception
return self.response
class DummyRootFactory:
@@ -662,3 +953,12 @@ class DummyLogger:
warn = info
debug = info
+def exc_raised(exc, func, *arg, **kw):
+ try:
+ func(*arg, **kw)
+ except exc, e:
+ return e
+ else:
+ raise AssertionError('%s not raised' % exc) # pragma: no cover
+
+
diff --git a/repoze/bfg/tests/test_security.py b/repoze/bfg/tests/test_security.py
index 0a15831b7..13a0e2d9b 100644
--- a/repoze/bfg/tests/test_security.py
+++ b/repoze/bfg/tests/test_security.py
@@ -118,6 +118,7 @@ class TestViewExecutionPermitted(unittest.TestCase):
from repoze.bfg.threadlocal import get_current_registry
from zope.interface import Interface
from repoze.bfg.interfaces import ISecuredView
+ from repoze.bfg.interfaces import IViewClassifier
class Checker(object):
def __permitted__(self, context, request):
self.context = context
@@ -125,7 +126,7 @@ class TestViewExecutionPermitted(unittest.TestCase):
return allow
checker = Checker()
reg = get_current_registry()
- reg.registerAdapter(checker, (Interface, Interface),
+ reg.registerAdapter(checker, (IViewClassifier, Interface, Interface),
ISecuredView, view_name)
return checker
diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py
index 5f053d94d..bcfa45e91 100644
--- a/repoze/bfg/tests/test_view.py
+++ b/repoze/bfg/tests/test_view.py
@@ -11,7 +11,8 @@ class BaseTest(object):
def _registerView(self, reg, app, name):
from repoze.bfg.interfaces import IRequest
- for_ = (IRequest, IContext)
+ from repoze.bfg.interfaces import IViewClassifier
+ for_ = (IViewClassifier, IRequest, IContext)
from repoze.bfg.interfaces import IView
reg.registerAdapter(app, for_, IView, name)
diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py
index 426e6e24d..452769de8 100644
--- a/repoze/bfg/tests/test_zcml.py
+++ b/repoze/bfg/tests/test_zcml.py
@@ -23,6 +23,7 @@ class TestViewDirective(unittest.TestCase):
def test_request_type_ashttpmethod(self):
from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRequest
context = DummyContext()
view = lambda *arg: None
@@ -37,7 +38,8 @@ class TestViewDirective(unittest.TestCase):
register = action['callable']
register()
reg = get_current_registry()
- wrapper = reg.adapters.lookup((IRequest, IDummy), IView, name='')
+ wrapper = reg.adapters.lookup(
+ (IViewClassifier, IRequest, IDummy), IView, name='')
request = DummyRequest()
request.method = 'GET'
self.assertEqual(wrapper.__predicated__(None, request), True)
@@ -48,6 +50,7 @@ class TestViewDirective(unittest.TestCase):
from zope.interface import directlyProvides
from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRequest
context = DummyContext(IDummy)
view = lambda *arg: 'OK'
@@ -61,7 +64,8 @@ class TestViewDirective(unittest.TestCase):
register = actions[0]['callable']
register()
reg = get_current_registry()
- regview = reg.adapters.lookup((IRequest, IDummy), IView, name='')
+ regview = reg.adapters.lookup(
+ (IViewClassifier, IRequest, IDummy), IView, name='')
self.assertNotEqual(view, regview)
request = DummyRequest()
directlyProvides(request, IDummy)
@@ -81,6 +85,7 @@ class TestViewDirective(unittest.TestCase):
def test_with_dotted_renderer(self):
from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRendererFactory
from repoze.bfg.interfaces import IRequest
context = DummyContext()
@@ -100,12 +105,14 @@ class TestViewDirective(unittest.TestCase):
self.assertEqual(actions[0]['discriminator'], discrim)
register = actions[0]['callable']
register()
- regview = reg.adapters.lookup((IRequest, IDummy), IView, name='')
+ regview = reg.adapters.lookup(
+ (IViewClassifier, IRequest, IDummy), IView, name='')
self.assertEqual(regview(None, None).body, 'OK')
def test_with_custom_predicates(self):
from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRequest
context = DummyContext()
reg = get_current_registry()
@@ -125,12 +132,14 @@ class TestViewDirective(unittest.TestCase):
self.assertEqual(actions[0]['discriminator'], discrim)
register = actions[0]['callable']
register()
- regview = reg.adapters.lookup((IRequest, IDummy), IView, name='')
+ regview = reg.adapters.lookup(
+ (IViewClassifier, IRequest, IDummy), IView, name='')
self.assertEqual(regview(None, None), 'OK')
def test_context_trumps_for(self):
from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRequest
context = DummyContext()
reg = get_current_registry()
@@ -146,12 +155,14 @@ class TestViewDirective(unittest.TestCase):
self.assertEqual(actions[0]['discriminator'], discrim)
register = actions[0]['callable']
register()
- regview = reg.adapters.lookup((IRequest, IDummy), IView, name='')
+ regview = reg.adapters.lookup(
+ (IViewClassifier, IRequest, IDummy), IView, name='')
self.assertEqual(regview(None, None), 'OK')
def test_with_for(self):
from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRequest
context = DummyContext()
reg = get_current_registry()
@@ -166,7 +177,8 @@ class TestViewDirective(unittest.TestCase):
self.assertEqual(actions[0]['discriminator'], discrim)
register = actions[0]['callable']
register()
- regview = reg.adapters.lookup((IRequest, IDummy), IView, name='')
+ regview = reg.adapters.lookup(
+ (IViewClassifier, IRequest, IDummy), IView, name='')
self.assertEqual(regview(None, None), 'OK')
class TestNotFoundDirective(unittest.TestCase):
@@ -176,13 +188,17 @@ class TestNotFoundDirective(unittest.TestCase):
def tearDown(self):
testing.tearDown()
- def _callFUT(self, context, view):
+ def _callFUT(self, context, view, **kw):
from repoze.bfg.zcml import notfound
- return notfound(context, view)
+ return notfound(context, view, **kw)
def test_it(self):
+ from zope.interface import implementedBy
from repoze.bfg.threadlocal import get_current_registry
- from repoze.bfg.interfaces import INotFoundView
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.exceptions import NotFound
context = DummyContext()
def view(request):
@@ -191,14 +207,48 @@ class TestNotFoundDirective(unittest.TestCase):
actions = context.actions
self.assertEqual(len(actions), 1)
+ discrim = ('view', NotFound, '', None, IView, None, None, None, None,
+ None, False, None, None, None)
regadapt = actions[0]
- self.assertEqual(regadapt['discriminator'], INotFoundView)
+ self.assertEqual(regadapt['discriminator'], discrim)
register = regadapt['callable']
register()
reg = get_current_registry()
- derived_view = reg.getUtility(INotFoundView)
+ derived_view = reg.adapters.lookup(
+ (IViewClassifier, IRequest, implementedBy(NotFound)),
+ IView, default=None)
+
+ self.assertNotEqual(derived_view, None)
self.assertEqual(derived_view(None, None), 'OK')
- self.assertEqual(derived_view.__name__, view.__name__)
+ self.assertEqual(derived_view.__name__, 'bwcompat_view')
+
+ def test_it_with_dotted_renderer(self):
+ from zope.interface import implementedBy
+ from repoze.bfg.threadlocal import get_current_registry
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.exceptions import NotFound
+ from repoze.bfg.configuration import Configurator
+ context = DummyContext()
+ reg = get_current_registry()
+ config = Configurator(reg)
+ def dummy_renderer_factory(*arg, **kw):
+ return lambda *arg, **kw: 'OK'
+ config.add_renderer('.pt', dummy_renderer_factory)
+ def view(request):
+ return {}
+ self._callFUT(context, view, renderer='fake.pt')
+ actions = context.actions
+ regadapt = actions[0]
+ register = regadapt['callable']
+ register()
+ derived_view = reg.adapters.lookup(
+ (IViewClassifier, IRequest, implementedBy(NotFound)),
+ IView, default=None)
+ self.assertNotEqual(derived_view, None)
+ self.assertEqual(derived_view(None, None).body, 'OK')
+ self.assertEqual(derived_view.__name__, 'bwcompat_view')
class TestForbiddenDirective(unittest.TestCase):
def setUp(self):
@@ -207,92 +257,67 @@ class TestForbiddenDirective(unittest.TestCase):
def tearDown(self):
testing.tearDown()
- def _callFUT(self, context, view):
+ def _callFUT(self, context, view, **kw):
from repoze.bfg.zcml import forbidden
- return forbidden(context, view)
+ return forbidden(context, view, **kw)
def test_it(self):
+ from zope.interface import implementedBy
from repoze.bfg.threadlocal import get_current_registry
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.exceptions import Forbidden
context = DummyContext()
def view(request):
return 'OK'
self._callFUT(context, view)
actions = context.actions
- from repoze.bfg.interfaces import IForbiddenView
self.assertEqual(len(actions), 1)
+ discrim = ('view', Forbidden, '', None, IView, None, None, None, None,
+ None, False, None, None, None)
regadapt = actions[0]
- self.assertEqual(regadapt['discriminator'], IForbiddenView)
+ self.assertEqual(regadapt['discriminator'], discrim)
register = regadapt['callable']
register()
reg = get_current_registry()
- derived_view = reg.getUtility(IForbiddenView)
- self.assertEqual(derived_view(None, None), 'OK')
- self.assertEqual(derived_view.__name__, view.__name__)
-
-class TestSystemViewHandler(unittest.TestCase):
- def setUp(self):
- testing.setUp()
-
- def tearDown(self):
- testing.tearDown()
+ derived_view = reg.adapters.lookup(
+ (IViewClassifier, IRequest, implementedBy(Forbidden)),
+ IView, default=None)
- def _makeOne(self, iface):
- from repoze.bfg.zcml import SystemViewHandler
- return SystemViewHandler(iface)
+ self.assertNotEqual(derived_view, None)
+ self.assertEqual(derived_view(None, None), 'OK')
+ self.assertEqual(derived_view.__name__, 'bwcompat_view')
- def test_no_view_no_renderer(self):
- handler = self._makeOne(IDummy)
- from repoze.bfg.exceptions import ConfigurationError
- context = DummyContext()
- handler(context)
- actions = context.actions
- self.assertEqual(len(actions), 1)
- regadapt = actions[0]
- self.assertEqual(regadapt['discriminator'], IDummy)
- register = regadapt['callable']
- self.assertRaises(ConfigurationError, register)
-
- def test_no_view_with_renderer(self):
+ def test_it_with_dotted_renderer(self):
+ from zope.interface import implementedBy
from repoze.bfg.threadlocal import get_current_registry
- from repoze.bfg.interfaces import IRendererFactory
- reg = get_current_registry()
- def renderer(path):
- return lambda *arg: 'OK'
- reg.registerUtility(renderer, IRendererFactory, name='dummy')
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
+ from repoze.bfg.exceptions import Forbidden
+ from repoze.bfg.configuration import Configurator
context = DummyContext()
- handler = self._makeOne(IDummy)
- handler(context, renderer='dummy')
- actions = context.actions
- self.assertEqual(len(actions), 1)
- regadapt = actions[0]
- self.assertEqual(regadapt['discriminator'], IDummy)
- register = regadapt['callable']
- register()
- derived_view = reg.getUtility(IDummy)
- request = DummyRequest()
- self.assertEqual(derived_view(None, request).body, 'OK')
-
- def test_template_renderer(self):
- from repoze.bfg.threadlocal import get_current_registry
- from repoze.bfg.interfaces import IRendererFactory
reg = get_current_registry()
- def renderer(path):
- return lambda *arg: 'OK'
- reg.registerUtility(renderer, IRendererFactory, name='.pt')
- context = DummyContext()
- handler = self._makeOne(IDummy)
- handler(context, renderer='fixtures/minimal.pt')
+ config = Configurator(reg)
+ def dummy_renderer_factory(*arg, **kw):
+ return lambda *arg, **kw: 'OK'
+ config.add_renderer('.pt', dummy_renderer_factory)
+ def view(request):
+ return {}
+ self._callFUT(context, view, renderer='fake.pt')
actions = context.actions
- self.assertEqual(len(actions), 1)
regadapt = actions[0]
- self.assertEqual(regadapt['discriminator'], IDummy)
register = regadapt['callable']
register()
- derived_view = reg.getUtility(IDummy)
- request = DummyRequest()
- self.assertEqual(derived_view(None, request).body, 'OK')
+ derived_view = reg.adapters.lookup(
+ (IViewClassifier, IRequest, implementedBy(Forbidden)),
+ IView, default=None)
+ self.assertNotEqual(derived_view, None)
+ self.assertEqual(derived_view(None, None).body, 'OK')
+ self.assertEqual(derived_view.__name__, 'bwcompat_view')
class TestRepozeWho1AuthenticationPolicyDirective(unittest.TestCase):
def setUp(self):
@@ -506,6 +531,7 @@ class TestRouteDirective(unittest.TestCase):
from repoze.bfg.threadlocal import get_current_registry
from zope.interface import Interface
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRouteRequest
context = DummyContext()
view = lambda *arg: 'OK'
@@ -526,12 +552,14 @@ class TestRouteDirective(unittest.TestCase):
view_discriminator = view_action['discriminator']
discrim = ('view', None, '', None, IView, 'name', None)
self.assertEqual(view_discriminator, discrim)
- wrapped = reg.adapters.lookup((request_type, Interface), IView, name='')
+ wrapped = reg.adapters.lookup(
+ (IViewClassifier, request_type, Interface), IView, name='')
self.failUnless(wrapped)
def test_with_view_and_view_context(self):
from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRouteRequest
context = DummyContext()
view = lambda *arg: 'OK'
@@ -552,12 +580,14 @@ class TestRouteDirective(unittest.TestCase):
view_discriminator = view_action['discriminator']
discrim = ('view', IDummy, '', None, IView, 'name', None)
self.assertEqual(view_discriminator, discrim)
- wrapped = reg.adapters.lookup((request_type, IDummy), IView, name='')
+ wrapped = reg.adapters.lookup(
+ (IViewClassifier, request_type, IDummy), IView, name='')
self.failUnless(wrapped)
def test_with_view_context_trumps_view_for(self):
from repoze.bfg.threadlocal import get_current_registry
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRouteRequest
context = DummyContext()
view = lambda *arg: 'OK'
@@ -581,7 +611,8 @@ class TestRouteDirective(unittest.TestCase):
view_discriminator = view_action['discriminator']
discrim = ('view', IDummy, '', None, IView, 'name', None)
self.assertEqual(view_discriminator, discrim)
- wrapped = reg.adapters.lookup((request_type, IDummy), IView, name='')
+ wrapped = reg.adapters.lookup(
+ (IViewClassifier, request_type, IDummy), IView, name='')
self.failUnless(wrapped)
def test_with_dotted_renderer(self):
@@ -589,9 +620,8 @@ class TestRouteDirective(unittest.TestCase):
from repoze.bfg.threadlocal import get_current_registry
from zope.interface import Interface
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRouteRequest
-
-
from repoze.bfg.interfaces import IRendererFactory
reg = get_current_registry()
def renderer(path):
@@ -617,7 +647,8 @@ class TestRouteDirective(unittest.TestCase):
view_discriminator = view_action['discriminator']
discrim = ('view', None, '', None, IView, 'name', None)
self.assertEqual(view_discriminator, discrim)
- wrapped = reg.adapters.lookup((request_type, Interface), IView, name='')
+ wrapped = reg.adapters.lookup(
+ (IViewClassifier, request_type, Interface), IView, name='')
self.failUnless(wrapped)
request = DummyRequest()
result = wrapped(None, request)
@@ -658,6 +689,7 @@ class TestStaticDirective(unittest.TestCase):
from zope.interface import implementedBy
from repoze.bfg.static import StaticRootFactory
from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IViewClassifier
from repoze.bfg.interfaces import IRouteRequest
from repoze.bfg.interfaces import IRoutesMapper
context = DummyContext()
@@ -684,7 +716,8 @@ class TestStaticDirective(unittest.TestCase):
self.assertEqual(discriminator[4], IView)
iface = implementedBy(StaticRootFactory)
request_type = reg.getUtility(IRouteRequest, 'name')
- view = reg.adapters.lookup((request_type, iface), IView, name='')
+ view = reg.adapters.lookup(
+ (IViewClassifier, request_type, iface), IView, name='')
request = DummyRequest()
self.assertEqual(view(None, request).__class__, PackageURLParser)