def test_action_decorator_prevent_empty_form(): class Root(Controller): @action(prevent_empty_form=True) def index(self): yield 'default' @action(prevent_empty_form='777 Form Is Required Here') def custom_status(self): yield 'custom' with Given(Root(), verb='POST', form=dict(a=1)): assert status == 200 when(form={}) assert status == 400 when(form=None) assert status == 400 when('/custom_status', form={}) assert status == 777 when('/custom_status', form=None) assert status == 777 when('/custom_status', form=dict(a=1)) assert status == 200
def test_json_decorator(): class Root(Controller): @json def index(self, a, b): return dict(a=a, b=b) @json def custom(self): class A: def to_dict(self): return dict(c=1) return A() @json def badobject(self): class A: pass return A() with Given(Root(), '/1/2'): assert status == 200 assert response.json == dict(a='1', b='2') assert response.content_type == 'application/json' assert response.encoding == 'utf-8' when('/custom') assert status == 200 assert response.json == dict(c=1) with pytest.raises(ValueError): when('/badobject')
def test_chunked_streaming(): class Root(Controller): @action @chunked def index(self): yield 'first' yield 'second' @action @chunked('trailer1', 'end') def trailer(self): yield 'first' yield 'second' @action @chunked def error(self): yield 'first' raise Exception('error in streaming') with Given(Root()): assert status == 200 assert response.text == \ '5\r\nfirst\r\n6\r\nsecond\r\n0\r\n\r\n' when('/trailer') assert status == 200 assert response.text == \ '5\r\nfirst\r\n6\r\nsecond\r\n0\r\ntrailer1: end\r\n\r\n' when('/error') assert status == 200 assert response.text == \ '5\r\nfirst\r\n18\r\nerror in streaming0\r\n\r\n'
def test_http_multipart_form(): class Root(Controller): @action def index(self): def read_form_field(v): return v.file.read().decode() \ if isinstance(v, cgi.FieldStorage) else v yield context.request_content_type yield ', ' yield ', '.join( f'{k}=' f'{read_form_field(v)}' \ for k, v in sorted(context.form.items()) ) with Given(Root(), verb='POST'): assert status == 200 assert response.text == ', ' when(multipart=dict(a=1, b=2)) assert status == 200 assert response.text == 'multipart/form-data, a=1, b=2' filelike = io.BytesIO(b'abcdef') when(multipart=dict(a=filelike)) assert status == 200 assert response.text == 'multipart/form-data, a=abcdef'
def test_action_decorator_verbs(): class Root(Controller): @action(verbs=['get', 'view']) def index(self, a, b): yield f'{a}, {b}' with Given(Root(), '/1/2'): assert status == 200 assert response.text == '1, 2' when(verb='put') assert status == 405
def test_vary_optional_arguments_url_parameters(): class Root(Controller): @action def index(self, **kw): yield ', '.join(f'{k}={v}' for k, v in kw.items()) with Given(Root()): assert status == 200 assert response.text == '' when('/a') assert status == 404
def test_no_default_handler(): class Root(Controller): @action def foo(self): yield 'Foo' with Given(Root(), '/foo'): assert status == 200 assert response.text == 'Foo' when('/') assert status == 404
def test_action_decorator_prevent_form(): class Root(Controller): @action(prevent_form=True) def index(self): yield 'default' @action(prevent_form='777 Form Not Allowed Here') def custom_status(self): yield 'custom' with Given(Root(), verb='POST'): assert status == 200 when(body='foo=1') assert status == '400 Form Not Allowed' when('/custom_status', form=dict(a=1)) assert status == 777 when('/custom_status') assert status == 200 # Trying custom verb #123 when(verb='LIST') assert status == 200
def test_json_decorator(): class Root(Controller): @json def index(self, a, b): return dict(a=a, b=b) @json def custom(self): class A: def to_dict(self): return dict(c=1) return A() @json def non_object(self, value_type): return {'None': None, 'str': 'Yes', 'int': 123}[value_type] @json def badobject(self): class A: pass return A() with Given(Root(), '/1/2'): assert status == 200 assert response.json == dict(a='1', b='2') assert response.content_type == 'application/json' assert response.encoding == 'utf-8' when('/custom') assert status == 200 assert response.json == dict(c=1) with pytest.raises(ValueError): when('/badobject') when('/non_object/None') assert status == 200 assert response.json is None when('/non_object/str') assert status == 200 assert response.json == 'Yes' when('/non_object/int') assert status == 200 assert response.json == 123
def test_nested_static_controller(make_temp_directory): class Root(Controller): static = Static(make_temp_directory(a=dict(a1='A1', a2='A2'), b='B'), default_document='b') with Given(Root()): assert status == 404 when('/static/b') assert status == 200 assert response.text == 'B' when('/static/a/a1') assert status == 200 assert response.text == 'A1'
def test_fixed_positional_and_vary_optional_arguments_url_parameters(): class Root(Controller): @action def index(self, a, b, **kw): yield f'{a}, {b}, {kw}' with Given(Root(), '/a/b'): assert status == 200 assert response.text == 'a, b, {}' when('/a') assert status == 404 when('/a/b/c') assert status == 404
def test_invalid_form(): class Root(Controller): @action def index(self): form = context.form yield context.request_content_type yield ', ' yield ', '.join(f'{k}={v}' for k, v in sorted(form.items())) with Given(Root(), verb='POST', json={}): assert status == 200 assert response.text == ', ' when(body='', content_type='multipart/form-data; boundary=') assert status == '400 Cannot parse the request'
def test_both_vary_optional_and_positional_arguments_url_parameters(): class Root(Controller): @action def index(self, *a, **kw): yield ', '.join(a) with Given(Root()): assert status == 200 assert response.text == '' when('/a') assert status == 200 assert response.text == 'a' when('/a/b/c/d') assert status == 200 assert response.text == 'a, b, c, d'
def test_vary_positional_url_parameters(): class Root(Controller): @action def index(self, *args): yield ', '.join(args) with Given(Root()): assert status == 200 assert response.text == '' when('/a') assert status == 200 assert response.text == 'a' when('/a/b') assert status == 200 assert response.text == 'a, b'
def test_application_hooks(): class Root(Controller): @action def index(self): foo = context.foo del context.foo context.bar = foo yield f'Index: {foo}' class TestApp(Application): def app_init(self): global app_init_calls app_init_calls += 1 def begin_request(self): global begin_request_calls context.foo = 'Bar' begin_request_calls += 1 def begin_response(self): global begin_response_calls assert not hasattr(context, 'foo') assert hasattr(context, 'bar') begin_response_calls += 1 def end_response(self): global end_response_calls end_response_calls += 1 with Given(TestApp(Root())): assert status == 200 assert response.text == 'Index: Bar' assert app_init_calls == 1 assert begin_response_calls == 1 assert begin_request_calls == 1 assert end_response_calls == 1 when() assert status == 200 assert app_init_calls == 1 assert begin_response_calls == 2 assert begin_request_calls == 2 assert end_response_calls == 2
def test_json_form(): class Root(Controller): @action def index(self): form = context.form yield context.request_content_type yield ', ' yield ', '.join(f'{k}={v}' for k, v in sorted(form.items())) with Given(Root(), verb='POST', json={}, configuration='debug: false'): assert status == 200 assert response.text == ', ' when(json=dict(a=1, b=2)) assert status == 200 assert response.text == 'application/json, a=1, b=2' # No content length when(body='', content_type='application/json') assert status == 400 assert response.text == 'Content-Length required' when(body='malformed', content_type='application/json', headers={'Content-Length': '9'}) assert status == 400 assert response.text == 'Cannot parse the request'
def test_http_url_encoded_form(): class Root(Controller): @action def index(self): yield context.request_content_type yield ', ' yield ', '.join(f'{k}={v}' for k, v in sorted(context.form.items())) with Given(Root(), verb='POST'): assert status == 200 assert response.text == ', ' when(form=dict(a=1, b=2)) assert status == 200 assert response.text == 'application/x-www-form-urlencoded, a=1, b=2' when(body='a') assert status == 200 assert response.text == ', a=' # Duplicated fields when(body='a=1&a=2', content_type='application/x-www-form-urlencoded') assert status == 200 assert response.text == \ 'application/x-www-form-urlencoded, a=[\'1\', \'2\']'
def test_nested_rest_controllers(): class BarController(RestController): @action def get(self, *args): yield f'Bars, {", ".join(args)}' class Root(RestController): bars = BarController() @action def get(self, *args): yield f'{", ".join(args)}' with Given(Root()): assert status == 200 assert response.text == '' when('/bars') assert status == 200 assert response.text == 'Bars, ' when('/bars/a') assert status == 200 assert response.text == 'Bars, a'
def test_action_decorator_form_whitelist(): class Root(Controller): @action(form_whitelist=['a', 'b']) def index(self): yield 'default' @action(form_whitelist=(['a', 'b'], '888 Only a & b accepted')) def custom_status(self): yield 'custom' with Given(Root(), verb='POST', form=dict(a=1)): assert status == 200 when(form=given + dict(b=2)) assert status == 200 when(form=given + dict(c=2)) assert status == 400 when('/custom_status', form=dict(c=2)) assert status == 888 when('/custom_status', form=dict(a=2)) assert status == 200
def test_regex_controller(): class Root(RegexRouteController): def __init__(self): super().__init__(((r'/foos/(?P<id>\d+)/bars', self.bars), )) @action def bars(self, id: int): return f'{id}' with Given(Root(), '/foos/1/bars'): assert status == 200 assert response.text == '1' when('/foos') assert status == 404 when('/foos/bars') assert status == 404 when('/foos/1/2/bars') assert status == 404 when('/foos/a/bars') assert status == 404
def test_both_foxed_and_vary_positional_arguments(): class Root(Controller): @action def index(self, a, b, *args): yield f'{a}, {b}, {", ".join(args)}' with Given(Root(), '/a/b'): assert status == 200 assert response.text == 'a, b, ' when('/a/b/c') assert status == 200 assert response.text == 'a, b, c' when('/a') assert status == 404 when('/a/b/c/d') assert status == 200
def test_fixed_positional_and_both_vary_and_fixed_optional_arguments(): class Root(Controller): @action def index(self, a, b, c=None, **kw): yield f'{a}, {b}, {c}, {kw}' with Given(Root(), '/a/b'): assert status == 200 assert response.text == 'a, b, None, {}' when('/a/b/c') assert status == 200 assert response.text == 'a, b, c, {}' when('/a') assert status == 404 when('/a/b/c/d') assert status == 404
def test_fixed_optional_arguments_url_parameters(): class Root(Controller): @action def index(self, a=None, b=1): yield f'{a}, {b}' with Given(Root()): assert status == 200 assert response.text == 'None, 1' when('/a') assert status == 200 assert response.text == 'a, 1' when('/a/b') assert status == 200 assert response.text == 'a, b' when('/a/b/c') assert status == 404
def test_query_strign(): class Root(Controller): @action def index(self, *, a=1, b=2): query = ', '.join(f'{k}={v}' for k, v in context.query.items()) yield f'{a}, {b}, {query}' with Given(Root()): assert status == 200 assert response.text == '1, 2, ' when(query=dict(a='a')) assert status == 200 assert response.text == 'a, 2, a=a' when(query=dict(a='a', c='c')) assert status == 200 assert response.text == 'a, 2, a=a, c=c' when(query=dict(c='c')) assert status == 200 assert response.text == '1, 2, c=c'
def test_fixed_positional_url_parameter(): class Root(Controller): @action def index(self, a, b): yield f'{a}, {b}' with Given(Root(), '/1/2'): assert status == 200 assert response.text == '1, 2' # Extra trailing slash when('/1/2/') assert status == 200 assert response.text == '1, 2' # Insufficient URL parameters when('/1') assert status == 404 # Extra URL parameters when('/1/2/3') assert status == 404
def test_object_dispatcher(): class RegularClass: pass class BarController(Controller): @action def index(self, *args): yield f'Bars, {", ".join(args)}' def private(self): # pragma: no cover raise Exception() @action def lorem(self, *args): yield f'Lorem, {", ".join(args)}' class Root(Controller): bars = BarController() requlars = RegularClass() @action def index(self): yield 'Index' @action def foo(self): yield 'Foo' def private(self): # pragma: no cover raise Exception() with Given(Root()): assert status == 200 assert response.text == 'Index' when('/foo') assert status == 200 assert response.text == 'Foo' when(url='/a') assert status == '404 Not Found' when(url='/a/') assert status == '404 Not Found' when(url='/requlars') assert status == '404 Not Found' when('/private') assert status == 404 when('/bars') assert status == 200 assert response.text == 'Bars, ' when('/bars/a') assert status == 200 assert response.text == 'Bars, a' when('/bars/lorem') assert status == 200 assert response.text == 'Lorem, ' when('/bars/lorem/a/b') assert status == 200 assert response.text == 'Lorem, a, b' when('/bars/private') assert status == 404
def test_static_controller(make_temp_directory): static = Static(make_temp_directory(a=dict(a1='A1', a2='A2'), b='B'), default_document='b') with Given(static): assert status == 200 assert response.text == 'B' when('/a/a1') assert status == 200 assert response.text == 'A1' when('/a/a2') assert status == 200 assert response.text == 'A2' when('/a/a3') assert status == 404 when('/../') assert status == 403 when('/a/../a/a2') assert status == 200 # When default document is not exists static.default_document = 'BadFile' when('/') assert status == 404 # When default document is not given static.default_document = None when('/') assert status == 404
def test_rest_controller(): class Root(RestController): @action def index(self): # pragma: no cover raise Exception() @action def foo(self, *args): yield f'Foo, {", ".join(args)}' def private(self): # pragma: no cover raise Exception() with Given(Root(), verb='foo'): assert status == 200 assert response.text == 'Foo, ' when(verb='FOO') assert status == 200 assert response.text == 'Foo, ' when('/a', verb='FOO') assert status == 200 assert response.text == 'Foo, a' when('/a/b', verb='FOO') assert status == 200 assert response.text == 'Foo, a, b' when(verb='GET') assert status == 405 when('/private') assert status == 404 when('/private', verb='GET') assert status == 404