|
|
@ -5,6 +5,7 @@ import pytest |
|
|
from dirty_equals import IsList, IsOneOf, IsPartialDict |
|
|
from dirty_equals import IsList, IsOneOf, IsPartialDict |
|
|
from fastapi import Body, FastAPI |
|
|
from fastapi import Body, FastAPI |
|
|
from fastapi.testclient import TestClient |
|
|
from fastapi.testclient import TestClient |
|
|
|
|
|
from inline_snapshot import Is, snapshot |
|
|
from pydantic import BaseModel, BeforeValidator, field_validator |
|
|
from pydantic import BaseModel, BeforeValidator, field_validator |
|
|
|
|
|
|
|
|
from .utils import get_body_model_name |
|
|
from .utils import get_body_model_name |
|
|
@ -92,7 +93,8 @@ def test_nullable_required_schema(path: str): |
|
|
openapi = app.openapi() |
|
|
openapi = app.openapi() |
|
|
body_model_name = get_body_model_name(openapi, path) |
|
|
body_model_name = get_body_model_name(openapi, path) |
|
|
|
|
|
|
|
|
assert app.openapi()["components"]["schemas"][body_model_name] == { |
|
|
assert openapi["components"]["schemas"][body_model_name] == snapshot( |
|
|
|
|
|
{ |
|
|
"properties": { |
|
|
"properties": { |
|
|
"int_val": { |
|
|
"int_val": { |
|
|
"title": "Int Val", |
|
|
"title": "Int Val", |
|
|
@ -111,9 +113,10 @@ def test_nullable_required_schema(path: str): |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
"required": ["int_val", "str_val", "list_val"], |
|
|
"required": ["int_val", "str_val", "list_val"], |
|
|
"title": body_model_name, |
|
|
"title": Is(body_model_name), |
|
|
"type": "object", |
|
|
"type": "object", |
|
|
} |
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize( |
|
|
@pytest.mark.parametrize( |
|
|
@ -165,7 +168,8 @@ def test_nullable_required_missing(path: str): |
|
|
client = TestClient(app) |
|
|
client = TestClient(app) |
|
|
response = client.post(path, json={}) |
|
|
response = client.post(path, json={}) |
|
|
assert response.status_code == 422 |
|
|
assert response.status_code == 422 |
|
|
assert response.json() == { |
|
|
assert response.json() == snapshot( |
|
|
|
|
|
{ |
|
|
"detail": [ |
|
|
"detail": [ |
|
|
{ |
|
|
{ |
|
|
"type": "missing", |
|
|
"type": "missing", |
|
|
@ -187,6 +191,7 @@ def test_nullable_required_missing(path: str): |
|
|
}, |
|
|
}, |
|
|
] |
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize( |
|
|
@pytest.mark.parametrize( |
|
|
@ -205,7 +210,8 @@ def test_nullable_required_no_body(path: str): |
|
|
client = TestClient(app) |
|
|
client = TestClient(app) |
|
|
response = client.post(path) |
|
|
response = client.post(path) |
|
|
assert response.status_code == 422 |
|
|
assert response.status_code == 422 |
|
|
assert response.json() == { |
|
|
assert response.json() == snapshot( |
|
|
|
|
|
{ |
|
|
"detail": [ |
|
|
"detail": [ |
|
|
{ |
|
|
{ |
|
|
"type": "missing", |
|
|
"type": "missing", |
|
|
@ -215,6 +221,7 @@ def test_nullable_required_no_body(path: str): |
|
|
}, |
|
|
}, |
|
|
] |
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize( |
|
|
@pytest.mark.parametrize( |
|
|
@ -229,7 +236,8 @@ def test_nullable_required_no_embed_missing(path: str): |
|
|
client = TestClient(app) |
|
|
client = TestClient(app) |
|
|
response = client.post(path) |
|
|
response = client.post(path) |
|
|
assert response.status_code == 422 |
|
|
assert response.status_code == 422 |
|
|
assert response.json() == { |
|
|
assert response.json() == snapshot( |
|
|
|
|
|
{ |
|
|
"detail": [ |
|
|
"detail": [ |
|
|
{ |
|
|
{ |
|
|
"input": None, |
|
|
"input": None, |
|
|
@ -239,6 +247,7 @@ def test_nullable_required_no_embed_missing(path: str): |
|
|
} |
|
|
} |
|
|
] |
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize( |
|
|
@pytest.mark.parametrize( |
|
|
@ -267,16 +276,18 @@ def test_nullable_required_no_embed_pass_empty_dict( |
|
|
client = TestClient(app) |
|
|
client = TestClient(app) |
|
|
response = client.post(path, json={}) |
|
|
response = client.post(path, json={}) |
|
|
assert response.status_code == 422 |
|
|
assert response.status_code == 422 |
|
|
assert response.json() == { |
|
|
assert response.json() == snapshot( |
|
|
|
|
|
{ |
|
|
"detail": [ |
|
|
"detail": [ |
|
|
{ |
|
|
{ |
|
|
"input": {}, |
|
|
"input": {}, |
|
|
"loc": ["body"], |
|
|
"loc": ["body"], |
|
|
"msg": msg, |
|
|
"msg": Is(msg), |
|
|
"type": error_type, |
|
|
"type": Is(error_type), |
|
|
} |
|
|
} |
|
|
] |
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize( |
|
|
@pytest.mark.parametrize( |
|
|
@ -487,7 +498,8 @@ def test_nullable_non_required_schema(path: str): |
|
|
openapi = app.openapi() |
|
|
openapi = app.openapi() |
|
|
body_model_name = get_body_model_name(openapi, path) |
|
|
body_model_name = get_body_model_name(openapi, path) |
|
|
|
|
|
|
|
|
assert app.openapi()["components"]["schemas"][body_model_name] == { |
|
|
assert openapi["components"]["schemas"][body_model_name] == snapshot( |
|
|
|
|
|
{ |
|
|
"properties": { |
|
|
"properties": { |
|
|
"int_val": { |
|
|
"int_val": { |
|
|
"title": "Int Val", |
|
|
"title": "Int Val", |
|
|
@ -508,9 +520,10 @@ def test_nullable_non_required_schema(path: str): |
|
|
# "default": None, # `None` values are omitted in OpenAPI schema |
|
|
# "default": None, # `None` values are omitted in OpenAPI schema |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
"title": body_model_name, |
|
|
"title": Is(body_model_name), |
|
|
"type": "object", |
|
|
"type": "object", |
|
|
} |
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize( |
|
|
@pytest.mark.parametrize( |
|
|
@ -595,7 +608,8 @@ def test_nullable_non_required_no_body(path: str): |
|
|
client = TestClient(app) |
|
|
client = TestClient(app) |
|
|
response = client.post(path) |
|
|
response = client.post(path) |
|
|
assert response.status_code == 422 |
|
|
assert response.status_code == 422 |
|
|
assert response.json() == { |
|
|
assert response.json() == snapshot( |
|
|
|
|
|
{ |
|
|
"detail": [ |
|
|
"detail": [ |
|
|
{ |
|
|
{ |
|
|
"type": "missing", |
|
|
"type": "missing", |
|
|
@ -605,6 +619,7 @@ def test_nullable_non_required_no_body(path: str): |
|
|
}, |
|
|
}, |
|
|
] |
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize( |
|
|
@pytest.mark.parametrize( |
|
|
@ -836,7 +851,8 @@ def test_nullable_with_non_null_default_schema(path: str): |
|
|
body_model_name = get_body_model_name(openapi, path) |
|
|
body_model_name = get_body_model_name(openapi, path) |
|
|
body_model = app.openapi()["components"]["schemas"][body_model_name] |
|
|
body_model = app.openapi()["components"]["schemas"][body_model_name] |
|
|
|
|
|
|
|
|
assert body_model == { |
|
|
assert body_model == snapshot( |
|
|
|
|
|
{ |
|
|
"properties": { |
|
|
"properties": { |
|
|
"int_val": { |
|
|
"int_val": { |
|
|
"title": "Int Val", |
|
|
"title": "Int Val", |
|
|
@ -858,9 +874,10 @@ def test_nullable_with_non_null_default_schema(path: str): |
|
|
}, |
|
|
}, |
|
|
), |
|
|
), |
|
|
}, |
|
|
}, |
|
|
"title": body_model_name, |
|
|
"title": Is(body_model_name), |
|
|
"type": "object", |
|
|
"type": "object", |
|
|
} |
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
if path == "/model-nullable-with-non-null-default": |
|
|
if path == "/model-nullable-with-non-null-default": |
|
|
# Check default value for list_val param for model-based parameters only. |
|
|
# Check default value for list_val param for model-based parameters only. |
|
|
@ -949,7 +966,8 @@ def test_nullable_with_non_null_default_no_body(path: str): |
|
|
client = TestClient(app) |
|
|
client = TestClient(app) |
|
|
response = client.post(path) |
|
|
response = client.post(path) |
|
|
assert response.status_code == 422 |
|
|
assert response.status_code == 422 |
|
|
assert response.json() == { |
|
|
assert response.json() == snapshot( |
|
|
|
|
|
{ |
|
|
"detail": [ |
|
|
"detail": [ |
|
|
{ |
|
|
{ |
|
|
"type": "missing", |
|
|
"type": "missing", |
|
|
@ -959,6 +977,7 @@ def test_nullable_with_non_null_default_no_body(path: str): |
|
|
}, |
|
|
}, |
|
|
] |
|
|
] |
|
|
} |
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize( |
|
|
@pytest.mark.parametrize( |
|
|
|