Ejemplo n.º 1
0
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')
Ejemplo n.º 3
0
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'
Ejemplo n.º 4
0
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'
Ejemplo n.º 5
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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
Ejemplo n.º 12
0
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'
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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'
Ejemplo n.º 17
0
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\']'
Ejemplo n.º 18
0
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'
Ejemplo n.º 19
0
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
Ejemplo n.º 24
0
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
Ejemplo n.º 26
0
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
Ejemplo n.º 27
0
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
Ejemplo n.º 28
0
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