summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2008-09-01 03:03:51 +0000
committerChris McDonough <chrism@agendaless.com>2008-09-01 03:03:51 +0000
commit885bfb1a58303d197f689d13f79fb621b67860f2 (patch)
tree4f5d486663b77aec8f11d989439d287093bdf94f
parent7e2c6cbb452aa986891b2a99653a147bfb053e19 (diff)
downloadpyramid-885bfb1a58303d197f689d13f79fb621b67860f2.tar.gz
pyramid-885bfb1a58303d197f689d13f79fb621b67860f2.tar.bz2
pyramid-885bfb1a58303d197f689d13f79fb621b67860f2.zip
Add render_view function.
-rw-r--r--CHANGES.txt9
-rw-r--r--docs/api/view.rst2
-rw-r--r--repoze/bfg/tests/test_view.py106
-rw-r--r--repoze/bfg/view.py30
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