Browse files

Allow `view_permission` keyword arg to be passed to `add_handler()`.

If `view_permission` (or its alias, `permission`) is passed to `add_handler()`, it will be used as the default permission for all views registered via the handler. Handler views can override this default permission via the `action` decorator.

Added two tests to exercise this new functionality on both types of `add_handler()` calls--i.e., with '{action}' in route path and with `action` as a keyword arg.

References: #1
  • Loading branch information...
1 parent 7ae145e commit ed710e8ad78a29747d39d59d8ff6b138a7a59ddb @wylee wylee committed Jun 5, 2011
Showing with 65 additions and 8 deletions.
  1. +20 −8 pyramid_handlers/__init__.py
  2. +45 −0 pyramid_handlers/tests.py
View
28 pyramid_handlers/__init__.py
@@ -44,6 +44,10 @@ def add_handler(self, route_name, pattern, handler, action=None, **kw):
This method returns the result of add_route."""
handler = self.maybe_dotted(handler)
+ default_view_args = {
+ 'permission': kw.pop('view_permission', kw.pop('permission', None))
+ }
+
if pattern is not None:
route = self.add_route(route_name, pattern, **kw)
else:
@@ -79,19 +83,22 @@ def add_handler(self, route_name, pattern, handler, action=None, **kw):
'path %r' % (action, pattern))
if path_has_action:
- scan_handler(self, handler, route_name, action_decorator)
+ scan_handler(self, handler, route_name, action_decorator,
+ **default_view_args)
else:
locate_view_by_name(
config=self,
handler=handler,
route_name=route_name,
action_decorator=action_decorator,
- name=action
+ name=action,
+ **default_view_args
)
return route
-def scan_handler(config, handler, route_name, action_decorator):
+def scan_handler(config, handler, route_name, action_decorator,
+ **default_view_args):
"""Scan a handler for automatically exposed views to register"""
autoexpose = getattr(handler, '__autoexpose__', r'[A-Za-z]+')
if autoexpose:
@@ -107,7 +114,8 @@ def scan_handler(config, handler, route_name, action_decorator):
for expose_config in configs:
# we don't want to mutate any dict in __exposed__,
# so we copy each
- view_args = expose_config.copy()
+ view_args = default_view_args.copy()
+ view_args.update(expose_config.copy())
action = view_args.pop('name', method_name)
preds = list(view_args.pop('custom_predicates', []))
preds.append(ActionPredicate(action))
@@ -117,7 +125,8 @@ def scan_handler(config, handler, route_name, action_decorator):
decorator=action_decorator, **view_args)
-def locate_view_by_name(config, handler, route_name, action_decorator, name):
+def locate_view_by_name(config, handler, route_name, action_decorator, name,
+ **default_view_args):
"""Locate and add all the views in a handler with the matching name, or
the method itself if it exists."""
method_name = name
@@ -137,7 +146,8 @@ def locate_view_by_name(config, handler, route_name, action_decorator, name):
continue
# we don't want to mutate any dict in __exposed__,
# so we copy each
- view_args = expose_config.copy()
+ view_args = default_view_args.copy()
+ view_args.update(expose_config.copy())
del view_args['name']
config.add_view(view=handler, attr=attr,
route_name=route_name,
@@ -152,11 +162,13 @@ def locate_view_by_name(config, handler, route_name, action_decorator, name):
if 'name' in expose_config and expose_config['name'] != name:
continue
view_regged = True
+ view_args = default_view_args.copy()
+ view_args.update(expose_config.copy())
config.add_view(view=handler, attr=name, route_name=route_name,
- decorator=action_decorator, **expose_config)
+ decorator=action_decorator, **view_args)
if not view_regged:
config.add_view(view=handler, attr=name, route_name=route_name,
- decorator=action_decorator)
+ decorator=action_decorator, **default_view_args)
class ActionPredicate(object):
View
45 pyramid_handlers/tests.py
@@ -313,6 +313,51 @@ def two(self): pass
view = views[0]
self.assertEqual(view['view'], DummyHandler)
+ def test_add_handler_with_view_permission_and_action_in_path(self):
+ from pyramid_handlers import action
+ config = self._makeOne()
+ views = []
+ def dummy_add_view(**kw):
+ views.append(kw) # pragma: no cover
+ config.add_view = dummy_add_view
+ class MyView(DummyHandler):
+ @action(permission='different_perm')
+ def action_with_non_default_permission(self): # pragma: no cover
+ return 'My permission is different!'
+ config.add_handler('name', '/{action}', MyView, view_permission='perm')
+ self._assertRoute(config, 'name', '/{action}', 0)
+ self.assertEqual(len(views), 3)
+ for view in views:
+ self.assert_('permission' in view)
+ if view['attr'] == 'action_with_non_default_permission':
+ self.assertEqual(view['permission'], 'different_perm')
+ else:
+ self.assertEqual(view['permission'], 'perm')
+
+ def test_add_handler_with_view_permission_and_action_as_kwarg(self):
+ from pyramid_handlers import action
+ config = self._makeOne()
+ views = []
+ def dummy_add_view(**kw):
+ views.append(kw) # pragma: no cover
+ config.add_view = dummy_add_view
+ class MyView(DummyHandler):
+ def index(self): # pragma: no cover
+ return 'Index'
+ @action(name='index', permission='different_perm')
+ def index2(self): # pragma: no cover
+ return 'Index with different permission.'
+ config.add_handler('name', '/', MyView, action='index',
+ view_permission='perm')
+ self._assertRoute(config, 'name', '/', 0)
+ self.assertEqual(len(views), 2)
+ for view in views:
+ self.assert_('permission' in view)
+ if view['attr'] == 'index':
+ self.assertEqual(view['permission'], 'perm')
+ elif view['attr'] == 'index2':
+ self.assertEqual(view['permission'], 'different_perm')
+
def _assertRoute(self, config, name, path, num_predicates=0):
from pyramid.interfaces import IRoutesMapper
mapper = config.registry.getUtility(IRoutesMapper)

0 comments on commit ed710e8

Please sign in to comment.