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]
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'
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']
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
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
def app(asgi): return create_app(asgi)
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
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'] == '*'
def make(middleware): app = create_app(asgi, middleware=middleware) return testing.TestClient(app)
def make_app(asgi=False): app = create_app(asgi) app.add_route('/test', DummyResourceAsync() if asgi else DummyResource()) return app
def client(asgi): app = create_app(asgi) app.add_route('/media', MediaMirrorAsync() if asgi else MediaMirror()) return testing.TestClient(app)
def client(asgi): app = _util.create_app(asgi=asgi) client = testing.TestClient(app) client.asgi = asgi return client
def hook_test_client(request): app = create_app(asgi=request.param) app.add_route('/status', TestHookResource()) return testing.TestClient(app)
def body_client(asgi): app = create_app(asgi=asgi) app.add_route('/status', NoBodyResource()) return testing.TestClient(app)
def client(asgi): app = create_app(asgi) if not asgi: app.req_options.auto_parse_form_urlencoded = True return testing.TestClient(app)
def client(asgi): app = create_app(asgi) return testing.TestClient(app)
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)
def client(asgi): return testing.TestClient(create_app(asgi))
def client(asgi, request, resource): app = create_app(asgi) app.add_route('/', resource) return testing.TestClient(app)
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)
def client(request): app = _util.create_app(asgi=request.param) client = testing.TestClient(app) client.asgi = request.param return client
def client(asgi): app = create_app(asgi) app.add_route('/', ErroredClassResource()) return testing.TestClient(app)
def test_not_str(asgi, uri_template): app = create_app(asgi) with pytest.raises(TypeError): app.add_route(uri_template, ResourceWithId(-1))
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={})