From 6225a24982dfaeffbc53f85d214159c08a0dbfc2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 19 Dec 2009 18:40:19 +0000 Subject: - Add a ``custom_predicates`` argument to the ``Configurator`` ``add_view`` method, the ``bfg_view`` decorator and the attribute list of the ZCML ``view`` directive. If ``custom_predicates`` is specified, it must be a sequence of predicate callables (a predicate callable accepts two arguments: ``context`` and ``request`` and returns ``True`` or ``False``). The associated view callable will only be invoked if all custom predicates return ``True``. Use one or more custom predicates when no existing predefined predicate is useful. Predefined and custom predicates can be mixed freely. - Add a ``custom_predicates`` argument to the ``Configurator`` ``add_route`` and the attribute list of the ZCML ``route`` directive. If ``custom_predicates`` is specified, it must be a sequence of predicate callables (a predicate callable accepts two arguments: ``context`` and ``request`` and returns ``True`` or ``False``). The associated route will match will only be invoked if all custom predicates return ``True``, else route matching continues. Use one or more custom predicates when no existing predefined predicate is useful. Predefined and custom predicates can be mixed freely. --- repoze/bfg/tests/test_configuration.py | 34 +++++++++++++++++++++++++++ repoze/bfg/tests/test_view.py | 7 ++++++ repoze/bfg/tests/test_zcml.py | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) (limited to 'repoze/bfg/tests') diff --git a/repoze/bfg/tests/test_configuration.py b/repoze/bfg/tests/test_configuration.py index a42e230f1..7d714f42a 100644 --- a/repoze/bfg/tests/test_configuration.py +++ b/repoze/bfg/tests/test_configuration.py @@ -926,6 +926,32 @@ class ConfiguratorTests(unittest.TestCase): request.path_info = '/' self._assertNotFound(wrapper, None, request) + def test_add_view_with_custom_predicates_match(self): + view = lambda *arg: 'OK' + config = self._makeOne() + def pred1(context, request): + return True + def pred2(context, request): + return True + predicates = (pred1, pred2) + config.add_view(view=view, custom_predicates=predicates) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_custom_predicates_nomatch(self): + view = lambda *arg: 'OK' + config = self._makeOne() + def pred1(context, request): + return True + def pred2(context, request): + return False + predicates = (pred1, pred2) + config.add_view(view=view, custom_predicates=predicates) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + self._assertNotFound(wrapper, None, request) + def _assertRoute(self, config, name, path, num_predicates=0): from repoze.bfg.interfaces import IRoutesMapper mapper = config.registry.getUtility(IRoutesMapper) @@ -990,6 +1016,14 @@ class ConfiguratorTests(unittest.TestCase): request.params = {} self.assertEqual(predicate(None, request), False) + def test_add_route_with_custom_predicates(self): + config = self._makeOne() + def pred1(context, request): pass + def pred2(context, request): pass + config.add_route('name', 'path', custom_predicates=(pred1, pred2)) + route = self._assertRoute(config, 'name', 'path', 2) + self.assertEqual(route.predicates, [pred1, pred2]) + def test_add_route_with_header(self): config = self._makeOne() config.add_route('name', 'path', header='Host') diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py index 6fbedb934..677c15bc8 100644 --- a/repoze/bfg/tests/test_view.py +++ b/repoze/bfg/tests/test_view.py @@ -361,6 +361,13 @@ class TestBFGViewDecorator(unittest.TestCase): self.assertEqual(settings[0]['attr'], 'foo') self.assertEqual(settings[1]['attr'], 'bar') + def test_with_custom_predicates(self): + decorator = self._makeOne(custom_predicates=(1,)) + def foo(context, request): return 'OK' + decorated = decorator(foo) + settings = decorated.__bfg_view_settings__ + self.assertEqual(settings[0]['custom_predicates'], (1,)) + class TestDefaultForbiddenView(BaseTest, unittest.TestCase): def _callFUT(self, context, request): from repoze.bfg.view import default_forbidden_view diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py index f3e0ed80f..cbbbe664c 100644 --- a/repoze/bfg/tests/test_zcml.py +++ b/repoze/bfg/tests/test_zcml.py @@ -92,6 +92,31 @@ class TestViewDirective(unittest.TestCase): regview = reg.adapters.lookup((IDummy, IRequest), IView, name='') self.assertEqual(regview(None, None).body, 'OK') + def test_with_custom_predicates(self): + from repoze.bfg.threadlocal import get_current_registry + from repoze.bfg.interfaces import IView + from repoze.bfg.interfaces import IRequest + context = DummyContext() + reg = get_current_registry() + view = lambda *arg: 'OK' + def pred1(context, request): + return True + def pred2(context, request): + return True + preds = (pred1, pred2) + self._callFUT(context, 'repoze.view', IDummy, view=view, + custom_predicates=preds) + actions = context.actions + self.assertEqual(len(actions), 1) + discrim = ('view', IDummy, '', None, IView, None, None, None, None, + None, False, None, None, None) + discrim = discrim + tuple(sorted(preds)) + self.assertEqual(actions[0]['discriminator'], discrim) + register = actions[0]['callable'] + register() + regview = reg.adapters.lookup((IDummy, IRequest), IView, name='') + self.assertEqual(regview(None, None), 'OK') + class TestNotFoundDirective(unittest.TestCase): def setUp(self): testing.setUp() @@ -490,6 +515,24 @@ class TestRouteDirective(unittest.TestCase): result = wrapped(None, request) self.assertEqual(result.body, 'OK') + def test_with_custom_predicates(self): + def pred1(context, request): pass + def pred2(context, request): pass + preds = tuple(sorted([pred1, pred2])) + + context = DummyContext() + self._callFUT(context, 'name', 'path', custom_predicates=(pred1, pred2)) + actions = context.actions + self.assertEqual(len(actions), 1) + + route_action = actions[0] + route_action['callable']() + route_discriminator = route_action['discriminator'] + self.assertEqual( + route_discriminator, + ('route', 'name', False, None, None, None, None,None) + preds) + self._assertRoute('name', 'path', 2) + class TestStaticDirective(unittest.TestCase): def setUp(self): testing.setUp() -- cgit v1.2.3