Michael Merickel
2018-10-26 4149922e64aecf2a213f8efb120cd2d61fed3eb7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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