def test_repr_result_when_body_varies(self, asgi, value, simulate): if isinstance(value, str): value = bytes(value, 'UTF-8') if asgi: resource = testing.SimpleTestResourceAsync(body=value) else: resource = testing.SimpleTestResource(body=value) app = create_app(asgi) app.add_route('/hello', resource) result = simulate(app, '/hello') captured_resp = resource.captured_resp content = captured_resp.text if len(value) > 40: content = value[:20] + b'...' + value[-20:] else: content = value args = [ captured_resp.status, captured_resp.headers['content-type'], str(content), ] expected_content = ' '.join(filter(None, args)) expected_result = 'Result<{}>'.format(expected_content) assert str(result) == expected_result
def test_root_route(self, client): doc = {'message': 'Hello world!'} resource = testing.SimpleTestResourceAsync(json=doc) client.app.add_route('/', resource) result = client.simulate_get() assert result.json == doc
def test_lifespan_scope_default_version(): app = App() resource = testing.SimpleTestResourceAsync() app.add_route('/', resource) shutting_down = asyncio.Condition() req_event_emitter = testing.ASGILifespanEventEmitter(shutting_down) resp_event_collector = testing.ASGIResponseEventCollector() scope = {'type': 'lifespan'} async def t(): t = asyncio.get_event_loop().create_task( app(scope, req_event_emitter, resp_event_collector)) # NOTE(kgriffs): Yield to the lifespan task above await asyncio.sleep(0.001) async with shutting_down: shutting_down.notify() await t falcon.invoke_coroutine_sync(t) assert not resource.called
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 _call_with_scope(scope): app = App() resource = testing.SimpleTestResourceAsync() app.add_route('/', resource) req_event_emitter = testing.ASGIRequestEventEmitter() resp_event_collector = testing.ASGIResponseEventCollector() falcon.invoke_coroutine_sync(app.__call__, scope, req_event_emitter, resp_event_collector) assert resource.called return resource
def create_client(asgi, handlers=None, resource=None): if not resource: resource = testing.SimpleTestResourceAsync( ) if asgi else testing.SimpleTestResource() app = create_app(asgi) app.add_route('/', resource) if handlers: app.req_options.media_handlers.update(handlers) client = testing.TestClient(app, headers={'capture-req-media': 'yes'}) client.resource = resource return client
def test_simulate_content_type_extra_handler(self, asgi, content_type): class TrackingJSONHandler(media.JSONHandler): def __init__(self): super().__init__() self.deserialize_count = 0 def deserialize(self, *args, **kwargs): result = super().deserialize(*args, **kwargs) self.deserialize_count += 1 return result async def deserialize_async(self, *args, **kwargs): result = await super().deserialize_async(*args, **kwargs) self.deserialize_count += 1 return result resource = testing.SimpleTestResourceAsync( ) if asgi else testing.SimpleTestResource() app = create_app(asgi) app.add_route('/', resource) handler = TrackingJSONHandler() extra_handlers = {'application/json': 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', } payload = b'{"hello": "world"}' resp = client.simulate_post('/', headers=headers, body=payload) if MEDIA_JSON in content_type: # Test that our custom deserializer was called assert handler.deserialize_count == 1 assert resource.captured_req_media == {'hello': 'world'} assert resp.status_code == 200 else: # YAML should not get handled assert handler.deserialize_count == 0 assert resource.captured_req_media is None assert resp.status_code == 415
def test_supported_asgi_version(version, supported): scope = { 'type': 'lifespan', 'asgi': { 'spec_version': '2.0', 'version': version }, } if version is None: del scope['asgi']['version'] app = App() resource = testing.SimpleTestResourceAsync() app.add_route('/', resource) shutting_down = asyncio.Condition() req_event_emitter = testing.ASGILifespanEventEmitter(shutting_down) resp_event_collector = testing.ASGIResponseEventCollector() async def task(): coro = asyncio.get_event_loop().create_task( app(scope, req_event_emitter, resp_event_collector)) # NOTE(vytas): Yield to the lifespan task above. await asyncio.sleep(0) assert len(resp_event_collector.events) == 1 event = resp_event_collector.events[0] if supported: assert event['type'] == 'lifespan.startup.complete' else: assert event['type'] == 'lifespan.startup.failed' assert event['message'].startswith( 'Falcon requires ASGI version 3.x') async with shutting_down: shutting_down.notify() await coro falcon.async_to_sync(task)
def resource(): return testing.SimpleTestResourceAsync()