Example #1
0
def test_can_pass_additional_params_to_add_route(asgi):

    check = []

    class CustomRouter:
        def add_route(self, uri_template, resource, **kwargs):
            name = kwargs['name']
            self._index = {name: uri_template}
            check.append(name)

        def find(self, uri):
            pass

    app = create_app(asgi=asgi, router=CustomRouter())
    app.add_route('/test', 'resource', name='my-url-name')

    assert len(check) == 1
    assert 'my-url-name' in check

    # NOTE(kgriffs): Extra values must be passed as kwargs, since that makes
    #   it a lot easier for overriden methods to simply ignore options they
    #   don't care about.
    with pytest.raises(TypeError):
        app.add_route('/test', 'resource', 'xarg1', 'xarg2')
def test_async_handler_returning_none():
    app = create_app(asgi=True)

    class SimpleHandler(media.BaseHandler):
        def serialize(self, media, content_type):
            return json.dumps(media).encode()

        def deserialize(self, stream, content_type, content_length):
            return None

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

    class ResourceAsync:
        async def on_post(self, req, resp):
            resp.media = [await req.get_media()]

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

    doc = {'event': 'serialized'}
    result = testing.simulate_post(app, '/', json=doc)
    assert result.status_code == 200
    assert result.json == [None]
Example #3
0
    def test_simulate_json_body(self, asgi, document):
        resource = (testing.SimpleTestResourceAsync()
                    if asgi else testing.SimpleTestResource())
        app = create_app(asgi)
        app.add_route('/', resource)

        json_types = ('application/json', 'application/json; charset=UTF-8')
        client = testing.TestClient(app)
        client.simulate_post('/',
                             json=document,
                             headers={'capture-req-body-bytes': '-1'})
        assert json.loads(resource.captured_req_body.decode()) == document
        assert resource.captured_req.content_type in json_types

        headers = {
            'Content-Type': 'x-falcon/peregrine',
            'X-Falcon-Type': 'peregrine',
            'capture-req-media': 'y',
        }
        body = 'If provided, `json` parameter overrides `body`.'
        client.simulate_post('/', headers=headers, body=body, json=document)
        assert resource.captured_req_media == document
        assert resource.captured_req.content_type in json_types
        assert resource.captured_req.get_header('X-Falcon-Type') == 'peregrine'
Example #4
0
    def test_order_independent_mw_executed_when_exception_in_resp(self, asgi):
        """Test that error in inner middleware leaves"""
        global context

        class RaiseErrorMiddleware:
            def process_response(self, req, resp, resource):
                raise Exception('Always fail')

        app = create_app(asgi,
                         independent_middleware=True,
                         middleware=[
                             ExecutedFirstMiddleware(),
                             RaiseErrorMiddleware(),
                             ExecutedLastMiddleware()
                         ])

        def handler(req, resp, ex, params):
            pass

        app.add_error_handler(Exception, handler)

        app.add_route(TEST_ROUTE, MiddlewareClassResource())
        client = testing.TestClient(app)

        client.simulate_request(path=TEST_ROUTE)

        # Any mw is executed now...
        expectedExecutedMethods = [
            'ExecutedFirstMiddleware.process_request',
            'ExecutedLastMiddleware.process_request',
            'ExecutedFirstMiddleware.process_resource',
            'ExecutedLastMiddleware.process_resource',
            'ExecutedLastMiddleware.process_response',
            'ExecutedFirstMiddleware.process_response'
        ]
        assert expectedExecutedMethods == context['executed_methods']
Example #5
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())

    # 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
Example #6
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
Example #7
0
def app(asgi):
    return create_app(asgi)
Example #8
0
    def test_simulate_content_type_extra_handler(self, asgi, content_type):
        class TestResourceAsync(testing.SimpleTestResourceAsync):
            def __init__(self):
                super().__init__()

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

                resp.media = {'hello': 'back'}
                resp.content_type = content_type

        class TestResource(testing.SimpleTestResource):
            def __init__(self):
                super().__init__()

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

                resp.media = {'hello': 'back'}
                resp.content_type = content_type

        resource = TestResourceAsync() if asgi else TestResource()
        app = create_app(asgi)
        app.add_route('/', resource)

        json_handler = TrackingJSONHandler()
        msgpack_handler = TrackingMessagePackHandler()
        form_handler = TrackingFormHandler()

        # NOTE(kgriffs): Do not use MEDIA_* so that we can sanity-check that
        #   our constants that are used in the pytest parametrization match
        #   up to what we expect them to be.
        extra_handlers = {
            'application/json': json_handler,
            'application/msgpack': msgpack_handler,
            'application/x-www-form-urlencoded': form_handler,
        }
        app.req_options.media_handlers.update(extra_handlers)
        app.resp_options.media_handlers.update(extra_handlers)

        client = testing.TestClient(app)
        headers = {
            'Content-Type': content_type,
            'capture-req-media': 'y',
        }

        if MEDIA_JSON in content_type:
            payload = b'{"hello": "world"}'
        elif content_type == MEDIA_MSGPACK:
            payload = b'\x81\xa5hello\xa5world'
        elif content_type == MEDIA_URLENCODED:
            payload = b'hello=world'
        else:
            payload = None

        resp = client.simulate_post('/', headers=headers, body=payload)

        if MEDIA_JSON in content_type:
            assert resp.status_code == 200
            assert resp.json == {'hello': 'back'}

            # Test that our custom deserializer was called
            assert json_handler.deserialize_count == 1
            assert resource.captured_req_media == {'hello': 'world'}

            # Verify that other handlers were not called
            assert msgpack_handler.deserialize_count == 0
            assert form_handler.deserialize_count == 0

        elif content_type == MEDIA_MSGPACK:
            assert resp.status_code == 200
            assert resp.content == b'\x81\xa5hello\xa4back'

            # Test that our custom deserializer was called
            assert msgpack_handler.deserialize_count == 1
            assert resource.captured_req_media == {'hello': 'world'}

            # Verify that other handlers were not called
            assert json_handler.deserialize_count == 0
            assert form_handler.deserialize_count == 0

        elif content_type == MEDIA_URLENCODED:
            assert resp.status_code == 200
            assert resp.content == b'hello=back'

            # Test that our custom deserializer was called
            assert form_handler.deserialize_count == 1
            assert resource.captured_req_media == {'hello': 'world'}

            # Verify that other handlers were not called
            assert json_handler.deserialize_count == 0
            assert msgpack_handler.deserialize_count == 0

        else:
            # YAML should not get handled
            for handler in (json_handler, msgpack_handler):
                assert handler.deserialize_count == 0

            assert resource.captured_req_media is None
            assert resp.status_code == 415
Example #9
0
 def test_api_initialization_with_cors_enabled_and_middleware_param(self, mw, asgi):
     app = create_app(asgi, middleware=mw, cors_enable=True)
     app.add_route('/', TestCorsResource())
     client = testing.TestClient(app)
     result = client.simulate_get(headers={'Origin': 'localhost'})
     assert result.headers['Access-Control-Allow-Origin'] == '*'
Example #10
0
 def make(middleware):
     app = create_app(asgi, middleware=middleware)
     return testing.TestClient(app)
Example #11
0
def make_app(asgi=False):
    app = create_app(asgi)
    app.add_route('/test', DummyResourceAsync() if asgi else DummyResource())

    return app
Example #12
0
def client(asgi):
    app = create_app(asgi)
    app.add_route('/media', MediaMirrorAsync() if asgi else MediaMirror())
    return testing.TestClient(app)
Example #13
0
def client(asgi):
    app = _util.create_app(asgi=asgi)
    client = testing.TestClient(app)
    client.asgi = asgi
    return client
Example #14
0
def hook_test_client(request):
    app = create_app(asgi=request.param)
    app.add_route('/status', TestHookResource())
    return testing.TestClient(app)
Example #15
0
def body_client(asgi):
    app = create_app(asgi=asgi)
    app.add_route('/status', NoBodyResource())
    return testing.TestClient(app)
Example #16
0
def client(asgi):
    app = create_app(asgi)
    if not asgi:
        app.req_options.auto_parse_form_urlencoded = True

    return testing.TestClient(app)
Example #17
0
def client(asgi):
    app = create_app(asgi)
    return testing.TestClient(app)
Example #18
0
def cors_client(asgi):
    # NOTE(kgriffs): Disable wrapping to test that built-in middleware does
    #   not require it (since this will be the case for non-test apps).
    with disable_asgi_non_coroutine_wrapping():
        app = create_app(asgi, cors_enable=True)
    return testing.TestClient(app)
Example #19
0
def client(asgi):
    return testing.TestClient(create_app(asgi))
Example #20
0
def client(asgi, request, resource):
    app = create_app(asgi)
    app.add_route('/', resource)
    return testing.TestClient(app)
Example #21
0
def custom_http_client(asgi, request, cleanup_constants, resource_things):
    falcon.constants.COMBINED_METHODS += FALCON_CUSTOM_HTTP_METHODS

    app = create_app(asgi)
    app.add_route('/things', resource_things)
    return testing.TestClient(app)
Example #22
0
def client(request):
    app = _util.create_app(asgi=request.param)
    client = testing.TestClient(app)
    client.asgi = request.param
    return client
Example #23
0
def client(asgi):
    app = create_app(asgi)
    app.add_route('/', ErroredClassResource())
    return testing.TestClient(app)
Example #24
0
def test_not_str(asgi, uri_template):
    app = create_app(asgi)
    with pytest.raises(TypeError):
        app.add_route(uri_template, ResourceWithId(-1))
Example #25
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={})