summaryrefslogtreecommitdiff
path: root/tests/test_router.py
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2018-10-14 21:11:41 -0500
committerMichael Merickel <michael@merickel.org>2018-10-14 21:11:41 -0500
commit3670c2cdb732d378ba6d38e72e7cd875ff726aa9 (patch)
tree5213452a778c992d42602efe7d3b3655a349abd5 /tests/test_router.py
parent2b024920847481592b1a13d4006d2a9fa8881d72 (diff)
downloadpyramid-3670c2cdb732d378ba6d38e72e7cd875ff726aa9.tar.gz
pyramid-3670c2cdb732d378ba6d38e72e7cd875ff726aa9.tar.bz2
pyramid-3670c2cdb732d378ba6d38e72e7cd875ff726aa9.zip
move tests out of the package
Diffstat (limited to 'tests/test_router.py')
-rw-r--r--tests/test_router.py1410
1 files changed, 1410 insertions, 0 deletions
diff --git a/tests/test_router.py b/tests/test_router.py
new file mode 100644
index 000000000..6097018f0
--- /dev/null
+++ b/tests/test_router.py
@@ -0,0 +1,1410 @@
+import unittest
+
+from pyramid import testing
+
+class TestRouter(unittest.TestCase):
+ def setUp(self):
+ self.config = testing.setUp()
+ self.registry = self.config.registry
+
+ def tearDown(self):
+ testing.tearDown()
+
+ def _registerRouteRequest(self, name):
+ from pyramid.interfaces import IRouteRequest
+ from pyramid.request import route_request_iface
+ iface = route_request_iface(name)
+ self.registry.registerUtility(iface, IRouteRequest, name=name)
+ return iface
+
+ def _connectRoute(self, name, path, factory=None):
+ from pyramid.interfaces import IRoutesMapper
+ from pyramid.urldispatch import RoutesMapper
+ mapper = self.registry.queryUtility(IRoutesMapper)
+ if mapper is None:
+ mapper = RoutesMapper()
+ self.registry.registerUtility(mapper, IRoutesMapper)
+ return mapper.connect(name, path, factory)
+
+ def _registerLogger(self):
+ from pyramid.interfaces import IDebugLogger
+ logger = DummyLogger()
+ self.registry.registerUtility(logger, IDebugLogger)
+ return logger
+
+ def _registerSettings(self, **kw):
+ settings = {'debug_authorization':False,
+ 'debug_notfound':False,
+ 'debug_routematch':False}
+ settings.update(kw)
+ self.registry.settings = settings
+
+ def _registerTraverserFactory(self, context, view_name='', subpath=None,
+ traversed=None, virtual_root=None,
+ virtual_root_path=None, raise_error=None,
+ **kw):
+ from pyramid.interfaces import ITraverser
+
+ if virtual_root is None:
+ virtual_root = context
+ if subpath is None:
+ subpath = []
+ if traversed is None:
+ traversed = []
+ if virtual_root_path is None:
+ virtual_root_path = []
+
+ class DummyTraverserFactory:
+ def __init__(self, root):
+ self.root = root
+
+ def __call__(self, request):
+ if raise_error:
+ raise raise_error
+ values = {'root':self.root,
+ 'context':context,
+ 'view_name':view_name,
+ 'subpath':subpath,
+ 'traversed':traversed,
+ 'virtual_root':virtual_root,
+ 'virtual_root_path':virtual_root_path}
+ kw.update(values)
+ return kw
+
+ self.registry.registerAdapter(DummyTraverserFactory, (None,),
+ ITraverser, name='')
+
+ def _registerView(self, app, name, classifier, req_iface, ctx_iface):
+ from pyramid.interfaces import IView
+ self.registry.registerAdapter(
+ app, (classifier, req_iface, ctx_iface), IView, name)
+
+ def _registerEventListener(self, iface):
+ L = []
+ def listener(event):
+ L.append(event)
+ self.registry.registerHandler(listener, (iface,))
+ return L
+
+ def _registerRootFactory(self, val):
+ rootfactory = DummyRootFactory(val)
+ from pyramid.interfaces import IRootFactory
+ self.registry.registerUtility(rootfactory, IRootFactory)
+ return rootfactory
+
+ def _getTargetClass(self):
+ from pyramid.router import Router
+ return Router
+
+ def _makeOne(self):
+ klass = self._getTargetClass()
+ return klass(self.registry)
+
+ def _makeEnviron(self, **extras):
+ environ = {
+ 'wsgi.url_scheme':'http',
+ 'SERVER_NAME':'localhost',
+ 'SERVER_PORT':'8080',
+ 'REQUEST_METHOD':'GET',
+ 'PATH_INFO':'/',
+ }
+ environ.update(extras)
+ return environ
+
+ def test_ctor_registry_has_no_settings(self):
+ self.registry.settings = None
+ router = self._makeOne()
+ self.assertEqual(router.debug_notfound, False)
+ self.assertEqual(router.debug_routematch, False)
+ self.assertFalse('debug_notfound' in router.__dict__)
+ self.assertFalse('debug_routematch' in router.__dict__)
+
+ def test_root_policy(self):
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ rootfactory = self._registerRootFactory('abc')
+ router = self._makeOne()
+ self.assertEqual(router.root_policy, rootfactory)
+
+ def test_request_factory(self):
+ from pyramid.interfaces import IRequestFactory
+ class DummyRequestFactory(object):
+ pass
+ self.registry.registerUtility(DummyRequestFactory, IRequestFactory)
+ router = self._makeOne()
+ self.assertEqual(router.request_factory, DummyRequestFactory)
+
+ def test_tween_factories(self):
+ from pyramid.interfaces import ITweens
+ from pyramid.config.tweens import Tweens
+ from pyramid.response import Response
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IResponse
+ tweens = Tweens()
+ self.registry.registerUtility(tweens, ITweens)
+ L = []
+ def tween_factory1(handler, registry):
+ L.append((handler, registry))
+ def wrapper(request):
+ request.environ['handled'].append('one')
+ return handler(request)
+ wrapper.name = 'one'
+ wrapper.child = handler
+ return wrapper
+ def tween_factory2(handler, registry):
+ L.append((handler, registry))
+ def wrapper(request):
+ request.environ['handled'] = ['two']
+ return handler(request)
+ wrapper.name = 'two'
+ wrapper.child = handler
+ return wrapper
+ tweens.add_implicit('one', tween_factory1)
+ tweens.add_implicit('two', tween_factory2)
+ router = self._makeOne()
+ self.assertEqual(router.handle_request.name, 'two')
+ self.assertEqual(router.handle_request.child.name, 'one')
+ self.assertEqual(router.handle_request.child.child.__name__,
+ 'handle_request')
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ environ = self._makeEnviron()
+ view = DummyView('abc')
+ self._registerView(self.config.derive_view(view), '',
+ IViewClassifier, None, None)
+ start_response = DummyStartResponse()
+ def make_response(s):
+ return Response(s)
+ router.registry.registerAdapter(make_response, (str,), IResponse)
+ app_iter = router(environ, start_response)
+ self.assertEqual(app_iter, [b'abc'])
+ self.assertEqual(start_response.status, '200 OK')
+ self.assertEqual(environ['handled'], ['two', 'one'])
+
+ def test_call_traverser_default(self):
+ from pyramid.httpexceptions import HTTPNotFound
+ environ = self._makeEnviron()
+ logger = self._registerLogger()
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPNotFound, router, environ, start_response)
+ self.assertTrue('/' in why.args[0], why)
+ self.assertFalse('debug_notfound' in why.args[0])
+ self.assertEqual(len(logger.messages), 0)
+
+ def test_traverser_raises_notfound_class(self):
+ from pyramid.httpexceptions import HTTPNotFound
+ environ = self._makeEnviron()
+ context = DummyContext()
+ self._registerTraverserFactory(context, raise_error=HTTPNotFound)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(HTTPNotFound, router, environ, start_response)
+
+ def test_traverser_raises_notfound_instance(self):
+ from pyramid.httpexceptions import HTTPNotFound
+ environ = self._makeEnviron()
+ context = DummyContext()
+ self._registerTraverserFactory(context, raise_error=HTTPNotFound('foo'))
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPNotFound, router, environ, start_response)
+ self.assertTrue('foo' in why.args[0], why)
+
+ def test_traverser_raises_forbidden_class(self):
+ from pyramid.httpexceptions import HTTPForbidden
+ environ = self._makeEnviron()
+ context = DummyContext()
+ self._registerTraverserFactory(context, raise_error=HTTPForbidden)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(HTTPForbidden, router, environ, start_response)
+
+ def test_traverser_raises_forbidden_instance(self):
+ from pyramid.httpexceptions import HTTPForbidden
+ environ = self._makeEnviron()
+ context = DummyContext()
+ self._registerTraverserFactory(context,
+ raise_error=HTTPForbidden('foo'))
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPForbidden, router, environ, start_response)
+ self.assertTrue('foo' in why.args[0], why)
+
+ def test_call_no_view_registered_no_isettings(self):
+ from pyramid.httpexceptions import HTTPNotFound
+ environ = self._makeEnviron()
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ logger = self._registerLogger()
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPNotFound, router, environ, start_response)
+ self.assertTrue('/' in why.args[0], why)
+ self.assertFalse('debug_notfound' in why.args[0])
+ self.assertEqual(len(logger.messages), 0)
+
+ def test_call_no_view_registered_debug_notfound_false(self):
+ from pyramid.httpexceptions import HTTPNotFound
+ environ = self._makeEnviron()
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ logger = self._registerLogger()
+ self._registerSettings(debug_notfound=False)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPNotFound, router, environ, start_response)
+ self.assertTrue('/' in why.args[0], why)
+ self.assertFalse('debug_notfound' in why.args[0])
+ self.assertEqual(len(logger.messages), 0)
+
+ def test_call_no_view_registered_debug_notfound_true(self):
+ from pyramid.httpexceptions import HTTPNotFound
+ environ = self._makeEnviron()
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ self._registerSettings(debug_notfound=True)
+ logger = self._registerLogger()
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPNotFound, router, environ, start_response)
+ self.assertTrue(
+ "debug_notfound of url http://localhost:8080/; " in why.args[0])
+ self.assertTrue("view_name: '', subpath: []" in why.args[0])
+ self.assertTrue('http://localhost:8080' in why.args[0], why)
+
+ self.assertEqual(len(logger.messages), 1)
+ message = logger.messages[0]
+ self.assertTrue('of url http://localhost:8080' in message)
+ self.assertTrue("path_info: " in message)
+ self.assertTrue('DummyContext' in message)
+ self.assertTrue("view_name: ''" in message)
+ self.assertTrue("subpath: []" in message)
+
+ def test_call_view_returns_non_iresponse(self):
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ environ = self._makeEnviron()
+ view = DummyView('abc')
+ self._registerView(self.config.derive_view(view), '', IViewClassifier,
+ None, None)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(ValueError, router, environ, start_response)
+
+ def test_call_view_returns_adapted_response(self):
+ from pyramid.response import Response
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IResponse
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ environ = self._makeEnviron()
+ view = DummyView('abc')
+ self._registerView(self.config.derive_view(view), '',
+ IViewClassifier, None, None)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ def make_response(s):
+ return Response(s)
+ router.registry.registerAdapter(make_response, (str,), IResponse)
+ app_iter = router(environ, start_response)
+ self.assertEqual(app_iter, [b'abc'])
+ self.assertEqual(start_response.status, '200 OK')
+
+ def test_call_with_request_extensions(self):
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IRequestExtensions
+ from pyramid.interfaces import IRequest
+ from pyramid.request import Request
+ from pyramid.util import InstancePropertyHelper
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ class Extensions(object):
+ def __init__(self):
+ self.methods = {}
+ self.descriptors = {}
+ extensions = Extensions()
+ ext_method = lambda r: 'bar'
+ name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')
+ extensions.descriptors[name] = fn
+ request = Request.blank('/')
+ request.request_iface = IRequest
+ request.registry = self.registry
+ def request_factory(environ):
+ return request
+ self.registry.registerUtility(extensions, IRequestExtensions)
+ environ = self._makeEnviron()
+ response = DummyResponse()
+ response.app_iter = ['Hello world']
+ view = DummyView(response)
+ self._registerView(self.config.derive_view(view), '',
+ IViewClassifier, None, None)
+ router = self._makeOne()
+ router.request_factory = request_factory
+ start_response = DummyStartResponse()
+ router(environ, start_response)
+ self.assertEqual(view.request.foo, 'bar')
+
+ def test_call_view_registered_nonspecific_default_path(self):
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ response = DummyResponse()
+ response.app_iter = ['Hello world']
+ view = DummyView(response)
+ environ = self._makeEnviron()
+ self._registerView(self.config.derive_view(view), '',
+ IViewClassifier, None, None)
+ self._registerRootFactory(context)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, ['Hello world'])
+ self.assertEqual(start_response.headers, ())
+ self.assertEqual(start_response.status, '200 OK')
+ request = view.request
+ self.assertEqual(request.view_name, '')
+ self.assertEqual(request.subpath, [])
+ self.assertEqual(request.context, context)
+ self.assertEqual(request.root, context)
+
+ def test_call_view_registered_nonspecific_nondefault_path_and_subpath(self):
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ self._registerTraverserFactory(context, view_name='foo',
+ subpath=['bar'],
+ traversed=['context'])
+ self._registerRootFactory(context)
+ response = DummyResponse()
+ response.app_iter = ['Hello world']
+ view = DummyView(response)
+ environ = self._makeEnviron()
+ self._registerView(view, 'foo', IViewClassifier, None, None)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, ['Hello world'])
+ self.assertEqual(start_response.headers, ())
+ self.assertEqual(start_response.status, '200 OK')
+ request = view.request
+ self.assertEqual(request.view_name, 'foo')
+ self.assertEqual(request.subpath, ['bar'])
+ self.assertEqual(request.context, context)
+ self.assertEqual(request.root, context)
+
+ def test_call_view_registered_specific_success(self):
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ class IContext(Interface):
+ pass
+ from pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ self._registerTraverserFactory(context)
+ self._registerRootFactory(context)
+ response = DummyResponse()
+ response.app_iter = ['Hello world']
+ view = DummyView(response)
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, ['Hello world'])
+ self.assertEqual(start_response.headers, ())
+ self.assertEqual(start_response.status, '200 OK')
+ request = view.request
+ self.assertEqual(request.view_name, '')
+ self.assertEqual(request.subpath, [])
+ self.assertEqual(request.context, context)
+ self.assertEqual(request.root, context)
+
+ def test_call_view_registered_specific_fail(self):
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ from pyramid.httpexceptions import HTTPNotFound
+ from pyramid.interfaces import IViewClassifier
+ class IContext(Interface):
+ pass
+ class INotContext(Interface):
+ pass
+ from pyramid.interfaces import IRequest
+ context = DummyContext()
+ directlyProvides(context, INotContext)
+ self._registerTraverserFactory(context, subpath=[''])
+ response = DummyResponse()
+ view = DummyView(response)
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(HTTPNotFound, router, environ, start_response)
+
+ def test_call_view_raises_forbidden(self):
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ from pyramid.httpexceptions import HTTPForbidden
+ class IContext(Interface):
+ pass
+ from pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ self._registerTraverserFactory(context, subpath=[''])
+ response = DummyResponse()
+ view = DummyView(response,
+ raise_exception=HTTPForbidden("unauthorized"))
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPForbidden, router, environ, start_response)
+ self.assertEqual(why.args[0], 'unauthorized')
+
+ def test_call_view_raises_notfound(self):
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ class IContext(Interface):
+ pass
+ from pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.httpexceptions import HTTPNotFound
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ self._registerTraverserFactory(context, subpath=[''])
+ response = DummyResponse()
+ view = DummyView(response, raise_exception=HTTPNotFound("notfound"))
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPNotFound, router, environ, start_response)
+ self.assertEqual(why.args[0], 'notfound')
+
+ def test_call_view_raises_response_cleared(self):
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ from pyramid.interfaces import IExceptionViewClassifier
+ class IContext(Interface):
+ pass
+ from pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ self._registerTraverserFactory(context, subpath=[''])
+ def view(context, request):
+ request.response.a = 1
+ raise KeyError
+ def exc_view(context, request):
+ self.assertFalse(hasattr(request.response, 'a'))
+ request.response.body = b'OK'
+ return request.response
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ self._registerView(exc_view, '', IExceptionViewClassifier,
+ IRequest, KeyError)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ itera = router(environ, start_response)
+ self.assertEqual(itera, [b'OK'])
+
+ def test_call_request_has_response_callbacks(self):
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ class IContext(Interface):
+ pass
+ from pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ self._registerTraverserFactory(context, subpath=[''])
+ response = DummyResponse('200 OK')
+ def view(context, request):
+ def callback(request, response):
+ response.called_back = True
+ request.add_response_callback(callback)
+ return response
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ router(environ, start_response)
+ self.assertEqual(response.called_back, True)
+
+ def test_call_request_has_finished_callbacks_when_view_succeeds(self):
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ class IContext(Interface):
+ pass
+ from pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ self._registerTraverserFactory(context, subpath=[''])
+ response = DummyResponse('200 OK')
+ def view(context, request):
+ def callback(request):
+ request.environ['called_back'] = True
+ request.add_finished_callback(callback)
+ return response
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ router(environ, start_response)
+ self.assertEqual(environ['called_back'], True)
+
+ def test_call_request_has_finished_callbacks_when_view_raises(self):
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ class IContext(Interface):
+ pass
+ from pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ self._registerTraverserFactory(context, subpath=[''])
+ def view(context, request):
+ def callback(request):
+ request.environ['called_back'] = True
+ request.add_finished_callback(callback)
+ raise NotImplementedError
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ exc_raised(NotImplementedError, router, environ, start_response)
+ self.assertEqual(environ['called_back'], True)
+
+ def test_call_request_factory_raises(self):
+ # making sure finally doesnt barf when a request cannot be created
+ environ = self._makeEnviron()
+ router = self._makeOne()
+ def dummy_request_factory(environ):
+ raise NotImplementedError
+ router.request_factory = dummy_request_factory
+ start_response = DummyStartResponse()
+ exc_raised(NotImplementedError, router, environ, start_response)
+
+ def test_call_eventsends(self):
+ from pyramid.interfaces import INewRequest
+ from pyramid.interfaces import INewResponse
+ from pyramid.interfaces import IBeforeTraversal
+ from pyramid.interfaces import IContextFound
+ from pyramid.interfaces import IViewClassifier
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ response = DummyResponse()
+ response.app_iter = ['Hello world']
+ view = DummyView(response)
+ environ = self._makeEnviron()
+ self._registerView(view, '', IViewClassifier, None, None)
+ request_events = self._registerEventListener(INewRequest)
+ beforetraversal_events = self._registerEventListener(IBeforeTraversal)
+ context_found_events = self._registerEventListener(IContextFound)
+ response_events = self._registerEventListener(INewResponse)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(len(request_events), 1)
+ self.assertEqual(request_events[0].request.environ, environ)
+ self.assertEqual(len(beforetraversal_events), 1)
+ self.assertEqual(beforetraversal_events[0].request.environ, environ)
+ self.assertEqual(len(context_found_events), 1)
+ self.assertEqual(context_found_events[0].request.environ, environ)
+ self.assertEqual(context_found_events[0].request.context, context)
+ self.assertEqual(len(response_events), 1)
+ self.assertEqual(response_events[0].response, response)
+ self.assertEqual(response_events[0].request.context, context)
+ self.assertEqual(result, response.app_iter)
+
+ def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):
+ from pyramid.interfaces import INewRequest
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.interfaces import IRequest
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ environ = self._makeEnviron()
+ def listener(event):
+ raise KeyError
+ self.registry.registerHandler(listener, (INewRequest,))
+ exception_response = DummyResponse()
+ exception_response.app_iter = ["Hello, world"]
+ exception_view = DummyView(exception_response)
+ environ = self._makeEnviron()
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, KeyError)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, exception_response.app_iter)
+
+ def test_call_route_matches_and_has_factory(self):
+ from pyramid.interfaces import IViewClassifier
+ logger = self._registerLogger()
+ self._registerSettings(debug_routematch=True)
+ self._registerRouteRequest('foo')
+ root = object()
+ def factory(request):
+ return root
+ route = self._connectRoute('foo', 'archives/:action/:article', factory)
+ route.predicates = [DummyPredicate()]
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ response = DummyResponse()
+ response.app_iter = ['Hello world']
+ view = DummyView(response)
+ environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
+ self._registerView(view, '', IViewClassifier, None, None)
+ self._registerRootFactory(context)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, ['Hello world'])
+ self.assertEqual(start_response.headers, ())
+ self.assertEqual(start_response.status, '200 OK')
+ request = view.request
+ self.assertEqual(request.view_name, '')
+ self.assertEqual(request.subpath, [])
+ self.assertEqual(request.context, context)
+ self.assertEqual(request.root, root)
+ matchdict = {'action':'action1', 'article':'article1'}
+ self.assertEqual(request.matchdict, matchdict)
+ self.assertEqual(request.matched_route.name, 'foo')
+ self.assertEqual(len(logger.messages), 1)
+ self.assertTrue(
+ logger.messages[0].startswith(
+ "route matched for url http://localhost:8080"
+ "/archives/action1/article1; "
+ "route_name: 'foo', "
+ "path_info: ")
+ )
+ self.assertTrue(
+ "predicates: 'predicate'" in logger.messages[0]
+ )
+
+ def test_call_route_match_miss_debug_routematch(self):
+ from pyramid.httpexceptions import HTTPNotFound
+ logger = self._registerLogger()
+ self._registerSettings(debug_routematch=True)
+ self._registerRouteRequest('foo')
+ self._connectRoute('foo', 'archives/:action/:article')
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ environ = self._makeEnviron(PATH_INFO='/wontmatch')
+ self._registerRootFactory(context)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(HTTPNotFound, router, environ, start_response)
+
+ self.assertEqual(len(logger.messages), 1)
+ self.assertEqual(
+ logger.messages[0],
+ 'no route matched for url http://localhost:8080/wontmatch')
+
+ def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):
+ from pyramid.interfaces import INewRequest
+ from pyramid.interfaces import IViewClassifier
+ from zope.interface import alsoProvides
+ from zope.interface import Interface
+ self._registerRouteRequest('foo')
+ class IFoo(Interface):
+ pass
+ def listener(event):
+ alsoProvides(event.request, IFoo)
+ self.registry.registerHandler(listener, (INewRequest,))
+ root = object()
+ def factory(request):
+ return root
+ self._connectRoute('foo', 'archives/:action/:article', factory)
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ response = DummyResponse()
+ response.app_iter = ['Hello world']
+ view = DummyView(response)
+ environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
+ self._registerView(view, '', IViewClassifier, None, None)
+ self._registerRootFactory(context)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, ['Hello world'])
+ self.assertEqual(start_response.headers, ())
+ self.assertEqual(start_response.status, '200 OK')
+ request = view.request
+ self.assertEqual(request.view_name, '')
+ self.assertEqual(request.subpath, [])
+ self.assertEqual(request.context, context)
+ self.assertEqual(request.root, root)
+ matchdict = {'action':'action1', 'article':'article1'}
+ self.assertEqual(request.matchdict, matchdict)
+ self.assertEqual(request.matched_route.name, 'foo')
+ self.assertTrue(IFoo.providedBy(request))
+
+ def test_root_factory_raises_notfound(self):
+ from pyramid.interfaces import IRootFactory
+ from pyramid.httpexceptions import HTTPNotFound
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ def rootfactory(request):
+ raise HTTPNotFound('from root factory')
+ self.registry.registerUtility(rootfactory, IRootFactory)
+ class IContext(Interface):
+ pass
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ environ = self._makeEnviron()
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPNotFound, router, environ, start_response)
+ self.assertTrue('from root factory' in why.args[0])
+
+ def test_root_factory_raises_forbidden(self):
+ from pyramid.interfaces import IRootFactory
+ from pyramid.httpexceptions import HTTPForbidden
+ from zope.interface import Interface
+ from zope.interface import directlyProvides
+ def rootfactory(request):
+ raise HTTPForbidden('from root factory')
+ self.registry.registerUtility(rootfactory, IRootFactory)
+ class IContext(Interface):
+ pass
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ environ = self._makeEnviron()
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ why = exc_raised(HTTPForbidden, router, environ, start_response)
+ self.assertTrue('from root factory' in why.args[0])
+
+ def test_root_factory_exception_propagating(self):
+ from pyramid.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 pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IRequestFactory
+ from pyramid.interfaces import IExceptionViewClassifier
+ def rfactory(environ):
+ return request
+ self.registry.registerUtility(rfactory, IRequestFactory)
+ from pyramid.request import Request
+ request = Request.blank('/')
+ context = DummyContext()
+ directlyProvides(context, IContext)
+ self._registerTraverserFactory(context, subpath=[''])
+ response = DummyResponse()
+ response.app_iter = ['OK']
+ error = RuntimeError()
+ view = DummyView(response, raise_exception=error)
+ environ = self._makeEnviron()
+ def exception_view(context, request):
+ self.assertEqual(request.exc_info[0], RuntimeError)
+ return response
+ self._registerView(view, '', IViewClassifier, IRequest, IContext)
+ self._registerView(exception_view, '', IExceptionViewClassifier,
+ IRequest, RuntimeError)
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ result = router(environ, start_response)
+ self.assertEqual(result, ['OK'])
+ # exc_info and exception should still be around on the request after
+ # the excview tween has run (see
+ # https://github.com/Pylons/pyramid/issues/1223)
+ self.assertEqual(request.exception, error)
+ self.assertEqual(request.exc_info[:2], (RuntimeError, error,))
+
+ def test_call_view_raises_exception_view(self):
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.interfaces import IRequest
+ response = DummyResponse()
+ exception_response = DummyResponse()
+ exception_response.app_iter = ["Hello, world"]
+ view = DummyView(response, raise_exception=RuntimeError)
+ def exception_view(context, request):
+ self.assertEqual(request.exception.__class__, RuntimeError)
+ return 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"])
+
+ def test_call_view_raises_super_exception_sub_exception_view(self):
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.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 pyramid.interfaces import IRootFactory
+ from pyramid.interfaces import IRequest
+ from pyramid.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(app_iter, ["Hello, world"])
+
+ def test_traverser_raises_exception_view(self):
+ from pyramid.interfaces import IRequest
+ from pyramid.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_iresponse(self):
+ from pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ environ = self._makeEnviron()
+ response = DummyResponse()
+ view = DummyView(response, raise_exception=RuntimeError)
+
+ self._registerView(self.config.derive_view(view), '',
+ IViewClassifier, IRequest, None)
+ exception_view = DummyView(None)
+ self._registerView(self.config.derive_view(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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('foo', 'archives/:action/:article', 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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.interfaces import IRequest
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('foo', 'archives/:action/:article', 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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.interfaces import IRequest
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('foo', 'archives/:action/:article', 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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.interfaces import IRequest
+ class SuperException(Exception):
+ pass
+ class SubException(SuperException):
+ pass
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('foo', 'archives/:action/:article', 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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.interfaces import IRequest
+ class SuperException(Exception):
+ pass
+ class SubException(SuperException):
+ pass
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('foo', 'archives/:action/:article', 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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.interfaces import IRequest
+ class MyException(Exception):
+ pass
+ class AnotherException(Exception):
+ pass
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('foo', 'archives/:action/:article', 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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.interfaces import IRequest
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('foo', 'archives/:action/:article', 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 pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ req_iface = self._registerRouteRequest('foo')
+ another_req_iface = self._registerRouteRequest('bar')
+ self._connectRoute('foo', 'archives/:action/:article', 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 pyramid.interfaces import IRequest
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.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)
+
+ def test_call_view_raises_predicate_mismatch(self):
+ from pyramid.exceptions import PredicateMismatch
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IRequest
+ view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)
+ self._registerView(view, '', IViewClassifier, IRequest, None)
+ environ = self._makeEnviron()
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(PredicateMismatch, router, environ, start_response)
+
+ def test_call_view_predicate_mismatch_doesnt_hide_views(self):
+ from pyramid.exceptions import PredicateMismatch
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IRequest, IResponse
+ from pyramid.response import Response
+ class BaseContext:
+ pass
+ class DummyContext(BaseContext):
+ pass
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)
+ self._registerView(view, '', IViewClassifier, IRequest,
+ DummyContext)
+ good_view = DummyView('abc')
+ self._registerView(self.config.derive_view(good_view),
+ '', IViewClassifier, IRequest, BaseContext)
+ router = self._makeOne()
+ def make_response(s):
+ return Response(s)
+ router.registry.registerAdapter(make_response, (str,), IResponse)
+ environ = self._makeEnviron()
+ start_response = DummyStartResponse()
+ app_iter = router(environ, start_response)
+ self.assertEqual(app_iter, [b'abc'])
+
+ def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):
+ from pyramid.exceptions import PredicateMismatch
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IRequest, IResponse
+ from pyramid.response import Response
+ from zope.interface import Interface, implementer
+ class IBaseContext(Interface):
+ pass
+ class IContext(IBaseContext):
+ pass
+ @implementer(IContext)
+ class DummyContext:
+ pass
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)
+ self._registerView(view1, '', IViewClassifier, IRequest,
+ DummyContext)
+ view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)
+ self._registerView(view2, '', IViewClassifier, IRequest,
+ IContext)
+ good_view = DummyView('abc')
+ self._registerView(self.config.derive_view(good_view),
+ '', IViewClassifier, IRequest, IBaseContext)
+ router = self._makeOne()
+ def make_response(s):
+ return Response(s)
+ router.registry.registerAdapter(make_response, (str,), IResponse)
+ environ = self._makeEnviron()
+ start_response = DummyStartResponse()
+ app_iter = router(environ, start_response)
+ self.assertEqual(app_iter, [b'abc'])
+
+ def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):
+ from pyramid.exceptions import PredicateMismatch
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IRequest
+ from zope.interface import Interface, implementer
+ class IContext(Interface):
+ pass
+ class IOtherContext(Interface):
+ pass
+ @implementer(IContext)
+ class DummyContext:
+ pass
+ context = DummyContext()
+ self._registerTraverserFactory(context)
+ view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)
+ self._registerView(view, '', IViewClassifier, IRequest,
+ DummyContext)
+ please_dont_call_me_view = DummyView('abc')
+ self._registerView(self.config.derive_view(please_dont_call_me_view),
+ '', IViewClassifier, IRequest, IOtherContext)
+ router = self._makeOne()
+ environ = self._makeEnviron()
+ router = self._makeOne()
+ start_response = DummyStartResponse()
+ self.assertRaises(PredicateMismatch, router, environ, start_response)
+
+ def test_custom_execution_policy(self):
+ from pyramid.interfaces import IExecutionPolicy
+ from pyramid.request import Request
+ from pyramid.response import Response
+ registry = self.config.registry
+ def dummy_policy(environ, router):
+ return Response(status=200, body=b'foo')
+ registry.registerUtility(dummy_policy, IExecutionPolicy)
+ router = self._makeOne()
+ resp = Request.blank('/').get_response(router)
+ self.assertEqual(resp.status_code, 200)
+ self.assertEqual(resp.body, b'foo')
+
+ def test_execution_policy_handles_exception(self):
+ from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import IExceptionViewClassifier
+ from pyramid.interfaces import IRequest
+ class Exception1(Exception):
+ pass
+ class Exception2(Exception):
+ pass
+ req_iface = self._registerRouteRequest('foo')
+ self._connectRoute('foo', 'archives/:action/:article', None)
+ view = DummyView(DummyResponse(), raise_exception=Exception1)
+ self._registerView(view, '', IViewClassifier, req_iface, None)
+ exception_view1 = DummyView(DummyResponse(),
+ raise_exception=Exception2)
+ self._registerView(exception_view1, '', IExceptionViewClassifier,
+ IRequest, Exception1)
+ response = DummyResponse()
+ response.app_iter = ["Hello, world"]
+ exception_view2 = DummyView(response)
+ self._registerView(exception_view2, '', IExceptionViewClassifier,
+ IRequest, Exception2)
+ 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_request_context_with_statement(self):
+ from pyramid.threadlocal import get_current_request
+ from pyramid.interfaces import IExecutionPolicy
+ from pyramid.request import Request
+ from pyramid.response import Response
+ registry = self.config.registry
+ result = []
+ def dummy_policy(environ, router):
+ with router.request_context(environ):
+ result.append(get_current_request())
+ result.append(get_current_request())
+ return Response(status=200, body=b'foo')
+ registry.registerUtility(dummy_policy, IExecutionPolicy)
+ router = self._makeOne()
+ resp = Request.blank('/test_path').get_response(router)
+ self.assertEqual(resp.status_code, 200)
+ self.assertEqual(resp.body, b'foo')
+ self.assertEqual(result[0].path_info, '/test_path')
+ self.assertEqual(result[1], None)
+
+ def test_request_context_manually(self):
+ from pyramid.threadlocal import get_current_request
+ from pyramid.interfaces import IExecutionPolicy
+ from pyramid.request import Request
+ from pyramid.response import Response
+ registry = self.config.registry
+ result = []
+ def dummy_policy(environ, router):
+ ctx = router.request_context(environ)
+ ctx.begin()
+ result.append(get_current_request())
+ ctx.end()
+ result.append(get_current_request())
+ return Response(status=200, body=b'foo')
+ registry.registerUtility(dummy_policy, IExecutionPolicy)
+ router = self._makeOne()
+ resp = Request.blank('/test_path').get_response(router)
+ self.assertEqual(resp.status_code, 200)
+ self.assertEqual(resp.body, b'foo')
+ self.assertEqual(result[0].path_info, '/test_path')
+ self.assertEqual(result[1], None)
+
+class DummyPredicate(object):
+ def __call__(self, info, request):
+ return True
+ def text(self):
+ return 'predicate'
+
+class DummyContext:
+ pass
+
+class DummyView:
+ def __init__(self, response, raise_exception=None):
+ self.response = response
+ self.raise_exception = raise_exception
+
+ def __call__(self, context, request):
+ self.context = context
+ self.request = request
+ if self.raise_exception is not None:
+ raise self.raise_exception
+ return self.response
+
+class DummyRootFactory:
+ def __init__(self, root):
+ self.root = root
+
+ def __call__(self, environ):
+ return self.root
+
+class DummyStartResponse:
+ status = ()
+ headers = ()
+ def __call__(self, status, headers):
+ self.status = status
+ self.headers = headers
+
+from pyramid.interfaces import IResponse
+from zope.interface import implementer
+
+@implementer(IResponse)
+class DummyResponse(object):
+ headerlist = ()
+ app_iter = ()
+ environ = None
+ def __init__(self, status='200 OK'):
+ self.status = status
+
+ def __call__(self, environ, start_response):
+ self.environ = environ
+ start_response(self.status, self.headerlist)
+ return self.app_iter
+
+class DummyAuthenticationPolicy:
+ pass
+
+class DummyLogger:
+ def __init__(self):
+ self.messages = []
+ def info(self, msg):
+ self.messages.append(msg)
+ warn = info
+ debug = info
+
+def exc_raised(exc, func, *arg, **kw):
+ try:
+ func(*arg, **kw)
+ except exc as e:
+ return e
+ else:
+ raise AssertionError('%s not raised' % exc) # pragma: no cover
+
+