diff options
| author | Chris McDonough <chrism@agendaless.com> | 2008-09-01 03:03:51 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2008-09-01 03:03:51 +0000 |
| commit | 885bfb1a58303d197f689d13f79fb621b67860f2 (patch) | |
| tree | 4f5d486663b77aec8f11d989439d287093bdf94f | |
| parent | 7e2c6cbb452aa986891b2a99653a147bfb053e19 (diff) | |
| download | pyramid-885bfb1a58303d197f689d13f79fb621b67860f2.tar.gz pyramid-885bfb1a58303d197f689d13f79fb621b67860f2.tar.bz2 pyramid-885bfb1a58303d197f689d13f79fb621b67860f2.zip | |
Add render_view function.
| -rw-r--r-- | CHANGES.txt | 9 | ||||
| -rw-r--r-- | docs/api/view.rst | 2 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_view.py | 106 | ||||
| -rw-r--r-- | repoze/bfg/view.py | 30 |
4 files changed, 139 insertions, 8 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 5fe8c0fdf..f8a5551e4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,10 +5,11 @@ Next release - Event notification is issued after application is created and configured (``IWSGIApplicationCreatedEvent``). - - New API module: ``repoze.bfg.view``. This module contains the functions - named ``render_view_to_response``, ``render_view_to_iterable`` and - ``is_response``, which are documented in the API docs. These features - aid programmatic (non-request-driven) view execution. + - New API module: ``repoze.bfg.view``. This module contains the + functions named ``render_view_to_response``, + ``render_view_to_iterable``, ``render_view`` and ``is_response``, + which are documented in the API docs. These features aid + programmatic (non-server-driven) view execution. 0.3.4 (08/28/2008) diff --git a/docs/api/view.rst b/docs/api/view.rst index d7d238154..02810471c 100644 --- a/docs/api/view.rst +++ b/docs/api/view.rst @@ -9,4 +9,6 @@ .. autofunction:: render_view_to_iterable + .. autofunction:: render_view + .. autofunction:: is_response diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py index 3b776b14f..6eee8fbab 100644 --- a/repoze/bfg/tests/test_view.py +++ b/repoze/bfg/tests/test_view.py @@ -230,6 +230,112 @@ class RenderViewToIterableTests(unittest.TestCase, BaseTest): self.assertRaises(ValueError, renderer, context, request, name='registered', secure=False) +class RenderViewTests(unittest.TestCase, BaseTest): + def _getFUT(self): + from repoze.bfg.view import render_view + return render_view + + def test_call_no_view_registered(self): + environ = self._makeEnviron() + from webob import Request + request = Request(environ) + context = DummyContext() + renderer = self._getFUT() + result = renderer(context, request, name='notregistered') + self.assertEqual(result, None) + + def test_call_view_registered_secure_permission_disallows(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) + response = DummyResponse() + secpol = DummySecurityPolicy() + permissionfactory = make_permission_factory(False) + view = make_view(response) + self._registerView(view, 'registered', IContext, IRequest) + self._registerSecurityPolicy(secpol) + self._registerPermission(permissionfactory, 'registered', IContext, + IRequest) + environ = self._makeEnviron() + from webob import Request + request = Request(environ) + directlyProvides(request, IRequest) + renderer = self._getFUT() + from repoze.bfg.security import Unauthorized + self.assertRaises(Unauthorized, renderer, context, request, + name='registered', secure=True) + + def test_call_view_registered_secure_permission_allows(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) + response = DummyResponse() + secpol = DummySecurityPolicy() + permissionfactory = make_permission_factory(True) + view = make_view(response) + self._registerView(view, 'registered', IContext, IRequest) + self._registerSecurityPolicy(secpol) + self._registerPermission(permissionfactory, 'registered', IContext, + IRequest) + environ = self._makeEnviron() + from webob import Request + request = Request(environ) + directlyProvides(request, IRequest) + renderer = self._getFUT() + s = renderer(context, request, name='registered', secure=True) + self.assertEqual(s, '') + + def test_call_view_registered_insecure_permission_disallows(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) + response = DummyResponse() + secpol = DummySecurityPolicy() + permissionfactory = make_permission_factory(False) + view = make_view(response) + self._registerView(view, 'registered', IContext, IRequest) + self._registerSecurityPolicy(secpol) + self._registerPermission(permissionfactory, 'registered', IContext, + IRequest) + environ = self._makeEnviron() + from webob import Request + request = Request(environ) + directlyProvides(request, IRequest) + renderer = self._getFUT() + s = renderer(context, request, name='registered', secure=False) + self.assertEqual(s, '') + + def test_call_view_response_doesnt_implement_IResponse(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) + response = 'abc' + view = make_view(response) + self._registerView(view, 'registered', IContext, IRequest) + environ = self._makeEnviron() + from webob import Request + request = Request(environ) + directlyProvides(request, IRequest) + renderer = self._getFUT() + self.assertRaises(ValueError, renderer, context, request, + name='registered', secure=False) + class TestIsResponse(unittest.TestCase): def _getFUT(self): from repoze.bfg.view import is_response diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py index 180c020a0..e3f22dc08 100644 --- a/repoze/bfg/view.py +++ b/repoze/bfg/view.py @@ -39,10 +39,11 @@ def render_view_to_iterable(context, request, name='', secure=True): found and called but the view does not return an object which implements ``repoze.bfg.interfaces.IResponse``. You can usually get the string representation of the return value of this function - by calling ``''.join(iterable)``. If ``secure`` is ``True``, and - the view is protected by a permission, the permission will be - checked before calling the view function. If the permission check - disallows view execution (based on the current security policy), a + by calling ``''.join(iterable)``, or just use ``render_view`` + instead. If ``secure`` is ``True``, and the view is protected by + a permission, the permission will be checked before calling the + view function. If the permission check disallows view execution + (based on the current security policy), a ``repoze.bfg.security.Unauthorized`` exception will be raised; its ``message`` attribute explains why the view access was disallowed. If ``secure`` is ``False``, no permission checking is done.""" @@ -53,6 +54,27 @@ def render_view_to_iterable(context, request, name='', secure=True): raise ValueError('response did not implement IResponse: %r' % response) return response.app_iter +def render_view(context, request, name='', secure=True): + """ Render the view named ``name`` against the specified + ``context`` and ``request``, and unwind the the view response's + ``app_iter`` (see the interface named + ``repoze.bfg.interfaces.IResponse``) into a single string. This + function will return ``None`` if a corresponding view cannot be + found. Additionally, this function will raise a ``ValueError`` if + a view function is found and called but the view does not return + an object which implements ``repoze.bfg.interfaces.IResponse``. + If ``secure`` is ``True``, and the view is protected by a + permission, the permission will be checked before calling the view + function. If the permission check disallows view execution (based + on the current security policy), a + ``repoze.bfg.security.Unauthorized`` exception will be raised; its + ``message`` attribute explains why the view access was disallowed. + If ``secure`` is ``False``, no permission checking is done.""" + iterable = render_view_to_iterable(context, request, name, secure) + if iterable is None: + return None + return ''.join(iterable) + def is_response(ob): """ Return True if ``ob`` implements the ``repoze.bfg.interfaces.IResponse`` interface, False if not. Note |
