summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-08-31 03:48:02 -0400
committerChris McDonough <chrism@plope.com>2011-08-31 03:48:02 -0400
commit49f0829352e52ee3ef7643905e534207210204f6 (patch)
tree033dbfb296b9f78a65aee6e6d0c10c88f0669e32
parent1aeae3565e07b99e737e6572ac5ba1b1bbf42abb (diff)
downloadpyramid-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.txt6
-rw-r--r--TODO.txt21
-rw-r--r--docs/whatsnew-1.2.rst6
-rw-r--r--pyramid/config/routes.py14
-rw-r--r--pyramid/config/util.py18
-rw-r--r--pyramid/config/views.py21
-rw-r--r--pyramid/tests/test_config/pkgs/asset/__init__.py11
-rw-r--r--pyramid/tests/test_config/test_init.py1504
-rw-r--r--pyramid/tests/test_config/test_tweens.py164
-rw-r--r--pyramid/tests/test_config/test_util.py20
-rw-r--r--pyramid/tests/test_config/test_views.py1369
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
------------
diff --git a/TODO.txt b/TODO.txt
index 9c939f94a..eca625904 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -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))
+