774 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			774 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from pecan import make_app, expose, request, redirect
 | |
| from pecan.core import state
 | |
| from pecan.hooks import PecanHook, TransactionHook, HookController
 | |
| from pecan.decorators import transactional
 | |
| from formencode import Schema, validators
 | |
| from webtest import TestApp
 | |
| 
 | |
| 
 | |
| class TestHooks(object):
 | |
|     
 | |
|     def test_basic_single_hook(self):
 | |
|         run_hook = []
 | |
|         
 | |
|         class RootController(object):
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside')
 | |
|                 return 'Hello, World!'
 | |
|         
 | |
|         class SimpleHook(PecanHook):
 | |
|             def on_route(self, state):
 | |
|                 run_hook.append('on_route')
 | |
|             
 | |
|             def before(self, state):
 | |
|                 run_hook.append('before')
 | |
| 
 | |
|             def after(self, state):
 | |
|                 run_hook.append('after')
 | |
| 
 | |
|             def on_error(self, state, e):
 | |
|                 run_hook.append('error')
 | |
|         
 | |
|         app = TestApp(make_app(RootController(), hooks=[SimpleHook()]))
 | |
|         response = app.get('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
|         
 | |
|         assert len(run_hook) == 4
 | |
|         assert run_hook[0] == 'on_route'
 | |
|         assert run_hook[1] == 'before'
 | |
|         assert run_hook[2] == 'inside'
 | |
|         assert run_hook[3] == 'after'
 | |
|     
 | |
|     def test_basic_multi_hook(self):
 | |
|         run_hook = []
 | |
|         
 | |
|         class RootController(object):
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside')
 | |
|                 return 'Hello, World!'
 | |
|         
 | |
|         class SimpleHook(PecanHook):
 | |
|             def __init__(self, id):
 | |
|                 self.id = str(id)
 | |
|             
 | |
|             def on_route(self, state):
 | |
|                 run_hook.append('on_route'+self.id)
 | |
|             
 | |
|             def before(self, state):
 | |
|                 run_hook.append('before'+self.id)
 | |
| 
 | |
|             def after(self, state):
 | |
|                 run_hook.append('after'+self.id)
 | |
| 
 | |
|             def on_error(self, state, e):
 | |
|                 run_hook.append('error'+self.id)
 | |
|         
 | |
|         app = TestApp(make_app(RootController(), hooks=[
 | |
|             SimpleHook(1), SimpleHook(2), SimpleHook(3)
 | |
|         ]))
 | |
|         response = app.get('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
|         
 | |
|         assert len(run_hook) == 10
 | |
|         assert run_hook[0] == 'on_route1'
 | |
|         assert run_hook[1] == 'on_route2'
 | |
|         assert run_hook[2] == 'on_route3'
 | |
|         assert run_hook[3] == 'before1'
 | |
|         assert run_hook[4] == 'before2'
 | |
|         assert run_hook[5] == 'before3'
 | |
|         assert run_hook[6] == 'inside'
 | |
|         assert run_hook[7] == 'after3'
 | |
|         assert run_hook[8] == 'after2'
 | |
|         assert run_hook[9] == 'after1'
 | |
| 
 | |
|     def test_partial_hooks(self):
 | |
|         run_hook = []
 | |
| 
 | |
|         class RootController(object):
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside')
 | |
|                 return 'Hello World!'
 | |
| 
 | |
|             @expose()
 | |
|             def causeerror(self):
 | |
|                 return [][1]
 | |
| 
 | |
|         class ErrorHook(PecanHook):
 | |
|             def on_error(self, state, e):
 | |
|                 run_hook.append('error')
 | |
| 
 | |
|         class OnRouteHook(PecanHook):
 | |
|             def on_route(self, state):
 | |
|                 run_hook.append('on_route')
 | |
| 
 | |
|         app = TestApp(make_app(RootController(), hooks=[
 | |
|             ErrorHook(), OnRouteHook()
 | |
|         ]))
 | |
| 
 | |
|         response = app.get('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello World!'
 | |
| 
 | |
|         assert len(run_hook) == 2
 | |
|         assert run_hook[0] == 'on_route'
 | |
|         assert run_hook[1] == 'inside'
 | |
| 
 | |
|         run_hook = []
 | |
|         try:
 | |
|             response = app.get('/causeerror')
 | |
|         except Exception, e:
 | |
|             assert isinstance(e, IndexError)
 | |
| 
 | |
|         assert len(run_hook) == 2
 | |
|         assert run_hook[0] == 'on_route'
 | |
|         assert run_hook[1] == 'error'
 | |
| 
 | |
|     def test_prioritized_hooks(self):
 | |
|         run_hook = []
 | |
|         
 | |
|         class RootController(object):
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside')
 | |
|                 return 'Hello, World!'
 | |
|         
 | |
|         class SimpleHook(PecanHook):
 | |
|             def __init__(self, id):
 | |
|                 self.id = str(id)
 | |
|             
 | |
|             def on_route(self, state):
 | |
|                 run_hook.append('on_route'+self.id)
 | |
|             
 | |
|             def before(self, state):
 | |
|                 run_hook.append('before'+self.id)
 | |
| 
 | |
|             def after(self, state):
 | |
|                 run_hook.append('after'+self.id)
 | |
| 
 | |
|             def on_error(self, state, e):
 | |
|                 run_hook.append('error'+self.id)
 | |
|         
 | |
|         papp = make_app(RootController(), hooks=[
 | |
|             SimpleHook(1), SimpleHook(2), SimpleHook(3)
 | |
|         ])
 | |
|         app = TestApp(papp)
 | |
|         response = app.get('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
|         
 | |
|         assert len(run_hook) == 10
 | |
|         assert run_hook[0] == 'on_route1'
 | |
|         assert run_hook[1] == 'on_route2'
 | |
|         assert run_hook[2] == 'on_route3'
 | |
|         assert run_hook[3] == 'before1'
 | |
|         assert run_hook[4] == 'before2'
 | |
|         assert run_hook[5] == 'before3'
 | |
|         assert run_hook[6] == 'inside'
 | |
|         assert run_hook[7] == 'after3'
 | |
|         assert run_hook[8] == 'after2'
 | |
|         assert run_hook[9] == 'after1'
 | |
|         
 | |
|         run_hook = []
 | |
|         
 | |
|         state.app.hooks[0].priority = 3
 | |
|         state.app.hooks[1].priority = 2
 | |
|         state.app.hooks[2].priority = 1
 | |
|         
 | |
|         response = app.get('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
|         
 | |
|         assert len(run_hook) == 10
 | |
|         assert run_hook[0] == 'on_route3'
 | |
|         assert run_hook[1] == 'on_route2'
 | |
|         assert run_hook[2] == 'on_route1'
 | |
|         assert run_hook[3] == 'before3'
 | |
|         assert run_hook[4] == 'before2'
 | |
|         assert run_hook[5] == 'before1'
 | |
|         assert run_hook[6] == 'inside'
 | |
|         assert run_hook[7] == 'after1'
 | |
|         assert run_hook[8] == 'after2'
 | |
|         assert run_hook[9] == 'after3'
 | |
|     
 | |
|     def test_transaction_hook(self):
 | |
|         run_hook = []
 | |
|         
 | |
|         class RootController(object):
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside')
 | |
|                 return 'Hello, World!'
 | |
|             
 | |
|             @expose()
 | |
|             def redirect(self):
 | |
|                 redirect('/')            
 | |
|             
 | |
|             @expose()
 | |
|             def error(self):
 | |
|                 return [][1]
 | |
|         
 | |
|         def gen(event):
 | |
|             return lambda: run_hook.append(event)
 | |
|         
 | |
|         app = TestApp(make_app(RootController(), hooks=[
 | |
|             TransactionHook(
 | |
|                 start    = gen('start'),
 | |
|                 start_ro = gen('start_ro'),
 | |
|                 commit   = gen('commit'),
 | |
|                 rollback = gen('rollback'),
 | |
|                 clear    = gen('clear')
 | |
|             )
 | |
|         ]))
 | |
|         
 | |
|         response = app.get('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
|         
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start_ro'
 | |
|         assert run_hook[1] == 'inside'
 | |
|         assert run_hook[2] == 'clear'
 | |
|         
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.post('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
|         
 | |
|         assert len(run_hook) == 4
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'inside'
 | |
|         assert run_hook[2] == 'commit'
 | |
|         assert run_hook[3] == 'clear'
 | |
|         
 | |
|         #
 | |
|         # test hooks for GET /redirect
 | |
|         # This controller should always be non-transactional
 | |
|         #
 | |
| 
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.get('/redirect')
 | |
|         assert response.status_int == 302
 | |
|         assert len(run_hook) == 2
 | |
|         assert run_hook[0] == 'start_ro'
 | |
|         assert run_hook[1] == 'clear'
 | |
|         
 | |
|         #
 | |
|         # test hooks for POST /redirect
 | |
|         # This controller should always be transactional,
 | |
|         # even in the case of redirects
 | |
|         #
 | |
|         
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.post('/redirect')
 | |
|         assert response.status_int == 302
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'commit'
 | |
|         assert run_hook[2] == 'clear'        
 | |
|         
 | |
|         run_hook = []
 | |
|         try:
 | |
|             response = app.post('/error')
 | |
|         except IndexError:
 | |
|             pass
 | |
|         
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'rollback'
 | |
|         assert run_hook[2] == 'clear'
 | |
|         
 | |
|     def test_transaction_hook_with_transactional_decorator(self):
 | |
|         run_hook = []
 | |
| 
 | |
|         class RootController(object):
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside')
 | |
|                 return 'Hello, World!'
 | |
| 
 | |
|             @expose()
 | |
|             def redirect(self):
 | |
|                 redirect('/')
 | |
|                 
 | |
|             @expose()
 | |
|             @transactional()
 | |
|             def redirect_transactional(self):
 | |
|                 redirect('/')
 | |
|                 
 | |
|             @expose()
 | |
|             @transactional(False)
 | |
|             def redirect_rollback(self):
 | |
|                 redirect('/')
 | |
| 
 | |
|             @expose()
 | |
|             def error(self):
 | |
|                 return [][1]
 | |
|                 
 | |
|             @expose()
 | |
|             @transactional(False)
 | |
|             def error_rollback(self):
 | |
|                 return [][1]                
 | |
|                 
 | |
|             @expose()
 | |
|             @transactional()
 | |
|             def error_transactional(self):
 | |
|                 return [][1]                
 | |
| 
 | |
|         def gen(event):
 | |
|             return lambda: run_hook.append(event)
 | |
| 
 | |
|         app = TestApp(make_app(RootController(), hooks=[
 | |
|             TransactionHook(
 | |
|                 start    = gen('start'),
 | |
|                 start_ro = gen('start_ro'),
 | |
|                 commit   = gen('commit'),
 | |
|                 rollback = gen('rollback'),
 | |
|                 clear    = gen('clear')
 | |
|             )
 | |
|         ]))
 | |
| 
 | |
|         response = app.get('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
| 
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start_ro'
 | |
|         assert run_hook[1] == 'inside'
 | |
|         assert run_hook[2] == 'clear'
 | |
| 
 | |
|         run_hook = []
 | |
| 
 | |
|         # test hooks for /
 | |
| 
 | |
|         response = app.post('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
| 
 | |
|         assert len(run_hook) == 4
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'inside'
 | |
|         assert run_hook[2] == 'commit'
 | |
|         assert run_hook[3] == 'clear'
 | |
| 
 | |
|         #
 | |
|         # test hooks for GET /redirect
 | |
|         # This controller should always be non-transactional
 | |
|         #
 | |
| 
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.get('/redirect')
 | |
|         assert response.status_int == 302
 | |
|         assert len(run_hook) == 2
 | |
|         assert run_hook[0] == 'start_ro'
 | |
|         assert run_hook[1] == 'clear'
 | |
|         
 | |
|         #
 | |
|         # test hooks for POST /redirect
 | |
|         # This controller should always be transactional,
 | |
|         # even in the case of redirects
 | |
|         #
 | |
|         
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.post('/redirect')
 | |
|         assert response.status_int == 302
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'commit'
 | |
|         assert run_hook[2] == 'clear'
 | |
|         
 | |
|         #
 | |
|         # test hooks for GET /redirect_transactional
 | |
|         # This controller should always be transactional,
 | |
|         # even in the case of redirects
 | |
|         #
 | |
|         
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.get('/redirect_transactional')
 | |
|         assert response.status_int == 302
 | |
|         assert len(run_hook) == 5
 | |
|         assert run_hook[0] == 'start_ro'
 | |
|         assert run_hook[1] == 'clear'        
 | |
|         assert run_hook[2] == 'start'
 | |
|         assert run_hook[3] == 'commit'
 | |
|         assert run_hook[4] == 'clear'
 | |
|         
 | |
|         #
 | |
|         # test hooks for POST /redirect_transactional
 | |
|         # This controller should always be transactional,
 | |
|         # even in the case of redirects
 | |
|         #
 | |
|         
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.post('/redirect_transactional')
 | |
|         assert response.status_int == 302
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'commit'
 | |
|         assert run_hook[2] == 'clear'
 | |
|         
 | |
|         #
 | |
|         # test hooks for GET /redirect_rollback
 | |
|         # This controller should always be transactional,
 | |
|         # *except* in the case of redirects
 | |
|         #
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.get('/redirect_rollback')
 | |
|         assert response.status_int == 302
 | |
|         assert len(run_hook) == 5
 | |
|         assert run_hook[0] == 'start_ro'
 | |
|         assert run_hook[1] == 'clear'        
 | |
|         assert run_hook[2] == 'start'        
 | |
|         assert run_hook[3] == 'rollback'
 | |
|         assert run_hook[4] == 'clear'
 | |
|         
 | |
|         #
 | |
|         # test hooks for POST /redirect_rollback
 | |
|         # This controller should always be transactional,
 | |
|         # *except* in the case of redirects
 | |
|         #
 | |
|         
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.post('/redirect_rollback')
 | |
|         assert response.status_int == 302
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'rollback'
 | |
|         assert run_hook[2] == 'clear'
 | |
|         
 | |
|         #
 | |
|         # Exceptions (other than HTTPFound) should *always*
 | |
|         # rollback no matter what
 | |
|         #
 | |
|         run_hook = []        
 | |
|         
 | |
|         try:
 | |
|             response = app.post('/error')
 | |
|         except IndexError:
 | |
|             pass
 | |
| 
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'rollback'
 | |
|         assert run_hook[2] == 'clear'
 | |
|         
 | |
|         run_hook = []        
 | |
|         
 | |
|         try:
 | |
|             response = app.get('/error')
 | |
|         except IndexError:
 | |
|             pass
 | |
| 
 | |
|         assert len(run_hook) == 2
 | |
|         assert run_hook[0] == 'start_ro'
 | |
|         assert run_hook[1] == 'clear'
 | |
|         
 | |
|         run_hook = []        
 | |
|         
 | |
|         try:
 | |
|             response = app.post('/error_transactional')
 | |
|         except IndexError:
 | |
|             pass
 | |
| 
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'rollback'
 | |
|         assert run_hook[2] == 'clear'
 | |
|         
 | |
|         run_hook = []        
 | |
|         
 | |
|         try:
 | |
|             response = app.get('/error_transactional')
 | |
|         except IndexError:
 | |
|             pass
 | |
| 
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'rollback'
 | |
|         assert run_hook[2] == 'clear'
 | |
|         
 | |
|         run_hook = []        
 | |
|         
 | |
|         try:
 | |
|             response = app.post('/error_rollback')
 | |
|         except IndexError:
 | |
|             pass
 | |
| 
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'rollback'
 | |
|         assert run_hook[2] == 'clear'
 | |
|         
 | |
|         run_hook = []        
 | |
|         
 | |
|         try:
 | |
|             response = app.get('/error_rollback')
 | |
|         except IndexError:
 | |
|             pass
 | |
| 
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'start'
 | |
|         assert run_hook[1] == 'rollback'
 | |
|         assert run_hook[2] == 'clear'
 | |
|     
 | |
|     def test_basic_isolated_hook(self):
 | |
|         run_hook = []
 | |
|         
 | |
|         class SimpleHook(PecanHook):
 | |
|             def on_route(self, state):
 | |
|                 run_hook.append('on_route')
 | |
|             
 | |
|             def before(self, state):
 | |
|                 run_hook.append('before')
 | |
| 
 | |
|             def after(self, state):
 | |
|                 run_hook.append('after')
 | |
| 
 | |
|             def on_error(self, state, e):
 | |
|                 run_hook.append('error')
 | |
| 
 | |
|         class SubSubController(object):
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside_sub_sub')
 | |
|                 return 'Deep inside here!'
 | |
|         
 | |
|         class SubController(HookController):
 | |
|             __hooks__ = [SimpleHook()]
 | |
|             
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside_sub')
 | |
|                 return 'Inside here!'
 | |
|             
 | |
|             sub = SubSubController()
 | |
|         
 | |
|         class RootController(object):
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside')
 | |
|                 return 'Hello, World!'
 | |
|             
 | |
|             sub = SubController()
 | |
|                 
 | |
|         app = TestApp(make_app(RootController()))
 | |
|         response = app.get('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
|         
 | |
|         assert len(run_hook) == 1
 | |
|         assert run_hook[0] == 'inside'
 | |
|         
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.get('/sub')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Inside here!'
 | |
|         
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'before'
 | |
|         assert run_hook[1] == 'inside_sub'
 | |
|         assert run_hook[2] == 'after'
 | |
| 
 | |
|         run_hook = []
 | |
|         response = app.get('/sub/sub')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Deep inside here!'
 | |
|         
 | |
|         assert len(run_hook) == 3
 | |
|         assert run_hook[0] == 'before'
 | |
|         assert run_hook[1] == 'inside_sub_sub'
 | |
|         assert run_hook[2] == 'after'
 | |
|     
 | |
|     def test_isolated_hook_with_global_hook(self):
 | |
|         run_hook = []
 | |
|         
 | |
|         class SimpleHook(PecanHook):
 | |
|             def __init__(self, id):
 | |
|                 self.id = str(id)
 | |
|             
 | |
|             def on_route(self, state):
 | |
|                 run_hook.append('on_route'+self.id)
 | |
|             
 | |
|             def before(self, state):
 | |
|                 run_hook.append('before'+self.id)
 | |
| 
 | |
|             def after(self, state):
 | |
|                 run_hook.append('after'+self.id)
 | |
| 
 | |
|             def on_error(self, state, e):
 | |
|                 run_hook.append('error'+self.id)
 | |
|         
 | |
|         class SubController(HookController):
 | |
|             __hooks__ = [SimpleHook(2)]
 | |
|             
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside_sub')
 | |
|                 return 'Inside here!'
 | |
|         
 | |
|         class RootController(object):
 | |
|             @expose()
 | |
|             def index(self):
 | |
|                 run_hook.append('inside')
 | |
|                 return 'Hello, World!'
 | |
|             
 | |
|             sub = SubController()
 | |
|                 
 | |
|         app = TestApp(make_app(RootController(), hooks=[SimpleHook(1)]))
 | |
|         response = app.get('/')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Hello, World!'
 | |
|         
 | |
|         assert len(run_hook) == 4
 | |
|         assert run_hook[0] == 'on_route1'
 | |
|         assert run_hook[1] == 'before1'
 | |
|         assert run_hook[2] == 'inside'
 | |
|         assert run_hook[3] == 'after1'
 | |
|         
 | |
|         run_hook = []
 | |
|         
 | |
|         response = app.get('/sub')
 | |
|         assert response.status_int == 200
 | |
|         assert response.body == 'Inside here!'
 | |
|         
 | |
|         assert len(run_hook) == 6
 | |
|         assert run_hook[0] == 'on_route1'
 | |
|         assert run_hook[1] == 'before2'
 | |
|         assert run_hook[2] == 'before1'
 | |
|         assert run_hook[3] == 'inside_sub'
 | |
|         assert run_hook[4] == 'after1'
 | |
|         assert run_hook[5] == 'after2'
 | |
|     
 | |
|     def test_hooks_with_validation(self):
 | |
|         run_hook = []
 | |
|         
 | |
|         class RegistrationSchema(Schema):
 | |
|             first_name         = validators.String(not_empty=True)
 | |
|             last_name          = validators.String(not_empty=True)
 | |
|             email              = validators.Email()
 | |
|             username           = validators.PlainText()
 | |
|             password           = validators.String()
 | |
|             password_confirm   = validators.String()
 | |
|             age                = validators.Int()
 | |
|             chained_validators = [
 | |
|                 validators.FieldsMatch('password', 'password_confirm')
 | |
|             ]
 | |
|         
 | |
|         class SimpleHook(PecanHook):
 | |
|             def on_route(self, state):
 | |
|                 run_hook.append('on_route')
 | |
|             
 | |
|             def before(self, state):
 | |
|                 run_hook.append('before')
 | |
| 
 | |
|             def after(self, state):
 | |
|                 run_hook.append('after')
 | |
| 
 | |
|             def on_error(self, state, e):
 | |
|                 run_hook.append('error')
 | |
|         
 | |
|         class RootController(object):            
 | |
|             @expose()
 | |
|             def errors(self, *args, **kwargs):
 | |
|                 run_hook.append('inside')
 | |
|                 return 'errors'
 | |
|             
 | |
|             @expose(schema=RegistrationSchema())
 | |
|             def index(self, first_name, 
 | |
|                             last_name, 
 | |
|                             email, 
 | |
|                             username, 
 | |
|                             password,
 | |
|                             password_confirm,
 | |
|                             age):
 | |
|                 run_hook.append('inside')
 | |
|                 return str(len(request.validation_errors) > 0)
 | |
|             
 | |
|             @expose(schema=RegistrationSchema(), error_handler='/errors')
 | |
|             def with_handler(self, first_name, 
 | |
|                             last_name, 
 | |
|                             email, 
 | |
|                             username, 
 | |
|                             password,
 | |
|                             password_confirm,
 | |
|                             age):
 | |
|                 run_hook.append('inside')
 | |
|                 return str(len(request.validation_errors) > 0)
 | |
|         
 | |
|         # test that the hooks get properly run with no validation errors        
 | |
|         app = TestApp(make_app(RootController(), hooks=[SimpleHook()]))
 | |
|         r = app.post('/', dict(
 | |
|             first_name       = 'Jonathan',
 | |
|             last_name        = 'LaCour',
 | |
|             email            = 'jonathan@cleverdevil.org',
 | |
|             username         = 'jlacour',
 | |
|             password         = '123456',
 | |
|             password_confirm = '123456',
 | |
|             age              = '31'
 | |
|         ))
 | |
|         assert r.status_int == 200
 | |
|         assert r.body == 'False'
 | |
|         assert len(run_hook) == 4
 | |
|         assert run_hook[0] == 'on_route'
 | |
|         assert run_hook[1] == 'before'
 | |
|         assert run_hook[2] == 'inside'
 | |
|         assert run_hook[3] == 'after'
 | |
|         run_hook = []
 | |
|         
 | |
|         # test that the hooks get properly run with validation errors        
 | |
|         app = TestApp(make_app(RootController(), hooks=[SimpleHook()]))
 | |
|         r = app.post('/', dict(
 | |
|             first_name       = 'Jonathan',
 | |
|             last_name        = 'LaCour',
 | |
|             email            = 'jonathan@cleverdevil.org',
 | |
|             username         = 'jlacour',
 | |
|             password         = '654321',
 | |
|             password_confirm = '123456',
 | |
|             age              = '31'
 | |
|         ))
 | |
|         assert r.status_int == 200
 | |
|         assert r.body == 'True'
 | |
|         assert len(run_hook) == 4
 | |
|         assert run_hook[0] == 'on_route'
 | |
|         assert run_hook[1] == 'before'
 | |
|         assert run_hook[2] == 'inside'
 | |
|         assert run_hook[3] == 'after'
 | |
|         run_hook = []
 | |
|         
 | |
|         # test that the hooks get properly run with validation errors 
 | |
|         # and an error handler       
 | |
|         app = TestApp(make_app(RootController(), hooks=[SimpleHook()]))
 | |
|         r = app.post('/with_handler', dict(
 | |
|             first_name       = 'Jonathan',
 | |
|             last_name        = 'LaCour',
 | |
|             email            = 'jonathan@cleverdevil.org',
 | |
|             username         = 'jlacour',
 | |
|             password         = '654321',
 | |
|             password_confirm = '123456',
 | |
|             age              = '31'
 | |
|         ))
 | |
|         assert r.status_int == 200
 | |
|         assert r.body == 'errors'
 | |
|         assert len(run_hook) == 7
 | |
|         assert run_hook[0] == 'on_route'
 | |
|         assert run_hook[1] == 'before'
 | |
|         assert run_hook[2] == 'after'
 | |
|         assert run_hook[3] == 'on_route'
 | |
|         assert run_hook[4] == 'before'
 | |
|         assert run_hook[5] == 'inside'
 | |
|         assert run_hook[6] == 'after'
 | 
