mirror of https://github.com/encode/starlette.git
136 lines
3.8 KiB
Python
136 lines
3.8 KiB
Python
import anyio
|
|
import pytest
|
|
|
|
from starlette.applications import Starlette
|
|
from starlette.middleware import Middleware
|
|
from starlette.responses import JSONResponse
|
|
from starlette.websockets import WebSocket, WebSocketDisconnect
|
|
|
|
mock_service = Starlette()
|
|
|
|
|
|
@mock_service.route("/")
|
|
def mock_service_endpoint(request):
|
|
return JSONResponse({"mock": "example"})
|
|
|
|
|
|
def create_app(test_client_factory):
|
|
app = Starlette()
|
|
|
|
@app.route("/")
|
|
def homepage(request):
|
|
client = test_client_factory(mock_service)
|
|
response = client.get("/")
|
|
return JSONResponse(response.json())
|
|
|
|
return app
|
|
|
|
|
|
startup_error_app = Starlette()
|
|
|
|
|
|
@startup_error_app.on_event("startup")
|
|
def startup():
|
|
raise RuntimeError()
|
|
|
|
|
|
def test_use_testclient_in_endpoint(test_client_factory):
|
|
"""
|
|
We should be able to use the test client within applications.
|
|
|
|
This is useful if we need to mock out other services,
|
|
during tests or in development.
|
|
"""
|
|
client = test_client_factory(create_app(test_client_factory))
|
|
response = client.get("/")
|
|
assert response.json() == {"mock": "example"}
|
|
|
|
|
|
def test_use_testclient_as_contextmanager(test_client_factory):
|
|
with test_client_factory(create_app(test_client_factory)):
|
|
pass
|
|
|
|
|
|
def test_error_on_startup(test_client_factory):
|
|
with pytest.raises(RuntimeError):
|
|
with test_client_factory(startup_error_app):
|
|
pass # pragma: no cover
|
|
|
|
|
|
def test_exception_in_middleware(test_client_factory):
|
|
class MiddlewareException(Exception):
|
|
pass
|
|
|
|
class BrokenMiddleware:
|
|
def __init__(self, app):
|
|
self.app = app
|
|
|
|
async def __call__(self, scope, receive, send):
|
|
raise MiddlewareException()
|
|
|
|
broken_middleware = Starlette(middleware=[Middleware(BrokenMiddleware)])
|
|
|
|
with pytest.raises(MiddlewareException):
|
|
with test_client_factory(broken_middleware):
|
|
pass # pragma: no cover
|
|
|
|
|
|
def test_testclient_asgi2(test_client_factory):
|
|
def app(scope):
|
|
async def inner(receive, send):
|
|
await send(
|
|
{
|
|
"type": "http.response.start",
|
|
"status": 200,
|
|
"headers": [[b"content-type", b"text/plain"]],
|
|
}
|
|
)
|
|
await send({"type": "http.response.body", "body": b"Hello, world!"})
|
|
|
|
return inner
|
|
|
|
client = test_client_factory(app)
|
|
response = client.get("/")
|
|
assert response.text == "Hello, world!"
|
|
|
|
|
|
def test_testclient_asgi3(test_client_factory):
|
|
async def app(scope, receive, send):
|
|
await send(
|
|
{
|
|
"type": "http.response.start",
|
|
"status": 200,
|
|
"headers": [[b"content-type", b"text/plain"]],
|
|
}
|
|
)
|
|
await send({"type": "http.response.body", "body": b"Hello, world!"})
|
|
|
|
client = test_client_factory(app)
|
|
response = client.get("/")
|
|
assert response.text == "Hello, world!"
|
|
|
|
|
|
def test_websocket_blocking_receive(test_client_factory):
|
|
def app(scope):
|
|
async def respond(websocket):
|
|
await websocket.send_json({"message": "test"})
|
|
|
|
async def asgi(receive, send):
|
|
websocket = WebSocket(scope, receive=receive, send=send)
|
|
await websocket.accept()
|
|
async with anyio.create_task_group() as task_group:
|
|
task_group.start_soon(respond, websocket)
|
|
try:
|
|
# this will block as the client does not send us data
|
|
# it should not prevent `respond` from executing though
|
|
await websocket.receive_json()
|
|
except WebSocketDisconnect:
|
|
pass
|
|
|
|
return asgi
|
|
|
|
client = test_client_factory(app)
|
|
with client.websocket_connect("/") as websocket:
|
|
data = websocket.receive_json()
|
|
assert data == {"message": "test"}
|