diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-11-19 18:21:09 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-11-19 18:21:09 +0000 |
| commit | 1c02105e4fce880bca80e58be3191d2e1368596a (patch) | |
| tree | 6c0858b9ad1924e03a8f230d3762ee29d8cbd0d4 | |
| parent | a664df6400b3721a40f665d04b751e7a50b42ebc (diff) | |
| download | pyramid-1c02105e4fce880bca80e58be3191d2e1368596a.tar.gz pyramid-1c02105e4fce880bca80e58be3191d2e1368596a.tar.bz2 pyramid-1c02105e4fce880bca80e58be3191d2e1368596a.zip | |
- Each of the ``repoze.bfg.view.render_view``,
``repoze.bfg.view.render_view_to_iterable``,
``repoze.bfg.view.render_view_to_response``,
``repoze.bfg.view.append_slash_notfound_view``,
``repoze.bfg.view.default_notfound_view``,
``repoze.bfg.view.default_forbidden_view``, and the
``repoze.bfg.configuration.rendered_response`` functions now expects
to be called with a request object that has a ``registry`` attribute
which represents the current ZCA registry. This should only be a
problem when passing a custom request object to code which ends up
calling these functions in a unit test. To retrofit tests that end
up calling these functions which expect to be able to use a
non-registry-aware request object, use the
``repoze.bfg.threadlocal.get_current_request`` API in the test to
create the request; this will return a
``repoze.bfg.testing.DummyRequest`` that has the current registry as
its ``registry`` attribute. Alternatively, use the
``repoze.bfg.threadlocal.get_current_registry`` API: call this
function and add an attribute to your unit test request object named
``registry`` with the result.
- The ``repoze.bfg.view.derive_view`` callable has been removed. Use
``repoze.bfg.configuration.Configurator.derive_view`` instead (still
not an API, however).
| -rw-r--r-- | CHANGES.txt | 29 | ||||
| -rw-r--r-- | repoze/bfg/configuration.py | 18 | ||||
| -rw-r--r-- | repoze/bfg/testing.py | 4 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_configuration.py | 505 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_integration.py | 5 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_testing.py | 29 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_view.py | 573 | ||||
| -rw-r--r-- | repoze/bfg/view.py | 27 | ||||
| -rw-r--r-- | repoze/bfg/zcml.py | 31 |
9 files changed, 624 insertions, 597 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 6696fbe42..cd63e8ed3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -31,7 +31,13 @@ Internals - The ``repoze.bfg.view.authdebug_view`` callable has been removed. -- The ``repoze.bfg.view.renderer_from_name`` callable has been removed. +- The ``repoze.bfg.view.renderer_from_name`` callable has been + removed. Use ``repoze.bfg.configuration.Configurator.renderer_from_name`` + instead (still not an API, however). + +- The ``repoze.bfg.view.derive_view`` callable has been removed. Use + ``repoze.bfg.configuration.Configurator.derive_view`` instead (still + not an API, however). - The ``repoze.bfg.settings.get_options`` callable has been removed. Its job has been subsumed by the ``repoze.bfg.settings.Settings`` @@ -77,6 +83,27 @@ Backwards Incompatibilites attributes didn't actually work in any useful way (see entry above this one). +- Each of the ``repoze.bfg.view.render_view``, + ``repoze.bfg.view.render_view_to_iterable``, + ``repoze.bfg.view.render_view_to_response``, + ``repoze.bfg.view.append_slash_notfound_view``, + ``repoze.bfg.view.default_notfound_view``, + ``repoze.bfg.view.default_forbidden_view``, and the + ``repoze.bfg.configuration.rendered_response`` functions now expects + to be called with a request object that has a ``registry`` attribute + which represents the current ZCA registry. This should only be a + problem when passing a custom request object to code which ends up + calling these functions in a unit test. To retrofit tests that end + up calling these functions which expect to be able to use a + non-registry-aware request object, use the + ``repoze.bfg.threadlocal.get_current_request`` API in the test to + create the request; this will return a + ``repoze.bfg.testing.DummyRequest`` that has the current registry as + its ``registry`` attribute. Alternatively, use the + ``repoze.bfg.threadlocal.get_current_registry`` API: call this + function and add an attribute to your unit test request object named + ``registry`` with the result. + 1.1 (2009-11-15) ================ diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py index 4024484d6..6e1185a65 100644 --- a/repoze/bfg/configuration.py +++ b/repoze/bfg/configuration.py @@ -13,7 +13,6 @@ from zope.configuration import xmlconfig from zope.component import getGlobalSiteManager from zope.component import getSiteManager -from zope.component import queryUtility from zope.interface import Interface from zope.interface import implementedBy @@ -51,7 +50,6 @@ from repoze.bfg.registry import Registry from repoze.bfg.request import route_request_iface from repoze.bfg.resource import PackageOverrides from repoze.bfg.settings import Settings -from repoze.bfg.settings import get_settings from repoze.bfg.static import StaticRootFactory from repoze.bfg.threadlocal import get_current_registry from repoze.bfg.threadlocal import manager @@ -59,7 +57,7 @@ from repoze.bfg.traversal import find_interface from repoze.bfg.traversal import DefaultRootFactory from repoze.bfg.urldispatch import RoutesMapper from repoze.bfg.view import render_view_to_response -from repoze.bfg.view import static as static_view +from repoze.bfg.view import static import martian @@ -69,6 +67,7 @@ class Configurator(object): if registry is None: registry = self.make_default_registry() self.reg = registry + self.reg['bfg_configurator'] = self # yes, a cycle; see get_configurator def make_default_registry(self): self.reg = Registry() @@ -397,7 +396,7 @@ class Configurator(object): wrapped_view = view authn_policy = self.reg.queryUtility(IAuthenticationPolicy) authz_policy = self.reg.queryUtility(IAuthorizationPolicy) - settings = get_settings() + settings = self.reg.queryUtility(ISettings) debug_authorization = False if settings is not None: debug_authorization = settings.get('debug_authorization', False) @@ -577,7 +576,7 @@ class Configurator(object): self.reg.registerUtility(derived_view, iface, '', info=_info) def static(self, name, path, cache_max_age=3600, _info=u''): - view = static_view(path, cache_max_age=cache_max_age) + view = static(path, cache_max_age=cache_max_age) self.route(name, "%s*subpath" % name, view=view, view_for=StaticRootFactory, factory=StaticRootFactory(path), _info=_info) @@ -772,14 +771,19 @@ def decorate_view(wrapped_view, original_view): pass return True -def rendered_response(renderer, response, view, context,request, +def rendered_response(renderer, response, view, context, request, renderer_name): if ( hasattr(response, 'app_iter') and hasattr(response, 'headerlist') and hasattr(response, 'status') ): return response result = renderer(response, {'view':view, 'renderer_name':renderer_name, 'context':context, 'request':request}) - response_factory = queryUtility(IResponseFactory, default=Response) + response_factory = Response + reg = getattr(request, 'registry', None) + if reg is not None: + # be kind to old unit tests + response_factory = reg.queryUtility(IResponseFactory, + default=Response) response = response_factory(result) if request is not None: # in tests, it may be None attrs = request.__dict__ diff --git a/repoze/bfg/testing.py b/repoze/bfg/testing.py index 128e5cf32..79fa3bb9c 100644 --- a/repoze/bfg/testing.py +++ b/repoze/bfg/testing.py @@ -538,7 +538,9 @@ def setUp(): from repoze.bfg.registry import Registry registry = Registry('testing') manager.clear() - manager.push({'registry':registry, 'request':None}) + request = DummyRequest() + request.registry = registry + manager.push({'registry':registry, 'request':request}) getSiteManager.sethook(get_current_registry) _clearContext() diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py index 491e3125e..24a6760e2 100644 --- a/repoze/bfg/tests/test_configuration.py +++ b/repoze/bfg/tests/test_configuration.py @@ -68,6 +68,28 @@ class ConfiguratorTests(unittest.TestCase): config.reg.registerHandler(subscriber, (event_iface,)) return L + def _registerLogger(self, config): + from repoze.bfg.interfaces import ILogger + logger = DummyLogger() + config.reg.registerUtility(logger, ILogger, 'repoze.bfg.debug') + return logger + + def _makeRequest(self, config): + request = DummyRequest() + request.registry = config.reg + return request + + def _registerSecurityPolicy(self, config, permissive): + from repoze.bfg.interfaces import IAuthenticationPolicy + from repoze.bfg.interfaces import IAuthorizationPolicy + policy = DummySecurityPolicy(permissive) + config.reg.registerUtility(policy, IAuthenticationPolicy) + config.reg.registerUtility(policy, IAuthorizationPolicy) + + def _registerSettings(self, config, **settings): + from repoze.bfg.interfaces import ISettings + config.reg.registerUtility(settings, ISettings) + def test_ctor_no_registry(self): from repoze.bfg.interfaces import ISettings from repoze.bfg.configuration import Configurator @@ -404,53 +426,53 @@ class ConfiguratorTests(unittest.TestCase): wrapper = self._getViewCallable(config) ctx = DummyContext() - request = DummyRequest() + request = self._makeRequest(config) request.method = 'GET' request.params = {} self.assertEqual(wrapper(ctx, request), 'view1') ctx = DummyContext() - request = DummyRequest() + request = self._makeRequest(config) request.params = {} request.method = 'POST' self.assertEqual(wrapper(ctx, request), 'view2') ctx = DummyContext() - request = DummyRequest() + request = self._makeRequest(config) request.params = {'param':'1'} request.method = 'GET' self.assertEqual(wrapper(ctx, request), 'view3') ctx = DummyContext() directlyProvides(ctx, IDummy) - request = DummyRequest() + request = self._makeRequest(config) request.method = 'GET' request.params = {} self.assertEqual(wrapper(ctx, request), 'view4') ctx = DummyContext() - request = DummyRequest() + request = self._makeRequest(config) request.method = 'POST' request.params = {'param':'1'} self.assertEqual(wrapper(ctx, request), 'view5') ctx = DummyContext() directlyProvides(ctx, IDummy) - request = DummyRequest() + request = self._makeRequest(config) request.params = {} request.method = 'POST' self.assertEqual(wrapper(ctx, request), 'view6') ctx = DummyContext() directlyProvides(ctx, IDummy) - request = DummyRequest() + request = self._makeRequest(config) request.method = 'GET' request.params = {'param':'1'} self.assertEqual(wrapper(ctx, request), 'view7') ctx = DummyContext() directlyProvides(ctx, IDummy) - request = DummyRequest() + request = self._makeRequest(config) request.method = 'POST' request.params = {'param':'1'} self.assertEqual(wrapper(ctx, request), 'view8') @@ -468,7 +490,7 @@ class ConfiguratorTests(unittest.TestCase): fixture = 'repoze.bfg.tests:fixtures/minimal.txt' config.view(view=view, renderer=fixture) wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) result = wrapper(None, request) self.assertEqual(result.body, 'Hello!') self.assertEqual(renderer.path, 'repoze.bfg.tests:fixtures/minimal.txt') @@ -479,7 +501,7 @@ class ConfiguratorTests(unittest.TestCase): fixture = 'repoze.bfg.tests:fixtures/minimal.txt' config.view(view=None, renderer=fixture) wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) result = wrapper(None, request) self.assertEqual(result.body, 'Hello!') self.assertEqual(renderer.path, 'repoze.bfg.tests:fixtures/minimal.txt') @@ -517,7 +539,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, request_method='POST') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.method = 'POST' self.assertEqual(wrapper(None, request), 'OK') @@ -526,7 +548,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, request_method='POST') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.method = 'GET' self._assertNotFound(wrapper, None, request) @@ -535,7 +557,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, request_param='abc') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.params = {'abc':''} self.assertEqual(wrapper(None, request), 'OK') @@ -544,7 +566,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, request_param='abc') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.params = {} self._assertNotFound(wrapper, None, request) @@ -553,7 +575,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, request_param='abc=123') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.params = {'abc':'123'} self.assertEqual(wrapper(None, request), 'OK') @@ -562,7 +584,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, request_param='abc=123') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.params = {'abc':''} self._assertNotFound(wrapper, None, request) @@ -571,7 +593,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, xhr=True) wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.is_xhr = True self.assertEqual(wrapper(None, request), 'OK') @@ -580,7 +602,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, xhr=True) wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.is_xhr = False self._assertNotFound(wrapper, None, request) @@ -596,7 +618,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, header='Host') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.headers = {'Host':'whatever'} self.assertEqual(wrapper(None, request), 'OK') @@ -605,7 +627,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, header='Host') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.headers = {'NotHost':'whatever'} self._assertNotFound(wrapper, None, request) @@ -614,7 +636,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, header=r'Host:\d') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.headers = {'Host':'1'} self.assertEqual(wrapper(None, request), 'OK') @@ -623,7 +645,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, header=r'Host:\d') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.headers = {'Host':'abc'} self._assertNotFound(wrapper, None, request) @@ -632,7 +654,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, accept='text/xml') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.accept = ['text/xml'] self.assertEqual(wrapper(None, request), 'OK') @@ -641,7 +663,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, accept='text/xml') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.accept = ['text/html'] self._assertNotFound(wrapper, None, request) @@ -651,7 +673,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, containment=IDummy) wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) context = DummyContext() directlyProvides(context, IDummy) self.assertEqual(wrapper(context, None), 'OK') @@ -661,7 +683,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, containment=IDummy) wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) context = DummyContext() self._assertNotFound(wrapper, context, None) @@ -677,7 +699,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, path_info='/foo') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.path_info = '/foo' self.assertEqual(wrapper(None, request), 'OK') @@ -686,7 +708,7 @@ class ConfiguratorTests(unittest.TestCase): config = self._makeOne() config.view(view=view, path_info='/foo') wrapper = self._getViewCallable(config) - request = DummyRequest() + request = self._makeRequest(config) request.path_info = '/' self._assertNotFound(wrapper, None, request) @@ -713,10 +735,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') route = self._assertRoute(config, 'name', 'path', 1) predicate = route.predicates[0] - request = DummyRequest() + request = self._makeRequest(config) request.is_xhr = True self.assertEqual(predicate(None, request), True) - request = DummyRequest() + request = self._makeRequest(config) request.is_xhr = False self.assertEqual(predicate(None, request), False) @@ -727,10 +749,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') route = self._assertRoute(config, 'name', 'path', 1) predicate = route.predicates[0] - request = DummyRequest() + request = self._makeRequest(config) request.method = 'GET' self.assertEqual(predicate(None, request), True) - request = DummyRequest() + request = self._makeRequest(config) request.method = 'POST' self.assertEqual(predicate(None, request), False) @@ -741,10 +763,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') route = self._assertRoute(config, 'name', 'path', 1) predicate = route.predicates[0] - request = DummyRequest() + request = self._makeRequest(config) request.path_info = '/foo' self.assertEqual(predicate(None, request), True) - request = DummyRequest() + request = self._makeRequest(config) request.path_info = '/' self.assertEqual(predicate(None, request), False) @@ -755,10 +777,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') route = self._assertRoute(config, 'name', 'path', 1) predicate = route.predicates[0] - request = DummyRequest() + request = self._makeRequest(config) request.params = {'abc':'123'} self.assertEqual(predicate(None, request), True) - request = DummyRequest() + request = self._makeRequest(config) request.params = {} self.assertEqual(predicate(None, request), False) @@ -769,10 +791,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') route = self._assertRoute(config, 'name', 'path', 1) predicate = route.predicates[0] - request = DummyRequest() + request = self._makeRequest(config) request.headers = {'Host':'example.com'} self.assertEqual(predicate(None, request), True) - request = DummyRequest() + request = self._makeRequest(config) request.headers = {} self.assertEqual(predicate(None, request), False) @@ -783,10 +805,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') route = self._assertRoute(config, 'name', 'path', 1) predicate = route.predicates[0] - request = DummyRequest() + request = self._makeRequest(config) request.accept = ['text/xml'] self.assertEqual(predicate(None, request), True) - request = DummyRequest() + request = self._makeRequest(config) request.accept = ['text/html'] self.assertEqual(predicate(None, request), False) @@ -828,10 +850,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) route = self._assertRoute(config, 'name', 'path') - request = DummyRequest() + request = self._makeRequest(config) request.method = 'GET' self.assertEqual(wrapper(None, request), 'OK') - request = DummyRequest() + request = self._makeRequest(config) request.method = 'POST' self._assertNotFound(wrapper, None, request) @@ -842,10 +864,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) route = self._assertRoute(config, 'name', 'path') - request = DummyRequest() + request = self._makeRequest(config) request.headers = {'Host':'abc'} self.assertEqual(wrapper(None, request), 'OK') - request = DummyRequest() + request = self._makeRequest(config) request.headers = {} self._assertNotFound(wrapper, None, request) @@ -856,10 +878,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) route = self._assertRoute(config, 'name', 'path') - request = DummyRequest() + request = self._makeRequest(config) request.is_xhr = True self.assertEqual(wrapper(None, request), 'OK') - request = DummyRequest() + request = self._makeRequest(config) request.is_xhr = False self._assertNotFound(wrapper, None, request) @@ -870,10 +892,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) route = self._assertRoute(config, 'name', 'path') - request = DummyRequest() + request = self._makeRequest(config) request.path_info = '/foo' self.assertEqual(wrapper(None, request), 'OK') - request = DummyRequest() + request = self._makeRequest(config) request.path_info = '/' self._assertNotFound(wrapper, None, request) @@ -884,10 +906,10 @@ class ConfiguratorTests(unittest.TestCase): request_type = self._getRouteRequestIface(config, 'name') wrapper = self._getViewCallable(config, None, request_type) route = self._assertRoute(config, 'name', 'path') - request = DummyRequest() + request = self._makeRequest(config) request.accept = ['text/xml'] self.assertEqual(wrapper(None, request), 'OK') - request = DummyRequest() + request = self._makeRequest(config) request.accept = ['text/html'] self._assertNotFound(wrapper, None, request) @@ -1045,7 +1067,7 @@ class ConfiguratorTests(unittest.TestCase): self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.assertEqual(view.__name__, result.__name__) - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(result(None, request).body, 'Hello!') def test__map_view_as_newstyle_class_requestonly(self): @@ -1092,7 +1114,7 @@ class ConfiguratorTests(unittest.TestCase): self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.assertEqual(view.__name__, result.__name__) - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(result(None, request).body, 'Hello!') def test__map_view_as_oldstyle_class_context_and_request(self): @@ -1139,7 +1161,7 @@ class ConfiguratorTests(unittest.TestCase): self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.assertEqual(view.__name__, result.__name__) - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(result(None, request).body, 'Hello!') def test__map_view_as_oldstyle_class_requestonly(self): @@ -1185,7 +1207,7 @@ class ConfiguratorTests(unittest.TestCase): self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.assertEqual(view.__name__, result.__name__) - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(result(None, request).body, 'Hello!') def test__map_view_as_instance_context_and_request(self): @@ -1219,7 +1241,7 @@ class ConfiguratorTests(unittest.TestCase): view, attr='index', renderer_name='repoze.bfg.tests:fixtures/minimal.txt') self.failIf(result is view) - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(result(None, request).body, 'Hello!') def test__map_view_as_instance_requestonly(self): @@ -1262,7 +1284,7 @@ class ConfiguratorTests(unittest.TestCase): self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) self.failUnless('instance' in result.__name__) - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(result(None, request).body, 'Hello!') def test__map_view_rendereronly(self): @@ -1276,7 +1298,7 @@ class ConfiguratorTests(unittest.TestCase): self.failIf(result is view) self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(result(None, request).body, 'Hello!') def test__map_view_defaultrendereronly(self): @@ -1288,7 +1310,7 @@ class ConfiguratorTests(unittest.TestCase): self.failIf(result is view) self.assertEqual(view.__module__, result.__module__) self.assertEqual(view.__doc__, result.__doc__) - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(result(None, request).body, 'Hello!') def test__override_not_yet_registered(self): @@ -1329,7 +1351,7 @@ class ConfiguratorTests(unittest.TestCase): iface = implementedBy(StaticRootFactory) wrapped = config.reg.adapters.lookup( (iface, request_type), IView, name='') - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(wrapped(None, request).__class__, PackageURLParser) def test_static_package_relative(self): @@ -1345,7 +1367,7 @@ class ConfiguratorTests(unittest.TestCase): iface = implementedBy(StaticRootFactory) wrapped = config.reg.adapters.lookup( (iface, request_type), IView, name='') - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(wrapped(None, request).__class__, PackageURLParser) def test_static_absolute(self): @@ -1364,9 +1386,351 @@ class ConfiguratorTests(unittest.TestCase): iface = implementedBy(StaticRootFactory) wrapped = config.reg.adapters.lookup( (iface, request_type), IView, name='') - request = DummyRequest() + request = self._makeRequest(config) self.assertEqual(wrapped(None, request).__class__, StaticURLParser) + def test_system_view_no_view_no_renderer(self): + from zope.configuration.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises(ConfigurationError, config.system_view, IDummy) + + def test_system_view_no_view_with_renderer(self): + config = self._makeOne() + self._registerRenderer(config, name='.pt') + config.system_view(IDummy, + renderer='repoze.bfg.tests:fixtures/minimal.pt') + request = self._makeRequest(config) + view = config.reg.getUtility(IDummy) + result = view(None, request) + self.assertEqual(result.body, 'Hello!') + + def test_system_view_with_attr(self): + config = self._makeOne() + class view(object): + def __init__(self, context, request): + pass + def index(self): + return 'OK' + config.system_view(IDummy, view=view, attr='index') + view = config.reg.getUtility(IDummy) + request = self._makeRequest(config) + result = view(None, request) + self.assertEqual(result, 'OK') + + def test_system_view_with_wrapper(self): + from zope.interface import Interface + from zope.interface import directlyProvides + from repoze.bfg.interfaces import IRequest + from repoze.bfg.interfaces import IView + config = self._makeOne() + view = lambda *arg: DummyResponse() + wrapper = lambda *arg: 'OK2' + config.reg.registerAdapter(wrapper, (Interface, Interface), + IView, name='wrapper') + config.system_view(IDummy, view=view, wrapper='wrapper') + view = config.reg.getUtility(IDummy) + request = self._makeRequest(config) + directlyProvides(request, IRequest) + request.registry = config.reg + context = DummyContext() + result = view(context, request) + self.assertEqual(result, 'OK2') + + def test_view_as_function_context_and_request(self): + def view(context, request): + return 'OK' + config = self._makeOne() + result = config.derive_view(view) + self.failUnless(result is view) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(view(None, None), 'OK') + + def test_derive_view_as_function_requestonly(self): + def view(request): + return 'OK' + config = self._makeOne() + result = config.derive_view(view) + self.failIf(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_as_newstyle_class_context_and_request(self): + class view(object): + def __init__(self, context, request): + pass + def __call__(self): + return 'OK' + config = self._makeOne() + result = config.derive_view(view) + self.failIf(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_as_newstyle_class_requestonly(self): + class view(object): + def __init__(self, context, request): + pass + def __call__(self): + return 'OK' + config = self._makeOne() + result = config.derive_view(view) + self.failIf(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_as_oldstyle_class_context_and_request(self): + class view: + def __init__(self, context, request): + pass + def __call__(self): + return 'OK' + config = self._makeOne() + result = config.derive_view(view) + self.failIf(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_as_oldstyle_class_requestonly(self): + class view: + def __init__(self, context, request): + pass + def __call__(self): + return 'OK' + config = self._makeOne() + result = config.derive_view(view) + self.failIf(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_as_instance_context_and_request(self): + class View: + def __call__(self, context, request): + return 'OK' + view = View() + config = self._makeOne() + result = config.derive_view(view) + self.failUnless(result is view) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_as_instance_requestonly(self): + class View: + def __call__(self, request): + return 'OK' + view = View() + config = self._makeOne() + result = config.derive_view(view) + self.failIf(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.failUnless('instance' in result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_with_debug_authorization_no_authpol(self): + view = lambda *arg: 'OK' + config = self._makeOne() + self._registerSettings(config, + debug_authorization=True, reload_templates=True) + logger = self._registerLogger(config) + result = config.derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + request = self._makeRequest(config) + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), 'OK') + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): Allowed " + "(no authorization policy in use)") + + def test_derive_view_with_debug_authorization_no_permission(self): + view = lambda *arg: 'OK' + config = self._makeOne() + self._registerSettings(config, + debug_authorization=True, reload_templates=True) + self._registerSecurityPolicy(config, True) + logger = self._registerLogger(config) + result = config.derive_view(view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.failIf(hasattr(result, '__call_permissive__')) + request = self._makeRequest(config) + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), 'OK') + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): Allowed (" + "no permission registered)") + + def test_derive_view_debug_authorization_permission_authpol_permitted(self): + view = lambda *arg: 'OK' + config = self._makeOne() + self._registerSettings(config, debug_authorization=True, + reload_templates=True) + logger = self._registerLogger(config) + self._registerSecurityPolicy(config, True) + result = config.derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertEqual(result.__call_permissive__, view) + request = self._makeRequest(config) + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), 'OK') + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): True") + + def test_derive_view_debug_authorization_permission_authpol_denied(self): + from repoze.bfg.exceptions import Forbidden + view = lambda *arg: 'OK' + config = self._makeOne() + self._registerSettings(config, + debug_authorization=True, reload_templates=True) + logger = self._registerLogger(config) + self._registerSecurityPolicy(config, False) + result = config.derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertEqual(result.__call_permissive__, view) + request = self._makeRequest(config) + request.view_name = 'view_name' + request.url = 'url' + self.assertRaises(Forbidden, result, None, request) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): False") + + def test_derive_view_debug_authorization_permission_authpol_denied2(self): + view = lambda *arg: 'OK' + config = self._makeOne() + self._registerSettings(config, + debug_authorization=True, reload_templates=True) + logger = self._registerLogger(config) + self._registerSecurityPolicy(config, False) + result = config.derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + request = self._makeRequest(config) + request.view_name = 'view_name' + request.url = 'url' + permitted = result.__permitted__(None, None) + self.assertEqual(permitted, False) + + def test_derive_view_with_predicates_all(self): + view = lambda *arg: 'OK' + predicates = [] + def predicate1(context, request): + predicates.append(True) + return True + def predicate2(context, request): + predicates.append(True) + return True + config = self._makeOne() + result = config.derive_view(view, predicates=[predicate1, predicate2]) + request = self._makeRequest(config) + request.method = 'POST' + next = result(None, None) + self.assertEqual(next, 'OK') + self.assertEqual(predicates, [True, True]) + + def test_derive_view_with_predicates_checker(self): + view = lambda *arg: 'OK' + predicates = [] + def predicate1(context, request): + predicates.append(True) + return True + def predicate2(context, request): + predicates.append(True) + return True + config = self._makeOne() + result = config.derive_view(view, predicates=[predicate1, predicate2]) + request = self._makeRequest(config) + request.method = 'POST' + next = result.__predicated__(None, None) + self.assertEqual(next, True) + self.assertEqual(predicates, [True, True]) + + def test_derive_view_with_predicates_notall(self): + from repoze.bfg.exceptions import NotFound + view = lambda *arg: 'OK' + predicates = [] + def predicate1(context, request): + predicates.append(True) + return True + def predicate2(context, request): + predicates.append(True) + return False + config = self._makeOne() + result = config.derive_view(view, predicates=[predicate1, predicate2]) + request = self._makeRequest(config) + request.method = 'POST' + self.assertRaises(NotFound, result, None, None) + self.assertEqual(predicates, [True, True]) + + def test_derive_view_with_wrapper_viewname(self): + from webob import Response + from repoze.bfg.interfaces import IView + inner_response = Response('OK') + def inner_view(context, request): + return inner_response + def outer_view(context, request): + self.assertEqual(request.wrapped_response, inner_response) + self.assertEqual(request.wrapped_body, inner_response.body) + self.assertEqual(request.wrapped_view, inner_view) + return Response('outer ' + request.wrapped_body) + config = self._makeOne() + config.reg.registerAdapter(outer_view, (None, None), IView, 'owrap') + result = config.derive_view(inner_view, viewname='inner', + wrapper_viewname='owrap') + self.failIf(result is inner_view) + self.assertEqual(inner_view.__module__, result.__module__) + self.assertEqual(inner_view.__doc__, result.__doc__) + request = self._makeRequest(config) + request.registry = config.reg + response = result(None, request) + self.assertEqual(response.body, 'outer OK') + + def test_derive_view_with_wrapper_viewname_notfound(self): + from webob import Response + inner_response = Response('OK') + def inner_view(context, request): + return inner_response + config = self._makeOne() + request = self._makeRequest(config) + request.registry = config.reg + wrapped = config.derive_view( + inner_view, viewname='inner', wrapper_viewname='owrap') + result = self.assertRaises(ValueError, wrapped, None, request) + class TestBFGViewGrokker(unittest.TestCase): def setUp(self): cleanUp() @@ -1904,3 +2268,22 @@ class DummyResponse: status = '200 OK' headerlist = () app_iter = () + body = '' + +class DummyLogger: + def __init__(self): + self.messages = [] + def info(self, msg): + self.messages.append(msg) + warn = info + debug = info + +class DummySecurityPolicy: + def __init__(self, permitted=True): + self.permitted = permitted + + def effective_principals(self, request): + return [] + + def permits(self, context, principals, permission): + return self.permitted diff --git a/repoze/bfg/tests/test_integration.py b/repoze/bfg/tests/test_integration.py index 57d22c286..9175efe4c 100644 --- a/repoze/bfg/tests/test_integration.py +++ b/repoze/bfg/tests/test_integration.py @@ -96,10 +96,9 @@ class TestGrokkedApp(unittest.TestCase): cleanUp() def test_it(self): + from repoze.bfg.threadlocal import get_current_request from repoze.bfg.view import render_view_to_response - from zope.interface import directlyProvides from repoze.bfg.zcml import zcml_configure - from repoze.bfg.interfaces import IRequest import repoze.bfg.tests.grokkedapp as package actions = zcml_configure('configure.zcml', package) @@ -109,7 +108,7 @@ class TestGrokkedApp(unittest.TestCase): ctx = DummyContext() req = DummyRequest() - directlyProvides(req, IRequest) + req = get_current_request() req.method = 'GET' result = render_view_to_response(ctx, req, '') diff --git a/repoze/bfg/tests/test_testing.py b/repoze/bfg/tests/test_testing.py index 4981b6d68..8bd31050a 100644 --- a/repoze/bfg/tests/test_testing.py +++ b/repoze/bfg/tests/test_testing.py @@ -1,17 +1,25 @@ -from repoze.bfg.testing import cleanUp +from repoze.bfg.testing import setUp +from repoze.bfg.testing import tearDown + import unittest class TestTestingFunctions(unittest.TestCase): def setUp(self): - cleanUp() + setUp() from zope.deprecation import __show__ __show__.off() def tearDown(self): - cleanUp() + tearDown() from zope.deprecation import __show__ __show__.on() + def _makeRequest(self, **extra_environ): + from repoze.bfg.threadlocal import get_current_request + request = get_current_request() + request.environ.update(extra_environ) + return request + def test_registerDummySecurityPolicy(self): from repoze.bfg import testing testing.registerDummySecurityPolicy('user', ('group1', 'group2'), @@ -123,7 +131,8 @@ class TestTestingFunctions(unittest.TestCase): import types self.failUnless(isinstance(view, types.FunctionType)) from repoze.bfg.view import render_view_to_response - response = render_view_to_response(None, None, 'moo.html') + request = self._makeRequest() + response = render_view_to_response(None, request, 'moo.html') self.assertEqual(view(None, None).body, response.body) def test_registerView_withresult(self): @@ -132,7 +141,8 @@ class TestTestingFunctions(unittest.TestCase): import types self.failUnless(isinstance(view, types.FunctionType)) from repoze.bfg.view import render_view_to_response - response = render_view_to_response(None, None, 'moo.html') + request = self._makeRequest() + response = render_view_to_response(None, request, 'moo.html') self.assertEqual(response.body, 'yo') def test_registerView_custom(self): @@ -144,7 +154,8 @@ class TestTestingFunctions(unittest.TestCase): import types self.failUnless(isinstance(view, types.FunctionType)) from repoze.bfg.view import render_view_to_response - response = render_view_to_response(None, None, 'moo.html') + request = self._makeRequest() + response = render_view_to_response(None, request, 'moo.html') self.assertEqual(response.body, '123') def test_registerView_with_permission_denying(self): @@ -157,8 +168,9 @@ class TestTestingFunctions(unittest.TestCase): import types self.failUnless(isinstance(view, types.FunctionType)) from repoze.bfg.view import render_view_to_response + request = self._makeRequest() self.assertRaises(Forbidden, render_view_to_response, - None, None, 'moo.html') + None, request, 'moo.html') def test_registerView_with_permission_denying2(self): from repoze.bfg import testing @@ -182,7 +194,8 @@ class TestTestingFunctions(unittest.TestCase): import types self.failUnless(isinstance(view, types.FunctionType)) from repoze.bfg.view import render_view_to_response - result = render_view_to_response(None, None, 'moo.html') + request = self._makeRequest() + result = render_view_to_response(None, request, 'moo.html') self.assertEqual(result.app_iter, ['123']) def test_registerViewPermission_defaults(self): diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py index c293394c1..43e435eab 100644 --- a/repoze/bfg/tests/test_view.py +++ b/repoze/bfg/tests/test_view.py @@ -9,11 +9,12 @@ class BaseTest(object): def tearDown(self): cleanUp() - def _registerView(self, app, name, *for_): - import zope.component - sm = zope.component.getSiteManager() + def _registerView(self, reg, app, name, *for_): + from repoze.bfg.interfaces import IRequest + if not for_: + for_ = (IContext, IRequest) from repoze.bfg.interfaces import IView - sm.registerAdapter(app, for_, IView, name) + reg.registerAdapter(app, for_, IView, name) def _makeEnviron(self, **extras): environ = { @@ -26,76 +27,64 @@ class BaseTest(object): environ.update(extras) return environ + def _makeRequest(self, **environ): + from repoze.bfg.interfaces import IRequest + from zope.interface import directlyProvides + from webob import Request + from repoze.bfg.registry import Registry + environ = self._makeEnviron(**environ) + request = Request(environ) + request.registry = Registry() + directlyProvides(request, IRequest) + return request + + def _makeContext(self): + from zope.interface import directlyProvides + context = DummyContext() + directlyProvides(context, IContext) + return context + + class RenderViewToResponseTests(BaseTest, unittest.TestCase): def _callFUT(self, *arg, **kw): from repoze.bfg.view import render_view_to_response return render_view_to_response(*arg, **kw) def test_call_no_view_registered(self): - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - context = DummyContext() + request = self._makeRequest() + context = self._makeContext() result = self._callFUT(context, request, name='notregistered') self.assertEqual(result, None) def test_call_view_registered_secure(self): - context = DummyContext() - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - directlyProvides(context, IContext) + request = self._makeRequest() + context = self._makeContext() response = DummyResponse() view = make_view(response) - self._registerView(view, 'registered', IContext, IRequest) - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - directlyProvides(request, IRequest) + self._registerView(request.registry, view, 'registered') response = self._callFUT(context, request, name='registered', secure=True) self.assertEqual(response.status, '200 OK') - def test_call_view_registered_insecure_no_call_permissive(self): - context = DummyContext() - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - directlyProvides(context, IContext) + context = self._makeContext() + request = self._makeRequest() response = DummyResponse() view = make_view(response) - self._registerView(view, 'registered', IContext, IRequest) - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - directlyProvides(request, IRequest) + self._registerView(request.registry, view, 'registered') response = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(response.status, '200 OK') def test_call_view_registered_insecure_with_call_permissive(self): - context = DummyContext() - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - directlyProvides(context, IContext) + context = self._makeContext() + request = self._makeRequest() response = DummyResponse() view = make_view(response) def anotherview(context, request): return DummyResponse('anotherview') view.__call_permissive__ = anotherview - self._registerView(view, 'registered', IContext, IRequest) - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - directlyProvides(request, IRequest) + self._registerView(request.registry, view, 'registered') response = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(response.status, '200 OK') @@ -107,140 +96,82 @@ class RenderViewToIterableTests(BaseTest, unittest.TestCase): return render_view_to_iterable(*arg, **kw) def test_call_no_view_registered(self): - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - context = DummyContext() + request = self._makeRequest() + context = self._makeContext() result = self._callFUT(context, request, name='notregistered') self.assertEqual(result, None) def test_call_view_registered_secure(self): - context = DummyContext() - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - directlyProvides(context, IContext) + request = self._makeRequest() + context = self._makeContext() response = DummyResponse() view = make_view(response) - self._registerView(view, 'registered', IContext, IRequest) - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - directlyProvides(request, IRequest) + self._registerView(request.registry, view, 'registered') iterable = self._callFUT(context, request, name='registered', secure=True) self.assertEqual(iterable, ()) def test_call_view_registered_insecure_no_call_permissive(self): - context = DummyContext() - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - directlyProvides(context, IContext) + context = self._makeContext() + request = self._makeRequest() response = DummyResponse() view = make_view(response) - self._registerView(view, 'registered', IContext, IRequest) - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - directlyProvides(request, IRequest) + self._registerView(request.registry, view, 'registered') iterable = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(iterable, ()) def test_call_view_registered_insecure_with_call_permissive(self): - context = DummyContext() - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - directlyProvides(context, IContext) + context = self._makeContext() + request = self._makeRequest() response = DummyResponse() view = make_view(response) def anotherview(context, request): return DummyResponse('anotherview') view.__call_permissive__ = anotherview - self._registerView(view, 'registered', IContext, IRequest) - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - directlyProvides(request, IRequest) + self._registerView(request.registry, view, 'registered') iterable = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(iterable, ['anotherview']) -class RenderViewTests(unittest.TestCase, BaseTest): +class RenderViewTests(BaseTest, unittest.TestCase): def _callFUT(self, *arg, **kw): from repoze.bfg.view import render_view return render_view(*arg, **kw) def test_call_no_view_registered(self): - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - context = DummyContext() + request = self._makeRequest() + context = self._makeContext() result = self._callFUT(context, request, name='notregistered') self.assertEqual(result, None) def test_call_view_registered_secure(self): - context = DummyContext() - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - directlyProvides(context, IContext) + request = self._makeRequest() + context = self._makeContext() response = DummyResponse() view = make_view(response) - self._registerView(view, 'registered', IContext, IRequest) - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - directlyProvides(request, IRequest) + self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=True) self.assertEqual(s, '') def test_call_view_registered_insecure_no_call_permissive(self): - context = DummyContext() - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - directlyProvides(context, IContext) + context = self._makeContext() + request = self._makeRequest() response = DummyResponse() view = make_view(response) - self._registerView(view, 'registered', IContext, IRequest) - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - directlyProvides(request, IRequest) + self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(s, '') def test_call_view_registered_insecure_with_call_permissive(self): - context = DummyContext() - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - directlyProvides(context, IContext) + context = self._makeContext() + request = self._makeRequest() response = DummyResponse() view = make_view(response) def anotherview(context, request): return DummyResponse('anotherview') view.__call_permissive__ = anotherview - self._registerView(view, 'registered', IContext, IRequest) - environ = self._makeEnviron() - from webob import Request - request = Request(environ) - directlyProvides(request, IRequest) + self._registerView(request.registry, view, 'registered') s = self._callFUT(context, request, name='registered', secure=False) self.assertEqual(s, 'anotherview') @@ -267,7 +198,7 @@ class TestIsResponse(unittest.TestCase): response.status = None self.assertEqual(self._callFUT(response), False) -class TestStaticView(unittest.TestCase, BaseTest): +class TestStaticView(BaseTest, unittest.TestCase): def setUp(self): cleanUp() @@ -431,56 +362,52 @@ class TestBFGViewDecorator(unittest.TestCase): self.assertEqual(settings[0]['attr'], 'foo') self.assertEqual(settings[1]['attr'], 'bar') -class TestDefaultForbiddenView(unittest.TestCase): +class TestDefaultForbiddenView(BaseTest, unittest.TestCase): def _callFUT(self, context, request): from repoze.bfg.view import default_forbidden_view return default_forbidden_view(context, request) def test_nomessage(self): - request = DummyRequest({}) - context = DummyContext() + request = self._makeRequest() + context = self._makeContext() response = self._callFUT(context, request) self.assertEqual(response.status, '401 Unauthorized') self.failUnless('<code></code>' in response.body) def test_withmessage(self): - request = DummyRequest({'repoze.bfg.message':'abc&123'}) - context = DummyContext() + request = self._makeRequest() + request.environ['repoze.bfg.message'] = 'abc&123' + context = self._makeContext() response = self._callFUT(context, request) self.assertEqual(response.status, '401 Unauthorized') self.failUnless('<code>abc&123</code>' in response.body) -class TestDefaultNotFoundView(unittest.TestCase): +class TestDefaultNotFoundView(BaseTest, unittest.TestCase): def _callFUT(self, context, request): from repoze.bfg.view import default_notfound_view return default_notfound_view(context, request) def test_nomessage(self): - request = DummyRequest({}) - context = DummyContext() + request = self._makeRequest() + context = self._makeContext() response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') self.failUnless('<code></code>' in response.body) def test_withmessage(self): - request = DummyRequest({'repoze.bfg.message':'abc&123'}) - context = DummyContext() + request = self._makeRequest() + request.environ['repoze.bfg.message'] = 'abc&123' + context = self._makeContext() response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') self.failUnless('<code>abc&123</code>' in response.body) -class AppendSlashNotFoundView(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - +class AppendSlashNotFoundView(BaseTest, unittest.TestCase): def _callFUT(self, context, request): from repoze.bfg.view import append_slash_notfound_view return append_slash_notfound_view(context, request) - def _registerMapper(self, match=True): + def _registerMapper(self, reg, match=True): from repoze.bfg.interfaces import IRoutesMapper class DummyRoute(object): def __init__(self, val): @@ -493,354 +420,38 @@ class AppendSlashNotFoundView(unittest.TestCase): def get_routes(self): return self.routelist mapper = DummyMapper() - import zope.component - sm = zope.component.getSiteManager() - sm.registerUtility(mapper, IRoutesMapper) + reg.registerUtility(mapper, IRoutesMapper) return mapper def test_no_mapper(self): - request = DummyRequest({'PATH_INFO':'/abc'}) + request = self._makeRequest(PATH_INFO='/abc') context = DummyContext() response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') def test_no_path(self): - self._registerMapper(True) - request = DummyRequest({}) - context = DummyContext() + request = self._makeRequest() + context = self._makeContext() + self._registerMapper(request.registry, True) response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') def test_mapper_path_already_slash_ending(self): - self._registerMapper(True) - request = DummyRequest({'PATH_INFO':'/abc/'}) + request = self._makeRequest(PATH_INFO='/abc/') context = DummyContext() + self._registerMapper(request.registry, True) response = self._callFUT(context, request) self.assertEqual(response.status, '404 Not Found') def test_matches(self): - self._registerMapper(True) - request = DummyRequest({'PATH_INFO':'/abc'}) + request = self._makeRequest(PATH_INFO='/abc') context = DummyContext() + self._registerMapper(request.registry, True) response = self._callFUT(context, request) self.assertEqual(response.status, '302 Found') self.assertEqual(response.location, '/abc/') -class TestDeriveView(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, view, *arg, **kw): - from repoze.bfg.view import derive_view - return derive_view(view, *arg, **kw) - - def _registerLogger(self): - from repoze.bfg.interfaces import ILogger - from zope.component import getSiteManager - logger = DummyLogger() - sm = getSiteManager() - sm.registerUtility(logger, ILogger, 'repoze.bfg.debug') - return logger - - def _registerSettings(self, **settings): - from repoze.bfg.interfaces import ISettings - from zope.component import getSiteManager - sm = getSiteManager() - sm.registerUtility(settings, ISettings) - - def _registerSecurityPolicy(self, permissive): - from repoze.bfg.interfaces import IAuthenticationPolicy - from repoze.bfg.interfaces import IAuthorizationPolicy - from zope.component import getSiteManager - policy = DummySecurityPolicy(permissive) - sm = getSiteManager() - sm.registerUtility(policy, IAuthenticationPolicy) - sm.registerUtility(policy, IAuthorizationPolicy) - - def test_view_as_function_context_and_request(self): - def view(context, request): - return 'OK' - result = self._callFUT(view) - self.failUnless(result is view) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(view(None, None), 'OK') - - def test_view_as_function_requestonly(self): - def view(request): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test_view_as_newstyle_class_context_and_request(self): - class view(object): - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test_view_as_newstyle_class_requestonly(self): - class view(object): - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test_view_as_oldstyle_class_context_and_request(self): - class view: - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test_view_as_oldstyle_class_requestonly(self): - class view: - def __init__(self, context, request): - pass - def __call__(self): - return 'OK' - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test_view_as_instance_context_and_request(self): - class View: - def __call__(self, context, request): - return 'OK' - view = View() - result = self._callFUT(view) - self.failUnless(result is view) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test_view_as_instance_requestonly(self): - class View: - def __call__(self, request): - return 'OK' - view = View() - result = self._callFUT(view) - self.failIf(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.failUnless('instance' in result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), 'OK') - - def test_view_with_debug_authorization_no_authpol(self): - def view(context, request): - return 'OK' - self._registerSettings(debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - result = self._callFUT(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - request = DummyRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed " - "(no authorization policy in use)") - - def test_view_with_debug_authorization_no_permission(self): - def view(context, request): - return 'OK' - self._registerSettings(debug_authorization=True, reload_templates=True) - self._registerSecurityPolicy(True) - logger = self._registerLogger() - result = self._callFUT(view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.failIf(hasattr(result, '__call_permissive__')) - request = DummyRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed (" - "no permission registered)") - - def test_view_with_debug_authorization_permission_authpol_permitted(self): - def view(context, request): - return 'OK' - self._registerSettings(debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - self._registerSecurityPolicy(True) - result = self._callFUT(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__, view) - request = DummyRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), 'OK') - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): True") - - def test_view_with_debug_authorization_permission_authpol_denied(self): - from repoze.bfg.exceptions import Forbidden - def view(context, request): - """ """ - self._registerSettings(debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - self._registerSecurityPolicy(False) - result = self._callFUT(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__, view) - request = DummyRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertRaises(Forbidden, result, None, request) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): False") - - def test_view_with_debug_authorization_permission_authpol_denied2(self): - def view(context, request): - """ """ - self._registerSettings(debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - self._registerSecurityPolicy(False) - result = self._callFUT(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - request = DummyRequest() - request.view_name = 'view_name' - request.url = 'url' - permitted = result.__permitted__(None, None) - self.assertEqual(permitted, False) - - def test_view_with_predicates_all(self): - def view(context, request): - return '123' - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return True - result = self._callFUT(view, predicates=[predicate1, predicate2]) - request = DummyRequest() - request.method = 'POST' - next = result(None, None) - self.assertEqual(next, '123') - self.assertEqual(predicates, [True, True]) - - def test_view_with_predicates_notall(self): - from repoze.bfg.exceptions import NotFound - def view(context, request): - """ """ - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return False - result = self._callFUT(view, predicates=[predicate1, predicate2]) - request = DummyRequest() - request.method = 'POST' - self.assertRaises(NotFound, result, None, None) - self.assertEqual(predicates, [True, True]) - - def test_view_with_predicates_checker(self): - def view(context, request): - """ """ - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return True - result = self._callFUT(view, predicates=[predicate1, predicate2]) - request = DummyRequest() - request.method = 'POST' - next = result.__predicated__(None, None) - self.assertEqual(next, True) - self.assertEqual(predicates, [True, True]) - - def test_view_with_wrapper_viewname(self): - from webob import Response - from zope.component import getSiteManager - from repoze.bfg.interfaces import IView - inner_response = Response('OK') - def inner_view(context, request): - return inner_response - def outer_view(context, request): - self.assertEqual(request.wrapped_response, inner_response) - self.assertEqual(request.wrapped_body, inner_response.body) - self.assertEqual(request.wrapped_view, inner_view) - return Response('outer ' + request.wrapped_body) - sm = getSiteManager() - sm.registerAdapter(outer_view, (None, None), IView, 'owrap') - result = self._callFUT(inner_view, viewname='inner', - wrapper_viewname='owrap') - self.failIf(result is inner_view) - self.assertEqual(inner_view.__module__, result.__module__) - self.assertEqual(inner_view.__doc__, result.__doc__) - request = DummyRequest() - response = result(None, request) - self.assertEqual(response.body, 'outer OK') - - def test_view_with_wrapper_viewname_notfound(self): - from webob import Response - inner_response = Response('OK') - def inner_view(context, request): - return inner_response - request = DummyRequest() - wrapped = self._callFUT( - inner_view, viewname='inner', wrapper_viewname='owrap') - result = self.assertRaises(ValueError, wrapped, None, request) - class DummyContext: pass @@ -870,21 +481,7 @@ class DummyResponse: self.app_iter = () else: self.app_iter = [body] - -class DummyLogger: - def __init__(self): - self.messages = [] - def info(self, msg): - self.messages.append(msg) - warn = info - debug = info - -class DummySecurityPolicy: - def __init__(self, permitted=True): - self.permitted = permitted - - def effective_principals(self, request): - return [] - - def permits(self, context, principals, permission): - return self.permitted + +from zope.interface import Interface +class IContext(Interface): + pass diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py index 8ef8f3bb6..d94da9570 100644 --- a/repoze/bfg/view.py +++ b/repoze/bfg/view.py @@ -18,9 +18,7 @@ from webob.exc import HTTPFound from paste.urlparser import StaticURLParser -from zope.component import getSiteManager from zope.component import providedBy -from zope.component import queryUtility from zope.deprecation import deprecated from zope.interface.advice import getFrameInfo @@ -62,8 +60,8 @@ def render_view_to_response(context, request, name='', secure=True): ``args`` attribute explains why the view access was disallowed. If ``secure`` is ``False``, no permission checking is done.""" provides = map(providedBy, (context, request)) - sm = getSiteManager() - view = sm.adapters.lookup(provides, IView, name=name) + reg = request.registry + view = reg.adapters.lookup(provides, IView, name=name) if view is None: return None @@ -454,7 +452,12 @@ def default_view(context, request, status): """ % (status, status, msg) headers = [('Content-Length', str(len(html))), ('Content-Type', 'text/html')] - response_factory = queryUtility(IResponseFactory, default=Response) + response_factory = Response + registry = getattr(request, 'registry', None) + if registry is not None: + # be kind to old tests + response_factory = registry.queryUtility(IResponseFactory, + default=Response) return response_factory(status = status, headerlist = headers, app_iter = [html]) @@ -490,7 +493,8 @@ def append_slash_notfound_view(context, request): """ path = request.environ.get('PATH_INFO', '/') - mapper = queryUtility(IRoutesMapper) + registry = request.registry + mapper = registry.queryUtility(IRoutesMapper) if mapper is not None and not path.endswith('/'): slashpath = path + '/' for route in mapper.get_routes(): @@ -498,14 +502,3 @@ def append_slash_notfound_view(context, request): return HTTPFound(location=slashpath) return default_view(context, request, '404 Not Found') -def derive_view(original_view, permission=None, predicates=(), attr=None, - renderer_name=None, wrapper_viewname=None, viewname=None): - reg = getSiteManager() - from repoze.bfg.configuration import Configurator - config = Configurator(reg) - return config.derive_view(original_view, permission=permission, - predicates=predicates, attr=attr, - renderer_name=renderer_name, - wrapper_viewname=wrapper_viewname, - viewname=viewname) - diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py index 6cbea96df..7d6e2a14b 100644 --- a/repoze/bfg/zcml.py +++ b/repoze/bfg/zcml.py @@ -24,7 +24,6 @@ from repoze.bfg.authentication import RepozeWho1AuthenticationPolicy from repoze.bfg.authentication import RemoteUserAuthenticationPolicy from repoze.bfg.authentication import AuthTktAuthenticationPolicy from repoze.bfg.authorization import ACLAuthorizationPolicy -from repoze.bfg.configuration import Configurator from repoze.bfg.path import package_name from repoze.bfg.request import route_request_iface from repoze.bfg.resource import resource_spec @@ -168,7 +167,7 @@ def view( renderer = resource_spec(renderer, zcml_package) def register(): - config = Configurator(reg) + config = get_configurator(reg) config.view( permission=permission, for_=for_, view=view, name=name, request_type=request_type, route_name=route_name, @@ -248,7 +247,7 @@ def route(_context, name, path, view=None, view_for=None, view_renderer = resource_spec(view_renderer, zcml_package) def register(): - config = Configurator(reg) + config = get_configurator(reg) config.route( name, path, @@ -327,7 +326,7 @@ class SystemViewHandler(object): def register(iface=self.iface): reg = get_current_registry() - config = Configurator(reg) + config = get_configurator(reg) config.system_view(iface, view=view, attr=attr, renderer=renderer, wrapper=wrapper, _info=_context.info) @@ -380,7 +379,7 @@ def resource(_context, to_override, override_with): 'at the end of to_override if necessary)') reg = get_current_registry() - config = Configurator(reg) + config = get_configurator(reg) _context.action( discriminator = None, @@ -400,7 +399,7 @@ def repozewho1authenticationpolicy(_context, identifier_name='auth_tkt', # authentication policies must be registered eagerly so they can # be found by the view registration machinery reg = get_current_registry() - config = Configurator(reg) + config = get_configurator(reg) config.authentication_policy(policy, _info=_context.info) _context.action(discriminator=IAuthenticationPolicy) @@ -416,7 +415,7 @@ def remoteuserauthenticationpolicy(_context, environ_key='REMOTE_USER', # authentication policies must be registered eagerly so they can # be found by the view registration machinery reg = get_current_registry() - config = Configurator(reg) + config = get_configurator(reg) config.authentication_policy(policy, _info=_context.info) _context.action(discriminator=IAuthenticationPolicy) @@ -454,7 +453,7 @@ def authtktauthenticationpolicy(_context, # authentication policies must be registered eagerly so they can # be found by the view registration machinery reg = get_current_registry() - config = Configurator(reg) + config = get_configurator(reg) config.authentication_policy(policy, _info=_context.info) _context.action(discriminator=IAuthenticationPolicy) @@ -466,7 +465,7 @@ def aclauthorizationpolicy(_context): # authorization policies must be registered eagerly so they can be # found by the view registration machinery reg = get_current_registry() - config = Configurator(reg) + config = get_configurator(reg) config.authorization_policy(policy, _info=_context.info) _context.action(discriminator=IAuthorizationPolicy) @@ -483,7 +482,7 @@ def renderer(_context, factory, name=''): # renderer factories must be registered eagerly so they can be # found by the view machinery reg = get_current_registry() - config = Configurator(reg) + config = get_configurator(reg) config.renderer(factory, name, _info=_context.info) _context.action(discriminator=(IRendererFactory, name)) @@ -524,7 +523,7 @@ def scan(_context, package, martian=martian): # martian overrideable only for unit tests def register(): reg = get_current_registry() - config = Configurator(reg) + config = get_configurator(reg) config.scan(package, _info=_context.info, martian=martian) _context.action(discriminator=None, callable=register) @@ -548,3 +547,13 @@ def zcml_configure(name, package): file_configure = zcml_configure # backwards compat (>0.8.1) +def get_configurator(reg): + # dont create a new configurator instance unless necessary, as + # frames will point to each configurator instance via closures + # when some configuration methods (such as config.view) are + # called. + from repoze.bfg.configuration import Configurator + config = reg.get('bfg_configurator') + if config is None: + config = Configurator(reg) + return config |
