Exemple #1
0
def test_validation_decorator():
    class Root(Controller):
        @validate(
            query1=dict(required=True, type_=int, query=True),
            field1=dict(required=True, type_=float),
            field2=dict(required=True, type_=int),
            field3=dict(required=True,
                        type_=lambda v: v.encode(),
                        min_length=1),
        )
        @action
        def index(self):
            query1 = context.query['query1']
            field1 = context.form['field1']
            field2 = context.form['field2']
            field3 = context.form['field3']
            yield \
                f'{type(query1).__name__}: {query1}, '\
                f'{type(field1).__name__}: {field1}, ' \
                f'{type(field2).__name__}: {field2}, ' \
                f'{type(field3).__name__}: {field3}'

    with Given(
            Root(),
            verb='POST',
            query=dict(query1=1),
            form=dict(field1='2.3', field2='2', field3='ab'),
    ):
        assert status == 200
        assert response.text == 'int: 1, float: 2.3, int: 2, bytes: b\'ab\''
Exemple #2
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'
Exemple #3
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\']'
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
Exemple #5
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'
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')
Exemple #7
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
Exemple #8
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'
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_action_decorator_prevent_form_rest_controller():
    class Root(RestController):
        @action(prevent_form=True)
        def foo(self):
            yield 'default'

    with Given(Root(), verb='foo'):
        assert status == 200
Exemple #11
0
def test_not_iterable_response():
    class Root(Controller):
        @action
        def index(self):
            return 352345352

    with pytest.raises(ValueError):
        Given(Root())
Exemple #12
0
def test_http_not_modified():
    class Root(Controller):
        @action
        def index(self):
            raise HTTPNotModified()

    with Given(Root()):
        assert status == 304
Exemple #13
0
def test_iterable_pipeline():
    class Root(Controller):
        @action
        def index(self):
            return ['a', 'b']

    with Given(Root()):
        assert status == 200
        assert response.text == 'ab'
Exemple #14
0
def test_http_status_no_debug_mode_json_content_type():
    class Root(Controller):
        @json
        def index(self):
            raise HTTPStatus('603 Bad Happened')

    with Given(Root(), configuration='debug: false'):
        assert status == '603 Bad Happened'
        assert response.json == {}
Exemple #15
0
def test_empty_response():
    class Root(Controller):
        @action
        def index(self):
            return None

    with Given(Root()):
        assert status == 200
        assert response.text == ''
Exemple #16
0
def test_http_status_debug_mode():
    class Root(Controller):
        @action
        def index(self):
            raise HTTPStatus('603 Bad Happened')

    with Given(Root()):
        assert status == '603 Bad Happened'
        assert 'traceback' in response.text.casefold()
Exemple #17
0
def test_http_bad_request():
    class Root(Controller):
        @action
        def index(self):
            raise HTTPBadRequest('My Bad')

    with Given(Root(), configuration='debug: false'):
        assert status == '400 My Bad'
        assert response.text == 'My Bad'
Exemple #18
0
def test_iterable_but_bad_response():
    class Root(Controller):
        @action
        def index(self):
            yield '1'
            yield 352345352

    with pytest.raises(TypeError):
        Given(Root())
Exemple #19
0
def test_basic_pipeline():
    class Root(Controller):
        @action
        def index(self):
            yield f'Index: {context.request_scheme}, {context.request_uri}'

    with Given(Root()):
        assert status == 200
        assert response.text == 'Index: http, http://bddrest-interceptor/'
Exemple #20
0
def test_http_status_debug_mode_json_content_type():
    class Root(Controller):
        @json
        def index(self):
            raise HTTPStatus('603 Bad Happened')

    with Given(Root()):
        assert status == '603 Bad Happened'
        assert 'stackTrace' in response.json
Exemple #21
0
def test_http_redirect():
    class Root(Controller):
        @action
        def index(self):
            raise HTTPMovedPermanently('http://example.com')

    with Given(Root(), configuration='debug: false'):
        assert status == '301 Moved Permanently'
        assert response.text == 'Moved Permanently'
        assert response.headers['Location'] == 'http://example.com'
Exemple #22
0
def test_http_status_no_debug_mode():
    class Root(Controller):
        @action
        def index(self):
            raise HTTPStatus('603 Bad Happened')

    with Given(Root(), configuration='debug: false'):
        assert status == '603 Bad Happened'
        assert 'traceback' not in response.text.casefold()
        assert response.text == 'Bad Happened'
Exemple #23
0
def test_http_success_headers(http_success_exception):
    class Root(Controller):
        @action
        def index(self):
            context.response_headers['x-app-extra'] = 'yep'
            raise http_success_exception

    with Given(Root()):
        assert status == http_success_exception.status
        assert response.headers['x-app-extra'] == 'yep'
Exemple #24
0
def test_unhandled_exceptions_no_debug_mode():
    class E(Exception):
        pass

    class Root(Controller):
        @action
        def index(self):
            raise E()

    with pytest.raises(E):
        Given(Root(), configuration='debug: false')
def test_action_decorator_content_type():
    class Root(Controller):
        @action(encoding='utf32', content_type='text/plain')
        def index(self, a, b):
            yield f'{a}, {b}'

    with Given(Root(), '/1/2'):
        assert status == 200
        assert response.encoding == 'utf32'
        assert response.content_type == 'text/plain'
        assert response.text == '1, 2'
def test_text_decorator():
    class Root(Controller):
        @text
        def index(self):
            yield 'abc'

    with Given(Root()):
        assert status == 200
        assert response.text == 'abc'
        assert response.content_type == 'text/plain'
        assert response.encoding == 'utf-8'
def test_xml_decorator():
    class Root(Controller):
        @xml
        def index(self):
            yield '<xml></xml>'

    with Given(Root()):
        assert status == 200
        assert response.text == '<xml></xml>'
        assert response.content_type == 'application/xml'
        assert response.encoding == 'utf-8'
def test_binary_decorator():
    class Root(Controller):
        @binary
        def index(self):
            yield b'abc'

    with Given(Root()):
        assert status == 200
        assert response.body == b'abc'
        assert response.content_type == 'application/octet'
        assert response.encoding is None
Exemple #29
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
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