import os import unittest from zope.interface import implementer from pyramid import testing from pyramid.compat import im_func, text_ from pyramid.exceptions import ConfigurationError from pyramid.exceptions import ConfigurationExecutionError from pyramid.exceptions import ConfigurationConflictError from pyramid.interfaces import IResponse, IRequest, IMultiView from . import IDummy from . import dummy_view class TestViewsConfigurationMixin(unittest.TestCase): def _makeOne(self, *arg, **kw): from pyramid.config import Configurator config = Configurator(*arg, **kw) config.set_default_csrf_options(require_csrf=False) return config def _getViewCallable( self, config, ctx_iface=None, exc_iface=None, request_iface=None, name='', ): from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IExceptionViewClassifier if exc_iface: classifier = IExceptionViewClassifier ctx_iface = exc_iface else: classifier = IViewClassifier if ctx_iface is None: ctx_iface = Interface if request_iface is None: request_iface = IRequest return config.registry.adapters.lookup( (classifier, request_iface, ctx_iface), IView, name=name, default=None, ) def _registerRenderer(self, config, name='.txt'): from pyramid.interfaces import IRendererFactory class Renderer: def __init__(self, info): self.__class__.info = info def __call__(self, *arg): return b'Hello!' config.registry.registerUtility(Renderer, IRendererFactory, name=name) return Renderer def _makeRequest(self, config): request = DummyRequest() request.registry = config.registry return request def _assertNotFound(self, wrapper, *arg): from pyramid.httpexceptions import HTTPNotFound self.assertRaises(HTTPNotFound, wrapper, *arg) def _getRouteRequestIface(self, config, name): from pyramid.interfaces import IRouteRequest iface = config.registry.getUtility(IRouteRequest, name) return iface def _assertRoute(self, config, name, path, num_predicates=0): from pyramid.interfaces import IRoutesMapper mapper = config.registry.getUtility(IRoutesMapper) routes = mapper.get_routes() route = routes[0] self.assertEqual(len(routes), 1) self.assertEqual(route.name, name) self.assertEqual(route.path, path) self.assertEqual(len(routes[0].predicates), num_predicates) return route def test_add_view_view_callable_None_no_renderer(self): config = self._makeOne(autocommit=True) self.assertRaises(ConfigurationError, config.add_view) def test_add_view_with_request_type_and_route_name(self): config = self._makeOne(autocommit=True) view = lambda *arg: 'OK' self.assertRaises( ConfigurationError, config.add_view, view, '', None, None, True, True, ) def test_add_view_with_request_type(self): from pyramid.renderers import null_renderer from zope.interface import directlyProvides from pyramid.interfaces import IRequest view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( view=view, request_type='pyramid.interfaces.IRequest', renderer=null_renderer, ) wrapper = self._getViewCallable(config) request = DummyRequest() self._assertNotFound(wrapper, None, request) directlyProvides(request, IRequest) result = wrapper(None, request) self.assertEqual(result, 'OK') def test_add_view_view_callable_None_with_renderer(self): config = self._makeOne(autocommit=True) self._registerRenderer(config, name='dummy') config.add_view(renderer='dummy') view = self._getViewCallable(config) self.assertTrue(b'Hello!' in view(None, None).body) def test_add_view_with_tmpl_renderer_factory_introspector_missing(self): config = self._makeOne(autocommit=True) config.introspection = False config.introspector = None config.add_view(renderer='dummy.pt') view = self._getViewCallable(config) self.assertRaises(ValueError, view, None, None) def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self): config = self._makeOne(autocommit=True) introspector = DummyIntrospector() config.introspector = introspector config.add_view(renderer='dummy.pt') self.assertFalse( ('renderer factories', '.pt') in introspector.related[-1] ) view = self._getViewCallable(config) self.assertRaises(ValueError, view, None, None) def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self): config = self._makeOne(autocommit=True) introspector = DummyIntrospector(True) config.introspector = introspector def dummy_factory(helper): return lambda val, system_vals: 'Hello!' config.add_renderer('.pt', dummy_factory) config.add_view(renderer='dummy.pt') self.assertTrue( ('renderer factories', '.pt') in introspector.related[-1] ) view = self._getViewCallable(config) self.assertTrue(b'Hello!' in view(None, None).body) def test_add_view_wrapped_view_is_decorated(self): def view(request): # request-only wrapper """ """ config = self._makeOne(autocommit=True) config.add_view(view=view) wrapper = self._getViewCallable(config) self.assertEqual(wrapper.__module__, view.__module__) self.assertEqual(wrapper.__name__, view.__name__) self.assertEqual(wrapper.__doc__, view.__doc__) self.assertEqual( wrapper.__discriminator__(None, None).resolve()[0], 'view' ) def test_add_view_view_callable_dottedname(self): from pyramid.renderers import null_renderer config = self._makeOne(autocommit=True) config.add_view( view='tests.test_config.dummy_view', renderer=null_renderer ) wrapper = self._getViewCallable(config) self.assertEqual(wrapper(None, None), 'OK') def test_add_view_with_function_callable(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) wrapper = self._getViewCallable(config) result = wrapper(None, None) self.assertEqual(result, 'OK') def test_add_view_with_function_callable_requestonly(self): from pyramid.renderers import null_renderer def view(request): return 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) wrapper = self._getViewCallable(config) result = wrapper(None, None) self.assertEqual(result, 'OK') def test_add_view_with_name(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, name='abc', renderer=null_renderer) wrapper = self._getViewCallable(config, name='abc') result = wrapper(None, None) self.assertEqual(result, 'OK') def test_add_view_with_name_unicode(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) name = text_(b'La Pe\xc3\xb1a', 'utf-8') config.add_view(view=view, name=name, renderer=null_renderer) wrapper = self._getViewCallable(config, name=name) result = wrapper(None, None) self.assertEqual(result, 'OK') def test_add_view_with_decorator(self): from pyramid.renderers import null_renderer def view(request): """ ABC """ return 'OK' def view_wrapper(fn): def inner(context, request): return fn(context, request) return inner config = self._makeOne(autocommit=True) config.add_view( view=view, decorator=view_wrapper, renderer=null_renderer ) wrapper = self._getViewCallable(config) self.assertFalse(wrapper is view) self.assertEqual(wrapper.__doc__, view.__doc__) result = wrapper(None, None) self.assertEqual(result, 'OK') def test_add_view_with_decorator_tuple(self): from pyramid.renderers import null_renderer def view(request): """ ABC """ return 'OK' def view_wrapper1(fn): def inner(context, request): return 'wrapped1' + fn(context, request) return inner def view_wrapper2(fn): def inner(context, request): return 'wrapped2' + fn(context, request) return inner config = self._makeOne(autocommit=True) config.add_view( view=view, decorator=(view_wrapper2, view_wrapper1), renderer=null_renderer, ) wrapper = self._getViewCallable(config) self.assertFalse(wrapper is view) self.assertEqual(wrapper.__doc__, view.__doc__) result = wrapper(None, None) self.assertEqual(result, 'wrapped2wrapped1OK') def test_add_view_with_http_cache(self): import datetime from pyramid.response import Response response = Response('OK') def view(request): """ ABC """ return response config = self._makeOne(autocommit=True) config.add_view(view=view, http_cache=(86400, {'public': True})) wrapper = self._getViewCallable(config) self.assertFalse(wrapper is view) self.assertEqual(wrapper.__doc__, view.__doc__) request = testing.DummyRequest() when = datetime.datetime.utcnow() + datetime.timedelta(days=1) result = wrapper(None, request) self.assertEqual(result, response) headers = dict(response.headerlist) self.assertEqual(headers['Cache-Control'], 'max-age=86400, public') expires = parse_httpdate(headers['Expires']) assert_similar_datetime(expires, when) def test_add_view_as_instance(self): from pyramid.renderers import null_renderer class AView: def __call__(self, context, request): """ """ return 'OK' view = AView() config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) wrapper = self._getViewCallable(config) result = wrapper(None, None) self.assertEqual(result, 'OK') def test_add_view_as_instancemethod(self): from pyramid.renderers import null_renderer class View: def index(self, context, request): return 'OK' view = View() config = self._makeOne(autocommit=True) config.add_view(view=view.index, renderer=null_renderer) wrapper = self._getViewCallable(config) result = wrapper(None, None) self.assertEqual(result, 'OK') def test_add_view_as_instancemethod_requestonly(self): from pyramid.renderers import null_renderer class View: def index(self, request): return 'OK' view = View() config = self._makeOne(autocommit=True) config.add_view(view=view.index, renderer=null_renderer) wrapper = self._getViewCallable(config) result = wrapper(None, None) self.assertEqual(result, 'OK') def test_add_view_as_instance_requestonly(self): from pyramid.renderers import null_renderer class AView: def __call__(self, request): """ """ return 'OK' view = AView() config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) wrapper = self._getViewCallable(config) result = wrapper(None, None) self.assertEqual(result, 'OK') def test_add_view_as_oldstyle_class(self): from pyramid.renderers import null_renderer class view: def __init__(self, context, request): self.context = context self.request = request def __call__(self): return 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) wrapper = self._getViewCallable(config) request = self._makeRequest(config) result = wrapper(None, request) self.assertEqual(result, 'OK') self.assertEqual(request.__view__.__class__, view) def test_add_view_as_oldstyle_class_requestonly(self): from pyramid.renderers import null_renderer class view: def __init__(self, request): self.request = request def __call__(self): return 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) wrapper = self._getViewCallable(config) request = self._makeRequest(config) result = wrapper(None, request) self.assertEqual(result, 'OK') self.assertEqual(request.__view__.__class__, view) def test_add_view_context_as_class(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy view = lambda *arg: 'OK' class Foo: pass config = self._makeOne(autocommit=True) config.add_view(context=Foo, view=view, renderer=null_renderer) foo = implementedBy(Foo) wrapper = self._getViewCallable(config, foo) self.assertEqual(wrapper, view) def test_add_view_context_as_iface(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(context=IDummy, view=view, renderer=null_renderer) wrapper = self._getViewCallable(config, IDummy) self.assertEqual(wrapper, view) def test_add_view_context_as_dottedname(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( context='tests.test_config.IDummy', view=view, renderer=null_renderer, ) wrapper = self._getViewCallable(config, IDummy) self.assertEqual(wrapper, view) def test_add_view_for__as_dottedname(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( for_='tests.test_config.IDummy', view=view, renderer=null_renderer ) wrapper = self._getViewCallable(config, IDummy) self.assertEqual(wrapper, view) def test_add_view_for_as_class(self): # ``for_`` is older spelling for ``context`` from pyramid.renderers import null_renderer from zope.interface import implementedBy view = lambda *arg: 'OK' class Foo: pass config = self._makeOne(autocommit=True) config.add_view(for_=Foo, view=view, renderer=null_renderer) foo = implementedBy(Foo) wrapper = self._getViewCallable(config, foo) self.assertEqual(wrapper, view) def test_add_view_for_as_iface(self): # ``for_`` is older spelling for ``context`` from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(for_=IDummy, view=view, renderer=null_renderer) wrapper = self._getViewCallable(config, IDummy) self.assertEqual(wrapper, view) def test_add_view_context_trumps_for(self): # ``for_`` is older spelling for ``context`` from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) class Foo: pass config.add_view( context=IDummy, for_=Foo, view=view, renderer=null_renderer ) wrapper = self._getViewCallable(config, IDummy) self.assertEqual(wrapper, view) def test_add_view_register_secured_view(self): from pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import ISecuredView from pyramid.interfaces import IViewClassifier view = lambda *arg: 'OK' view.__call_permissive__ = view config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) wrapper = config.registry.adapters.lookup( (IViewClassifier, IRequest, Interface), ISecuredView, name='', default=None, ) self.assertEqual(wrapper, view) def test_add_view_exception_register_secured_view(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IExceptionViewClassifier view = lambda *arg: 'OK' view.__call_permissive__ = view config = self._makeOne(autocommit=True) config.add_view( view=view, context=RuntimeError, renderer=null_renderer ) 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 pyramid.renderers import null_renderer from hashlib import md5 from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IMultiView phash = md5() phash.update(b'xhr = True') view = lambda *arg: 'NOT OK' view.__phash__ = phash.hexdigest() config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, Interface), IView, name='' ) def newview(context, request): return 'OK' config.add_view(view=newview, xhr=True, renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertFalse(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 pyramid.renderers import null_renderer from hashlib import md5 from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IExceptionViewClassifier from pyramid.interfaces import IMultiView phash = md5() phash.update(b'xhr = True') view = lambda *arg: 'NOT OK' view.__phash__ = phash.hexdigest() config = self._makeOne(autocommit=True) 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, renderer=null_renderer, ) wrapper = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError) ) self.assertFalse(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 pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IMultiView view = lambda *arg: 'NOT OK' config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, Interface), IView, name='' ) def newview(context, request): return 'OK' config.add_view(view=newview, renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertFalse(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 pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IExceptionViewClassifier from pyramid.interfaces import IMultiView view = lambda *arg: 'NOT OK' config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), IView, name='', ) def newview(context, request): return 'OK' config.add_view( view=newview, context=RuntimeError, renderer=null_renderer ) wrapper = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError) ) self.assertFalse(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 pyramid.config.predicates import DEFAULT_PHASH from pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IMultiView view = lambda *arg: 'NOT OK' view.__phash__ = DEFAULT_PHASH config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, Interface), IView, name='' ) def newview(context, request): return 'OK' config.add_view(view=newview, renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertFalse(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 pyramid.config.predicates import DEFAULT_PHASH from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IExceptionViewClassifier from pyramid.interfaces import IMultiView view = lambda *arg: 'NOT OK' view.__phash__ = DEFAULT_PHASH config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), IView, name='', ) def newview(context, request): return 'OK' config.add_view( view=newview, context=RuntimeError, renderer=null_renderer ) wrapper = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError) ) self.assertFalse(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 pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IMultiView view = lambda *arg: 'OK' view.__phash__ = 'abc' config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, Interface), IView, name='' ) config.add_view(view=view, renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertTrue(IMultiView.providedBy(wrapper)) self.assertEqual(wrapper(None, None), 'OK') def test_add_view_exc_multiview_replaces_existing_view(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IExceptionViewClassifier from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IMultiView view = lambda *arg: 'OK' view.__phash__ = 'abc' config = self._makeOne(autocommit=True) 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, renderer=null_renderer ) wrapper = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError) ) self.assertTrue(IMultiView.providedBy(wrapper)) self.assertEqual(wrapper(None, None), 'OK') def test_add_view_multiview_replaces_existing_securedview(self): from pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import ISecuredView from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier view = lambda *arg: 'OK' view.__phash__ = 'abc' config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, Interface), ISecuredView, name='' ) config.add_view(view=view, renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertTrue(IMultiView.providedBy(wrapper)) self.assertEqual(wrapper(None, None), 'OK') def test_add_view_exc_multiview_replaces_existing_securedview(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import ISecuredView from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IExceptionViewClassifier view = lambda *arg: 'OK' view.__phash__ = 'abc' config = self._makeOne(autocommit=True) 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, renderer=null_renderer ) wrapper = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError) ) self.assertTrue(IMultiView.providedBy(wrapper)) self.assertEqual(wrapper(None, None), 'OK') def test_add_view_with_accept_multiview_replaces_existing_view(self): from pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier def view(context, request): return 'OK' def view2(context, request): return 'OK2' config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, Interface), IView, name='' ) config.add_view(view=view2, accept='text/html', renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertTrue(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_mixed_case_replaces_existing_view(self): from pyramid.renderers import null_renderer def view(context, request): return 'OK' def view2(context, request): # pragma: no cover return 'OK2' def view3(context, request): return 'OK3' config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) config.add_view(view=view2, accept='text/html', renderer=null_renderer) config.add_view(view=view3, accept='text/HTML', renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertTrue(IMultiView.providedBy(wrapper)) self.assertEqual(len(wrapper.media_views.items()), 1) self.assertFalse('text/HTML' in wrapper.media_views) self.assertEqual(wrapper(None, None), 'OK') request = DummyRequest() request.accept = DummyAccept('text/html', 'text/html') self.assertEqual(wrapper(None, request), 'OK3') def test_add_views_with_accept_multiview_replaces_existing(self): from pyramid.renderers import null_renderer def view(context, request): return 'OK' def view2(context, request): # pragma: no cover return 'OK2' def view3(context, request): return 'OK3' config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) config.add_view(view=view2, accept='text/html', renderer=null_renderer) config.add_view(view=view3, accept='text/html', renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertEqual(len(wrapper.media_views['text/html']), 1) self.assertEqual(wrapper(None, None), 'OK') request = DummyRequest() request.accept = DummyAccept('text/html', 'text/html') self.assertEqual(wrapper(None, request), 'OK3') def test_add_view_exc_with_accept_multiview_replaces_existing_view(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IExceptionViewClassifier def view(context, request): return 'OK' def view2(context, request): return 'OK2' config = self._makeOne(autocommit=True) 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, renderer=null_renderer, ) wrapper = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError) ) self.assertTrue(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 pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IMultiView from pyramid.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(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, Interface), IView, name='' ) config.add_view(view=view2, renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertTrue(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_exc_mulview_replaces_existing_view_with___accept__(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier from pyramid.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(autocommit=True) 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, renderer=null_renderer ) wrapper = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError) ) self.assertTrue(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 pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier view = DummyMultiView() config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, Interface), IMultiView, name='' ) view2 = lambda *arg: 'OK2' config.add_view(view=view2, renderer=null_renderer) wrapper = self._getViewCallable(config) self.assertTrue(IMultiView.providedBy(wrapper)) self.assertEqual( [(x[0], x[2]) for x in wrapper.views], [(view2, None)] ) self.assertEqual(wrapper(None, None), 'OK1') def test_add_view_exc_multiview_replaces_multiviews(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IExceptionViewClassifier hot_view = DummyMultiView() exc_view = DummyMultiView() config = self._makeOne(autocommit=True) config.registry.registerAdapter( hot_view, (IViewClassifier, IRequest, implementedBy(RuntimeError)), IMultiView, name='', ) config.registry.registerAdapter( exc_view, (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), IMultiView, name='', ) view2 = lambda *arg: 'OK2' config.add_view( view=view2, context=RuntimeError, renderer=null_renderer ) hot_wrapper = self._getViewCallable( config, ctx_iface=implementedBy(RuntimeError) ) self.assertTrue(IMultiView.providedBy(hot_wrapper)) self.assertEqual( [(x[0], x[2]) for x in hot_wrapper.views], [(view2, None)] ) self.assertEqual(hot_wrapper(None, None), 'OK1') exc_wrapper = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError) ) self.assertTrue(IMultiView.providedBy(exc_wrapper)) self.assertEqual( [(x[0], x[2]) for x in exc_wrapper.views], [(view2, None)] ) self.assertEqual(exc_wrapper(None, None), 'OK1') def test_add_view_exc_multiview_replaces_only_exc_multiview(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IExceptionViewClassifier hot_view = DummyMultiView() exc_view = DummyMultiView() config = self._makeOne(autocommit=True) config.registry.registerAdapter( hot_view, (IViewClassifier, IRequest, implementedBy(RuntimeError)), IMultiView, name='', ) config.registry.registerAdapter( exc_view, (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), IMultiView, name='', ) view2 = lambda *arg: 'OK2' config.add_view( view=view2, context=RuntimeError, exception_only=True, renderer=null_renderer, ) hot_wrapper = self._getViewCallable( config, ctx_iface=implementedBy(RuntimeError) ) self.assertTrue(IMultiView.providedBy(hot_wrapper)) self.assertEqual(len(hot_wrapper.views), 0) self.assertEqual(hot_wrapper(None, None), 'OK1') exc_wrapper = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError) ) self.assertTrue(IMultiView.providedBy(exc_wrapper)) self.assertEqual( [(x[0], x[2]) for x in exc_wrapper.views], [(view2, None)] ) self.assertEqual(exc_wrapper(None, None), 'OK1') def test_add_view_multiview_context_superclass_then_subclass(self): from pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier class ISuper(Interface): pass class ISub(ISuper): pass view = lambda *arg: 'OK' view2 = lambda *arg: 'OK2' config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, ISuper), IView, name='' ) config.add_view(view=view2, for_=ISub, renderer=null_renderer) wrapper = self._getViewCallable( config, ctx_iface=ISuper, request_iface=IRequest ) self.assertFalse(IMultiView.providedBy(wrapper)) self.assertEqual(wrapper(None, None), 'OK') wrapper = self._getViewCallable( config, ctx_iface=ISub, request_iface=IRequest ) self.assertFalse(IMultiView.providedBy(wrapper)) self.assertEqual(wrapper(None, None), 'OK2') def test_add_view_multiview_exception_superclass_then_subclass(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IMultiView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IExceptionViewClassifier class Super(Exception): pass class Sub(Super): pass view = lambda *arg: 'OK' view2 = lambda *arg: 'OK2' config = self._makeOne(autocommit=True) 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, renderer=null_renderer) wrapper = self._getViewCallable( config, ctx_iface=implementedBy(Super), request_iface=IRequest ) wrapper_exc_view = self._getViewCallable( config, exc_iface=implementedBy(Super), request_iface=IRequest ) self.assertEqual(wrapper_exc_view, wrapper) self.assertFalse(IMultiView.providedBy(wrapper_exc_view)) self.assertEqual(wrapper_exc_view(None, None), 'OK') wrapper = self._getViewCallable( config, ctx_iface=implementedBy(Sub), request_iface=IRequest ) wrapper_exc_view = self._getViewCallable( config, exc_iface=implementedBy(Sub), request_iface=IRequest ) self.assertEqual(wrapper_exc_view, wrapper) self.assertFalse(IMultiView.providedBy(wrapper_exc_view)) self.assertEqual(wrapper_exc_view(None, None), 'OK2') def test_add_view_multiview_call_ordering(self): from pyramid.renderers import null_renderer as nr from zope.interface import directlyProvides def view1(context, request): return 'view1' def view2(context, request): return 'view2' def view3(context, request): return 'view3' def view4(context, request): return 'view4' def view5(context, request): return 'view5' def view6(context, request): return 'view6' def view7(context, request): return 'view7' def view8(context, request): return 'view8' config = self._makeOne(autocommit=True) config.add_view(view=view1, renderer=nr) config.add_view(view=view2, request_method='POST', renderer=nr) config.add_view(view=view3, request_param='param', renderer=nr) config.add_view(view=view4, containment=IDummy, renderer=nr) config.add_view( view=view5, request_method='POST', request_param='param', renderer=nr, ) config.add_view( view=view6, request_method='POST', containment=IDummy, renderer=nr ) config.add_view( view=view7, request_param='param', containment=IDummy, renderer=nr ) config.add_view( view=view8, request_method='POST', request_param='param', containment=IDummy, renderer=nr, ) wrapper = self._getViewCallable(config) ctx = DummyContext() request = self._makeRequest(config) request.method = 'GET' request.params = {} self.assertEqual(wrapper(ctx, request), 'view1') ctx = DummyContext() request = self._makeRequest(config) request.params = {} request.method = 'POST' self.assertEqual(wrapper(ctx, request), 'view2') ctx = DummyContext() request = self._makeRequest(config) request.params = {'param': '1'} request.method = 'GET' self.assertEqual(wrapper(ctx, request), 'view3') ctx = DummyContext() directlyProvides(ctx, IDummy) request = self._makeRequest(config) request.method = 'GET' request.params = {} self.assertEqual(wrapper(ctx, request), 'view4') ctx = DummyContext() request = self._makeRequest(config) request.method = 'POST' request.params = {'param': '1'} self.assertEqual(wrapper(ctx, request), 'view5') ctx = DummyContext() directlyProvides(ctx, IDummy) request = self._makeRequest(config) request.params = {} request.method = 'POST' self.assertEqual(wrapper(ctx, request), 'view6') ctx = DummyContext() directlyProvides(ctx, IDummy) request = self._makeRequest(config) request.method = 'GET' request.params = {'param': '1'} self.assertEqual(wrapper(ctx, request), 'view7') ctx = DummyContext() directlyProvides(ctx, IDummy) request = self._makeRequest(config) request.method = 'POST' request.params = {'param': '1'} self.assertEqual(wrapper(ctx, request), 'view8') def test_view_with_most_specific_predicate(self): from pyramid.renderers import null_renderer as nr from pyramid.router import Router class OtherBase(object): pass class Int1(object): pass class Int2(object): pass class Resource(OtherBase, Int1, Int2): def __init__(self, request): pass def unknown(context, request): # pragma: no cover return 'unknown' def view(context, request): return 'hello' config = self._makeOne(autocommit=True) config.add_route('root', '/', factory=Resource) config.add_view(unknown, route_name='root', renderer=nr) config.add_view( view, renderer=nr, route_name='root', context=Int1, request_method='GET', ) config.add_view( view=view, renderer=nr, route_name='root', context=Int2, request_method='POST', ) request = self._makeRequest(config) request.method = 'POST' request.params = {} router = Router(config.registry) response = router.handle_request(request) self.assertEqual(response, 'hello') def test_view_with_most_specific_predicate_with_mismatch(self): from pyramid.renderers import null_renderer as nr from pyramid.router import Router class OtherBase(object): pass class Int1(object): pass class Int2(object): pass class Resource(OtherBase, Int1, Int2): def __init__(self, request): pass def unknown(context, request): # pragma: no cover return 'unknown' def view(context, request): return 'hello' config = self._makeOne(autocommit=True) config.add_route('root', '/', factory=Resource) config.add_view( unknown, route_name='root', renderer=nr, request_method=('POST',), xhr=True, ) config.add_view( view, renderer=nr, route_name='root', context=Int1, request_method='GET', ) config.add_view( view=view, renderer=nr, route_name='root', context=Int2, request_method='POST', ) request = self._makeRequest(config) request.method = 'POST' request.params = {} router = Router(config.registry) response = router.handle_request(request) self.assertEqual(response, 'hello') def test_add_view_multiview___discriminator__(self): from pyramid.renderers import null_renderer from zope.interface import Interface class IFoo(Interface): pass class IBar(Interface): pass @implementer(IFoo) class Foo(object): pass @implementer(IBar) class Bar(object): pass foo = Foo() bar = Bar() from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IMultiView view = lambda *arg: 'OK' view.__phash__ = 'abc' config = self._makeOne(autocommit=True) config.registry.registerAdapter( view, (IViewClassifier, IRequest, Interface), IView, name='' ) config.add_view(view=view, renderer=null_renderer, containment=IFoo) config.add_view(view=view, renderer=null_renderer, containment=IBar) wrapper = self._getViewCallable(config) self.assertTrue(IMultiView.providedBy(wrapper)) request = self._makeRequest(config) self.assertNotEqual( wrapper.__discriminator__(foo, request), wrapper.__discriminator__(bar, request), ) def test_add_view_with_template_renderer(self): from tests import test_config from pyramid.interfaces import ISettings class view(object): def __init__(self, context, request): self.request = request self.context = context def __call__(self): return {'a': '1'} config = self._makeOne(autocommit=True) renderer = self._registerRenderer(config) fixture = 'tests.test_config:files/minimal.txt' config.introspection = False config.add_view(view=view, renderer=fixture) wrapper = self._getViewCallable(config) request = self._makeRequest(config) result = wrapper(None, request) self.assertEqual(result.body, b'Hello!') settings = config.registry.queryUtility(ISettings) result = renderer.info self.assertEqual(result.registry, config.registry) self.assertEqual(result.type, '.txt') self.assertEqual(result.package, test_config) self.assertEqual(result.name, fixture) self.assertEqual(result.settings, settings) def test_add_view_with_default_renderer(self): class view(object): def __init__(self, context, request): self.request = request self.context = context def __call__(self): return {'a': '1'} config = self._makeOne(autocommit=True) class moo(object): def __init__(self, *arg, **kw): pass def __call__(self, *arg, **kw): return b'moo' config.add_renderer(None, moo) config.add_view(view=view) wrapper = self._getViewCallable(config) request = self._makeRequest(config) result = wrapper(None, request) self.assertEqual(result.body, b'moo') def test_add_view_with_template_renderer_no_callable(self): from tests import test_config from pyramid.interfaces import ISettings config = self._makeOne(autocommit=True) renderer = self._registerRenderer(config) fixture = 'tests.test_config:files/minimal.txt' config.introspection = False config.add_view(view=None, renderer=fixture) wrapper = self._getViewCallable(config) request = self._makeRequest(config) result = wrapper(None, request) self.assertEqual(result.body, b'Hello!') settings = config.registry.queryUtility(ISettings) result = renderer.info self.assertEqual(result.registry, config.registry) self.assertEqual(result.type, '.txt') self.assertEqual(result.package, test_config) self.assertEqual(result.name, fixture) self.assertEqual(result.settings, settings) def test_add_view_with_request_type_as_iface(self): from pyramid.renderers import null_renderer from zope.interface import directlyProvides def view(context, request): return 'OK' config = self._makeOne(autocommit=True) config.add_view(request_type=IDummy, view=view, renderer=null_renderer) wrapper = self._getViewCallable(config, None) request = self._makeRequest(config) directlyProvides(request, IDummy) result = wrapper(None, request) self.assertEqual(result, 'OK') def test_add_view_with_request_type_as_noniface(self): view = lambda *arg: 'OK' config = self._makeOne() self.assertRaises( ConfigurationError, config.add_view, view, '', None, None, object ) def test_add_view_with_route_name(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_route('foo', '/a/b') config.add_view(view=view, route_name='foo', renderer=null_renderer) request_iface = self._getRouteRequestIface(config, 'foo') self.assertNotEqual(request_iface, None) wrapper = self._getViewCallable(config, request_iface=request_iface) self.assertNotEqual(wrapper, None) self.assertEqual(wrapper(None, None), 'OK') def test_add_view_with_nonexistant_route_name(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne() config.add_view(view=view, route_name='foo', renderer=null_renderer) self.assertRaises(ConfigurationExecutionError, config.commit) def test_add_view_with_route_name_exception(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_route('foo', '/a/b') config.add_view( view=view, route_name='foo', context=RuntimeError, renderer=null_renderer, ) request_iface = self._getRouteRequestIface(config, 'foo') wrapper_exc_view = self._getViewCallable( config, exc_iface=implementedBy(RuntimeError), request_iface=request_iface, ) self.assertNotEqual(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): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( view=view, request_method='POST', renderer=null_renderer ) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.method = 'POST' self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_request_method_false(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, request_method='POST') wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.method = 'GET' self._assertNotFound(wrapper, None, request) def test_add_view_with_request_method_sequence_true(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( view=view, request_method=('POST', 'GET'), renderer=null_renderer ) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.method = 'POST' self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_request_method_sequence_conflict(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne() config.add_view( view=view, request_method=('POST', 'GET'), renderer=null_renderer ) config.add_view( view=view, request_method=('GET', 'POST'), renderer=null_renderer ) self.assertRaises(ConfigurationConflictError, config.commit) def test_add_view_with_request_method_sequence_false(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, request_method=('POST', 'HEAD')) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.method = 'GET' self._assertNotFound(wrapper, None, request) def test_add_view_with_request_method_get_implies_head(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( view=view, request_method='GET', renderer=null_renderer ) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.method = 'HEAD' self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_request_param_noval_true(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, request_param='abc', renderer=null_renderer) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.params = {'abc': ''} self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_request_param_noval_false(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, request_param='abc') wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.params = {} self._assertNotFound(wrapper, None, request) def test_add_view_with_request_param_val_true(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( view=view, request_param='abc=123', renderer=null_renderer ) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.params = {'abc': '123'} self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_request_param_val_false(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, request_param='abc=123') wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.params = {'abc': ''} self._assertNotFound(wrapper, None, request) def test_add_view_with_xhr_true(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, xhr=True, renderer=null_renderer) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.is_xhr = True self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_xhr_false(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, xhr=True) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.is_xhr = False self._assertNotFound(wrapper, None, request) def test_add_view_with_header_badregex(self): view = lambda *arg: 'OK' config = self._makeOne() config.add_view(view, header='Host:a\\') self.assertRaises(ConfigurationError, config.commit) def test_add_view_with_header_noval_match(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, header='Host', renderer=null_renderer) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.headers = {'Host': 'whatever'} self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_header_noval_nomatch(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, header='Host') wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.headers = {'NotHost': 'whatever'} self._assertNotFound(wrapper, None, request) def test_add_view_with_header_val_match(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, header=r'Host:\d', renderer=null_renderer) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.headers = {'Host': '1'} self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_header_val_nomatch(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, header=r'Host:\d') wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.headers = {'Host': 'abc'} self._assertNotFound(wrapper, None, request) def test_add_view_with_header_val_missing(self): from pyramid.httpexceptions import HTTPNotFound view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, header=r'Host:\d') wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.headers = {'NoHost': '1'} self.assertRaises(HTTPNotFound, wrapper, None, request) def test_add_view_with_accept_match(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, accept='text/xml', renderer=null_renderer) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.accept = DummyAccept('text/xml') self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_accept_nomatch(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, accept='text/xml') wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.accept = DummyAccept('text/html') self._assertNotFound(wrapper, None, request) def test_add_view_with_range_accept_match(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, accept='text/*', renderer=null_renderer) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.accept = DummyAccept('text/html', contains=True) self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_range_accept_nomatch(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, accept='text/*') wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.accept = DummyAccept('application/json', contains=False) self._assertNotFound(wrapper, None, request) def test_add_view_with_containment_true(self): from pyramid.renderers import null_renderer from zope.interface import directlyProvides view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, containment=IDummy, renderer=null_renderer) wrapper = self._getViewCallable(config) context = DummyContext() directlyProvides(context, IDummy) self.assertEqual(wrapper(context, None), 'OK') def test_add_view_with_containment_false(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, containment=IDummy) wrapper = self._getViewCallable(config) context = DummyContext() self._assertNotFound(wrapper, context, None) def test_add_view_with_containment_dottedname(self): from pyramid.renderers import null_renderer from zope.interface import directlyProvides view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( view=view, containment='tests.test_config.IDummy', renderer=null_renderer, ) wrapper = self._getViewCallable(config) context = DummyContext() directlyProvides(context, IDummy) self.assertEqual(wrapper(context, None), 'OK') def test_add_view_with_path_info_badregex(self): view = lambda *arg: 'OK' config = self._makeOne() config.add_view(view, path_info='\\') self.assertRaises(ConfigurationError, config.commit) def test_add_view_with_path_info_match(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, path_info='/foo', renderer=null_renderer) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.upath_info = text_(b'/foo') self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_path_info_nomatch(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, path_info='/foo') wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.upath_info = text_('/') self._assertNotFound(wrapper, None, request) def test_add_view_with_check_csrf_predicates_match(self): import warnings from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always') config.add_view(view=view, check_csrf=True, renderer=null_renderer) self.assertEqual(len(w), 1) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.method = "POST" request.session = DummySession({'csrf_token': 'foo'}) request.POST = {'csrf_token': 'foo'} request.headers = {} self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_custom_predicates_match(self): import warnings from pyramid.renderers import null_renderer view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) def pred1(context, request): return True def pred2(context, request): return True predicates = (pred1, pred2) with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always') config.add_view( view=view, custom_predicates=predicates, renderer=null_renderer ) self.assertEqual(len(w), 1) wrapper = self._getViewCallable(config) request = self._makeRequest(config) self.assertEqual(wrapper(None, request), 'OK') def test_add_view_with_custom_predicates_nomatch(self): import warnings view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) def pred1(context, request): return True def pred2(context, request): return False predicates = (pred1, pred2) with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always') config.add_view(view=view, custom_predicates=predicates) self.assertEqual(len(w), 1) wrapper = self._getViewCallable(config) request = self._makeRequest(config) self._assertNotFound(wrapper, None, request) def test_add_view_custom_predicate_bests_standard_predicate(self): import warnings from pyramid.renderers import null_renderer view = lambda *arg: 'OK' view2 = lambda *arg: 'NOT OK' config = self._makeOne(autocommit=True) def pred1(context, request): return True with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always') config.add_view( view=view, custom_predicates=(pred1,), renderer=null_renderer ) config.add_view( view=view2, request_method='GET', renderer=null_renderer ) self.assertEqual(len(w), 1) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.method = 'GET' self.assertEqual(wrapper(None, request), 'OK') def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self): from pyramid.renderers import null_renderer view = lambda *arg: 'OK' view2 = lambda *arg: 'NOT OK' config = self._makeOne(autocommit=True) config.add_view( view=view, request_method='GET', xhr=True, renderer=null_renderer ) config.add_view( view=view2, request_method='GET', renderer=null_renderer ) wrapper = self._getViewCallable(config) request = self._makeRequest(config) request.method = 'GET' 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) self.assertRaises(ConfigurationConflictError, config.commit) def test_add_view_with_csrf_param(self): from pyramid.renderers import null_renderer def view(request): return 'OK' config = self._makeOne(autocommit=True) config.add_view(view, require_csrf='st', renderer=null_renderer) view = self._getViewCallable(config) request = self._makeRequest(config) request.scheme = "http" request.method = 'POST' request.POST = {'st': 'foo'} request.headers = {} request.session = DummySession({'csrf_token': 'foo'}) self.assertEqual(view(None, request), 'OK') def test_add_view_with_csrf_header(self): from pyramid.renderers import null_renderer def view(request): return 'OK' config = self._makeOne(autocommit=True) config.add_view(view, require_csrf=True, renderer=null_renderer) view = self._getViewCallable(config) request = self._makeRequest(config) request.scheme = "http" request.method = 'POST' request.POST = {} request.headers = {'X-CSRF-Token': 'foo'} request.session = DummySession({'csrf_token': 'foo'}) self.assertEqual(view(None, request), 'OK') def test_add_view_with_missing_csrf_header(self): from pyramid.exceptions import BadCSRFToken from pyramid.renderers import null_renderer def view(request): # pragma: no cover return 'OK' config = self._makeOne(autocommit=True) config.add_view(view, require_csrf=True, renderer=null_renderer) view = self._getViewCallable(config) request = self._makeRequest(config) request.scheme = "http" request.method = 'POST' request.POST = {} request.headers = {} request.session = DummySession({'csrf_token': 'foo'}) self.assertRaises(BadCSRFToken, lambda: view(None, request)) def test_add_view_with_permission(self): from pyramid.renderers import null_renderer view1 = lambda *arg: 'OK' outerself = self class DummyPolicy(object): def effective_principals(self, r): outerself.assertEqual(r, request) return ['abc'] def permits(self, context, principals, permission): outerself.assertEqual(context, None) outerself.assertEqual(principals, ['abc']) outerself.assertEqual(permission, 'view') return True policy = DummyPolicy() config = self._makeOne( authorization_policy=policy, authentication_policy=policy, autocommit=True, ) config.add_view(view=view1, permission='view', renderer=null_renderer) view = self._getViewCallable(config) request = self._makeRequest(config) self.assertEqual(view(None, request), 'OK') def test_add_view_with_default_permission_no_explicit_permission(self): from pyramid.renderers import null_renderer view1 = lambda *arg: 'OK' outerself = self class DummyPolicy(object): def effective_principals(self, r): outerself.assertEqual(r, request) return ['abc'] def permits(self, context, principals, permission): outerself.assertEqual(context, None) outerself.assertEqual(principals, ['abc']) outerself.assertEqual(permission, 'view') return True policy = DummyPolicy() config = self._makeOne( authorization_policy=policy, authentication_policy=policy, default_permission='view', autocommit=True, ) config.add_view(view=view1, renderer=null_renderer) view = self._getViewCallable(config) request = self._makeRequest(config) self.assertEqual(view(None, request), 'OK') def test_add_view_with_no_default_permission_no_explicit_permission(self): from pyramid.renderers import null_renderer view1 = lambda *arg: 'OK' class DummyPolicy(object): pass # wont be called policy = DummyPolicy() config = self._makeOne( authorization_policy=policy, authentication_policy=policy, autocommit=True, ) config.add_view(view=view1, renderer=null_renderer) view = self._getViewCallable(config) request = self._makeRequest(config) self.assertEqual(view(None, request), 'OK') def test_add_view_with_mapper(self): from pyramid.renderers import null_renderer class Mapper(object): def __init__(self, **kw): self.__class__.kw = kw def __call__(self, view): return view config = self._makeOne(autocommit=True) def view(context, request): return 'OK' config.add_view(view=view, mapper=Mapper, renderer=null_renderer) view = self._getViewCallable(config) self.assertEqual(view(None, None), 'OK') self.assertEqual(Mapper.kw['mapper'], Mapper) def test_add_view_with_view_defaults(self): from pyramid.renderers import null_renderer from pyramid.exceptions import PredicateMismatch from zope.interface import directlyProvides class view(object): __view_defaults__ = {'containment': 'tests.test_config.IDummy'} def __init__(self, request): pass def __call__(self): return 'OK' config = self._makeOne(autocommit=True) config.add_view(view=view, renderer=null_renderer) wrapper = self._getViewCallable(config) context = DummyContext() directlyProvides(context, IDummy) request = self._makeRequest(config) self.assertEqual(wrapper(context, request), 'OK') context = DummyContext() request = self._makeRequest(config) self.assertRaises(PredicateMismatch, wrapper, context, request) def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self): from pyramid.renderers import null_renderer from pyramid.exceptions import PredicateMismatch from zope.interface import directlyProvides config = self._makeOne(autocommit=True) config.add_view( view='tests.test_config.test_views.DummyViewDefaultsClass', renderer=null_renderer, ) wrapper = self._getViewCallable(config) context = DummyContext() directlyProvides(context, IDummy) request = self._makeRequest(config) self.assertEqual(wrapper(context, request), 'OK') context = DummyContext() request = self._makeRequest(config) self.assertRaises(PredicateMismatch, wrapper, context, request) def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self): from pyramid.renderers import null_renderer from pyramid.exceptions import PredicateMismatch from zope.interface import directlyProvides config = self._makeOne(autocommit=True) config.add_view( 'tests.test_config.test_views.DummyViewDefaultsClass', renderer=null_renderer, ) wrapper = self._getViewCallable(config) context = DummyContext() directlyProvides(context, IDummy) request = self._makeRequest(config) self.assertEqual(wrapper(context, request), 'OK') context = DummyContext() request = self._makeRequest(config) self.assertRaises(PredicateMismatch, wrapper, context, request) def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self): from pyramid.renderers import null_renderer class view(object): __view_defaults__ = {'containment': 'tests.test_config.IDummy'} class view2(object): __view_defaults__ = {'containment': 'tests.test_config.IFactory'} config = self._makeOne(autocommit=False) config.add_view(view=view, renderer=null_renderer) config.add_view(view=view2, renderer=null_renderer) config.commit() # does not raise def test_add_view_with_view_config_and_view_defaults_conflicts(self): from pyramid.renderers import null_renderer class view(object): __view_defaults__ = {'containment': 'tests.test_config.IDummy'} class view2(object): __view_defaults__ = {'containment': 'tests.test_config.IDummy'} config = self._makeOne(autocommit=False) config.add_view(view=view, renderer=null_renderer) config.add_view(view=view2, renderer=null_renderer) self.assertRaises(ConfigurationConflictError, config.commit) def test_add_view_class_method_no_attr(self): from pyramid.renderers import null_renderer from pyramid.exceptions import ConfigurationError config = self._makeOne(autocommit=True) class DummyViewClass(object): def run(self): # pragma: no cover pass def configure_view(): config.add_view(view=DummyViewClass.run, renderer=null_renderer) self.assertRaises(ConfigurationError, configure_view) def test_add_view_exception_only_no_regular_view(self): from zope.interface import implementedBy from pyramid.renderers import null_renderer view1 = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( view=view1, context=Exception, exception_only=True, renderer=null_renderer, ) view = self._getViewCallable( config, ctx_iface=implementedBy(Exception) ) self.assertTrue(view is None) def test_add_view_exception_only(self): from zope.interface import implementedBy from pyramid.renderers import null_renderer view1 = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_view( view=view1, context=Exception, exception_only=True, renderer=null_renderer, ) view = self._getViewCallable( config, exc_iface=implementedBy(Exception) ) self.assertEqual(view1, view) def test_add_view_exception_only_misconfiguration(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) class NotAnException(object): pass self.assertRaises( ConfigurationError, config.add_view, view, context=NotAnException, exception_only=True, ) def test_add_exception_view(self): from zope.interface import implementedBy from pyramid.renderers import null_renderer view1 = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_exception_view(view=view1, renderer=null_renderer) wrapper = self._getViewCallable( config, exc_iface=implementedBy(Exception) ) context = Exception() request = self._makeRequest(config) self.assertEqual(wrapper(context, request), 'OK') def test_add_exception_view_with_subclass(self): from zope.interface import implementedBy from pyramid.renderers import null_renderer view1 = lambda *arg: 'OK' config = self._makeOne(autocommit=True) config.add_exception_view( view=view1, context=ValueError, renderer=null_renderer ) wrapper = self._getViewCallable( config, exc_iface=implementedBy(ValueError) ) context = ValueError() request = self._makeRequest(config) self.assertEqual(wrapper(context, request), 'OK') def test_add_exception_view_disallows_name(self): config = self._makeOne(autocommit=True) self.assertRaises( ConfigurationError, config.add_exception_view, context=Exception(), name='foo', ) def test_add_exception_view_disallows_permission(self): config = self._makeOne(autocommit=True) self.assertRaises( ConfigurationError, config.add_exception_view, context=Exception(), permission='foo', ) def test_add_exception_view_disallows_require_csrf(self): config = self._makeOne(autocommit=True) self.assertRaises( ConfigurationError, config.add_exception_view, context=Exception(), require_csrf=True, ) def test_add_exception_view_disallows_for_(self): config = self._makeOne(autocommit=True) self.assertRaises( ConfigurationError, config.add_exception_view, context=Exception(), for_='foo', ) def test_add_exception_view_disallows_exception_only(self): config = self._makeOne(autocommit=True) self.assertRaises( ConfigurationError, config.add_exception_view, context=Exception(), exception_only=True, ) def test_add_exception_view_with_view_defaults(self): from pyramid.renderers import null_renderer from pyramid.exceptions import PredicateMismatch from zope.interface import directlyProvides from zope.interface import implementedBy class view(object): __view_defaults__ = {'containment': 'tests.test_config.IDummy'} def __init__(self, request): pass def __call__(self): return 'OK' config = self._makeOne(autocommit=True) config.add_exception_view( view=view, context=Exception, renderer=null_renderer ) wrapper = self._getViewCallable( config, exc_iface=implementedBy(Exception) ) context = DummyContext() directlyProvides(context, IDummy) request = self._makeRequest(config) self.assertEqual(wrapper(context, request), 'OK') context = DummyContext() request = self._makeRequest(config) self.assertRaises(PredicateMismatch, wrapper, context, request) def test_derive_view_function(self): from pyramid.renderers import null_renderer def view(request): return 'OK' config = self._makeOne() result = config.derive_view(view, renderer=null_renderer) self.assertFalse(result is view) self.assertEqual(result(None, None), 'OK') def test_derive_view_dottedname(self): from pyramid.renderers import null_renderer config = self._makeOne() result = config.derive_view( 'tests.test_config.dummy_view', renderer=null_renderer ) self.assertFalse(result is dummy_view) self.assertEqual(result(None, None), 'OK') def test_derive_view_with_default_renderer_no_explicit_renderer(self): config = self._makeOne() class moo(object): def __init__(self, view): pass def __call__(self, *arg, **kw): return 'moo' config.add_renderer(None, moo) config.commit() def view(request): return 'OK' result = config.derive_view(view) self.assertFalse(result is view) self.assertEqual(result(None, None).body, b'moo') def test_derive_view_with_default_renderer_with_explicit_renderer(self): class moo(object): pass class foo(object): def __init__(self, view): pass def __call__(self, *arg, **kw): return b'foo' def view(request): return 'OK' config = self._makeOne() config.add_renderer(None, moo) config.add_renderer('foo', foo) config.commit() result = config.derive_view(view, renderer='foo') self.assertFalse(result is view) request = self._makeRequest(config) self.assertEqual(result(None, request).body, b'foo') def test_add_static_view_here_no_utility_registered(self): from pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier config = self._makeOne(autocommit=True) config.add_static_view('static', 'files', renderer=null_renderer) request_type = self._getRouteRequestIface(config, '__static/') self._assertRoute(config, '__static/', 'static/*subpath') wrapped = config.registry.adapters.lookup( (IViewClassifier, request_type, Interface), IView, name='' ) from pyramid.request import Request request = Request.blank('/static/minimal.txt') request.subpath = ('minimal.txt',) result = wrapped(None, request) self.assertEqual(result.status, '200 OK') self.assertTrue(result.body.startswith(b'