Merge pull request #59 from jdandrea/master

Pecan "after" hooks are called during internal redirects.
This commit is contained in:
Ryan Petrello 2016-05-31 17:43:22 -04:00
commit 37248d86a2
2 changed files with 36 additions and 5 deletions

View File

@ -668,6 +668,9 @@ class PecanBase(object):
}
controller = None
# track internal redirects
internal_redirect = False
# handle the request
try:
# add context and environment to the request
@ -697,9 +700,12 @@ class PecanBase(object):
state.response.content_type = best_match
environ['pecan.original_exception'] = e
# note if this is an internal redirect
internal_redirect = isinstance(e, ForwardRequestException)
# if this is not an internal redirect, run error hooks
on_error_result = None
if not isinstance(e, ForwardRequestException):
if not internal_redirect:
on_error_result = self.handle_hooks(
self.determine_hooks(state.controller),
'on_error',
@ -720,10 +726,13 @@ class PecanBase(object):
if allowed_methods:
state.response.allow = sorted(allowed_methods)
finally:
# handle "after" hooks
self.handle_hooks(
self.determine_hooks(state.controller), 'after', state
)
# if this is not an internal redirect, run "after" hooks
if not internal_redirect:
self.handle_hooks(
self.determine_hooks(state.controller),
'after',
state
)
self._handle_empty_response_body(state)

View File

@ -416,6 +416,28 @@ class TestHooks(PecanTestCase):
# for each different instance of the Hook in the two Controllers
assert run_hook[3] == 'last - before hook', run_hook[3]
def test_internal_redirect_with_after_hook(self):
run_hook = []
class RootController(object):
@expose()
def internal(self):
redirect('/testing', internal=True)
@expose()
def testing(self):
return 'it worked!'
class SimpleHook(PecanHook):
def after(self, state):
run_hook.append('after')
app = TestApp(make_app(RootController(), hooks=[SimpleHook()]))
response = app.get('/internal')
assert response.body == b_('it worked!')
assert len(run_hook) == 1
class TestStateAccess(PecanTestCase):