diff options
| author | Chris McDonough <chrism@plope.com> | 2011-08-31 03:48:02 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-08-31 03:48:02 -0400 |
| commit | 49f0829352e52ee3ef7643905e534207210204f6 (patch) | |
| tree | 033dbfb296b9f78a65aee6e6d0c10c88f0669e32 | |
| parent | 1aeae3565e07b99e737e6572ac5ba1b1bbf42abb (diff) | |
| download | pyramid-49f0829352e52ee3ef7643905e534207210204f6.tar.gz pyramid-49f0829352e52ee3ef7643905e534207210204f6.tar.bz2 pyramid-49f0829352e52ee3ef7643905e534207210204f6.zip | |
- The ``request_method`` predicate argument to
``pyramid.config.Configurator.add_view`` and
``pyramid.config.Configurator.add_route`` is now permitted to be a tuple of
HTTP method names. Previously it was restricted to being a string
representing a single HTTP method name.
- Move add_view tests and tween tests to more reasonable places.
| -rw-r--r-- | CHANGES.txt | 6 | ||||
| -rw-r--r-- | TODO.txt | 21 | ||||
| -rw-r--r-- | docs/whatsnew-1.2.rst | 6 | ||||
| -rw-r--r-- | pyramid/config/routes.py | 14 | ||||
| -rw-r--r-- | pyramid/config/util.py | 18 | ||||
| -rw-r--r-- | pyramid/config/views.py | 21 | ||||
| -rw-r--r-- | pyramid/tests/test_config/pkgs/asset/__init__.py | 11 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_init.py | 1504 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_tweens.py | 164 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_util.py | 20 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_views.py | 1369 |
11 files changed, 1628 insertions, 1526 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index dd15e313e..7f2834542 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,12 @@ Features passed to ``venusian.Scanner.scan()`` to influence error behavior when an exception is raised during scanning. +- The ``request_method`` predicate argument to + ``pyramid.config.Configurator.add_view`` and + ``pyramid.config.Configurator.add_route`` is now permitted to be a tuple of + HTTP method names. Previously it was restricted to being a string + representing a single HTTP method name. + Dependencies ------------ @@ -8,13 +8,11 @@ Should-Have deploying via proxy: https://docs.pylonsproject.org/projects/pyramid_cookbook/dev/deployment/nginx.html#step-2-starting-paster -- Allow ``request_method`` predicate to be a list of methods. - Nice-to-Have ------------ -- Add a default-view-config-params decorator that can be applied to a class - which names defaults for method-based view_config decorator options. +- Consider adding exclog to all scaffolds to print tracebacks to the console + while the debug toolbar is enabled. - Flesh out "paste" chapter. @@ -29,8 +27,6 @@ Nice-to-Have - Deprecate pyramid.security.view_execution_permitted (it only works for traversal). -- Merge Michael's route group work (maybe a 1.3 thing). - - Some sort of API for rendering a view callable object to a response from within another view callable. @@ -92,11 +88,18 @@ Future - 1.3: Kill off ``bfg.routes`` envvars in router. -- 1.3: Kill off dependencies on Paste for non-deployment-related features. +- 1.3/1.4: Kill off dependencies on Paste for non-deployment-related + features. + +- 1.3/1.4: use zope.registry rather than zope.component. + +- 1.3/1.4: get rid of zope.configuration dependency. + +- 1.3: Michael's route group work -- 1.3: use zope.registry rather than zope.component. +- 1.3: Add a default-view-config-params decorator that can be applied to a + class which names defaults for method-based view_config decorator options. -- 1.3: get rid of zope.configuration dependency. Probably Bad Ideas ------------------ diff --git a/docs/whatsnew-1.2.rst b/docs/whatsnew-1.2.rst index 1ecf1d746..4147b4285 100644 --- a/docs/whatsnew-1.2.rst +++ b/docs/whatsnew-1.2.rst @@ -154,6 +154,12 @@ Minor Feature Additions :meth:`venusian.Scanner.scan` to influence error behavior when an exception is raised during scanning. +- The ``request_method`` predicate argument to + :meth:`pyramid.config.Configurator.add_view` and + :meth:`pyramid.config.Configurator.add_route` is now permitted to be a + tuple of HTTP method names. Previously it was restricted to being a string + representing a single HTTP method name. + Deprecations ------------ diff --git a/pyramid/config/routes.py b/pyramid/config/routes.py index 6de9b6e59..17e2073f3 100644 --- a/pyramid/config/routes.py +++ b/pyramid/config/routes.py @@ -164,11 +164,15 @@ class RoutesConfiguratorMixin(object): request_method - A string representing an HTTP method name, e.g. ``GET``, - ``POST``, ``HEAD``, ``DELETE``, ``PUT``. If this argument - is not specified, this route will match if the request has - *any* request method. If this predicate returns ``False``, - route matching continues. + A string representing an HTTP method name, e.g. ``GET``, ``POST``, + ``HEAD``, ``DELETE``, ``PUT`` or a tuple of elements containing + HTTP method names. If this argument is not specified, this route + will match if the request has *any* request method. If this + predicate returns ``False``, route matching continues. + + .. note:: The ability to pass a tuple of items as + ``request_method`` is new as of Pyramid 1.2. Previous + versions allowed only a string. path_info diff --git a/pyramid/config/util.py b/pyramid/config/util.py index c631da44c..298d73cfd 100644 --- a/pyramid/config/util.py +++ b/pyramid/config/util.py @@ -96,13 +96,17 @@ def make_predicates(xhr=None, request_method=None, path_info=None, h.update('xhr:%r' % bool(xhr)) if request_method is not None: + if not hasattr(request_method, '__iter__'): + request_method = (request_method,) + request_method = sorted(request_method) def request_method_predicate(context, request): - return request.method == request_method - text = "request method = %s" - request_method_predicate.__text__ = text % request_method + return request.method in request_method + text = "request method = %s" % repr(request_method) + request_method_predicate.__text__ = text weights.append(1 << 2) predicates.append(request_method_predicate) - h.update('request_method:%r' % request_method) + for m in request_method: + h.update('request_method:%r' % m) if path_info is not None: try: @@ -249,3 +253,9 @@ def make_predicates(xhr=None, request_method=None, path_info=None, phash = h.hexdigest() return order, predicates, phash +def as_sorted_tuple(val): + if not hasattr(val, '__iter__'): + val = (val,) + val = tuple(sorted(val)) + return val + diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 7e657905a..7def63962 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -42,6 +42,7 @@ from pyramid.config.util import MAX_ORDER from pyramid.config.util import DEFAULT_PHASH from pyramid.config.util import action_method from pyramid.config.util import make_predicates +from pyramid.config.util import as_sorted_tuple def wraps_view(wrapper): def inner(self, view): @@ -758,12 +759,17 @@ class ViewsConfiguratorMixin(object): request_method - This value can be one of the strings ``GET``, - ``POST``, ``PUT``, ``DELETE``, or ``HEAD`` representing an - HTTP ``REQUEST_METHOD``. A view declaration with this - argument ensures that the view will only be called when the - request's ``method`` attribute (aka the ``REQUEST_METHOD`` of - the WSGI environment) string matches the supplied value. + This value can be one of the strings ``GET``, ``POST``, ``PUT``, + ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``, or + a tuple containing one or more of these strings. A view + declaration with this argument ensures that the view will only be + called when the request's ``method`` attribute (aka the + ``REQUEST_METHOD`` of the WSGI environment) string matches a + supplied value. + + .. note:: The ability to pass a tuple of items as + ``request_method`` is new as of Pyramid 1.2. Previous + versions allowed only a string. request_param @@ -888,6 +894,9 @@ class ViewsConfiguratorMixin(object): raise ConfigurationError( 'request_type must be an interface, not %s' % request_type) + if request_method is not None: + request_method = as_sorted_tuple(request_method) + order, predicates, phash = make_predicates(xhr=xhr, request_method=request_method, path_info=path_info, request_param=request_param, header=header, accept=accept, diff --git a/pyramid/tests/test_config/pkgs/asset/__init__.py b/pyramid/tests/test_config/pkgs/asset/__init__.py index c74747bfd..db5619fbc 100644 --- a/pyramid/tests/test_config/pkgs/asset/__init__.py +++ b/pyramid/tests/test_config/pkgs/asset/__init__.py @@ -1,12 +1,3 @@ -def includeme(config): - config.add_view('.views.fixture_view') - config.add_view('.views.exception_view', context=RuntimeError) - config.add_view('.views.protected_view', name='protected.html') - config.add_view('.views.erroneous_view', name='error.html') - config.add_view('.views.fixture_view', name='dummyskin.html', - request_type='.views.IDummy') - from models import fixture, IFixture - config.registry.registerUtility(fixture, IFixture) - config.add_view('.views.fixture_view', name='another.html') +# package diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index 1c1f1ca15..f27fba9e4 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -13,7 +13,6 @@ locale3 = os.path.abspath( os.path.join(here, '..', 'localeapp', 'locale3')) from pyramid.tests.test_config import dummy_tween_factory -from pyramid.tests.test_config import dummy_tween_factory2 from pyramid.tests.test_config import dummyfactory from pyramid.tests.test_config import dummy_include from pyramid.tests.test_config import dummy_view @@ -32,19 +31,6 @@ class ConfiguratorTests(unittest.TestCase): config = Configurator(*arg, **kw) return config - def _registerRenderer(self, config, name='.txt'): - from pyramid.interfaces import IRendererFactory - from pyramid.interfaces import ITemplateRenderer - from zope.interface import implements - class Renderer: - implements(ITemplateRenderer) - def __init__(self, info): - self.__class__.info = info - def __call__(self, *arg): - return 'Hello!' - config.registry.registerUtility(Renderer, IRendererFactory, name=name) - return Renderer - def _getViewCallable(self, config, ctx_iface=None, request_iface=None, name='', exception_view=False): from zope.interface import Interface @@ -52,7 +38,7 @@ class ConfiguratorTests(unittest.TestCase): from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IExceptionViewClassifier - if exception_view: + if exception_view: # pragma: no cover classifier = IExceptionViewClassifier else: classifier = IViewClassifier @@ -69,10 +55,6 @@ class ConfiguratorTests(unittest.TestCase): iface = config.registry.getUtility(IRouteRequest, name) return iface - def _assertNotFound(self, wrapper, *arg): - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, wrapper, *arg) - def _registerEventListener(self, config, event_iface=None): if event_iface is None: # pragma: no cover from zope.interface import Interface @@ -94,6 +76,17 @@ class ConfiguratorTests(unittest.TestCase): for confinst in conflict: yield confinst[2] + 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_ctor_no_registry(self): import sys from pyramid.interfaces import ISettings @@ -718,161 +711,6 @@ pyramid.tests.test_config.dummy_include2""", settings = reg.getUtility(ISettings) self.assertEqual(settings['a'], 1) - def test_add_tweens_names_distinct(self): - from pyramid.interfaces import ITweens - from pyramid.tweens import excview_tween_factory - def factory1(handler, registry): return handler - def factory2(handler, registry): return handler - config = self._makeOne() - config.add_tween( - 'pyramid.tests.test_config.dummy_tween_factory') - config.add_tween( - 'pyramid.tests.test_config.dummy_tween_factory2') - config.commit() - tweens = config.registry.queryUtility(ITweens) - implicit = tweens.implicit() - self.assertEqual( - implicit, - [ - ('pyramid.tests.test_config.dummy_tween_factory2', - dummy_tween_factory2), - ('pyramid.tests.test_config.dummy_tween_factory', - dummy_tween_factory), - ('pyramid.tweens.excview_tween_factory', - excview_tween_factory), - ] - ) - - def test_add_tweens_names_with_underover(self): - from pyramid.interfaces import ITweens - from pyramid.tweens import excview_tween_factory - from pyramid.tweens import MAIN - config = self._makeOne() - config.add_tween( - 'pyramid.tests.test_config.dummy_tween_factory', - over=MAIN) - config.add_tween( - 'pyramid.tests.test_config.dummy_tween_factory2', - over=MAIN, - under='pyramid.tests.test_config.dummy_tween_factory') - config.commit() - tweens = config.registry.queryUtility(ITweens) - implicit = tweens.implicit() - self.assertEqual( - implicit, - [ - ('pyramid.tweens.excview_tween_factory', excview_tween_factory), - ('pyramid.tests.test_config.dummy_tween_factory', - dummy_tween_factory), - ('pyramid.tests.test_config.dummy_tween_factory2', - dummy_tween_factory2), - ]) - - def test_add_tweens_names_with_under_nonstringoriter(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises( - ConfigurationError, config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - under=False) - - def test_add_tweens_names_with_over_nonstringoriter(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises( - ConfigurationError, config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - over=False) - - def test_add_tween_dottedname(self): - from pyramid.interfaces import ITweens - from pyramid.tweens import excview_tween_factory - config = self._makeOne() - config.add_tween('pyramid.tests.test_config.dummy_tween_factory') - config.commit() - tweens = config.registry.queryUtility(ITweens) - self.assertEqual( - tweens.implicit(), - [ - ('pyramid.tests.test_config.dummy_tween_factory', - dummy_tween_factory), - ('pyramid.tweens.excview_tween_factory', - excview_tween_factory), - ]) - - def test_add_tween_instance(self): - from pyramid.exceptions import ConfigurationError - class ATween(object): pass - atween = ATween() - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_tween, atween) - - def test_add_tween_unsuitable(self): - from pyramid.exceptions import ConfigurationError - import pyramid.tests.test_config - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_tween, - pyramid.tests.test_config) - - def test_add_tween_name_ingress(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import INGRESS - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_tween, INGRESS) - - def test_add_tween_name_main(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import MAIN - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_tween, MAIN) - - def test_add_tweens_conflict(self): - from zope.configuration.config import ConfigurationConflictError - config = self._makeOne() - config.add_tween('pyramid.tests.test_config.dummy_tween_factory') - config.add_tween('pyramid.tests.test_config.dummy_tween_factory') - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_add_tween_over_ingress(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import INGRESS - config = self._makeOne() - self.assertRaises( - ConfigurationError, - config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - over=INGRESS) - - def test_add_tween_over_ingress_iterable(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import INGRESS - config = self._makeOne() - self.assertRaises( - ConfigurationError, - config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - over=('a', INGRESS)) - - def test_add_tween_under_main(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import MAIN - config = self._makeOne() - self.assertRaises( - ConfigurationError, - config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - under=MAIN) - - def test_add_tween_under_main_iterable(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import MAIN - config = self._makeOne() - self.assertRaises( - ConfigurationError, - config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - under=('a', MAIN)) - def test_add_subscriber_defaults(self): from zope.interface import implements from zope.interface import Interface @@ -1049,1283 +887,6 @@ pyramid.tests.test_config.dummy_include2""", newconfig = config.with_context(ctx) self.assertEqual(newconfig._ctx, ctx) - def test_add_view_view_callable_None_no_renderer(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne(autocommit=True) - self.assertRaises(ConfigurationError, config.add_view) - - def test_add_view_with_request_type_and_route_name(self): - from pyramid.exceptions import ConfigurationError - 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('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__) - - def test_add_view_view_callable_dottedname(self): - from pyramid.renderers import null_renderer - config = self._makeOne(autocommit=True) - config.add_view(view='pyramid.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_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_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_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='pyramid.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_='pyramid.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('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('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, ctx_iface=implementedBy(RuntimeError), exception_view=True) - 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) - 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.renderers import null_renderer - from pyramid.config.util import DEFAULT_PHASH - 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.renderers import null_renderer - from pyramid.config.util import DEFAULT_PHASH - 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) - 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) - 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) - 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_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, ctx_iface=implementedBy(RuntimeError), exception_view=True) - 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) - 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[:2] for x in wrapper.views], [(view2, None)]) - self.assertEqual(wrapper(None, None), 'OK1') - - def test_add_view_exc_multiview_replaces_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 - view = DummyMultiView() - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IMultiView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IMultiView, name='') - view2 = lambda *arg: 'OK2' - config.add_view(view=view2, context=RuntimeError, - renderer=null_renderer) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), exception_view=True) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)]) - self.assertEqual(wrapper(None, None), 'OK1') - - def test_add_view_multiview_context_superclass_then_subclass(self): - 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, ISuper, IRequest) - self.assertFalse(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - wrapper = self._getViewCallable(config, ISub, 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, implementedBy(Super), IRequest) - wrapper_exc_view = self._getViewCallable( - config, implementedBy(Super), IRequest, exception_view=True) - 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, implementedBy(Sub), IRequest) - wrapper_exc_view = self._getViewCallable( - config, implementedBy(Sub), IRequest, exception_view=True) - 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_add_view_with_template_renderer(self): - from pyramid.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 = 'pyramid.tests.test_config:files/minimal.txt' - config.add_view(view=view, renderer=fixture) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - result = wrapper(None, request) - self.assertEqual(result.body, '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 '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, 'moo') - - def test_add_view_with_template_renderer_no_callable(self): - from pyramid.tests import test_config - from pyramid.interfaces import ISettings - config = self._makeOne(autocommit=True) - renderer = self._registerRenderer(config) - fixture = 'pyramid.tests.test_config:files/minimal.txt' - config.add_view(view=None, renderer=fixture) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - result = wrapper(None, request) - self.assertEqual(result.body, '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): - from pyramid.exceptions import ConfigurationError - 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 - from zope.configuration.config import ConfigurationExecutionError - 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, ctx_iface=implementedBy(RuntimeError), - request_iface=request_iface, exception_view=True) - 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_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): - from pyramid.exceptions import ConfigurationError - view = lambda *arg: 'OK' - config = self._makeOne() - self.assertRaises(ConfigurationError, - config.add_view, view=view, header='Host:a\\') - - 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 = ['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 = ['text/html'] - 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='pyramid.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): - from pyramid.exceptions import ConfigurationError - view = lambda *arg: 'OK' - config = self._makeOne() - self.assertRaises(ConfigurationError, - config.add_view, view=view, path_info='\\') - - 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.path_info = '/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.path_info = '/' - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_custom_predicates_match(self): - 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) - config.add_view(view=view, custom_predicates=predicates, - renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_custom_predicates_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - def pred1(context, request): - return True - def pred2(context, request): - return False - predicates = (pred1, pred2) - config.add_view(view=view, custom_predicates=predicates) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - self._assertNotFound(wrapper, None, request) - - def test_add_view_custom_predicate_bests_standard_predicate(self): - 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 - config.add_view(view=view, custom_predicates=(pred1,), - 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' - 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): - from zope.configuration.config import ConfigurationConflictError - 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_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 _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_get_routes_mapper_not_yet_registered(self): config = self._makeOne() mapper = config.get_routes_mapper() @@ -3872,20 +2433,6 @@ class DummyResponse: app_iter = () body = '' -from zope.interface import implements -from pyramid.interfaces import IMultiView -class DummyMultiView: - implements(IMultiView) - def __init__(self): - self.views = [] - self.name = 'name' - def add(self, view, order, accept=None, phash=None): - self.views.append((view, accept, phash)) - def __call__(self, context, request): - return 'OK1' - def __permitted__(self, context, request): - """ """ - class DummyThreadLocalManager(object): pushed = None popped = False @@ -3894,6 +2441,7 @@ class DummyThreadLocalManager(object): def pop(self): self.popped = True +from zope.interface import implements class DummyEvent: implements(IDummy) @@ -3923,32 +2471,6 @@ from pyramid.interfaces import IResponse class DummyResponse(object): implements(IResponse) -class DummyAccept(object): - def __init__(self, *matches): - self.matches = list(matches) - - def best_match(self, offered): - if self.matches: - for match in self.matches: - if match in offered: - self.matches.remove(match) - return match - def __contains__(self, val): - return val in self.matches - -def parse_httpdate(s): - import datetime - # cannot use %Z, must use literal GMT; Jython honors timezone - # but CPython does not - return datetime.datetime.strptime(s, "%a, %d %b %Y %H:%M:%S GMT") - -def assert_similar_datetime(one, two): - for attr in ('year', 'month', 'day', 'hour', 'minute'): - one_attr = getattr(one, attr) - two_attr = getattr(two, attr) - if not one_attr == two_attr: # pragma: no cover - raise AssertionError('%r != %r in %s' % (one_attr, two_attr, attr)) - from zope.interface import Interface class IOther(Interface): pass diff --git a/pyramid/tests/test_config/test_tweens.py b/pyramid/tests/test_config/test_tweens.py index bdd0a1e2e..335b745e2 100644 --- a/pyramid/tests/test_config/test_tweens.py +++ b/pyramid/tests/test_config/test_tweens.py @@ -1,5 +1,169 @@ import unittest +from pyramid.tests.test_config import dummy_tween_factory +from pyramid.tests.test_config import dummy_tween_factory2 + +class TestTweensConfiguratorMixin(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_add_tweens_names_distinct(self): + from pyramid.interfaces import ITweens + from pyramid.tweens import excview_tween_factory + def factory1(handler, registry): return handler + def factory2(handler, registry): return handler + config = self._makeOne() + config.add_tween( + 'pyramid.tests.test_config.dummy_tween_factory') + config.add_tween( + 'pyramid.tests.test_config.dummy_tween_factory2') + config.commit() + tweens = config.registry.queryUtility(ITweens) + implicit = tweens.implicit() + self.assertEqual( + implicit, + [ + ('pyramid.tests.test_config.dummy_tween_factory2', + dummy_tween_factory2), + ('pyramid.tests.test_config.dummy_tween_factory', + dummy_tween_factory), + ('pyramid.tweens.excview_tween_factory', + excview_tween_factory), + ] + ) + + def test_add_tweens_names_with_underover(self): + from pyramid.interfaces import ITweens + from pyramid.tweens import excview_tween_factory + from pyramid.tweens import MAIN + config = self._makeOne() + config.add_tween( + 'pyramid.tests.test_config.dummy_tween_factory', + over=MAIN) + config.add_tween( + 'pyramid.tests.test_config.dummy_tween_factory2', + over=MAIN, + under='pyramid.tests.test_config.dummy_tween_factory') + config.commit() + tweens = config.registry.queryUtility(ITweens) + implicit = tweens.implicit() + self.assertEqual( + implicit, + [ + ('pyramid.tweens.excview_tween_factory', excview_tween_factory), + ('pyramid.tests.test_config.dummy_tween_factory', + dummy_tween_factory), + ('pyramid.tests.test_config.dummy_tween_factory2', + dummy_tween_factory2), + ]) + + def test_add_tweens_names_with_under_nonstringoriter(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises( + ConfigurationError, config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + under=False) + + def test_add_tweens_names_with_over_nonstringoriter(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises( + ConfigurationError, config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + over=False) + + def test_add_tween_dottedname(self): + from pyramid.interfaces import ITweens + from pyramid.tweens import excview_tween_factory + config = self._makeOne() + config.add_tween('pyramid.tests.test_config.dummy_tween_factory') + config.commit() + tweens = config.registry.queryUtility(ITweens) + self.assertEqual( + tweens.implicit(), + [ + ('pyramid.tests.test_config.dummy_tween_factory', + dummy_tween_factory), + ('pyramid.tweens.excview_tween_factory', + excview_tween_factory), + ]) + + def test_add_tween_instance(self): + from pyramid.exceptions import ConfigurationError + class ATween(object): pass + atween = ATween() + config = self._makeOne() + self.assertRaises(ConfigurationError, config.add_tween, atween) + + def test_add_tween_unsuitable(self): + from pyramid.exceptions import ConfigurationError + import pyramid.tests.test_config + config = self._makeOne() + self.assertRaises(ConfigurationError, config.add_tween, + pyramid.tests.test_config) + + def test_add_tween_name_ingress(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import INGRESS + config = self._makeOne() + self.assertRaises(ConfigurationError, config.add_tween, INGRESS) + + def test_add_tween_name_main(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import MAIN + config = self._makeOne() + self.assertRaises(ConfigurationError, config.add_tween, MAIN) + + def test_add_tweens_conflict(self): + from zope.configuration.config import ConfigurationConflictError + config = self._makeOne() + config.add_tween('pyramid.tests.test_config.dummy_tween_factory') + config.add_tween('pyramid.tests.test_config.dummy_tween_factory') + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_add_tween_over_ingress(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import INGRESS + config = self._makeOne() + self.assertRaises( + ConfigurationError, + config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + over=INGRESS) + + def test_add_tween_over_ingress_iterable(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import INGRESS + config = self._makeOne() + self.assertRaises( + ConfigurationError, + config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + over=('a', INGRESS)) + + def test_add_tween_under_main(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import MAIN + config = self._makeOne() + self.assertRaises( + ConfigurationError, + config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + under=MAIN) + + def test_add_tween_under_main_iterable(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import MAIN + config = self._makeOne() + self.assertRaises( + ConfigurationError, + config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + under=('a', MAIN)) + class TestTweens(unittest.TestCase): def _makeOne(self): from pyramid.config.tweens import Tweens diff --git a/pyramid/tests/test_config/test_util.py b/pyramid/tests/test_config/test_util.py index a7119eced..2fcef184b 100644 --- a/pyramid/tests/test_config/test_util.py +++ b/pyramid/tests/test_config/test_util.py @@ -243,7 +243,7 @@ class Test__make_predicates(unittest.TestCase): match_param='foo=bar') self.assertEqual(predicates[0].__text__, 'xhr = True') self.assertEqual(predicates[1].__text__, - 'request method = request_method') + "request method = ['request_method']") self.assertEqual(predicates[2].__text__, 'path_info = path_info') self.assertEqual(predicates[3].__text__, 'request_param param') self.assertEqual(predicates[4].__text__, 'header header') @@ -279,6 +279,24 @@ class Test__make_predicates(unittest.TestCase): request.matchdict = {'foo':'bar', 'baz':'foo'} self.assertFalse(predicates[0](Dummy(), request)) + def test_request_method_sequence(self): + _, predicates, _ = self._callFUT(request_method=('GET', 'HEAD')) + request = DummyRequest() + request.method = 'HEAD' + self.assertTrue(predicates[0](Dummy(), request)) + request.method = 'GET' + self.assertTrue(predicates[0](Dummy(), request)) + request.method = 'POST' + self.assertFalse(predicates[0](Dummy(), request)) + + def test_request_method_ordering_hashes_same(self): + hash1, _, __= self._callFUT(request_method=('GET', 'HEAD')) + hash2, _, __= self._callFUT(request_method=('HEAD', 'GET')) + self.assertEqual(hash1, hash2) + hash1, _, __= self._callFUT(request_method=('GET',)) + hash2, _, __= self._callFUT(request_method='GET') + self.assertEqual(hash1, hash2) + class DummyCustomPredicate(object): def __init__(self): self.__text__ = 'custom predicate' diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index c9c276368..16dfe2a22 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1,6 +1,1358 @@ import unittest from pyramid import testing +from pyramid.tests.test_config import IDummy + +class TestViewsConfigurationMixin(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def _getViewCallable(self, config, ctx_iface=None, request_iface=None, + name='', exception_view=False): + 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 exception_view: + classifier = IExceptionViewClassifier + else: + classifier = IViewClassifier + if ctx_iface is None: + ctx_iface = Interface + if request_iface is None: + request_iface = IRequest + return config.registry.adapters.lookup( + (classifier, request_iface, ctx_iface), IView, name=name, + default=None) + + def _registerRenderer(self, config, name='.txt'): + from pyramid.interfaces import IRendererFactory + from pyramid.interfaces import ITemplateRenderer + from zope.interface import implements + class Renderer: + implements(ITemplateRenderer) + def __init__(self, info): + self.__class__.info = info + def __call__(self, *arg): + return '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 test_add_view_view_callable_None_no_renderer(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne(autocommit=True) + self.assertRaises(ConfigurationError, config.add_view) + + def test_add_view_with_request_type_and_route_name(self): + from pyramid.exceptions import ConfigurationError + 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('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__) + + def test_add_view_view_callable_dottedname(self): + from pyramid.renderers import null_renderer + config = self._makeOne(autocommit=True) + config.add_view(view='pyramid.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_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_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_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='pyramid.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_='pyramid.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('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('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, ctx_iface=implementedBy(RuntimeError), exception_view=True) + 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) + 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.renderers import null_renderer + from pyramid.config.util import DEFAULT_PHASH + 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.renderers import null_renderer + from pyramid.config.util import DEFAULT_PHASH + 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) + 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) + 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) + 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_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, ctx_iface=implementedBy(RuntimeError), exception_view=True) + 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, ctx_iface=implementedBy(RuntimeError), exception_view=True) + 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[:2] for x in wrapper.views], [(view2, None)]) + self.assertEqual(wrapper(None, None), 'OK1') + + def test_add_view_exc_multiview_replaces_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 + view = DummyMultiView() + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, + (IViewClassifier, IRequest, implementedBy(RuntimeError)), + IMultiView, name='') + config.registry.registerAdapter( + view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IMultiView, name='') + view2 = lambda *arg: 'OK2' + config.add_view(view=view2, context=RuntimeError, + renderer=null_renderer) + wrapper = self._getViewCallable( + config, ctx_iface=implementedBy(RuntimeError), exception_view=True) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)]) + self.assertEqual(wrapper(None, None), 'OK1') + + def test_add_view_multiview_context_superclass_then_subclass(self): + 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, ISuper, IRequest) + self.assertFalse(IMultiView.providedBy(wrapper)) + self.assertEqual(wrapper(None, None), 'OK') + wrapper = self._getViewCallable(config, ISub, 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, implementedBy(Super), IRequest) + wrapper_exc_view = self._getViewCallable( + config, implementedBy(Super), IRequest, exception_view=True) + 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, implementedBy(Sub), IRequest) + wrapper_exc_view = self._getViewCallable( + config, implementedBy(Sub), IRequest, exception_view=True) + 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_add_view_with_template_renderer(self): + from pyramid.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 = 'pyramid.tests.test_config:files/minimal.txt' + config.add_view(view=view, renderer=fixture) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + result = wrapper(None, request) + self.assertEqual(result.body, '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 '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, 'moo') + + def test_add_view_with_template_renderer_no_callable(self): + from pyramid.tests import test_config + from pyramid.interfaces import ISettings + config = self._makeOne(autocommit=True) + renderer = self._registerRenderer(config) + fixture = 'pyramid.tests.test_config:files/minimal.txt' + config.add_view(view=None, renderer=fixture) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + result = wrapper(None, request) + self.assertEqual(result.body, '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): + from pyramid.exceptions import ConfigurationError + 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 + from zope.configuration.config import ConfigurationExecutionError + 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, ctx_iface=implementedBy(RuntimeError), + request_iface=request_iface, exception_view=True) + 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 + from zope.configuration.config import ConfigurationConflictError + 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_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): + from pyramid.exceptions import ConfigurationError + view = lambda *arg: 'OK' + config = self._makeOne() + self.assertRaises(ConfigurationError, + config.add_view, view=view, header='Host:a\\') + + 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 = ['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 = ['text/html'] + 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='pyramid.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): + from pyramid.exceptions import ConfigurationError + view = lambda *arg: 'OK' + config = self._makeOne() + self.assertRaises(ConfigurationError, + config.add_view, view=view, path_info='\\') + + 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.path_info = '/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.path_info = '/' + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_custom_predicates_match(self): + 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) + config.add_view(view=view, custom_predicates=predicates, + renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_custom_predicates_nomatch(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + def pred1(context, request): + return True + def pred2(context, request): + return False + predicates = (pred1, pred2) + config.add_view(view=view, custom_predicates=predicates) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + self._assertNotFound(wrapper, None, request) + + def test_add_view_custom_predicate_bests_standard_predicate(self): + 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 + config.add_view(view=view, custom_predicates=(pred1,), + 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' + 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): + from zope.configuration.config import ConfigurationConflictError + 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_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') + + class Test_requestonly(unittest.TestCase): def _callFUT(self, view, attr=None): from pyramid.config.views import requestonly @@ -1852,6 +3204,8 @@ class DummyAccept(object): if match in offered: self.matches.remove(match) return match + def __contains__(self, val): + return val in self.matches class DummyLogger: def __init__(self): @@ -1880,6 +3234,20 @@ class DummyConfig: self.view_args = args self.view_kw = kw +from zope.interface import implements +from pyramid.interfaces import IMultiView +class DummyMultiView: + implements(IMultiView) + def __init__(self): + self.views = [] + self.name = 'name' + def add(self, view, order, accept=None, phash=None): + self.views.append((view, accept, phash)) + def __call__(self, context, request): + return 'OK1' + def __permitted__(self, context, request): + """ """ + def parse_httpdate(s): import datetime # cannot use %Z, must use literal GMT; Jython honors timezone @@ -1892,3 +3260,4 @@ def assert_similar_datetime(one, two): two_attr = getattr(two, attr) if not one_attr == two_attr: # pragma: no cover raise AssertionError('%r != %r in %s' % (one_attr, two_attr, attr)) + |
