from zope.interface import Interface
|
|
from pyramid.interfaces import (
|
ITraverser,
|
IAuthorizationPolicy,
|
IAuthenticationPolicy,
|
IRendererFactory,
|
)
|
|
from pyramid.renderers import RendererHelper
|
|
from pyramid.traversal import decode_path_info, split_path_info
|
|
from pyramid.config.actions import action_method
|
|
|
class TestingConfiguratorMixin(object):
|
# testing API
|
def testing_securitypolicy(
|
self,
|
userid=None,
|
groupids=(),
|
permissive=True,
|
remember_result=None,
|
forget_result=None,
|
):
|
"""Unit/integration testing helper: Registers a pair of faux
|
:app:`Pyramid` security policies: a :term:`authentication
|
policy` and a :term:`authorization policy`.
|
|
The behavior of the registered :term:`authorization policy`
|
depends on the ``permissive`` argument. If ``permissive`` is
|
true, a permissive :term:`authorization policy` is registered;
|
this policy allows all access. If ``permissive`` is false, a
|
nonpermissive :term:`authorization policy` is registered; this
|
policy denies all access.
|
|
``remember_result``, if provided, should be the result returned by
|
the ``remember`` method of the faux authentication policy. If it is
|
not provided (or it is provided, and is ``None``), the default value
|
``[]`` (the empty list) will be returned by ``remember``.
|
|
``forget_result``, if provided, should be the result returned by
|
the ``forget`` method of the faux authentication policy. If it is
|
not provided (or it is provided, and is ``None``), the default value
|
``[]`` (the empty list) will be returned by ``forget``.
|
|
The behavior of the registered :term:`authentication policy`
|
depends on the values provided for the ``userid`` and
|
``groupids`` argument. The authentication policy will return
|
the userid identifier implied by the ``userid`` argument and
|
the group ids implied by the ``groupids`` argument when the
|
:attr:`pyramid.request.Request.authenticated_userid` or
|
:attr:`pyramid.request.Request.effective_principals` APIs are
|
used.
|
|
This function is most useful when testing code that uses
|
the APIs named :meth:`pyramid.request.Request.has_permission`,
|
:attr:`pyramid.request.Request.authenticated_userid`,
|
:attr:`pyramid.request.Request.effective_principals`, and
|
:func:`pyramid.security.principals_allowed_by_permission`.
|
|
.. versionadded:: 1.4
|
The ``remember_result`` argument.
|
|
.. versionadded:: 1.4
|
The ``forget_result`` argument.
|
"""
|
from pyramid.testing import DummySecurityPolicy
|
|
policy = DummySecurityPolicy(
|
userid, groupids, permissive, remember_result, forget_result
|
)
|
self.registry.registerUtility(policy, IAuthorizationPolicy)
|
self.registry.registerUtility(policy, IAuthenticationPolicy)
|
return policy
|
|
def testing_resources(self, resources):
|
"""Unit/integration testing helper: registers a dictionary of
|
:term:`resource` objects that can be resolved via the
|
:func:`pyramid.traversal.find_resource` API.
|
|
The :func:`pyramid.traversal.find_resource` API is called with
|
a path as one of its arguments. If the dictionary you
|
register when calling this method contains that path as a
|
string key (e.g. ``/foo/bar`` or ``foo/bar``), the
|
corresponding value will be returned to ``find_resource`` (and
|
thus to your code) when
|
:func:`pyramid.traversal.find_resource` is called with an
|
equivalent path string or tuple.
|
"""
|
|
class DummyTraverserFactory:
|
def __init__(self, context):
|
self.context = context
|
|
def __call__(self, request):
|
path = decode_path_info(request.environ['PATH_INFO'])
|
ob = resources[path]
|
traversed = split_path_info(path)
|
return {
|
'context': ob,
|
'view_name': '',
|
'subpath': (),
|
'traversed': traversed,
|
'virtual_root': ob,
|
'virtual_root_path': (),
|
'root': ob,
|
}
|
|
self.registry.registerAdapter(
|
DummyTraverserFactory, (Interface,), ITraverser
|
)
|
return resources
|
|
testing_models = testing_resources # b/w compat
|
|
@action_method
|
def testing_add_subscriber(self, event_iface=None):
|
"""Unit/integration testing helper: Registers a
|
:term:`subscriber` which listens for events of the type
|
``event_iface``. This method returns a list object which is
|
appended to by the subscriber whenever an event is captured.
|
|
When an event is dispatched that matches the value implied by
|
the ``event_iface`` argument, that event will be appended to
|
the list. You can then compare the values in the list to
|
expected event notifications. This method is useful when
|
testing code that wants to call
|
:meth:`pyramid.registry.Registry.notify`,
|
or :func:`zope.component.event.dispatch`.
|
|
The default value of ``event_iface`` (``None``) implies a
|
subscriber registered for *any* kind of event.
|
"""
|
event_iface = self.maybe_dotted(event_iface)
|
L = []
|
|
def subscriber(*event):
|
L.extend(event)
|
|
self.add_subscriber(subscriber, event_iface)
|
return L
|
|
def testing_add_renderer(self, path, renderer=None):
|
"""Unit/integration testing helper: register a renderer at
|
``path`` (usually a relative filename ala ``templates/foo.pt``
|
or an asset specification) and return the renderer object.
|
If the ``renderer`` argument is None, a 'dummy' renderer will
|
be used. This function is useful when testing code that calls
|
the :func:`pyramid.renderers.render` function or
|
:func:`pyramid.renderers.render_to_response` function or
|
any other ``render_*`` or ``get_*`` API of the
|
:mod:`pyramid.renderers` module.
|
|
Note that calling this method for with a ``path`` argument
|
representing a renderer factory type (e.g. for ``foo.pt``
|
usually implies the ``chameleon_zpt`` renderer factory)
|
clobbers any existing renderer factory registered for that
|
type.
|
|
.. note:: This method is also available under the alias
|
``testing_add_template`` (an older name for it).
|
|
"""
|
from pyramid.testing import DummyRendererFactory
|
|
helper = RendererHelper(name=path, registry=self.registry)
|
factory = self.registry.queryUtility(
|
IRendererFactory, name=helper.type
|
)
|
if not isinstance(factory, DummyRendererFactory):
|
factory = DummyRendererFactory(helper.type, factory)
|
self.registry.registerUtility(
|
factory, IRendererFactory, name=helper.type
|
)
|
|
from pyramid.testing import DummyTemplateRenderer
|
|
if renderer is None:
|
renderer = DummyTemplateRenderer()
|
factory.add(path, renderer)
|
return renderer
|
|
testing_add_template = testing_add_renderer
|