Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from zope.interface import Interface 

2 

3from pyramid.interfaces import ( 

4 ITraverser, 

5 IAuthorizationPolicy, 

6 IAuthenticationPolicy, 

7 IRendererFactory, 

8) 

9 

10from pyramid.renderers import RendererHelper 

11 

12from pyramid.traversal import decode_path_info, split_path_info 

13 

14from pyramid.config.actions import action_method 

15 

16 

17class TestingConfiguratorMixin(object): 

18 # testing API 

19 def testing_securitypolicy( 

20 self, 

21 userid=None, 

22 groupids=(), 

23 permissive=True, 

24 remember_result=None, 

25 forget_result=None, 

26 ): 

27 """Unit/integration testing helper: Registers a pair of faux 

28 :app:`Pyramid` security policies: a :term:`authentication 

29 policy` and a :term:`authorization policy`. 

30 

31 The behavior of the registered :term:`authorization policy` 

32 depends on the ``permissive`` argument. If ``permissive`` is 

33 true, a permissive :term:`authorization policy` is registered; 

34 this policy allows all access. If ``permissive`` is false, a 

35 nonpermissive :term:`authorization policy` is registered; this 

36 policy denies all access. 

37 

38 ``remember_result``, if provided, should be the result returned by 

39 the ``remember`` method of the faux authentication policy. If it is 

40 not provided (or it is provided, and is ``None``), the default value 

41 ``[]`` (the empty list) will be returned by ``remember``. 

42 

43 ``forget_result``, if provided, should be the result returned by 

44 the ``forget`` method of the faux authentication policy. If it is 

45 not provided (or it is provided, and is ``None``), the default value 

46 ``[]`` (the empty list) will be returned by ``forget``. 

47 

48 The behavior of the registered :term:`authentication policy` 

49 depends on the values provided for the ``userid`` and 

50 ``groupids`` argument. The authentication policy will return 

51 the userid identifier implied by the ``userid`` argument and 

52 the group ids implied by the ``groupids`` argument when the 

53 :attr:`pyramid.request.Request.authenticated_userid` or 

54 :attr:`pyramid.request.Request.effective_principals` APIs are 

55 used. 

56 

57 This function is most useful when testing code that uses 

58 the APIs named :meth:`pyramid.request.Request.has_permission`, 

59 :attr:`pyramid.request.Request.authenticated_userid`, 

60 :attr:`pyramid.request.Request.effective_principals`, and 

61 :func:`pyramid.security.principals_allowed_by_permission`. 

62 

63 .. versionadded:: 1.4 

64 The ``remember_result`` argument. 

65 

66 .. versionadded:: 1.4 

67 The ``forget_result`` argument. 

68 """ 

69 from pyramid.testing import DummySecurityPolicy 

70 

71 policy = DummySecurityPolicy( 

72 userid, groupids, permissive, remember_result, forget_result 

73 ) 

74 self.registry.registerUtility(policy, IAuthorizationPolicy) 

75 self.registry.registerUtility(policy, IAuthenticationPolicy) 

76 return policy 

77 

78 def testing_resources(self, resources): 

79 """Unit/integration testing helper: registers a dictionary of 

80 :term:`resource` objects that can be resolved via the 

81 :func:`pyramid.traversal.find_resource` API. 

82 

83 The :func:`pyramid.traversal.find_resource` API is called with 

84 a path as one of its arguments. If the dictionary you 

85 register when calling this method contains that path as a 

86 string key (e.g. ``/foo/bar`` or ``foo/bar``), the 

87 corresponding value will be returned to ``find_resource`` (and 

88 thus to your code) when 

89 :func:`pyramid.traversal.find_resource` is called with an 

90 equivalent path string or tuple. 

91 """ 

92 

93 class DummyTraverserFactory: 

94 def __init__(self, context): 

95 self.context = context 

96 

97 def __call__(self, request): 

98 path = decode_path_info(request.environ['PATH_INFO']) 

99 ob = resources[path] 

100 traversed = split_path_info(path) 

101 return { 

102 'context': ob, 

103 'view_name': '', 

104 'subpath': (), 

105 'traversed': traversed, 

106 'virtual_root': ob, 

107 'virtual_root_path': (), 

108 'root': ob, 

109 } 

110 

111 self.registry.registerAdapter( 

112 DummyTraverserFactory, (Interface,), ITraverser 

113 ) 

114 return resources 

115 

116 testing_models = testing_resources # b/w compat 

117 

118 @action_method 

119 def testing_add_subscriber(self, event_iface=None): 

120 """Unit/integration testing helper: Registers a 

121 :term:`subscriber` which listens for events of the type 

122 ``event_iface``. This method returns a list object which is 

123 appended to by the subscriber whenever an event is captured. 

124 

125 When an event is dispatched that matches the value implied by 

126 the ``event_iface`` argument, that event will be appended to 

127 the list. You can then compare the values in the list to 

128 expected event notifications. This method is useful when 

129 testing code that wants to call 

130 :meth:`pyramid.registry.Registry.notify`, 

131 or :func:`zope.component.event.dispatch`. 

132 

133 The default value of ``event_iface`` (``None``) implies a 

134 subscriber registered for *any* kind of event. 

135 """ 

136 event_iface = self.maybe_dotted(event_iface) 

137 L = [] 

138 

139 def subscriber(*event): 

140 L.extend(event) 

141 

142 self.add_subscriber(subscriber, event_iface) 

143 return L 

144 

145 def testing_add_renderer(self, path, renderer=None): 

146 """Unit/integration testing helper: register a renderer at 

147 ``path`` (usually a relative filename ala ``templates/foo.pt`` 

148 or an asset specification) and return the renderer object. 

149 If the ``renderer`` argument is None, a 'dummy' renderer will 

150 be used. This function is useful when testing code that calls 

151 the :func:`pyramid.renderers.render` function or 

152 :func:`pyramid.renderers.render_to_response` function or 

153 any other ``render_*`` or ``get_*`` API of the 

154 :mod:`pyramid.renderers` module. 

155 

156 Note that calling this method for with a ``path`` argument 

157 representing a renderer factory type (e.g. for ``foo.pt`` 

158 usually implies the ``chameleon_zpt`` renderer factory) 

159 clobbers any existing renderer factory registered for that 

160 type. 

161 

162 .. note:: This method is also available under the alias 

163 ``testing_add_template`` (an older name for it). 

164 

165 """ 

166 from pyramid.testing import DummyRendererFactory 

167 

168 helper = RendererHelper(name=path, registry=self.registry) 

169 factory = self.registry.queryUtility( 

170 IRendererFactory, name=helper.type 

171 ) 

172 if not isinstance(factory, DummyRendererFactory): 

173 factory = DummyRendererFactory(helper.type, factory) 

174 self.registry.registerUtility( 

175 factory, IRendererFactory, name=helper.type 

176 ) 

177 

178 from pyramid.testing import DummyTemplateRenderer 

179 

180 if renderer is None: 

181 renderer = DummyTemplateRenderer() 

182 factory.add(path, renderer) 

183 return renderer 

184 

185 testing_add_template = testing_add_renderer