diff --git a/async_asgi_testclient/tests/test_testing.py b/async_asgi_testclient/tests/test_testing.py index ed92f14..227825f 100644 --- a/async_asgi_testclient/tests/test_testing.py +++ b/async_asgi_testclient/tests/test_testing.py @@ -1,21 +1,20 @@ -import ast - -import starlette.status -from quart import websocket +from starlette.responses import RedirectResponse, StreamingResponse from async_asgi_testclient import TestClient from http.cookies import SimpleCookie from json import dumps from sys import version_info as PY_VER # noqa +import ast import asyncio import io import pytest +import starlette.status @pytest.fixture def quart_app(): - from quart import Quart, jsonify, request, redirect, Response + from quart import Quart, jsonify, request, redirect, Response, websocket app = Quart(__name__) @@ -97,7 +96,9 @@ async def websocket_endpoint(): @app.websocket("/ws-reject") async def websocket_reject(): - await websocket.close(code=starlette.status.WS_1003_UNSUPPORTED_DATA, reason="some reason") + await websocket.close( + code=starlette.status.WS_1003_UNSUPPORTED_DATA, reason="some reason" + ) yield app @@ -211,6 +212,10 @@ async def echoheaders(request): async def test_query(request): return Response(str(request.query_params)) + @app.route("/redir") + async def redir(request): + return RedirectResponse(request.query_params["path"], status_code=302) + yield app @@ -375,6 +380,28 @@ async def test_set_cookie_in_request(quart_app): assert resp.status_code == 200 assert resp.text == "my-cookie=1234; my-cookie-2=5678" +@pytest.mark.asyncio +async def test_set_cookie_in_request_starlette(starlette_app): + async with TestClient(starlette_app) as client: + resp = await client.post("/set_cookies") + assert resp.status_code == 200 + assert resp.cookies.get_dict() == {"my-cookie": "1234", "my-cookie-2": "5678"} + + # Uses 'custom_cookie_jar' instead of 'client.cookie_jar' + custom_cookie_jar = {"my-cookie": "6666"} + resp = await client.get("/cookies", cookies=custom_cookie_jar) + assert resp.status_code == 200 + assert resp.json() == custom_cookie_jar + + # Uses 'client.cookie_jar' again + resp = await client.get("/cookies") + assert resp.status_code == 200 + assert resp.json() == {"my-cookie": "1234", "my-cookie-2": "5678"} + + resp = await client.get("/cookies-raw") + assert resp.status_code == 200 + assert resp.text == "my-cookie=1234; my-cookie-2=5678" + @pytest.mark.asyncio @pytest.mark.skipif("PY_VER < (3,7)") @@ -478,14 +505,14 @@ async def test_ws_connect_custom_scheme(starlette_app): async def test_ws_endpoint_with_immediate_rejection(starlette_app): async with TestClient(starlette_app, timeout=0.1) as client: try: - async with client.websocket_connect("/ws-reject") as ws: + async with client.websocket_connect("/ws-reject"): pass except Exception as e: thrown_exception = e assert ast.literal_eval(str(thrown_exception)) == { "type": "websocket.close", - "code": starlette.status.WS_1003_UNSUPPORTED_DATA + "code": starlette.status.WS_1003_UNSUPPORTED_DATA, } @@ -493,14 +520,14 @@ async def test_ws_endpoint_with_immediate_rejection(starlette_app): async def test_invalid_ws_endpoint(starlette_app): async with TestClient(starlette_app, timeout=0.1) as client: try: - async with client.websocket_connect("/invalid") as ws: + async with client.websocket_connect("/invalid"): pass except Exception as e: thrown_exception = e assert ast.literal_eval(str(thrown_exception)) == { "type": "websocket.close", - "code": starlette.status.WS_1000_NORMAL_CLOSURE + "code": starlette.status.WS_1000_NORMAL_CLOSURE, } @@ -537,6 +564,7 @@ async def test_quart_ws_connect_inherits_test_client_cookies(quart_app): @pytest.mark.asyncio +@pytest.mark.skipif("PY_VER < (3,7)") async def test_quart_ws_connect_default_scheme(quart_app): async with TestClient(quart_app, timeout=0.1) as client: async with client.websocket_connect("/ws") as ws: @@ -560,14 +588,14 @@ async def test_quart_ws_connect_custom_scheme(quart_app): async def test_quart_ws_endpoint_with_immediate_rejection(quart_app): async with TestClient(quart_app, timeout=0.1) as client: try: - async with client.websocket_connect("/ws-reject") as ws: + async with client.websocket_connect("/ws-reject"): pass except Exception as e: thrown_exception = e assert ast.literal_eval(str(thrown_exception)) == { "type": "websocket.close", - "code": starlette.status.WS_1003_UNSUPPORTED_DATA + "code": starlette.status.WS_1003_UNSUPPORTED_DATA, } @@ -576,14 +604,14 @@ async def test_quart_ws_endpoint_with_immediate_rejection(quart_app): async def test_quart_invalid_ws_endpoint(quart_app): async with TestClient(quart_app, timeout=0.1) as client: try: - async with client.websocket_connect("/invalid") as ws: + async with client.websocket_connect("/invalid"): pass except Exception as e: thrown_exception = e assert ast.literal_eval(str(thrown_exception)) == { "type": "websocket.close", - "code": starlette.status.WS_1000_NORMAL_CLOSURE + "code": starlette.status.WS_1000_NORMAL_CLOSURE, } @@ -662,6 +690,22 @@ async def async_generator(): chunks = [c async for c in resp.iter_content(1024)] assert len(b"".join(chunks)) == 3 * 1024 +@pytest.mark.asyncio +async def test_response_stream(starlette_app): + @starlette_app.route("/download_stream") + async def down_stream(_): + async def async_generator(): + chunk = b"X" * 1024 + for _ in range(3): + yield chunk + + return StreamingResponse(async_generator()) + + async with TestClient(starlette_app) as client: + resp = await client.get("/download_stream", stream=False) + assert resp.status_code == 200 + assert len(resp.content) == 3 * 1024 + @pytest.mark.asyncio async def test_response_stream_crashes(starlette_app): @@ -701,3 +745,16 @@ async def test_no_follow_redirects(quart_app): async with TestClient(quart_app) as client: resp = await client.get("/redir?path=/", allow_redirects=False) assert resp.status_code == 302 + +@pytest.mark.asyncio +async def test_follow_redirects(starlette_app): + async with TestClient(starlette_app) as client: + resp = await client.get("/redir?path=/") + assert resp.status_code == 200 + assert resp.text == "full response" + +@pytest.mark.asyncio +async def test_no_follow_redirects(starlette_app): + async with TestClient(starlette_app) as client: + resp = await client.get("/redir?path=/", allow_redirects=False) + assert resp.status_code == 302 diff --git a/async_asgi_testclient/websocket.py b/async_asgi_testclient/websocket.py index e895cd2..84b2d04 100644 --- a/async_asgi_testclient/websocket.py +++ b/async_asgi_testclient/websocket.py @@ -87,10 +87,7 @@ async def receive_json(self): return json.loads(data) async def _receive(self): - try: - return await receive(self.output_queue) - except: - pass + return await receive(self.output_queue) def __aiter__(self): return self diff --git a/test-requirements.txt b/test-requirements.txt index 749a341..3ba301c 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,4 @@ -quart==0.10.0; python_version >= '3.7' +quart==0.17.0; python_version >= '3.7' starlette==0.12.13 python-multipart==0.0.5 pytest==6.2.5