starlette/tests/test_exceptions.py

110 lines
3.0 KiB
Python
Raw Normal View History

from starlette.exceptions import ExceptionMiddleware, HTTPException
from starlette.responses import PlainTextResponse
from starlette.routing import Router, Path
from starlette.testclient import TestClient
import pytest
def raise_runtime_error(scope):
async def asgi(receive, send):
raise RuntimeError("Yikes")
return asgi
def not_acceptable(scope):
async def asgi(receive, send):
raise HTTPException(status_code=406)
return asgi
def not_modified(scope):
async def asgi(receive, send):
raise HTTPException(status_code=304)
return asgi
def handled_exc_after_response(scope):
async def asgi(receive, send):
response = PlainTextResponse("OK", status_code=200)
await response(receive, send)
raise HTTPException(status_code=406)
return asgi
router = Router(
routes=[
Path("/runtime_error", app=raise_runtime_error),
Path("/not_acceptable", app=not_acceptable),
Path("/not_modified", app=not_modified),
Path("/handled_exc_after_response", app=handled_exc_after_response),
]
)
app = ExceptionMiddleware(router)
client = TestClient(app)
def test_server_error():
with pytest.raises(RuntimeError):
response = client.get("/runtime_error")
allow_500_client = TestClient(app, raise_server_exceptions=False)
response = allow_500_client.get("/runtime_error")
assert response.status_code == 500
assert response.text == "Internal Server Error"
def test_debug_enabled():
app = ExceptionMiddleware(router)
app.debug = True
allow_500_client = TestClient(app, raise_server_exceptions=False)
response = allow_500_client.get("/runtime_error")
assert response.status_code == 500
assert "RuntimeError" in response.text
def test_not_acceptable():
response = client.get("/not_acceptable")
assert response.status_code == 406
assert response.text == "Not Acceptable"
def test_not_modified():
response = client.get("/not_modified")
assert response.status_code == 304
assert response.text == ""
def test_websockets_should_raise():
with pytest.raises(RuntimeError):
client.websocket_connect("/runtime_error")
def test_handled_exc_after_response():
# A 406 HttpException is raised *after* the response has already been sent.
# The exception middleware should raise a RuntimeError.
with pytest.raises(RuntimeError):
client.get("/handled_exc_after_response")
# If `raise_server_exceptions=False` then the test client will still allow
# us to see the response as it will have been seen by the client.
allow_200_client = TestClient(app, raise_server_exceptions=False)
response = allow_200_client.get("/handled_exc_after_response")
assert response.status_code == 200
assert response.text == "OK"
def test_force_500_response():
def app(scope):
raise RuntimeError()
force_500_client = TestClient(app, raise_server_exceptions=False)
response = force_500_client.get("/")
assert response.status_code == 500
assert response.text == ""