committed by
GitHub
2 changed files with 106 additions and 0 deletions
@ -0,0 +1,90 @@ |
|||
"""Test that a warning is emitted when a returned Response already has a background |
|||
task set and the dependency-injected BackgroundTasks would be silently discarded. |
|||
|
|||
Ref: https://github.com/fastapi/fastapi/issues/11215 |
|||
""" |
|||
|
|||
import warnings |
|||
|
|||
from fastapi import BackgroundTasks, FastAPI |
|||
from fastapi.testclient import TestClient |
|||
from starlette.background import BackgroundTask |
|||
from starlette.responses import JSONResponse, Response |
|||
|
|||
|
|||
def test_warn_when_response_background_overwrites_injected_tasks(): |
|||
"""When the endpoint returns a Response with its own `background`, |
|||
and the user also injected `BackgroundTasks`, a UserWarning should |
|||
be emitted so the silent data loss is visible.""" |
|||
app = FastAPI() |
|||
|
|||
@app.get("/") |
|||
async def endpoint(tasks: BackgroundTasks): |
|||
tasks.add_task(lambda: None) |
|||
return Response( |
|||
content="Custom response", |
|||
background=BackgroundTask(lambda: None), |
|||
) |
|||
|
|||
client = TestClient(app, raise_server_exceptions=False) |
|||
|
|||
with warnings.catch_warnings(record=True) as caught: |
|||
warnings.simplefilter("always") |
|||
resp = client.get("/") |
|||
|
|||
assert resp.status_code == 200 |
|||
bg_warnings = [w for w in caught if "background" in str(w.message).lower()] |
|||
assert len(bg_warnings) == 1 |
|||
assert issubclass(bg_warnings[0].category, UserWarning) |
|||
|
|||
|
|||
def test_no_warn_when_response_has_no_background(): |
|||
"""When the endpoint returns a Response without a `background`, |
|||
no warning should be emitted (the injected tasks are attached).""" |
|||
app = FastAPI() |
|||
executed = [] |
|||
|
|||
def bg_task(): |
|||
executed.append(True) |
|||
|
|||
@app.get("/") |
|||
async def endpoint(tasks: BackgroundTasks): |
|||
tasks.add_task(bg_task) |
|||
return JSONResponse(content={"ok": True}) |
|||
|
|||
client = TestClient(app) |
|||
|
|||
with warnings.catch_warnings(record=True) as caught: |
|||
warnings.simplefilter("always") |
|||
resp = client.get("/") |
|||
|
|||
assert resp.status_code == 200 |
|||
bg_warnings = [w for w in caught if "background" in str(w.message).lower()] |
|||
assert len(bg_warnings) == 0 |
|||
# The injected task should have run |
|||
assert executed == [True] |
|||
|
|||
|
|||
def test_no_warn_when_no_injected_background_tasks(): |
|||
"""When the endpoint returns a Response with a `background` but did |
|||
NOT inject BackgroundTasks, no warning should be emitted.""" |
|||
app = FastAPI() |
|||
executed = [] |
|||
|
|||
@app.get("/") |
|||
async def endpoint(): |
|||
return Response( |
|||
content="ok", |
|||
background=BackgroundTask(lambda: executed.append(True)), |
|||
) |
|||
|
|||
client = TestClient(app) |
|||
|
|||
with warnings.catch_warnings(record=True) as caught: |
|||
warnings.simplefilter("always") |
|||
resp = client.get("/") |
|||
|
|||
assert resp.status_code == 200 |
|||
bg_warnings = [w for w in caught if "background" in str(w.message).lower()] |
|||
assert len(bg_warnings) == 0 |
|||
assert executed == [True] |
|||
Loading…
Reference in new issue