You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

64 lines
2.0 KiB

from typing import Annotated, Any
import pytest
from fastapi import Depends, FastAPI, Form, status
from fastapi.testclient import TestClient
from tests._annotated_body_depends_merge_common import (
BarPayload,
BasePayload,
FooPayload,
)
class TestAnnotatedBodyDependsMergeForm:
@pytest.mark.parametrize(
("path", "ann1", "ann2", "model_cls", "expected_ref_suffix"),
[
("/form-a", Form(), Depends(FooPayload), FooPayload, "FooPayload"),
("/form-b", Depends(BarPayload), Form(), BarPayload, "BarPayload"),
],
)
def test_openapi_form_depends_merge(
self,
path: str,
ann1: Any,
ann2: Any,
model_cls: type[BasePayload],
expected_ref_suffix: str,
) -> None:
app = FastAPI()
@app.post(path)
def route_form(
data: Annotated[BasePayload, ann1, ann2],
) -> None:
assert isinstance(data, model_cls)
client = TestClient(app)
schema = client.get("/openapi.json").json()
rb = schema["paths"][path]["post"]["requestBody"]
content = rb["content"]
assert "application/x-www-form-urlencoded" in content
ref = content["application/x-www-form-urlencoded"]["schema"]["$ref"]
assert ref.endswith(f"/{expected_ref_suffix}")
def test_runtime_form_validates_concrete_model(self) -> None:
app = FastAPI()
@app.post("/form-c")
def route_form(
data: Annotated[BasePayload, Form(), Depends(FooPayload)],
) -> dict[str, str]:
return {"extra": data.extra_foo}
client = TestClient(app)
r = client.post(
"/form-c",
data={"kind": "foo", "extra_foo": "z"},
)
assert r.status_code == status.HTTP_200_OK
assert r.json() == {"extra": "z"}
bad = client.post("/form-c", data={"kind": "foo"})
assert bad.status_code == status.HTTP_422_UNPROCESSABLE_CONTENT