示例#1
0
def test_parser_async(body, doc):
    with disable_asgi_non_coroutine_wrapping():

        class WrappedRespondersBodyParserAsyncResource:
            @falcon.before(validate_param_async, 'limit', 100)
            @falcon.before(parse_body_async)
            async def on_get(self, req, resp, doc=None):
                self.req = req
                self.resp = resp
                self.doc = doc

    app = create_app(asgi=True)

    resource = WrappedRespondersBodyParserAsyncResource()
    app.add_route('/', resource)

    testing.simulate_get(app, '/', body=body)
    assert resource.doc == doc

    async def test_direct():
        resource = WrappedRespondersBodyParserAsyncResource()

        req = testing.create_asgi_req()
        resp = create_resp(True)

        await resource.on_get(req, resp, doc)
        assert resource.doc == doc

    testing.invoke_coroutine_sync(test_direct)
示例#2
0
    def test_asgi_raises_error(self, resource):
        app = create_app(asgi=True)
        app.add_route('/', resource)
        app.req_options.auto_parse_form_urlencoded = True

        with pytest.raises(UnsupportedError):
            testing.simulate_get(app, '/')
示例#3
0
def test_parser_sync(body, doc):
    app = falcon.API()

    resource = WrappedRespondersBodyParserResource()
    app.add_route('/', resource)

    testing.simulate_get(app, '/', body=body)
    assert resource.doc == doc
示例#4
0
    def test_asgi_raises_error(self, resource):
        app = create_app(asgi=True)
        app.add_route('/', resource)
        app.req_options.auto_parse_form_urlencoded = True

        with pytest.raises(RuntimeError) as exc_info:
            testing.simulate_get(app, '/')
        assert 'RequestOptions.auto_parse_form_urlencoded' in exc_info.value.args[
            0]
def test_deserialization_raises(asgi):
    app = create_app(asgi)

    class SuchException(Exception):
        pass

    class FaultyHandler(media.BaseHandler):
        def deserialize(self, stream, content_type, content_length):
            raise SuchException('Wow such error.')

        def deserialize_async(self, stream, content_type, content_length):
            raise SuchException('Wow such error.')

        def serialize(self, media, content_type):
            raise SuchException('Wow such error.')

    handlers = media.Handlers({'application/json': FaultyHandler()})
    app.req_options.media_handlers = handlers
    app.resp_options.media_handlers = handlers

    class Resource:
        def on_get(self, req, resp):
            resp.media = {}

        def on_post(self, req, resp):
            req.media

    class ResourceAsync:
        async def on_get(self, req, resp):
            resp.media = {}

        async def on_post(self, req, resp):
            # NOTE(kgriffs): In this one case we use the property
            #   instead of get_media(), in order to test that the
            #   alias works as expected.
            await req.media

    app.add_route('/', ResourceAsync() if asgi else Resource())

    # NOTE(kgriffs): Now that we install a default handler for
    #   Exception, we have to clear them to test the path we want
    #   to trigger.
    # TODO(kgriffs): Since we always add a default error handler
    #   for Exception, should we take out the checks in the WSGI/ASGI
    #   callable and just always assume it will be handled? If so,
    #   it makes testing that the right exception is propagated harder;
    #   I suppose we'll have to look at what is logged.
    app._error_handlers.clear()

    with pytest.raises(SuchException):
        testing.simulate_get(app, '/')

    with pytest.raises(SuchException):
        testing.simulate_post(app, '/', json={})
def test_sync_methods_not_overridden(asgi):
    app = create_app(asgi)

    class FaultyHandler(media.BaseHandler):
        pass

    handlers = media.Handlers({'application/json': FaultyHandler()})
    app.req_options.media_handlers = handlers
    app.resp_options.media_handlers = handlers

    class Resource:
        def on_get(self, req, resp):
            resp.media = {}

        def on_post(self, req, resp):
            req.media

    class ResourceAsync:
        async def on_get(self, req, resp):
            resp.media = {}

        async def on_post(self, req, resp):
            await req.get_media()

    app.add_route('/', ResourceAsync() if asgi else Resource())

    # NOTE(caselit): force serialization in xml, since error.to_json uses the faulty handler
    result = testing.simulate_get(app, '/', headers={'Accept': 'text/xml'})
    assert result.status_code == 500

    result = testing.simulate_post(app, '/', json={}, headers={'Accept': 'text/xml'})
    assert result.status_code == 500
示例#7
0
def test_sync_methods_not_overridden(asgi):
    app = create_app(asgi)

    class FaultyHandler(media.BaseHandler):
        pass

    handlers = media.Handlers({'application/json': FaultyHandler()})
    app.req_options.media_handlers = handlers
    app.resp_options.media_handlers = handlers

    class Resource:
        def on_get(self, req, resp):
            resp.media = {}

        def on_post(self, req, resp):
            req.media

    class ResourceAsync:
        async def on_get(self, req, resp):
            resp.media = {}

        async def on_post(self, req, resp):
            await req.get_media()

    app.add_route('/', ResourceAsync() if asgi else Resource())

    result = testing.simulate_get(app, '/')
    assert result.status_code == 500

    result = testing.simulate_post(app, '/', json={})
    assert result.status_code == 500
示例#8
0
def test_response_body_rendition_error(asgi):
    class MalbolgeHandler(falcon.media.BaseHandler):
        def serialize(self, media, content_type):
            raise falcon.HTTPError(falcon.HTTP_753)

    app = create_app(asgi)
    app.resp_options.media_handlers['text/x-malbolge'] = MalbolgeHandler()
    app.add_route('/test.mal', CodeResource())

    resp = testing.simulate_get(app, '/test.mal')
    assert resp.status_code == 753

    # NOTE(kgriffs): Validate that del works on media handlers.
    del app.resp_options.media_handlers['text/x-malbolge']
    resp = testing.simulate_get(app, '/test.mal')
    assert resp.status_code == 415
示例#9
0
def test_custom_render_body():
    class CustomResponse(falcon.asgi.Response):
        async def render_body(self):
            body = await super().render_body()

            if not self.content_type.startswith('text/plain'):
                return body

            if not body.endswith(b'\n'):
                # Be a good Unix netizen
                return body + b'\n'

            return body

    class HelloResource:
        async def on_get(self, req, resp):
            resp.content_type = falcon.MEDIA_TEXT
            resp.text = 'Hello, World!'

    app = falcon.asgi.App(response_type=CustomResponse)
    app.add_route('/', HelloResource())

    resp = testing.simulate_get(app, '/')
    assert resp.headers['Content-Type'] == 'text/plain; charset=utf-8'
    assert resp.text == 'Hello, World!\n'
示例#10
0
def test_json_err_no_handler(asgi, monkeypatch_resolver):
    app = create_app(asgi)

    handlers = media.Handlers(
        {falcon.MEDIA_URLENCODED: media.URLEncodedFormHandler()})

    # NOTE(kgriffs): Test the pre-3.0 method. Although undocumented, it was
    #   technically a public method, and so we make sure it still works here.
    if monkeypatch_resolver:

        def _resolve(media_type, default, raise_not_found=True):
            with pytest.warns(DeprecatedWarning,
                              match='This undocumented method'):
                h = handlers.find_by_media_type(
                    media_type, default, raise_not_found=raise_not_found)
            return h, None, None

        handlers._resolve = _resolve

    app.req_options.media_handlers = handlers
    app.resp_options.media_handlers = handlers

    class Resource:
        def on_get(self, req, resp):
            raise falcon.HTTPForbidden()

    app.add_route('/', Resource())

    result = testing.simulate_get(app, '/')
    assert result.status_code == 403
    assert result.json == falcon.HTTPForbidden().to_dict()
示例#11
0
def query(endpoint, parameters):
    """Query API and print JSON response.

    Parameters must be supplied as --name value or --name=value. See
    https://brightsky.dev/docs/ for the available endpoints and arguments.

    \b
    Examples:
    python -m brightsky query weather --lat 52 --lon 7.6 --date 2018-08-13
    python -m brightsky query current_weather --lat=52 --lon=7.6
    """
    if not app._router.find(f'/{endpoint}'):
        raise click.UsageError(f"Unknown endpoint '{endpoint}'")
    resp = simulate_get(app, f'/{endpoint}', params=_parse_params(parameters))
    print(json.dumps(resp.json))
示例#12
0
def test_json_err_no_handler(asgi):
    app = create_app(asgi)

    handlers = media.Handlers({falcon.MEDIA_URLENCODED: media.URLEncodedFormHandler()})
    app.req_options.media_handlers = handlers
    app.resp_options.media_handlers = handlers

    class Resource:
        def on_get(self, req, resp):
            raise falcon.HTTPForbidden()

    app.add_route('/', Resource())

    result = testing.simulate_get(app, '/')
    assert result.status_code == 403
    assert result.json == falcon.HTTPForbidden().to_dict()
示例#13
0
def test_resource_with_uri_fields_async():
    app = create_app(asgi=True)

    resource = ClassResourceWithURIFieldsAsync()
    app.add_route('/{field1}/{field2}', resource)

    result = testing.simulate_get(app, '/a/b')

    assert result.status_code == 200
    assert result.headers['X-Fluffiness'] == 'fluffy'
    assert resource.fields == ('a', 'b')

    async def test_direct():
        resource = ClassResourceWithURIFieldsAsync()

        req = testing.create_asgi_req()
        resp = create_resp(True)

        await resource.on_get(req, resp, '1', '2')
        assert resource.fields == ('1', '2')

    testing.invoke_coroutine_sync(test_direct)
示例#14
0
def test_unsupported_response_content_type(asgi):
    app = create_app(asgi)
    app.add_route('/test.mal', CodeResource())

    resp = testing.simulate_get(app, '/test.mal')
    assert resp.status_code == 415
示例#15
0
def test_deserialization_raises(asgi, handler_mt, monkeypatch_resolver):
    app = create_app(asgi)

    class SuchException(Exception):
        pass

    class FaultyHandler(media.BaseHandler):
        def deserialize(self, stream, content_type, content_length):
            raise SuchException('Wow such error.')

        def deserialize_async(self, stream, content_type, content_length):
            raise SuchException('Wow such error.')

        def serialize(self, media, content_type):
            raise SuchException('Wow such error.')

    handlers = media.Handlers({handler_mt: FaultyHandler()})

    # NOTE(kgriffs): Test the pre-3.0 method. Although undocumented, it was
    #   technically a public method, and so we make sure it still works here.
    if monkeypatch_resolver:

        def _resolve(media_type, default, raise_not_found=True):
            with pytest.warns(DeprecatedWarning,
                              match='This undocumented method'):
                h = handlers.find_by_media_type(
                    media_type, default, raise_not_found=raise_not_found)
            return h, None, None

        handlers._resolve = _resolve

    app.req_options.media_handlers = handlers
    app.resp_options.media_handlers = handlers

    class Resource:
        def on_get(self, req, resp):
            resp.media = {}

        def on_post(self, req, resp):
            req.media

    class ResourceAsync:
        async def on_get(self, req, resp):
            resp.media = {}

        async def on_post(self, req, resp):
            # NOTE(kgriffs): In this one case we use the property
            #   instead of get_media(), in order to test that the
            #   alias works as expected.
            await req.media

    app.add_route('/', ResourceAsync() if asgi else Resource())

    # NOTE(kgriffs): Now that we install a default handler for
    #   Exception, we have to clear them to test the path we want
    #   to trigger.
    # TODO(kgriffs): Since we always add a default error handler
    #   for Exception, should we take out the checks in the WSGI/ASGI
    #   callable and just always assume it will be handled? If so,
    #   it makes testing that the right exception is propagated harder;
    #   I suppose we'll have to look at what is logged.
    app._error_handlers.clear()

    with pytest.raises(SuchException):
        testing.simulate_get(app, '/')

    with pytest.raises(SuchException):
        testing.simulate_post(app, '/', json={})