import unittest from zope.interface import Interface from zope.interface import implementer import sys from pyramid import testing from pyramid.interfaces import IRequest from pyramid.interfaces import IResponse class BaseTest(object): def setUp(self): self.config = testing.setUp() def tearDown(self): testing.tearDown() def _registerView(self, reg, app, name): from pyramid.interfaces import IViewClassifier for_ = (IViewClassifier, IRequest, IContext) from pyramid.interfaces import IView reg.registerAdapter(app, for_, IView, name) def _makeEnviron(self, **extras): environ = { 'wsgi.url_scheme': 'http', 'wsgi.version': (1, 0), 'SERVER_NAME': 'localhost', 'SERVER_PORT': '8080', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/', } environ.update(extras) return environ def _makeRequest(self, **environ): from pyramid.request import Request from pyramid.registry import Registry environ = self._makeEnviron(**environ) request = Request(environ) request.registry = Registry() return request def _makeContext(self): from zope.interface import directlyProvides context = DummyContext() directlyProvides(context, IContext) return context class Test_notfound_view_config(BaseTest, unittest.TestCase): def _makeOne(self, **kw): from pyramid.view import notfound_view_config return notfound_view_config(**kw) def test_ctor(self): inst = self._makeOne( attr='attr', path_info='path_info', append_slash=True ) self.assertEqual( inst.__dict__, {'attr': 'attr', 'path_info': 'path_info', 'append_slash': True}, ) def test_it_function(self): def view(request): # pragma: no cover pass decorator = self._makeOne( attr='attr', renderer='renderer', append_slash=True ) venusian = DummyVenusian() decorator.venusian = venusian wrapped = decorator(view) self.assertTrue(wrapped is view) config = call_venusian(venusian) settings = config.settings self.assertEqual( settings, [ { 'attr': 'attr', 'venusian': venusian, 'append_slash': True, 'renderer': 'renderer', '_info': 'codeinfo', 'view': None, } ], ) def test_it_class(self): decorator = self._makeOne() venusian = DummyVenusian() decorator.venusian = venusian decorator.venusian.info.scope = 'class' class view(object): pass wrapped = decorator(view) self.assertTrue(wrapped is view) config = call_venusian(venusian) settings = config.settings self.assertEqual(len(settings), 1) self.assertEqual(len(settings[0]), 4) self.assertEqual(settings[0]['venusian'], venusian) self.assertEqual(settings[0]['view'], None) # comes from call_venusian self.assertEqual(settings[0]['attr'], 'view') self.assertEqual(settings[0]['_info'], 'codeinfo') def test_call_with_venusian_args(self): decorator = self._makeOne(_depth=1, _category='foo') venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass decorator(foo) attachments = venusian.attachments category = attachments[0][2] depth = attachments[0][3] self.assertEqual(depth, 2) self.assertEqual(category, 'foo') class Test_forbidden_view_config(BaseTest, unittest.TestCase): def _makeOne(self, **kw): from pyramid.view import forbidden_view_config return forbidden_view_config(**kw) def test_ctor(self): inst = self._makeOne(attr='attr', path_info='path_info') self.assertEqual( inst.__dict__, {'attr': 'attr', 'path_info': 'path_info'} ) def test_it_function(self): def view(request): # pragma: no cover pass decorator = self._makeOne(attr='attr', renderer='renderer') venusian = DummyVenusian() decorator.venusian = venusian wrapped = decorator(view) self.assertTrue(wrapped is view) config = call_venusian(venusian) settings = config.settings self.assertEqual( settings, [ { 'attr': 'attr', 'venusian': venusian, 'renderer': 'renderer', '_info': 'codeinfo', 'view': None, } ], ) def test_it_class(self): decorator = self._makeOne() venusian = DummyVenusian() decorator.venusian = venusian decorator.venusian.info.scope = 'class' class view(object): pass wrapped = decorator(view) self.assertTrue(wrapped is view) config = call_venusian(venusian) settings = config.settings self.assertEqual(len(settings), 1) self.assertEqual(len(settings[0]), 4) self.assertEqual(settings[0]['venusian'], venusian) self.assertEqual(settings[0]['view'], None) # comes from call_venusian self.assertEqual(settings[0]['attr'], 'view') self.assertEqual(settings[0]['_info'], 'codeinfo') def test_call_with_venusian_args(self): decorator = self._makeOne(_depth=1, _category='foo') venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass decorator(foo) attachments = venusian.attachments category = attachments[0][2] depth = attachments[0][3] self.assertEqual(depth, 2) self.assertEqual(category, 'foo') class Test_exception_view_config(BaseTest, unittest.TestCase): def _makeOne(self, *args, **kw): from pyramid.view import exception_view_config return exception_view_config(*args, **kw) def test_ctor(self): inst = self._makeOne(context=Exception, path_info='path_info') self.assertEqual( inst.__dict__, {'context': Exception, 'path_info': 'path_info'} ) def test_ctor_positional_exception(self): inst = self._makeOne(Exception, path_info='path_info') self.assertEqual( inst.__dict__, {'context': Exception, 'path_info': 'path_info'} ) def test_ctor_positional_extras(self): from pyramid.exceptions import ConfigurationError self.assertRaises( ConfigurationError, lambda: self._makeOne(Exception, True) ) def test_it_function(self): def view(request): # pragma: no cover pass decorator = self._makeOne(context=Exception, renderer='renderer') venusian = DummyVenusian() decorator.venusian = venusian wrapped = decorator(view) self.assertTrue(wrapped is view) config = call_venusian(venusian) settings = config.settings self.assertEqual( settings, [ { 'venusian': venusian, 'context': Exception, 'renderer': 'renderer', '_info': 'codeinfo', 'view': None, } ], ) def test_it_class(self): decorator = self._makeOne() venusian = DummyVenusian() decorator.venusian = venusian decorator.venusian.info.scope = 'class' class view(object): pass wrapped = decorator(view) self.assertTrue(wrapped is view) config = call_venusian(venusian) settings = config.settings self.assertEqual(len(settings), 1) self.assertEqual(len(settings[0]), 4) self.assertEqual(settings[0]['venusian'], venusian) self.assertEqual(settings[0]['view'], None) # comes from call_venusian self.assertEqual(settings[0]['attr'], 'view') self.assertEqual(settings[0]['_info'], 'codeinfo') def test_call_with_venusian_args(self): decorator = self._makeOne(_depth=1, _category='foo') venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass decorator(foo) attachments = venusian.attachments category = attachments[0][2] depth = attachments[0][3] self.assertEqual(depth, 2) self.assertEqual(category, 'foo') class RenderViewToResponseTests(BaseTest, unittest.TestCase): def _callFUT(self, *arg, **kw): from pyramid.view import render_view_to_response return render_view_to_response(*arg, **kw) def test_call_no_view_registered(self): request = self._makeRequest() context = self._makeContext() result = self._callFUT(context, request, name='notregistered') self.assertEqual(result, None) def test_call_no_registry_on_request(self): request = self._makeRequest() del request.registry context = self._makeContext() result = self._callFUT(context, request, name='notregistered') self.assertEqual(result, None) def test_call_view_registered_secure(self): request = self._makeRequest() context = self._makeContext() response = DummyResponse() view = make_view(response) self._registerView(request.registry, view, 'registered') response = self._callFUT( context, request, name='registered', secure=True ) self.assertEqual(response.status, '200 OK') def test_call_view_registered_insecure_no_call_permissive(self): context = self._makeContext() request = self._makeRequest() response = DummyResponse() view = make_view(response) self._registerView(request.registry, view, 'registered') response = self._callFUT( context, request, name='registered', secure=False ) self.assertEqual(response.status, '200 OK') def test_call_view_registered_insecure_with_call_permissive(self): context = self._makeContext() request = self._makeRequest() response = DummyResponse() view = make_view(response) def anotherview(context, request): return DummyResponse('anotherview') view.__call_permissive__ = anotherview self._registerView(request.registry, view, 'registered') response = self._callFUT( context, request, name='registered', secure=False ) self.assertEqual(response.status, '200 OK') self.assertEqual(response.app_iter, ['anotherview']) def test_call_view_with_request_iface_on_request(self): # See https://github.com/Pylons/pyramid/issues/1643 from zope.interface import Interface class IWontBeFound(Interface): pass context = self._makeContext() request = self._makeRequest() request.request_iface = IWontBeFound response = DummyResponse('aview') view = make_view(response) self._registerView(request.registry, view, 'aview') response = self._callFUT(context, request, name='aview') self.assertEqual(response.status, '200 OK') self.assertEqual(response.app_iter, ['aview']) class RenderViewToIterableTests(BaseTest, unittest.TestCase): def _callFUT(self, *arg, **kw): from pyramid.view import render_view_to_iterable return render_view_to_iterable(*arg, **kw) def test_call_no_view_registered(self): request = self._makeRequest() context = self._makeContext() result = self._callFUT(context, request, name='notregistered') self.assertEqual(result, None) def test_call_view_registered_secure(self): request = self._makeRequest() context = self._makeContext() response = DummyResponse() view = make_view(response) self._registerView(request.registry, view, 'registered') iterable = self._callFUT( context, request, name='registered', secure=True ) self.assertEqual(iterable, ()) def test_call_view_registered_insecure_no_call_permissive(self): context = self._makeContext() request = self._makeRequest() response = DummyResponse() view = make_view(response) self._registerView(request.registry, view, 'registered') iterable = self._callFUT( context, request, name='registered', secure=False ) self.assertEqual(iterable, ()) def test_call_view_registered_insecure_with_call_permissive(self): context = self._makeContext() request = self._makeRequest() response = DummyResponse() view = make_view(response) def anotherview(context, request): return DummyResponse(b'anotherview') view.__call_permissive__ = anotherview self._registerView(request.registry, view, 'registered') iterable = self._callFUT( context, request, name='registered', secure=False ) self.assertEqual(iterable, [b'anotherview']) def test_verify_output_bytestring(self): from pyramid.request import Request from pyramid.config import Configurator from pyramid.view import render_view from webob.compat import text_type config = Configurator(settings={}) def view(request): request.response.text = text_type('') return request.response config.add_view(name='test', view=view) config.commit() r = Request({}) r.registry = config.registry self.assertEqual(render_view(object(), r, 'test'), b'') def test_call_request_has_no_registry(self): request = self._makeRequest() del request.registry registry = self.config.registry context = self._makeContext() response = DummyResponse() view = make_view(response) self._registerView(registry, view, 'registered') iterable = self._callFUT( context, request, name='registered', secure=True ) self.assertEqual(iterable, ()) class RenderViewTests(BaseTest, unittest.TestCase): def _callFUT(self, *arg, **kw): from pyramid.view import render_view return render_view(*arg, **kw) def test_call_no_view_registered(self): request = self._makeRequest() context = self._makeContext() result = self._callFUT(context, request, name='notregistered') self.assertEqual(result, None) def test_call_view_registered_secure(self): request = self._makeRequest() context = self._makeContext() response = DummyResponse() view = make_view(response) self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=True) self.assertEqual(s, b'') def test_call_view_registered_insecure_no_call_permissive(self): context = self._makeContext() request = self._makeRequest() response = DummyResponse() view = make_view(response) self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(s, b'') def test_call_view_registered_insecure_with_call_permissive(self): context = self._makeContext() request = self._makeRequest() response = DummyResponse() view = make_view(response) def anotherview(context, request): return DummyResponse(b'anotherview') view.__call_permissive__ = anotherview self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(s, b'anotherview') class TestViewConfigDecorator(unittest.TestCase): def setUp(self): testing.setUp() def tearDown(self): testing.tearDown() def _getTargetClass(self): from pyramid.view import view_config return view_config def _makeOne(self, *arg, **kw): return self._getTargetClass()(*arg, **kw) def test_create_defaults(self): decorator = self._makeOne() self.assertEqual(decorator.__dict__, {}) def test_create_context_trumps_for(self): decorator = self._makeOne(context='123', for_='456') self.assertEqual(decorator.context, '123') def test_create_for_trumps_context_None(self): decorator = self._makeOne(context=None, for_='456') self.assertEqual(decorator.context, '456') def test_create_nondefaults(self): decorator = self._makeOne( name=None, request_type=None, for_=None, permission='foo', mapper='mapper', decorator='decorator', match_param='match_param', ) self.assertEqual(decorator.name, None) self.assertEqual(decorator.request_type, None) self.assertEqual(decorator.context, None) self.assertEqual(decorator.permission, 'foo') self.assertEqual(decorator.mapper, 'mapper') self.assertEqual(decorator.decorator, 'decorator') self.assertEqual(decorator.match_param, 'match_param') def test_create_with_other_predicates(self): decorator = self._makeOne(foo=1) self.assertEqual(decorator.foo, 1) def test_create_decorator_tuple(self): decorator = self._makeOne(decorator=('decorator1', 'decorator2')) self.assertEqual(decorator.decorator, ('decorator1', 'decorator2')) def test_call_function(self): decorator = self._makeOne() venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass wrapped = decorator(foo) self.assertTrue(wrapped is foo) config = call_venusian(venusian) settings = config.settings self.assertEqual(len(settings), 1) self.assertEqual(len(settings), 1) self.assertEqual(len(settings[0]), 3) self.assertEqual(settings[0]['venusian'], venusian) self.assertEqual(settings[0]['view'], None) # comes from call_venusian self.assertEqual(settings[0]['_info'], 'codeinfo') def test_call_class(self): decorator = self._makeOne() venusian = DummyVenusian() decorator.venusian = venusian decorator.venusian.info.scope = 'class' class foo(object): pass wrapped = decorator(foo) self.assertTrue(wrapped is foo) config = call_venusian(venusian) settings = config.settings self.assertEqual(len(settings), 1) self.assertEqual(len(settings[0]), 4) self.assertEqual(settings[0]['venusian'], venusian) self.assertEqual(settings[0]['view'], None) # comes from call_venusian self.assertEqual(settings[0]['attr'], 'foo') self.assertEqual(settings[0]['_info'], 'codeinfo') def test_call_class_attr_already_set(self): decorator = self._makeOne(attr='abc') venusian = DummyVenusian() decorator.venusian = venusian decorator.venusian.info.scope = 'class' class foo(object): pass wrapped = decorator(foo) self.assertTrue(wrapped is foo) config = call_venusian(venusian) settings = config.settings self.assertEqual(len(settings), 1) self.assertEqual(len(settings[0]), 4) self.assertEqual(settings[0]['venusian'], venusian) self.assertEqual(settings[0]['view'], None) # comes from call_venusian self.assertEqual(settings[0]['attr'], 'abc') self.assertEqual(settings[0]['_info'], 'codeinfo') def test_stacking(self): decorator1 = self._makeOne(name='1') venusian1 = DummyVenusian() decorator1.venusian = venusian1 venusian2 = DummyVenusian() decorator2 = self._makeOne(name='2') decorator2.venusian = venusian2 def foo(): # pragma: no cover pass wrapped1 = decorator1(foo) wrapped2 = decorator2(wrapped1) self.assertTrue(wrapped1 is foo) self.assertTrue(wrapped2 is foo) config1 = call_venusian(venusian1) self.assertEqual(len(config1.settings), 1) self.assertEqual(config1.settings[0]['name'], '1') config2 = call_venusian(venusian2) self.assertEqual(len(config2.settings), 1) self.assertEqual(config2.settings[0]['name'], '2') def test_call_as_method(self): decorator = self._makeOne() venusian = DummyVenusian() decorator.venusian = venusian decorator.venusian.info.scope = 'class' def foo(self): # pragma: no cover pass def bar(self): # pragma: no cover pass class foo(object): foomethod = decorator(foo) barmethod = decorator(bar) config = call_venusian(venusian) settings = config.settings self.assertEqual(len(settings), 2) self.assertEqual(settings[0]['attr'], 'foo') self.assertEqual(settings[1]['attr'], 'bar') def test_with_custom_predicates(self): decorator = self._makeOne(custom_predicates=(1,)) venusian = DummyVenusian() decorator.venusian = venusian def foo(context, request): # pragma: no cover pass decorated = decorator(foo) self.assertTrue(decorated is foo) config = call_venusian(venusian) settings = config.settings self.assertEqual(settings[0]['custom_predicates'], (1,)) def test_call_with_renderer_string(self): import tests decorator = self._makeOne(renderer='fixtures/minimal.pt') venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass wrapped = decorator(foo) self.assertTrue(wrapped is foo) config = call_venusian(venusian) settings = config.settings self.assertEqual(len(settings), 1) renderer = settings[0]['renderer'] self.assertEqual(renderer, 'fixtures/minimal.pt') self.assertEqual(config.pkg, tests) def test_call_with_renderer_dict(self): import tests decorator = self._makeOne(renderer={'a': 1}) venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass wrapped = decorator(foo) self.assertTrue(wrapped is foo) config = call_venusian(venusian) settings = config.settings self.assertEqual(len(settings), 1) self.assertEqual(settings[0]['renderer'], {'a': 1}) self.assertEqual(config.pkg, tests) def test_call_with_renderer_IRendererInfo(self): import tests from pyramid.interfaces import IRendererInfo @implementer(IRendererInfo) class DummyRendererHelper(object): pass renderer_helper = DummyRendererHelper() decorator = self._makeOne(renderer=renderer_helper) venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass wrapped = decorator(foo) self.assertTrue(wrapped is foo) context = DummyVenusianContext() config = call_venusian(venusian, context) settings = config.settings self.assertEqual(len(settings), 1) renderer = settings[0]['renderer'] self.assertTrue(renderer is renderer_helper) self.assertEqual(config.pkg, tests) def test_call_withdepth(self): decorator = self._makeOne(_depth=1) venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass decorator(foo) attachments = venusian.attachments depth = attachments[0][3] self.assertEqual(depth, 2) def test_call_withoutcategory(self): decorator = self._makeOne() venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass decorator(foo) attachments = venusian.attachments category = attachments[0][2] self.assertEqual(category, 'pyramid') def test_call_withcategory(self): decorator = self._makeOne(_category='not_pyramid') venusian = DummyVenusian() decorator.venusian = venusian def foo(): # pragma: no cover pass decorator(foo) attachments = venusian.attachments category = attachments[0][2] self.assertEqual(category, 'not_pyramid') class Test_append_slash_notfound_view(BaseTest, unittest.TestCase): def _callFUT(self, context, request): from pyramid.view import append_slash_notfound_view return append_slash_notfound_view(context, request) def _registerMapper(self, reg, match=True): from pyramid.interfaces import IRoutesMapper class DummyRoute(object): def __init__(self, val): self.val = val def match(self, path): return self.val class DummyMapper(object): def __init__(self): self.routelist = [DummyRoute(match)] def get_routes(self): return self.routelist mapper = DummyMapper() reg.registerUtility(mapper, IRoutesMapper) return mapper def test_context_is_not_exception(self): request = self._makeRequest(PATH_INFO='/abc') request.exception = ExceptionResponse() context = DummyContext() response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') self.assertEqual(response.app_iter, ['Not Found']) def test_no_mapper(self): request = self._makeRequest(PATH_INFO='/abc') context = ExceptionResponse() response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') def test_no_path(self): request = self._makeRequest() context = ExceptionResponse() self._registerMapper(request.registry, True) response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') def test_mapper_path_already_slash_ending(self): request = self._makeRequest(PATH_INFO='/abc/') context = ExceptionResponse() self._registerMapper(request.registry, True) response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') def test_no_route_matches(self): request = self._makeRequest(PATH_INFO='/abc') context = ExceptionResponse() mapper = self._registerMapper(request.registry, True) mapper.routelist[0].val = None response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') def test_matches(self): request = self._makeRequest(PATH_INFO='/abc') context = ExceptionResponse() self._registerMapper(request.registry, True) response = self._callFUT(context, request) self.assertEqual(response.status, '307 Temporary Redirect') self.assertEqual(response.location, '/abc/') def test_matches_with_script_name(self): request = self._makeRequest(PATH_INFO='/abc', SCRIPT_NAME='/foo') context = ExceptionResponse() self._registerMapper(request.registry, True) response = self._callFUT(context, request) self.assertEqual(response.status, '307 Temporary Redirect') self.assertEqual(response.location, '/foo/abc/') def test_with_query_string(self): request = self._makeRequest(PATH_INFO='/abc', QUERY_STRING='a=1&b=2') context = ExceptionResponse() self._registerMapper(request.registry, True) response = self._callFUT(context, request) self.assertEqual(response.status, '307 Temporary Redirect') self.assertEqual(response.location, '/abc/?a=1&b=2') class TestAppendSlashNotFoundViewFactory(BaseTest, unittest.TestCase): def _makeOne(self, notfound_view): from pyramid.view import AppendSlashNotFoundViewFactory return AppendSlashNotFoundViewFactory(notfound_view) def test_custom_notfound_view(self): request = self._makeRequest(PATH_INFO='/abc') context = ExceptionResponse() def custom_notfound(context, request): return 'OK' view = self._makeOne(custom_notfound) response = view(context, request) self.assertEqual(response, 'OK') class Test_default_exceptionresponse_view(unittest.TestCase): def _callFUT(self, context, request): from pyramid.view import default_exceptionresponse_view return default_exceptionresponse_view(context, request) def test_is_exception(self): context = Exception() result = self._callFUT(context, None) self.assertTrue(result is context) def test_is_not_exception_context_is_false_still_chose(self): request = DummyRequest() request.exception = 0 result = self._callFUT(None, request) self.assertTrue(result is None) def test_is_not_exception_no_request_exception(self): context = object() request = DummyRequest() request.exception = None result = self._callFUT(context, request) self.assertTrue(result is context) def test_is_not_exception_request_exception(self): context = object() request = DummyRequest() request.exception = 'abc' result = self._callFUT(context, request) self.assertEqual(result, 'abc') class Test_view_defaults(unittest.TestCase): def test_it(self): from pyramid.view import view_defaults @view_defaults(route_name='abc', renderer='def') class Foo(object): pass self.assertEqual(Foo.__view_defaults__['route_name'], 'abc') self.assertEqual(Foo.__view_defaults__['renderer'], 'def') def test_it_inheritance_not_overridden(self): from pyramid.view import view_defaults @view_defaults(route_name='abc', renderer='def') class Foo(object): pass class Bar(Foo): pass self.assertEqual(Bar.__view_defaults__['route_name'], 'abc') self.assertEqual(Bar.__view_defaults__['renderer'], 'def') def test_it_inheritance_overriden(self): from pyramid.view import view_defaults @view_defaults(route_name='abc', renderer='def') class Foo(object): pass @view_defaults(route_name='ghi') class Bar(Foo): pass self.assertEqual(Bar.__view_defaults__['route_name'], 'ghi') self.assertFalse('renderer' in Bar.__view_defaults__) def test_it_inheritance_overriden_empty(self): from pyramid.view import view_defaults @view_defaults(route_name='abc', renderer='def') class Foo(object): pass @view_defaults() class Bar(Foo): pass self.assertEqual(Bar.__view_defaults__, {}) class TestViewMethodsMixin(unittest.TestCase): def setUp(self): self.config = testing.setUp() def tearDown(self): testing.tearDown() def _makeOne(self, environ=None): from pyramid.decorator import reify from pyramid.view import ViewMethodsMixin if environ is None: environ = {} class Request(ViewMethodsMixin): def __init__(self, environ): self.environ = environ @reify def response(self): return DummyResponse() request = Request(environ) request.registry = self.config.registry return request def test_it(self): def exc_view(exc, request): self.assertTrue(exc is dummy_exc) self.assertTrue(request.exception is dummy_exc) return DummyResponse(b'foo') self.config.add_view(exc_view, context=RuntimeError) request = self._makeOne() dummy_exc = RuntimeError() try: raise dummy_exc except RuntimeError: response = request.invoke_exception_view() self.assertEqual(response.app_iter, [b'foo']) else: # pragma: no cover self.fail() def test_it_hides_attrs(self): def exc_view(exc, request): self.assertTrue(exc is not orig_exc) self.assertTrue(request.exception is not orig_exc) self.assertTrue(request.exc_info is not orig_exc_info) self.assertTrue(request.response is not orig_response) request.response.app_iter = [b'bar'] return request.response self.config.add_view(exc_view, context=RuntimeError) request = self._makeOne() orig_exc = request.exception = DummyContext() orig_exc_info = request.exc_info = DummyContext() orig_response = request.response = DummyResponse(b'foo') try: raise RuntimeError except RuntimeError as ex: response = request.invoke_exception_view() self.assertEqual(response.app_iter, [b'bar']) self.assertTrue(request.exception is ex) self.assertTrue(request.exc_info[1] is ex) self.assertTrue(request.response is orig_response) else: # pragma: no cover self.fail() def test_it_supports_alternate_requests(self): def exc_view(exc, request): self.assertTrue(request is other_req) from pyramid.threadlocal import get_current_request self.assertTrue(get_current_request() is other_req) return DummyResponse(b'foo') self.config.add_view(exc_view, context=RuntimeError) request = self._makeOne() other_req = self._makeOne() try: raise RuntimeError except RuntimeError: response = request.invoke_exception_view(request=other_req) self.assertEqual(response.app_iter, [b'foo']) else: # pragma: no cover self.fail() def test_it_supports_threadlocal_registry(self): def exc_view(exc, request): return DummyResponse(b'foo') self.config.add_view(exc_view, context=RuntimeError) request = self._makeOne() del request.registry try: raise RuntimeError except RuntimeError: response = request.invoke_exception_view() self.assertEqual(response.app_iter, [b'foo']) else: # pragma: no cover self.fail() def test_it_raises_if_no_registry(self): request = self._makeOne() del request.registry from pyramid.threadlocal import manager manager.push({'registry': None, 'request': request}) try: raise RuntimeError except RuntimeError: try: request.invoke_exception_view() except RuntimeError as e: self.assertEqual(e.args[0], "Unable to retrieve registry") else: # pragma: no cover self.fail() finally: manager.pop() def test_it_supports_alternate_exc_info(self): def exc_view(exc, request): self.assertTrue(request.exc_info is exc_info) return DummyResponse(b'foo') self.config.add_view(exc_view, context=RuntimeError) request = self._makeOne() try: raise RuntimeError except RuntimeError: exc_info = sys.exc_info() response = request.invoke_exception_view(exc_info=exc_info) self.assertEqual(response.app_iter, [b'foo']) def test_it_rejects_secured_view(self): from pyramid.exceptions import Forbidden def exc_view(exc, request): # pragma: no cover pass self.config.testing_securitypolicy(permissive=False) self.config.add_view(exc_view, context=RuntimeError, permission='view') request = self._makeOne() try: raise RuntimeError except RuntimeError: self.assertRaises(Forbidden, request.invoke_exception_view) else: # pragma: no cover self.fail() def test_it_allows_secured_view(self): def exc_view(exc, request): return DummyResponse(b'foo') self.config.testing_securitypolicy(permissive=False) self.config.add_view(exc_view, context=RuntimeError, permission='view') request = self._makeOne() try: raise RuntimeError except RuntimeError: response = request.invoke_exception_view(secure=False) self.assertEqual(response.app_iter, [b'foo']) else: # pragma: no cover self.fail() def test_it_raises_if_not_found(self): from pyramid.httpexceptions import HTTPNotFound request = self._makeOne() dummy_exc = RuntimeError() try: raise dummy_exc except RuntimeError: self.assertRaises(HTTPNotFound, request.invoke_exception_view) else: # pragma: no cover self.fail() def test_it_reraises_if_not_found(self): request = self._makeOne() dummy_exc = RuntimeError() try: raise dummy_exc except RuntimeError: self.assertRaises( RuntimeError, lambda: request.invoke_exception_view(reraise=True), ) else: # pragma: no cover self.fail() def test_it_raises_predicate_mismatch(self): from pyramid.exceptions import PredicateMismatch def exc_view(exc, request): # pragma: no cover pass self.config.add_view( exc_view, context=Exception, request_method='POST' ) request = self._makeOne() request.method = 'GET' dummy_exc = RuntimeError() try: raise dummy_exc except RuntimeError: self.assertRaises(PredicateMismatch, request.invoke_exception_view) else: # pragma: no cover self.fail() def test_it_reraises_after_predicate_mismatch(self): def exc_view(exc, request): # pragma: no cover pass self.config.add_view( exc_view, context=Exception, request_method='POST' ) request = self._makeOne() request.method = 'GET' dummy_exc = RuntimeError() try: raise dummy_exc except RuntimeError: self.assertRaises( RuntimeError, lambda: request.invoke_exception_view(reraise=True), ) else: # pragma: no cover self.fail() class ExceptionResponse(Exception): status = '404 Not Found' app_iter = ['Not Found'] headerlist = [] class DummyContext: pass def make_view(response): def view(context, request): return response return view class DummyRequest: exception = None request_iface = IRequest def __init__(self, environ=None): if environ is None: environ = {} self.environ = environ @implementer(IResponse) class DummyResponse(object): headerlist = () app_iter = () status = '200 OK' environ = None def __init__(self, body=None): if body is None: self.app_iter = () else: self.app_iter = [body] class IContext(Interface): pass class DummyVenusianInfo(object): scope = 'notaclass' module = sys.modules['tests'] codeinfo = 'codeinfo' class DummyVenusian(object): def __init__(self, info=None): if info is None: info = DummyVenusianInfo() self.info = info self.attachments = [] def attach(self, wrapped, callback, category=None, depth=1): self.attachments.append((wrapped, callback, category, depth)) return self.info class DummyRegistry(object): pass class DummyConfig(object): def __init__(self): self.settings = [] self.registry = DummyRegistry() def add_view(self, **kw): self.settings.append(kw) add_notfound_view = add_forbidden_view = add_exception_view = add_view def with_package(self, pkg): self.pkg = pkg return self class DummyVenusianContext(object): def __init__(self): self.config = DummyConfig() def call_venusian(venusian, context=None): if context is None: context = DummyVenusianContext() for wrapped, callback, category, depth in venusian.attachments: callback(context, None, None) return context.config