|
|
@ -1,8 +1,9 @@ |
|
|
|
import pytest |
|
|
|
from fastapi import APIRouter, FastAPI |
|
|
|
from fastapi.testclient import TestClient |
|
|
|
from pydantic import BaseModel |
|
|
|
|
|
|
|
from .utils import needs_pydanticv2 |
|
|
|
from .utils import needs_pydanticv1, needs_pydanticv2 |
|
|
|
|
|
|
|
|
|
|
|
@needs_pydanticv2 |
|
|
@ -10,38 +11,51 @@ from .utils import needs_pydanticv2 |
|
|
|
"include_error_input,include_error_url", |
|
|
|
[(False, False), (False, True), (True, False), (True, True)], |
|
|
|
) |
|
|
|
def test_input_and_url_fields(include_error_input, include_error_url): |
|
|
|
def test_input_and_url_fields_with_pydanticv2(include_error_input, include_error_url): |
|
|
|
app = FastAPI( |
|
|
|
include_error_input=include_error_input, include_error_url=include_error_url |
|
|
|
) |
|
|
|
|
|
|
|
@app.get("/path1/{path_param}") |
|
|
|
def path1(path_param: int): |
|
|
|
return {"path_param": path_param} |
|
|
|
@app.get("/get1/{path_param}") |
|
|
|
def get1(path_param: int): |
|
|
|
... |
|
|
|
|
|
|
|
@app.get("/path2/") |
|
|
|
def path2(query_param: int): |
|
|
|
return query_param |
|
|
|
@app.get("/get2/") |
|
|
|
def get2(query_param: int): |
|
|
|
... |
|
|
|
|
|
|
|
class Body1(BaseModel): |
|
|
|
... |
|
|
|
|
|
|
|
class Body2(BaseModel): |
|
|
|
... |
|
|
|
|
|
|
|
@app.post("/post1/") |
|
|
|
def post1(body1: Body1, body2: Body2): |
|
|
|
... |
|
|
|
|
|
|
|
router = APIRouter( |
|
|
|
include_error_input=include_error_input, include_error_url=include_error_url |
|
|
|
) |
|
|
|
|
|
|
|
@router.get("/path3/{path_param}") |
|
|
|
def path3(path_param: int): |
|
|
|
return {"path_param": path_param} |
|
|
|
@router.get("/get3/{path_param}") |
|
|
|
def get3(path_param: int): |
|
|
|
... |
|
|
|
|
|
|
|
@router.get("/get4/") |
|
|
|
def get4(query_param: int): |
|
|
|
... |
|
|
|
|
|
|
|
@router.get("/path4/") |
|
|
|
def path4(query_param: int): |
|
|
|
return query_param |
|
|
|
@router.post("/post2/") |
|
|
|
def post2(body1: Body1, body2: Body2): |
|
|
|
... |
|
|
|
|
|
|
|
app.include_router(router) |
|
|
|
client = TestClient(app) |
|
|
|
|
|
|
|
with client: |
|
|
|
invalid = "not-an-integer" |
|
|
|
|
|
|
|
for path in ["path1", "path3"]: |
|
|
|
for path in ["get1", "get3"]: |
|
|
|
response = client.get(f"/{path}/{invalid}") |
|
|
|
assert response.status_code == 422, response.text |
|
|
|
error = response.json()["detail"][0] |
|
|
@ -54,7 +68,7 @@ def test_input_and_url_fields(include_error_input, include_error_url): |
|
|
|
else: |
|
|
|
assert "url" not in error |
|
|
|
|
|
|
|
for path in ["path2", "path4"]: |
|
|
|
for path in ["get2", "get4"]: |
|
|
|
response = client.get(f"/{path}/") |
|
|
|
assert response.status_code == 422, response.text |
|
|
|
error = response.json()["detail"][0] |
|
|
@ -79,3 +93,95 @@ def test_input_and_url_fields(include_error_input, include_error_url): |
|
|
|
assert "url" in error |
|
|
|
else: |
|
|
|
assert "url" not in error |
|
|
|
|
|
|
|
for path in ["post1", "post2"]: |
|
|
|
response = client.post(f"/{path}/", json=["not-a-dict"]) |
|
|
|
assert response.status_code == 422 |
|
|
|
error = response.json()["detail"][0] |
|
|
|
if include_error_input: |
|
|
|
assert error["type"] == "missing" |
|
|
|
assert error["input"] is None |
|
|
|
else: |
|
|
|
assert "input" not in error |
|
|
|
if include_error_url: |
|
|
|
assert "url" in error |
|
|
|
else: |
|
|
|
assert "url" not in error |
|
|
|
|
|
|
|
|
|
|
|
# TODO: remove when deprecating Pydantic v1 |
|
|
|
@needs_pydanticv1 |
|
|
|
@pytest.mark.parametrize( |
|
|
|
"include_error_input,include_error_url", |
|
|
|
[(False, False), (False, True), (True, False), (True, True)], |
|
|
|
) |
|
|
|
def test_input_and_url_fields_with_pydanticv1(include_error_input, include_error_url): |
|
|
|
app = FastAPI( |
|
|
|
include_error_input=include_error_input, include_error_url=include_error_url |
|
|
|
) |
|
|
|
|
|
|
|
@app.get("/get1/{path_param}") |
|
|
|
def get1(path_param: int): |
|
|
|
... |
|
|
|
|
|
|
|
@app.get("/get2/") |
|
|
|
def get2(query_param: int): |
|
|
|
... |
|
|
|
|
|
|
|
class Body1(BaseModel): |
|
|
|
... |
|
|
|
|
|
|
|
class Body2(BaseModel): |
|
|
|
... |
|
|
|
|
|
|
|
@app.post("/post1/") |
|
|
|
def post1(body1: Body1, body2: Body2): |
|
|
|
... |
|
|
|
|
|
|
|
router = APIRouter( |
|
|
|
include_error_input=include_error_input, include_error_url=include_error_url |
|
|
|
) |
|
|
|
|
|
|
|
@router.get("/get3/{path_param}") |
|
|
|
def get3(path_param: int): |
|
|
|
... |
|
|
|
|
|
|
|
@router.get("/get4/") |
|
|
|
def get4(query_param: int): |
|
|
|
... |
|
|
|
|
|
|
|
@router.post("/post2/") |
|
|
|
def post2(body1: Body1, body2: Body2): |
|
|
|
... |
|
|
|
|
|
|
|
app.include_router(router) |
|
|
|
client = TestClient(app) |
|
|
|
with client: |
|
|
|
invalid = "not-an-integer" |
|
|
|
|
|
|
|
for path in ["get1", "get3"]: |
|
|
|
response = client.get(f"/{path}/{invalid}") |
|
|
|
assert response.status_code == 422, response.text |
|
|
|
error = response.json()["detail"][0] |
|
|
|
assert "input" not in error |
|
|
|
assert "url" not in error |
|
|
|
|
|
|
|
for path in ["get2", "get4"]: |
|
|
|
response = client.get(f"/{path}/") |
|
|
|
assert response.status_code == 422, response.text |
|
|
|
error = response.json()["detail"][0] |
|
|
|
assert "input" not in error |
|
|
|
assert "url" not in error |
|
|
|
|
|
|
|
response = client.get(f"/{path}/?query_param={invalid}") |
|
|
|
assert response.status_code == 422, response.text |
|
|
|
error = response.json()["detail"][0] |
|
|
|
assert "input" not in error |
|
|
|
assert "url" not in error |
|
|
|
|
|
|
|
for path in ["post1", "post2"]: |
|
|
|
response = client.post(f"/{path}/", json=["not-a-dict"]) |
|
|
|
assert response.status_code == 422 |
|
|
|
error = response.json()["detail"][0] |
|
|
|
assert "input" not in error |
|
|
|
assert "url" not in error |
|
|
|