import os import unittest from zope.interface import implementer from pyramid import testing from pyramid.exceptions import ConfigurationError from pyramid.exceptions import ConfigurationExecutionError from pyramid.exceptions import ConfigurationConflictError from pyramid.interfaces import IResponse, IRequest, IMultiView from pyramid.util import text_ 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.path_info = '/' 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.path_info = '/' 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_wildcard_accept_raises(self): view = lambda *arg: 'OK' config = self._makeOne(autocommit=True) self.assertRaises( ValueError, lambda: config.add_view(view=view, accept='text/*') ) 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_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 identify(self, r): outerself.assertEqual(r, request) return 123 def permits(self, r, context, permission): outerself.assertEqual(r, request) outerself.assertEqual(context, None) outerself.assertEqual(permission, 'view') return True policy = DummyPolicy() config = self._makeOne(security_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 identify(self, r): outerself.assertEqual(r, request) return 123 def permits(self, r, context, permission): outerself.assertEqual(r, request) outerself.assertEqual(context, None) outerself.assertEqual(permission, 'view') return True policy = DummyPolicy() config = self._makeOne( security_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'