def app_(self): class RootController(object): @expose() def index(self, req, resp, id): return 'index: %s' % id @expose() def multiple(self, req, resp, one, two): return 'multiple: %s, %s' % (one, two) @expose() def optional(self, req, resp, id=None): return 'optional: %s' % str(id) @expose() def multiple_optional(self, req, resp, one=None, two=None, three=None): return 'multiple_optional: %s, %s, %s' % (one, two, three) @expose() def variable_args(self, req, resp, *args): return 'variable_args: %s' % ', '.join(args) @expose() def variable_kwargs(self, req, resp, **kwargs): data = [ '%s=%s' % (key, kwargs[key]) for key in sorted(kwargs.keys()) ] return 'variable_kwargs: %s' % ', '.join(data) @expose() def variable_all(self, req, resp, *args, **kwargs): data = [ '%s=%s' % (key, kwargs[key]) for key in sorted(kwargs.keys()) ] return 'variable_all: %s' % ', '.join(list(args) + data) @expose() def eater(self, req, resp, id, dummy=None, *args, **kwargs): data = [ '%s=%s' % (key, kwargs[key]) for key in sorted(kwargs.keys()) ] return 'eater: %s, %s, %s' % (id, dummy, ', '.join(list(args) + data)) @expose() def _route(self, args, request): if hasattr(self, args[0]): return getattr(self, args[0]), args[1:] else: return self.index, args return TestApp(Pecan(RootController(), use_context_locals=False))
def test_basic_single_hook(self): run_hook = [] class RootController(object): @expose() def index(self, req, resp): 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( Pecan(RootController(), hooks=[SimpleHook()], use_context_locals=False)) response = app.get('/') assert response.status_int == 200 assert response.body == b_('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_on_error_response_hook(self): run_hook = [] class RootController(object): @expose() def causeerror(self, req, resp): return [][1] class ErrorHook(PecanHook): def on_error(self, state, e): run_hook.append('error') r = webob.Response() r.text = u_('on_error') return r app = TestApp( Pecan(RootController(), hooks=[ErrorHook()], use_context_locals=False)) response = app.get('/causeerror') assert len(run_hook) == 1 assert run_hook[0] == 'error' assert response.text == 'on_error'
def test_simple_generic(self): class RootController(object): @expose(generic=True) def index(self): pass @index.when(method='POST', template='json') def do_post(self): return dict(result='POST') @index.when(method='GET') def do_get(self): return 'GET' app = TestApp(Pecan(RootController())) r = app.get('/') assert r.status_int == 200 assert r.body == b_('GET') r = app.post('/') assert r.status_int == 200 assert r.body == b_(dumps(dict(result='POST'))) r = app.get('/do_get', status=404) assert r.status_int == 404
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')))
def test_generics_with_im_self_with_method(self): uniq = str(time.time()) with mock.patch('threading.local', side_effect=AssertionError()): app = TestApp(Pecan(self.root(uniq), use_context_locals=False)) r = app.post_json('/', {'foo': 'bar'}, headers={'X-Unique': uniq}) assert r.status_int == 200 json_resp = loads(r.body.decode()) assert json_resp['foo'] == 'bar'
def test_locals_are_not_used(self): with mock.patch('threading.local', side_effect=AssertionError()): app = TestApp(Pecan(self.root(), use_context_locals=False)) r = app.get('/') assert r.status_int == 200 assert r.body == b_('Hello, World!') self.assertRaises(AssertionError, Pecan, self.root)
def test_generics_with_im_self_with_extra_args(self): uniq = str(time.time()) with mock.patch('threading.local', side_effect=AssertionError()): app = TestApp(Pecan(self.root(uniq), use_context_locals=False)) r = app.get('/extra/123/456', headers={'X-Unique': uniq}) assert r.status_int == 200 json_resp = loads(r.body.decode()) assert json_resp['first'] == '123' assert json_resp['second'] == '456'
def app_(self): class RootController(object): @expose() def index(self, req, resp): assert isinstance(req, webob.BaseRequest) assert isinstance(resp, webob.Response) return 'Hello, World!' return TestApp(Pecan(RootController(), use_context_locals=False))
def test_lookup_with_wrong_argspec(self): class RootController(object): @expose() def _lookup(self, someID): return 'Bad arg spec' # pragma: nocover with warnings.catch_warnings(): warnings.simplefilter("ignore") app = TestApp(Pecan(RootController(), use_context_locals=False)) r = app.get('/foo/bar', expect_errors=True) assert r.status_int == 404
def test_manual_response(self): class RootController(object): @expose() def index(self, req, resp): resp = webob.Response(resp.environ) resp.body = b_('Hello, World!') return resp app = TestApp(Pecan(RootController(), use_context_locals=False)) r = app.get('/') assert r.body == b_('Hello, World!'), r.body
def test_prioritized_hooks(self): run_hook = [] class RootController(object): @expose() def index(self, req, resp): run_hook.append('inside') return 'Hello, World!' class SimpleHook(PecanHook): def __init__(self, id, priority=None): self.id = str(id) if priority: self.priority = priority 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 = Pecan( RootController(), hooks=[SimpleHook(1, 3), SimpleHook(2, 2), SimpleHook(3, 1)], use_context_locals=False) app = TestApp(papp) response = app.get('/') assert response.status_int == 200 assert response.body == b_('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 make_app(self, schema=('key', 'value')): import pecan_notario from pecan import Pecan, expose, request from webtest import TestApp simple_schema = schema class RootController(object): @expose('json') @pecan_notario.validate(simple_schema, handler=False) def index(self, **kw): if request.validation_error is None: return dict(success=True) return dict(success=False, error=str(request.validation_error)) return TestApp(Pecan(RootController()))
def app_(self): class SubSubController(object): @expose() def index(self, req, resp): assert isinstance(req, webob.BaseRequest) assert isinstance(resp, webob.Response) return '/sub/sub/' @expose() def deeper(self, req, resp): assert isinstance(req, webob.BaseRequest) assert isinstance(resp, webob.Response) return '/sub/sub/deeper' class SubController(object): @expose() def index(self, req, resp): assert isinstance(req, webob.BaseRequest) assert isinstance(resp, webob.Response) return '/sub/' @expose() def deeper(self, req, resp): assert isinstance(req, webob.BaseRequest) assert isinstance(resp, webob.Response) return '/sub/deeper' sub = SubSubController() class RootController(object): @expose() def index(self, req, resp): assert isinstance(req, webob.BaseRequest) assert isinstance(resp, webob.Response) return '/' @expose() def deeper(self, req, resp): assert isinstance(req, webob.BaseRequest) assert isinstance(resp, webob.Response) return '/deeper' sub = SubController() return TestApp(Pecan(RootController(), use_context_locals=False))
def app_(self): class LookupController(object): def __init__(self, someID): self.someID = someID @expose() def index(self, req, resp): return self.someID class UserController(object): @expose() def _lookup(self, someID, *remainder): return LookupController(someID), remainder class RootController(object): users = UserController() return TestApp(Pecan(RootController(), use_context_locals=False))
def test_partial_hooks(self): run_hook = [] class RootController(object): @expose() def index(self, req, resp): run_hook.append('inside') return 'Hello World!' @expose() def causeerror(self, req, resp): 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( Pecan(RootController(), hooks=[ErrorHook(), OnRouteHook()], use_context_locals=False)) response = app.get('/') assert response.status_int == 200 assert response.body == b_('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 as e: assert isinstance(e, IndexError) assert len(run_hook) == 2 assert run_hook[0] == 'on_route' assert run_hook[1] == 'error'
def make_app(self, schema=('key', 'value')): import pecan_notario from pecan import Pecan, expose, request from pecan.middleware.recursive import RecursiveMiddleware from webtest import TestApp simple_schema = schema class RootControllerTwo(object): @expose('json') @pecan_notario.validate(simple_schema, handler='/error') def index(self, **kw): return dict(success=True) @expose('json') def error(self, **kw): return dict(success=False, error=str(request.validation_error)) return TestApp(RecursiveMiddleware(Pecan(RootControllerTwo())))
def test_simple_jsonify(self): Person = make_person() # register a generic JSON rule @jsonify.when_type(Person) def jsonify_person(obj): return dict(name=obj.name) class RootController(object): @expose('json') def index(self): # create a Person instance p = Person('Jonathan', 'LaCour') return p app = TestApp(Pecan(RootController())) r = app.get('/') assert r.status_int == 200 assert loads(r.body.decode()) == {'name': 'Jonathan LaCour'}
def test_generic_allow_header(self): class RootController(object): @expose(generic=True) def index(self): abort(405) @index.when(method='POST', template='json') def do_post(self): return dict(result='POST') @index.when(method='GET') def do_get(self): return 'GET' @index.when(method='PATCH') def do_patch(self): return 'PATCH' app = TestApp(Pecan(RootController())) r = app.delete('/', expect_errors=True) assert r.status_int == 405 assert r.headers['Allow'] == 'GET, PATCH, POST'
def app_(self): class OthersController(object): @expose() def index(self, req, resp): return 'OTHERS' @expose() def echo(self, req, resp, value): return str(value) class ThingsController(RestController): data = ['zero', 'one', 'two', 'three'] _custom_actions = {'count': ['GET'], 'length': ['GET', 'POST']} others = OthersController() @expose() def get_one(self, req, resp, id): return self.data[int(id)] @expose('json') def get_all(self, req, resp): return dict(items=self.data) @expose() def length(self, req, resp, id, value=None): length = len(self.data[int(id)]) if value: length += len(value) return str(length) @expose() def post(self, req, resp, value): self.data.append(value) resp.status = 302 return 'CREATED' @expose() def edit(self, req, resp, id): return 'EDIT %s' % self.data[int(id)] @expose() def put(self, req, resp, id, value): self.data[int(id)] = value return 'UPDATED' @expose() def get_delete(self, req, resp, id): return 'DELETE %s' % self.data[int(id)] @expose() def delete(self, req, resp, id): del self.data[int(id)] return 'DELETED' @expose() def reset(self, req, resp): return 'RESET' @expose() def post_options(self, req, resp): return 'OPTIONS' @expose() def options(self, req, resp): abort(500) @expose() def other(self, req, resp): abort(500) class RootController(object): things = ThingsController() # create the app return TestApp(Pecan(RootController(), use_context_locals=False))
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, req, resp): run_hook.append('inside_sub_sub') return 'Deep inside here!' class SubController(HookController): __hooks__ = [SimpleHook()] @expose() def index(self, req, resp): run_hook.append('inside_sub') return 'Inside here!' sub = SubSubController() class RootController(object): @expose() def index(self, req, resp): run_hook.append('inside') return 'Hello, World!' sub = SubController() app = TestApp(Pecan(RootController(), use_context_locals=False)) response = app.get('/') assert response.status_int == 200 assert response.body == b_('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 == b_('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 == b_('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_threadlocal_argument_warning_on_generic_delegate(self): with mock.patch('threading.local', side_effect=AssertionError()): app = TestApp(Pecan(self.root(), use_context_locals=False)) self.assertRaises(TypeError, app.put, '/generic/')
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, req, resp): run_hook.append('inside_sub') return 'Inside here!' class RootController(object): @expose() def index(self, req, resp): run_hook.append('inside') return 'Hello, World!' sub = SubController() app = TestApp( Pecan(RootController(), hooks=[SimpleHook(1)], use_context_locals=False)) response = app.get('/') assert response.status_int == 200 assert response.body == b_('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 == b_('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'