diff options
author | Ryan Petrello <lists@ryanpetrello.com> | 2014-09-23 13:30:00 -0400 |
---|---|---|
committer | Ryan Petrello <lists@ryanpetrello.com> | 2014-09-26 10:46:31 -0400 |
commit | 960d83971c712e98c45c830df84fdc61cb8cd15b (patch) | |
tree | 301e0ec5a8f870a55f713a6ea8f46b39dc01a8e0 /pecan | |
parent | 921a8b77dcb11d4e3668bf23a5731b665b748a92 (diff) | |
download | pecan-960d83971c712e98c45c830df84fdc61cb8cd15b.tar.gz |
Fix a routing bug for generic subcontrollers.
Change-Id: I3764da98f19f02c1f28a29377c6d24238d869930
Fixes-bug: 1361728
Diffstat (limited to 'pecan')
-rw-r--r-- | pecan/routing.py | 13 | ||||
-rw-r--r-- | pecan/tests/test_generic.py | 26 |
2 files changed, 38 insertions, 1 deletions
diff --git a/pecan/routing.py b/pecan/routing.py index 7acff76..58a74c6 100644 --- a/pecan/routing.py +++ b/pecan/routing.py @@ -3,7 +3,7 @@ import warnings from webob import exc from .secure import handle_security, cross_boundary -from .util import iscontroller, getargspec +from .util import iscontroller, getargspec, _cfg __all__ = ['lookup_controller', 'find_object'] @@ -148,6 +148,17 @@ def find_object(obj, remainder, notfound_handlers, request): if not remainder: raise PecanNotFound + + prev_remainder = remainder prev_obj = obj remainder = rest obj = getattr(obj, next_obj, None) + + # Last-ditch effort: if there's not a matching subcontroller, no + # `_default`, no `_lookup`, and no `_route`, look to see if there's + # an `index` that has a generic method defined for the current request + # method. + if not obj and not notfound_handlers and hasattr(prev_obj, 'index'): + if request.method in _cfg(prev_obj.index).get('generic_handlers', + {}): + return prev_obj.index, prev_remainder diff --git a/pecan/tests/test_generic.py b/pecan/tests/test_generic.py index 453f123..19127fc 100644 --- a/pecan/tests/test_generic.py +++ b/pecan/tests/test_generic.py @@ -60,3 +60,29 @@ class TestGeneric(PecanTestCase): r = app.delete('/', expect_errors=True) assert r.status_int == 405 assert r.headers['Allow'] == 'GET, PATCH, POST' + + def test_nested_generic(self): + + class SubSubController(object): + @expose(generic=True) + def index(self): + return 'GET' + + @index.when(method='DELETE', template='json') + def do_delete(self, name, *args): + return dict(result=name, args=', '.join(args)) + + class SubController(object): + sub = SubSubController() + + class RootController(object): + sub = SubController() + + app = TestApp(Pecan(RootController())) + r = app.get('/sub/sub/') + assert r.status_int == 200 + assert r.body == b_('GET') + + r = app.delete('/sub/sub/joe/is/cool') + assert r.status_int == 200 + assert r.body == b_(dumps(dict(result='joe', args='is, cool'))) |