🔥 Remove Pydantic v1 specific test variants (#14611)

This commit is contained in:
Sebastián Ramírez
2025-12-27 10:19:10 -08:00
committed by GitHub
parent 8322a4445a
commit 44c849c4fc
104 changed files with 4139 additions and 8074 deletions

View File

@@ -3,7 +3,6 @@ import os
import shutil
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from tests.utils import needs_py310
@@ -80,16 +79,10 @@ def test_openapi_schema(client: TestClient):
},
{
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "boolean"}, {"type": "null"}],
"title": "Img",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Img", "type": "boolean"}
),
"schema": {
"anyOf": [{"type": "boolean"}, {"type": "null"}],
"title": "Img",
},
"name": "img",
"in": "query",
},

View File

@@ -3,7 +3,6 @@ import os
import shutil
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from tests.utils import needs_py310
@@ -83,16 +82,10 @@ def test_openapi_schema(client: TestClient):
},
{
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "boolean"}, {"type": "null"}],
"title": "Img",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Img", "type": "boolean"}
),
"schema": {
"anyOf": [{"type": "boolean"}, {"type": "null"}],
"title": "Img",
},
"name": "img",
"in": "query",
},

View File

@@ -1,5 +1,5 @@
from dirty_equals import IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from docs_src.behind_a_proxy.tutorial003_py39 import app
@@ -15,40 +15,34 @@ def test_main():
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"servers": [
{"url": "/api/v1"},
{
"url": IsOneOf(
"https://stag.example.com/",
# TODO: remove when deprecating Pydantic v1
"https://stag.example.com",
),
"description": "Staging environment",
},
{
"url": IsOneOf(
"https://prod.example.com/",
# TODO: remove when deprecating Pydantic v1
"https://prod.example.com",
),
"description": "Production environment",
},
],
"paths": {
"/app": {
"get": {
"summary": "Read Main",
"operationId": "read_main_app_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"servers": [
{"url": "/api/v1"},
{
"url": "https://stag.example.com",
"description": "Staging environment",
},
{
"url": "https://prod.example.com",
"description": "Production environment",
},
],
"paths": {
"/app": {
"get": {
"summary": "Read Main",
"operationId": "read_main_app_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
}
}
}
},
}
},
}
)

View File

@@ -1,5 +1,5 @@
from dirty_equals import IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from docs_src.behind_a_proxy.tutorial004_py39 import app
@@ -15,39 +15,33 @@ def test_main():
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"servers": [
{
"url": IsOneOf(
"https://stag.example.com/",
# TODO: remove when deprecating Pydantic v1
"https://stag.example.com",
),
"description": "Staging environment",
},
{
"url": IsOneOf(
"https://prod.example.com/",
# TODO: remove when deprecating Pydantic v1
"https://prod.example.com",
),
"description": "Production environment",
},
],
"paths": {
"/app": {
"get": {
"summary": "Read Main",
"operationId": "read_main_app_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"servers": [
{
"url": "https://stag.example.com",
"description": "Staging environment",
},
{
"url": "https://prod.example.com",
"description": "Production environment",
},
],
"paths": {
"/app": {
"get": {
"summary": "Read Main",
"operationId": "read_main_app_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
}
}
}
},
}
},
}
)

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
@@ -28,29 +27,16 @@ def test_users_token_jessica(client: TestClient):
def test_users_with_no_token(client: TestClient):
response = client.get("/users")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
def test_users_foo_token_jessica(client: TestClient):
@@ -62,29 +48,16 @@ def test_users_foo_token_jessica(client: TestClient):
def test_users_foo_with_no_token(client: TestClient):
response = client.get("/users/foo")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
def test_users_me_token_jessica(client: TestClient):
@@ -96,29 +69,16 @@ def test_users_me_token_jessica(client: TestClient):
def test_users_me_with_no_token(client: TestClient):
response = client.get("/users/me")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
def test_users_token_monica_with_no_jessica(client: TestClient):
@@ -141,29 +101,16 @@ def test_items_token_jessica(client: TestClient):
def test_items_with_no_token_jessica(client: TestClient):
response = client.get("/items", headers={"X-Token": "fake-super-secret-token"})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
def test_items_plumbus_token_jessica(client: TestClient):
@@ -187,29 +134,16 @@ def test_items_plumbus_with_no_token(client: TestClient):
"/items/plumbus", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
def test_items_with_invalid_token(client: TestClient):
@@ -227,57 +161,31 @@ def test_items_bar_with_invalid_token(client: TestClient):
def test_items_with_missing_x_token_header(client: TestClient):
response = client.get("/items?token=jessica")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
}
]
}
def test_items_plumbus_with_missing_x_token_header(client: TestClient):
response = client.get("/items/plumbus?token=jessica")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
}
]
}
def test_root_token_jessica(client: TestClient):
@@ -289,68 +197,37 @@ def test_root_token_jessica(client: TestClient):
def test_root_with_no_token(client: TestClient):
response = client.get("/")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
}
]
}
def test_put_no_header(client: TestClient):
response = client.put("/items/foo")
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["query", "token"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
},
]
}
def test_put_invalid_header(client: TestClient):

View File

@@ -2,7 +2,6 @@ import importlib
from unittest.mock import patch
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -74,124 +73,67 @@ def test_post_with_str_float_description_tax(client: TestClient):
def test_post_with_only_name(client: TestClient):
response = client.post("/items/", json={"name": "Foo"})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "price"],
"msg": "Field required",
"input": {"name": "Foo"},
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "price"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "price"],
"msg": "Field required",
"input": {"name": "Foo"},
}
]
}
def test_post_with_only_name_price(client: TestClient):
response = client.post("/items/", json={"name": "Foo", "price": "twenty"})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "float_parsing",
"loc": ["body", "price"],
"msg": "Input should be a valid number, unable to parse string as a number",
"input": "twenty",
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "price"],
"msg": "value is not a valid float",
"type": "type_error.float",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "float_parsing",
"loc": ["body", "price"],
"msg": "Input should be a valid number, unable to parse string as a number",
"input": "twenty",
}
]
}
def test_post_with_no_data(client: TestClient):
response = client.post("/items/", json={})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "name"],
"msg": "Field required",
"input": {},
},
{
"type": "missing",
"loc": ["body", "price"],
"msg": "Field required",
"input": {},
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "name"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "price"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "name"],
"msg": "Field required",
"input": {},
},
{
"type": "missing",
"loc": ["body", "price"],
"msg": "Field required",
"input": {},
},
]
}
def test_post_with_none(client: TestClient):
response = client.post("/items/", json=None)
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body"],
"msg": "Field required",
"input": None,
}
]
}
def test_post_broken_body(client: TestClient):
@@ -201,67 +143,32 @@ def test_post_broken_body(client: TestClient):
content="{some broken json}",
)
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "json_invalid",
"loc": ["body", 1],
"msg": "JSON decode error",
"input": {},
"ctx": {
"error": "Expecting property name enclosed in double quotes"
},
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", 1],
"msg": "Expecting property name enclosed in double quotes: line 1 column 2 (char 1)",
"type": "value_error.jsondecode",
"ctx": {
"msg": "Expecting property name enclosed in double quotes",
"doc": "{some broken json}",
"pos": 1,
"lineno": 1,
"colno": 2,
},
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "json_invalid",
"loc": ["body", 1],
"msg": "JSON decode error",
"input": {},
"ctx": {"error": "Expecting property name enclosed in double quotes"},
}
]
}
def test_post_form_for_json(client: TestClient):
response = client.post("/items/", data={"name": "Foo", "price": 50.5})
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "model_attributes_type",
"loc": ["body"],
"msg": "Input should be a valid dictionary or object to extract fields from",
"input": "name=Foo&price=50.5",
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body"],
"msg": "value is not a valid dict",
"type": "type_error.dict",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "model_attributes_type",
"loc": ["body"],
"msg": "Input should be a valid dictionary or object to extract fields from",
"input": "name=Foo&price=50.5",
}
]
}
def test_explicit_content_type(client: TestClient):
@@ -302,84 +209,46 @@ def test_wrong_headers(client: TestClient):
"/items/", content=data, headers={"Content-Type": "text/plain"}
)
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "model_attributes_type",
"loc": ["body"],
"msg": "Input should be a valid dictionary or object to extract fields from",
"input": '{"name": "Foo", "price": 50.5}',
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body"],
"msg": "value is not a valid dict",
"type": "type_error.dict",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "model_attributes_type",
"loc": ["body"],
"msg": "Input should be a valid dictionary or object to extract fields from",
"input": '{"name": "Foo", "price": 50.5}',
}
]
}
response = client.post(
"/items/", content=data, headers={"Content-Type": "application/geo+json-seq"}
)
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "model_attributes_type",
"loc": ["body"],
"msg": "Input should be a valid dictionary or object to extract fields from",
"input": '{"name": "Foo", "price": 50.5}',
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body"],
"msg": "value is not a valid dict",
"type": "type_error.dict",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "model_attributes_type",
"loc": ["body"],
"msg": "Input should be a valid dictionary or object to extract fields from",
"input": '{"name": "Foo", "price": 50.5}',
}
]
}
response = client.post(
"/items/", content=data, headers={"Content-Type": "application/not-really-json"}
)
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "model_attributes_type",
"loc": ["body"],
"msg": "Input should be a valid dictionary or object to extract fields from",
"input": '{"name": "Foo", "price": 50.5}',
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body"],
"msg": "value is not a valid dict",
"type": "type_error.dict",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "model_attributes_type",
"loc": ["body"],
"msg": "Input should be a valid dictionary or object to extract fields from",
"input": '{"name": "Foo", "price": 50.5}',
}
]
}
def test_other_exceptions(client: TestClient):
@@ -435,26 +304,14 @@ def test_openapi_schema(client: TestClient):
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": IsDict(
{
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"tax": IsDict(
{
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Tax", "type": "number"}
),
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
"tax": {
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
},
},
},
"ValidationError": {

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -59,31 +58,17 @@ def test_items_6(client: TestClient):
def test_invalid_price(client: TestClient):
response = client.put("/items/5", json={"item": {"name": "Foo", "price": -3.0}})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "greater_than",
"loc": ["body", "item", "price"],
"msg": "Input should be greater than 0",
"input": -3.0,
"ctx": {"gt": 0.0},
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "greater_than",
"loc": ["body", "item", "price"],
"msg": "Input should be greater than 0",
"input": -3.0,
"ctx": {"gt": 0.0},
}
]
}
def test_openapi_schema(client: TestClient):
@@ -142,39 +127,23 @@ def test_openapi_schema(client: TestClient):
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"description": IsDict(
{
"title": "The description of the item",
"anyOf": [
{"maxLength": 300, "type": "string"},
{"type": "null"},
],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "The description of the item",
"maxLength": 300,
"type": "string",
}
),
"description": {
"title": "The description of the item",
"anyOf": [
{"maxLength": 300, "type": "string"},
{"type": "null"},
],
},
"price": {
"title": "Price",
"exclusiveMinimum": 0.0,
"type": "number",
"description": "The price must be greater than zero",
},
"tax": IsDict(
{
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Tax", "type": "number"}
),
"tax": {
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
},
},
},
"Body_update_item_items__item_id__put": {

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -53,29 +52,16 @@ def test_post_no_body(client: TestClient):
def test_post_id_foo(client: TestClient):
response = client.put("/items/foo", json=None)
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "int_parsing",
"loc": ["path", "item_id"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "foo",
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "int_parsing",
"loc": ["path", "item_id"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "foo",
}
]
}
def test_openapi_schema(client: TestClient):
@@ -119,16 +105,10 @@ def test_openapi_schema(client: TestClient):
},
{
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Q",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Q", "type": "string"}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Q",
},
"name": "q",
"in": "query",
},
@@ -136,19 +116,13 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
"schema": IsDict(
{
"anyOf": [
{"$ref": "#/components/schemas/Item"},
{"type": "null"},
],
"title": "Item",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"$ref": "#/components/schemas/Item"}
)
"schema": {
"anyOf": [
{"$ref": "#/components/schemas/Item"},
{"type": "null"},
],
"title": "Item",
}
}
}
},
@@ -163,27 +137,15 @@ def test_openapi_schema(client: TestClient):
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"description": IsDict(
{
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
"price": {"title": "Price", "type": "number"},
"tax": IsDict(
{
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Tax", "type": "number"}
),
"tax": {
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
},
},
},
"ValidationError": {

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -49,101 +48,55 @@ def test_post_body_valid(client: TestClient):
def test_post_body_no_data(client: TestClient):
response = client.put("/items/5", json=None)
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "item"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "user"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "importance"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "item"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "user"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "importance"],
"msg": "Field required",
"input": None,
},
]
}
def test_post_body_empty_list(client: TestClient):
response = client.put("/items/5", json=[])
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "item"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "user"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "importance"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "item"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "user"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "importance"],
"msg": "Field required",
"input": None,
},
]
}
def test_openapi_schema(client: TestClient):
@@ -202,27 +155,15 @@ def test_openapi_schema(client: TestClient):
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"description": IsDict(
{
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
"price": {"title": "Price", "type": "number"},
"tax": IsDict(
{
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Tax", "type": "number"}
),
"tax": {
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
},
},
},
"User": {
@@ -231,16 +172,10 @@ def test_openapi_schema(client: TestClient):
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"full_name": IsDict(
{
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Full Name", "type": "string"}
),
"full_name": {
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
},
},
"Body_update_item_items__item_id__put": {

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
@@ -29,29 +28,16 @@ def test_post_invalid_body(client: TestClient):
data = {"foo": 2.2, "3": 3.3}
response = client.post("/index-weights/", json=data)
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "int_parsing",
"loc": ["body", "foo", "[key]"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "foo",
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "__key__"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "int_parsing",
"loc": ["body", "foo", "[key]"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "foo",
}
]
}
def test_openapi_schema(client: TestClient):

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
@@ -54,30 +53,16 @@ def test_cookie_param_model_invalid(client: TestClient):
response = client.get("/items/")
assert response.status_code == 422
assert response.json() == snapshot(
IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["cookie", "session_id"],
"msg": "Field required",
"input": {},
}
]
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"type": "value_error.missing",
"loc": ["cookie", "session_id"],
"msg": "field required",
}
]
}
)
{
"detail": [
{
"type": "missing",
"loc": ["cookie", "session_id"],
"msg": "Field required",
"input": {},
}
]
}
)
@@ -115,37 +100,19 @@ def test_openapi_schema(client: TestClient):
"name": "fatebook_tracker",
"in": "cookie",
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Fatebook Tracker",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "Fatebook Tracker",
}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Fatebook Tracker",
},
},
{
"name": "googall_tracker",
"in": "cookie",
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Googall Tracker",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "Googall Tracker",
}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Googall Tracker",
},
},
],
"responses": {

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
@@ -72,30 +71,16 @@ def test_cookie_param_model_extra(client: TestClient):
response = c.get("/items/")
assert response.status_code == 422
assert response.json() == snapshot(
IsDict(
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["cookie", "extra"],
"msg": "Extra inputs are not permitted",
"input": "track-me-here-too",
}
]
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"type": "value_error.extra",
"loc": ["cookie", "extra"],
"msg": "extra fields not permitted",
}
]
}
)
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["cookie", "extra"],
"msg": "Extra inputs are not permitted",
"input": "track-me-here-too",
}
]
}
)
@@ -134,19 +119,10 @@ def test_openapi_schema(client: TestClient):
"name": "googall_tracker",
"in": "cookie",
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Googall Tracker",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "Googall Tracker",
}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Googall Tracker",
},
},
],
"responses": {

View File

@@ -2,7 +2,6 @@ import importlib
from types import ModuleType
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -75,16 +74,10 @@ def test_openapi_schema(mod: ModuleType):
"parameters": [
{
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Ads Id",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Ads Id", "type": "string"}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Ads Id",
},
"name": "ads_id",
"in": "cookie",
}

View File

@@ -1,7 +1,7 @@
import importlib
import pytest
from dirty_equals import IsDict, IsOneOf
from dirty_equals import IsOneOf
from fastapi.testclient import TestClient
from tests.utils import needs_py310
@@ -30,34 +30,17 @@ def test_endpoint_works(client: TestClient):
def test_exception_handler_body_access(client: TestClient):
response = client.post("/", json={"numbers": [1, 2, 3]})
assert response.json() == IsDict(
{
"detail": {
"errors": [
{
"type": "list_type",
"loc": ["body"],
"msg": "Input should be a valid list",
"input": {"numbers": [1, 2, 3]},
}
],
# httpx 0.28.0 switches to compact JSON https://github.com/encode/httpx/issues/3363
"body": IsOneOf('{"numbers": [1, 2, 3]}', '{"numbers":[1,2,3]}'),
}
assert response.json() == {
"detail": {
"errors": [
{
"type": "list_type",
"loc": ["body"],
"msg": "Input should be a valid list",
"input": {"numbers": [1, 2, 3]},
}
],
# httpx 0.28.0 switches to compact JSON https://github.com/encode/httpx/issues/3363
"body": IsOneOf('{"numbers": [1, 2, 3]}', '{"numbers":[1,2,3]}'),
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": {
# httpx 0.28.0 switches to compact JSON https://github.com/encode/httpx/issues/3363
"body": IsOneOf('{"numbers": [1, 2, 3]}', '{"numbers":[1,2,3]}'),
"errors": [
{
"loc": ["body"],
"msg": "value is not a valid list",
"type": "type_error.list",
}
],
}
}
)
}

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from tests.utils import needs_py310
@@ -36,29 +35,16 @@ def test_post_item(client: TestClient):
def test_post_invalid_item(client: TestClient):
response = client.post("/items/", json={"name": "Foo", "price": "invalid price"})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "float_parsing",
"loc": ["body", "price"],
"msg": "Input should be a valid number, unable to parse string as a number",
"input": "invalid price",
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "price"],
"msg": "value is not a valid float",
"type": "type_error.float",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "float_parsing",
"loc": ["body", "price"],
"msg": "Input should be a valid number, unable to parse string as a number",
"input": "invalid price",
}
]
}
def test_openapi_schema(client: TestClient):
@@ -119,26 +105,14 @@ def test_openapi_schema(client: TestClient):
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": IsDict(
{
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"tax": IsDict(
{
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Tax", "type": "number"}
),
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
"tax": {
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
},
},
},
"ValidationError": {

View File

@@ -1,8 +1,8 @@
import importlib
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from tests.utils import needs_py310
@@ -37,77 +37,53 @@ def test_get_item(client: TestClient):
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/next": {
"get": {
"summary": "Read Next Item",
"operationId": "read_next_item_items_next_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
}
},
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/next": {
"get": {
"summary": "Read Next Item",
"operationId": "read_next_item_items_next_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
}
},
}
}
}
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": IsOneOf(
["name", "price", "tags", "description", "tax"],
# TODO: remove when deprecating Pydantic v1
["name", "price"],
),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"tags": IsDict(
{
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"tags": {
"title": "Tags",
"type": "array",
"items": {"type": "string"},
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Tags",
"type": "array",
"items": {"type": "string"},
}
),
"description": IsDict(
{
},
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"tax": IsDict(
{
},
"tax": {
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Tax", "type": "number"}
),
},
},
},
}
}
}
},
}
},
}
)

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
@@ -22,40 +21,22 @@ def get_client(request: pytest.FixtureRequest):
def test_get_no_headers(client: TestClient):
response = client.get("/items/")
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["header", "x-key"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-key"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["header", "x-key"],
"msg": "Field required",
"input": None,
},
]
}
def test_get_invalid_one_header(client: TestClient):

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
@@ -22,79 +21,43 @@ def get_client(request: pytest.FixtureRequest):
def test_get_no_headers_items(client: TestClient):
response = client.get("/items/")
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["header", "x-key"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-key"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["header", "x-key"],
"msg": "Field required",
"input": None,
},
]
}
def test_get_no_headers_users(client: TestClient):
response = client.get("/users/")
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["header", "x-key"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-key"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["header", "x-token"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["header", "x-key"],
"msg": "Field required",
"input": None,
},
]
}
def test_get_invalid_one_header_items(client: TestClient):

View File

@@ -1,8 +1,8 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py310
@@ -47,146 +47,117 @@ def test_extra_types(client: TestClient):
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}": {
"put": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}": {
"put": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"422": {
"description": "Validation Error",
"summary": "Read Items",
"operationId": "read_items_items__item_id__put",
"parameters": [
{
"required": True,
"schema": {
"title": "Item Id",
"type": "string",
"format": "uuid",
},
"name": "item_id",
"in": "path",
}
],
"requestBody": {
"required": True,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
"$ref": "#/components/schemas/Body_read_items_items__item_id__put"
}
}
},
},
},
"summary": "Read Items",
"operationId": "read_items_items__item_id__put",
"parameters": [
{
"required": True,
"schema": {
"title": "Item Id",
"type": "string",
"format": "uuid",
},
"name": "item_id",
"in": "path",
}
],
"requestBody": {
"required": True,
"content": {
"application/json": {
"schema": IsDict(
{
"allOf": [
{
"$ref": "#/components/schemas/Body_read_items_items__item_id__put"
}
],
"title": "Body",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"$ref": "#/components/schemas/Body_read_items_items__item_id__put"
}
)
}
},
},
}
}
}
},
"components": {
"schemas": {
"Body_read_items_items__item_id__put": {
"title": "Body_read_items_items__item_id__put",
"type": "object",
"properties": {
"start_datetime": {
"title": "Start Datetime",
"type": "string",
"format": "date-time",
},
"end_datetime": {
"title": "End Datetime",
"type": "string",
"format": "date-time",
},
"repeat_at": IsDict(
{
},
"components": {
"schemas": {
"Body_read_items_items__item_id__put": {
"title": "Body_read_items_items__item_id__put",
"type": "object",
"properties": {
"start_datetime": {
"title": "Start Datetime",
"type": "string",
"format": "date-time",
},
"end_datetime": {
"title": "End Datetime",
"type": "string",
"format": "date-time",
},
"repeat_at": {
"title": "Repeat At",
"anyOf": [
{"type": "string", "format": "time"},
{"type": "null"},
],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Repeat At",
"type": "string",
"format": "time",
}
),
"process_after": IsDict(
{
},
"process_after": {
"title": "Process After",
"type": "string",
"format": "duration",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Process After",
"type": "number",
"format": "time-delta",
}
),
},
"required": ["start_datetime", "end_datetime", "process_after"],
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
"required": ["start_datetime", "end_datetime", "process_after"],
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
},
}
},
}
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
},
}
},
}
)

View File

@@ -1,8 +1,8 @@
import importlib
import pytest
from dirty_equals import IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py310
@@ -43,107 +43,115 @@ def test_get_plane(client: TestClient):
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"title": "Response Read Item Items Item Id Get",
"anyOf": [
{"$ref": "#/components/schemas/PlaneItem"},
{"$ref": "#/components/schemas/CarItem"},
],
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"title": "Response Read Item Items Item Id Get",
"anyOf": [
{
"$ref": "#/components/schemas/PlaneItem"
},
{
"$ref": "#/components/schemas/CarItem"
},
],
}
}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"summary": "Read Item",
"operationId": "read_item_items__item_id__get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
"summary": "Read Item",
"operationId": "read_item_items__item_id__get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
}
}
},
"components": {
"schemas": {
"PlaneItem": {
"title": "PlaneItem",
"required": IsOneOf(
["description", "type", "size"],
# TODO: remove when deprecating Pydantic v1
["description", "size"],
),
"type": "object",
"properties": {
"description": {"title": "Description", "type": "string"},
"type": {"title": "Type", "type": "string", "default": "plane"},
"size": {"title": "Size", "type": "integer"},
},
"components": {
"schemas": {
"PlaneItem": {
"title": "PlaneItem",
"required": ["description", "size"],
"type": "object",
"properties": {
"description": {"title": "Description", "type": "string"},
"type": {
"title": "Type",
"type": "string",
"default": "plane",
},
"size": {"title": "Size", "type": "integer"},
},
},
},
"CarItem": {
"title": "CarItem",
"required": IsOneOf(
["description", "type"],
# TODO: remove when deprecating Pydantic v1
["description"],
),
"type": "object",
"properties": {
"description": {"title": "Description", "type": "string"},
"type": {"title": "Type", "type": "string", "default": "car"},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
"CarItem": {
"title": "CarItem",
"required": ["description"],
"type": "object",
"properties": {
"description": {"title": "Description", "type": "string"},
"type": {
"title": "Type",
"type": "string",
"default": "car",
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
},
}
},
}
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
},
}
},
}
)

View File

@@ -1,4 +1,3 @@
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from docs_src.handling_errors.tutorial005_py39 import app
@@ -9,31 +8,17 @@ client = TestClient(app)
def test_post_validation_error():
response = client.post("/items/", json={"title": "towel", "size": "XL"})
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "int_parsing",
"loc": ["body", "size"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "XL",
}
],
"body": {"title": "towel", "size": "XL"},
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "size"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
],
"body": {"title": "towel", "size": "XL"},
}
)
assert response.json() == {
"detail": [
{
"type": "int_parsing",
"loc": ["body", "size"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "XL",
}
],
"body": {"title": "towel", "size": "XL"},
}
def test_post():

View File

@@ -1,4 +1,3 @@
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from docs_src.handling_errors.tutorial006_py39 import app
@@ -9,29 +8,16 @@ client = TestClient(app)
def test_get_validation_error():
response = client.get("/items/foo")
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "int_parsing",
"loc": ["path", "item_id"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "foo",
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "int_parsing",
"loc": ["path", "item_id"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "foo",
}
]
}
def test_get_http_error():

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
@@ -63,29 +62,19 @@ def test_header_param_model_invalid(client: TestClient):
assert response.json() == snapshot(
{
"detail": [
IsDict(
{
"type": "missing",
"loc": ["header", "save_data"],
"msg": "Field required",
"input": {
"x_tag": [],
"host": "testserver",
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"connection": "keep-alive",
"user-agent": "testclient",
},
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "value_error.missing",
"loc": ["header", "save_data"],
"msg": "field required",
}
)
{
"type": "missing",
"loc": ["header", "save_data"],
"msg": "Field required",
"input": {
"x_tag": [],
"host": "testserver",
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"connection": "keep-alive",
"user-agent": "testclient",
},
}
]
}
)
@@ -136,37 +125,19 @@ def test_openapi_schema(client: TestClient):
"name": "if-modified-since",
"in": "header",
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "If Modified Since",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "If Modified Since",
}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "If Modified Since",
},
},
{
"name": "traceparent",
"in": "header",
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Traceparent",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "Traceparent",
}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Traceparent",
},
},
{
"name": "x-tag",

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
@@ -64,22 +63,12 @@ def test_header_param_model_invalid(client: TestClient):
assert response.json() == snapshot(
{
"detail": [
IsDict(
{
"type": "missing",
"loc": ["header", "save_data"],
"msg": "Field required",
"input": {"x_tag": [], "host": "testserver"},
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "value_error.missing",
"loc": ["header", "save_data"],
"msg": "field required",
}
)
{
"type": "missing",
"loc": ["header", "save_data"],
"msg": "Field required",
"input": {"x_tag": [], "host": "testserver"},
}
]
}
)
@@ -93,22 +82,12 @@ def test_header_param_model_extra(client: TestClient):
assert response.json() == snapshot(
{
"detail": [
IsDict(
{
"type": "extra_forbidden",
"loc": ["header", "tool"],
"msg": "Extra inputs are not permitted",
"input": "plumbus",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "value_error.extra",
"loc": ["header", "tool"],
"msg": "extra fields not permitted",
}
)
{
"type": "extra_forbidden",
"loc": ["header", "tool"],
"msg": "Extra inputs are not permitted",
"input": "plumbus",
}
]
}
)
@@ -143,37 +122,19 @@ def test_openapi_schema(client: TestClient):
"name": "if-modified-since",
"in": "header",
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "If Modified Since",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "If Modified Since",
}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "If Modified Since",
},
},
{
"name": "traceparent",
"in": "header",
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Traceparent",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "Traceparent",
}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Traceparent",
},
},
{
"name": "x-tag",

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
@@ -60,33 +59,23 @@ def test_header_param_model_no_underscore(client: TestClient):
assert response.json() == snapshot(
{
"detail": [
IsDict(
{
"type": "missing",
"loc": ["header", "save_data"],
"msg": "Field required",
"input": {
"host": "testserver",
"traceparent": "123",
"x_tag": [],
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"connection": "keep-alive",
"user-agent": "testclient",
"save-data": "true",
"if-modified-since": "yesterday",
"x-tag": ["one", "two"],
},
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "value_error.missing",
"loc": ["header", "save_data"],
"msg": "field required",
}
)
{
"type": "missing",
"loc": ["header", "save_data"],
"msg": "Field required",
"input": {
"host": "testserver",
"traceparent": "123",
"x_tag": [],
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"connection": "keep-alive",
"user-agent": "testclient",
"save-data": "true",
"if-modified-since": "yesterday",
"x-tag": ["one", "two"],
},
}
]
}
)
@@ -110,29 +99,19 @@ def test_header_param_model_invalid(client: TestClient):
assert response.json() == snapshot(
{
"detail": [
IsDict(
{
"type": "missing",
"loc": ["header", "save_data"],
"msg": "Field required",
"input": {
"x_tag": [],
"host": "testserver",
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"connection": "keep-alive",
"user-agent": "testclient",
},
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "value_error.missing",
"loc": ["header", "save_data"],
"msg": "field required",
}
)
{
"type": "missing",
"loc": ["header", "save_data"],
"msg": "Field required",
"input": {
"x_tag": [],
"host": "testserver",
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"connection": "keep-alive",
"user-agent": "testclient",
},
}
]
}
)
@@ -183,37 +162,19 @@ def test_openapi_schema(client: TestClient):
"name": "if_modified_since",
"in": "header",
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "If Modified Since",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "If Modified Since",
}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "If Modified Since",
},
},
{
"name": "traceparent",
"in": "header",
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Traceparent",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "Traceparent",
}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Traceparent",
},
},
{
"name": "x_tag",

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -67,16 +66,10 @@ def test_openapi_schema(client: TestClient):
"parameters": [
{
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "User-Agent",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "User-Agent", "type": "string"}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "User-Agent",
},
"name": "user-agent",
"in": "header",
}

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -78,16 +77,10 @@ def test_openapi_schema(client: TestClient):
"parameters": [
{
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Strange Header",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Strange Header", "type": "string"}
),
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Strange Header",
},
"name": "strange_header",
"in": "header",
}

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -56,23 +55,13 @@ def test_openapi_schema(client: TestClient):
"parameters": [
{
"required": False,
"schema": IsDict(
{
"title": "X-Token",
"anyOf": [
{"type": "array", "items": {"type": "string"}},
{"type": "null"},
],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "X-Token",
"type": "array",
"items": {"type": "string"},
}
),
"schema": {
"title": "X-Token",
"anyOf": [
{"type": "array", "items": {"type": "string"}},
{"type": "null"},
],
},
"name": "x-token",
"in": "header",
}

View File

@@ -2,7 +2,6 @@ import importlib
from types import ModuleType
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from tests.utils import needs_py310
@@ -55,30 +54,18 @@ def test_openapi_schema(client: TestClient):
"parameters": [
{
"required": False,
"schema": IsDict(
{
"anyOf": [
{
"type": "string",
"format": "uri",
"minLength": 1,
"maxLength": 2083,
},
{"type": "null"},
],
"title": "Callback Url",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Callback Url",
"maxLength": 2083,
"minLength": 1,
"type": "string",
"format": "uri",
}
),
"schema": {
"anyOf": [
{
"type": "string",
"format": "uri",
"minLength": 1,
"maxLength": 2083,
},
{"type": "null"},
],
"title": "Callback Url",
},
"name": "callback_url",
"in": "query",
}
@@ -171,16 +158,10 @@ def test_openapi_schema(client: TestClient):
"type": "object",
"properties": {
"id": {"title": "Id", "type": "string"},
"title": IsDict(
{
"title": "Title",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Title", "type": "string"}
),
"title": {
"title": "Title",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
"customer": {"title": "Customer", "type": "string"},
"total": {"title": "Total", "type": "number"},
},

View File

@@ -1,4 +1,3 @@
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from docs_src.path_params.tutorial005_py39 import app
@@ -27,31 +26,17 @@ def test_get_enums_resnet():
def test_get_enums_invalid():
response = client.get("/models/foo")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "enum",
"loc": ["path", "model_name"],
"msg": "Input should be 'alexnet', 'resnet' or 'lenet'",
"input": "foo",
"ctx": {"expected": "'alexnet', 'resnet' or 'lenet'"},
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"ctx": {"enum_values": ["alexnet", "resnet", "lenet"]},
"loc": ["path", "model_name"],
"msg": "value is not a valid enumeration member; permitted: 'alexnet', 'resnet', 'lenet'",
"type": "type_error.enum",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "enum",
"loc": ["path", "model_name"],
"msg": "Input should be 'alexnet', 'resnet' or 'lenet'",
"input": "foo",
"ctx": {"expected": "'alexnet', 'resnet' or 'lenet'"},
}
]
}
def test_openapi_schema():
@@ -106,22 +91,11 @@ def test_openapi_schema():
}
},
},
"ModelName": IsDict(
{
"title": "ModelName",
"enum": ["alexnet", "resnet", "lenet"],
"type": "string",
}
)
| IsDict(
{
# TODO: remove when deprecating Pydantic v1
"title": "ModelName",
"enum": ["alexnet", "resnet", "lenet"],
"type": "string",
"description": "An enumeration.",
}
),
"ModelName": {
"title": "ModelName",
"enum": ["alexnet", "resnet", "lenet"],
"type": "string",
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
@@ -65,61 +64,31 @@ def test_query_param_model_invalid(client: TestClient):
)
assert response.status_code == 422
assert response.json() == snapshot(
IsDict(
{
"detail": [
{
"type": "less_than_equal",
"loc": ["query", "limit"],
"msg": "Input should be less than or equal to 100",
"input": "150",
"ctx": {"le": 100},
},
{
"type": "greater_than_equal",
"loc": ["query", "offset"],
"msg": "Input should be greater than or equal to 0",
"input": "-1",
"ctx": {"ge": 0},
},
{
"type": "literal_error",
"loc": ["query", "order_by"],
"msg": "Input should be 'created_at' or 'updated_at'",
"input": "invalid",
"ctx": {"expected": "'created_at' or 'updated_at'"},
},
]
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"type": "value_error.number.not_le",
"loc": ["query", "limit"],
"msg": "ensure this value is less than or equal to 100",
"ctx": {"limit_value": 100},
},
{
"type": "value_error.number.not_ge",
"loc": ["query", "offset"],
"msg": "ensure this value is greater than or equal to 0",
"ctx": {"limit_value": 0},
},
{
"type": "value_error.const",
"loc": ["query", "order_by"],
"msg": "unexpected value; permitted: 'created_at', 'updated_at'",
"ctx": {
"given": "invalid",
"permitted": ["created_at", "updated_at"],
},
},
]
}
)
{
"detail": [
{
"type": "less_than_equal",
"loc": ["query", "limit"],
"msg": "Input should be less than or equal to 100",
"input": "150",
"ctx": {"le": 100},
},
{
"type": "greater_than_equal",
"loc": ["query", "offset"],
"msg": "Input should be greater than or equal to 0",
"input": "-1",
"ctx": {"ge": 0},
},
{
"type": "literal_error",
"loc": ["query", "order_by"],
"msg": "Input should be 'created_at' or 'updated_at'",
"input": "invalid",
"ctx": {"expected": "'created_at' or 'updated_at'"},
},
]
}
)

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
@@ -65,61 +64,31 @@ def test_query_param_model_invalid(client: TestClient):
)
assert response.status_code == 422
assert response.json() == snapshot(
IsDict(
{
"detail": [
{
"type": "less_than_equal",
"loc": ["query", "limit"],
"msg": "Input should be less than or equal to 100",
"input": "150",
"ctx": {"le": 100},
},
{
"type": "greater_than_equal",
"loc": ["query", "offset"],
"msg": "Input should be greater than or equal to 0",
"input": "-1",
"ctx": {"ge": 0},
},
{
"type": "literal_error",
"loc": ["query", "order_by"],
"msg": "Input should be 'created_at' or 'updated_at'",
"input": "invalid",
"ctx": {"expected": "'created_at' or 'updated_at'"},
},
]
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"type": "value_error.number.not_le",
"loc": ["query", "limit"],
"msg": "ensure this value is less than or equal to 100",
"ctx": {"limit_value": 100},
},
{
"type": "value_error.number.not_ge",
"loc": ["query", "offset"],
"msg": "ensure this value is greater than or equal to 0",
"ctx": {"limit_value": 0},
},
{
"type": "value_error.const",
"loc": ["query", "order_by"],
"msg": "unexpected value; permitted: 'created_at', 'updated_at'",
"ctx": {
"given": "invalid",
"permitted": ["created_at", "updated_at"],
},
},
]
}
)
{
"detail": [
{
"type": "less_than_equal",
"loc": ["query", "limit"],
"msg": "Input should be less than or equal to 100",
"input": "150",
"ctx": {"le": 100},
},
{
"type": "greater_than_equal",
"loc": ["query", "offset"],
"msg": "Input should be greater than or equal to 0",
"input": "-1",
"ctx": {"ge": 0},
},
{
"type": "literal_error",
"loc": ["query", "order_by"],
"msg": "Input should be 'created_at' or 'updated_at'",
"input": "invalid",
"ctx": {"expected": "'created_at' or 'updated_at'"},
},
]
}
)
@@ -138,22 +107,12 @@ def test_query_param_model_extra(client: TestClient):
assert response.json() == snapshot(
{
"detail": [
IsDict(
{
"type": "extra_forbidden",
"loc": ["query", "tool"],
"msg": "Extra inputs are not permitted",
"input": "plumbus",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "value_error.extra",
"loc": ["query", "tool"],
"msg": "extra fields not permitted",
}
)
{
"type": "extra_forbidden",
"loc": ["query", "tool"],
"msg": "Extra inputs are not permitted",
"input": "plumbus",
}
]
}
)

View File

@@ -1,4 +1,3 @@
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from docs_src.query_params.tutorial005_py39 import app
@@ -15,29 +14,16 @@ def test_foo_needy_very():
def test_foo_no_needy():
response = client.get("/items/foo")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["query", "needy"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["query", "needy"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["query", "needy"],
"msg": "Field required",
"input": None,
}
]
}
def test_openapi_schema():

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -35,51 +34,28 @@ def test_foo_needy_very(client: TestClient):
def test_foo_no_needy(client: TestClient):
response = client.get("/items/foo?skip=a&limit=b")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["query", "needy"],
"msg": "Field required",
"input": None,
},
{
"type": "int_parsing",
"loc": ["query", "skip"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "a",
},
{
"type": "int_parsing",
"loc": ["query", "limit"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "b",
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["query", "needy"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["query", "skip"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
},
{
"loc": ["query", "limit"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["query", "needy"],
"msg": "Field required",
"input": None,
},
{
"type": "int_parsing",
"loc": ["query", "skip"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "a",
},
{
"type": "int_parsing",
"loc": ["query", "limit"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "b",
},
]
}
def test_openapi_schema(client: TestClient):
@@ -134,16 +110,10 @@ def test_openapi_schema(client: TestClient):
},
{
"required": False,
"schema": IsDict(
{
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Limit",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Limit", "type": "integer"}
),
"schema": {
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Limit",
},
"name": "limit",
"in": "query",
},

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi._compat import PYDANTIC_VERSION_MINOR_TUPLE
from fastapi.testclient import TestClient
@@ -50,31 +49,17 @@ def test_query_params_str_validations_q_fixedquery(client: TestClient):
def test_query_params_str_validations_item_query_nonregexquery(client: TestClient):
response = client.get("/items/", params={"item-query": "nonregexquery"})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "string_pattern_mismatch",
"loc": ["query", "item-query"],
"msg": "String should match pattern '^fixedquery$'",
"input": "nonregexquery",
"ctx": {"pattern": "^fixedquery$"},
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"ctx": {"pattern": "^fixedquery$"},
"loc": ["query", "item-query"],
"msg": 'string does not match regex "^fixedquery$"',
"type": "value_error.str.regex",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "string_pattern_mismatch",
"loc": ["query", "item-query"],
"msg": "String should match pattern '^fixedquery$'",
"input": "nonregexquery",
"ctx": {"pattern": "^fixedquery$"},
}
]
}
def test_openapi_schema(client: TestClient):
@@ -109,38 +94,25 @@ def test_openapi_schema(client: TestClient):
"description": "Query string for the items to search in the database that have a good match",
"required": False,
"deprecated": True,
"schema": IsDict(
{
"anyOf": [
{
"type": "string",
"minLength": 3,
"maxLength": 50,
"pattern": "^fixedquery$",
},
{"type": "null"},
],
"title": "Query string",
"description": "Query string for the items to search in the database that have a good match",
# See https://github.com/pydantic/pydantic/blob/80353c29a824c55dea4667b328ba8f329879ac9f/tests/test_fastapi.sh#L25-L34.
**(
{"deprecated": True}
if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 10)
else {}
),
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Query string",
"maxLength": 50,
"minLength": 3,
"pattern": "^fixedquery$",
"type": "string",
"description": "Query string for the items to search in the database that have a good match",
}
),
"schema": {
"anyOf": [
{
"type": "string",
"minLength": 3,
"maxLength": 50,
"pattern": "^fixedquery$",
},
{"type": "null"},
],
"title": "Query string",
"description": "Query string for the items to search in the database that have a good match",
# See https://github.com/pydantic/pydantic/blob/80353c29a824c55dea4667b328ba8f329879ac9f/tests/test_fastapi.sh#L25-L34.
**(
{"deprecated": True}
if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 10)
else {}
),
},
"name": "item-query",
"in": "query",
}

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -69,23 +68,13 @@ def test_openapi_schema(client: TestClient):
"parameters": [
{
"required": False,
"schema": IsDict(
{
"anyOf": [
{"type": "array", "items": {"type": "string"}},
{"type": "null"},
],
"title": "Q",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Q",
"type": "array",
"items": {"type": "string"},
}
),
"schema": {
"anyOf": [
{"type": "array", "items": {"type": "string"}},
{"type": "null"},
],
"title": "Q",
},
"name": "q",
"in": "query",
}

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
@@ -22,57 +21,31 @@ def get_client(request: pytest.FixtureRequest):
def test_post_form_no_body(client: TestClient):
response = client.post("/files/")
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "file"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
}
]
}
def test_post_body_json(client: TestClient):
response = client.post("/files/", json={"file": "Foo"})
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "file"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
}
]
}
def test_post_file(tmp_path, client: TestClient):

View File

@@ -2,8 +2,8 @@ import importlib
from pathlib import Path
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py310
@@ -59,166 +59,132 @@ def test_post_upload_file(tmp_path: Path, client: TestClient):
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/files/": {
"post": {
"summary": "Create File",
"operationId": "create_file_files__post",
"requestBody": {
"content": {
"multipart/form-data": {
"schema": IsDict(
{
"allOf": [
{
"$ref": "#/components/schemas/Body_create_file_files__post"
}
],
"title": "Body",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/files/": {
"post": {
"summary": "Create File",
"operationId": "create_file_files__post",
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/Body_create_file_files__post"
}
)
}
}
},
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
},
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
},
}
},
"/uploadfile/": {
"post": {
"summary": "Create Upload File",
"operationId": "create_upload_file_uploadfile__post",
"requestBody": {
"content": {
"multipart/form-data": {
"schema": IsDict(
{
"allOf": [
{
"$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
}
],
"title": "Body",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
}
},
"/uploadfile/": {
"post": {
"summary": "Create Upload File",
"operationId": "create_upload_file_uploadfile__post",
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
}
)
}
}
},
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
},
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
}
},
},
"components": {
"schemas": {
"Body_create_file_files__post": {
"title": "Body_create_file_files__post",
"type": "object",
"properties": {
"file": {
"title": "File",
"anyOf": [
{"type": "string", "format": "binary"},
{"type": "null"},
],
}
},
},
"Body_create_upload_file_uploadfile__post": {
"title": "Body_create_upload_file_uploadfile__post",
"type": "object",
"properties": {
"file": {
"title": "File",
"anyOf": [
{"type": "string", "format": "binary"},
{"type": "null"},
],
}
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
}
},
},
"components": {
"schemas": {
"Body_create_file_files__post": {
"title": "Body_create_file_files__post",
"type": "object",
"properties": {
"file": IsDict(
{
"title": "File",
"anyOf": [
{"type": "string", "format": "binary"},
{"type": "null"},
],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "File", "type": "string", "format": "binary"}
)
},
},
"Body_create_upload_file_uploadfile__post": {
"title": "Body_create_upload_file_uploadfile__post",
"type": "object",
"properties": {
"file": IsDict(
{
"title": "File",
"anyOf": [
{"type": "string", "format": "binary"},
{"type": "null"},
],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "File", "type": "string", "format": "binary"}
)
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
}
},
}
}
)

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI
from fastapi.testclient import TestClient
@@ -28,57 +27,31 @@ def get_client(app: FastAPI):
def test_post_form_no_body(client: TestClient):
response = client.post("/files/")
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "files"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "files"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "files"],
"msg": "Field required",
"input": None,
}
]
}
def test_post_body_json(client: TestClient):
response = client.post("/files/", json={"file": "Foo"})
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "files"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "files"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "files"],
"msg": "Field required",
"input": None,
}
]
}
def test_post_files(tmp_path, app: FastAPI):

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
@@ -28,135 +27,73 @@ def test_post_body_form(client: TestClient):
def test_post_body_form_no_password(client: TestClient):
response = client.post("/login/", data={"username": "Foo"})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": {"username": "Foo"},
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": {"username": "Foo"},
}
]
}
def test_post_body_form_no_username(client: TestClient):
response = client.post("/login/", data={"password": "secret"})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": {"password": "secret"},
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": {"password": "secret"},
}
]
}
def test_post_body_form_no_data(client: TestClient):
response = client.post("/login/")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": {},
},
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": {},
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": {},
},
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": {},
},
]
}
def test_post_body_json(client: TestClient):
response = client.post("/login/", json={"username": "Foo", "password": "secret"})
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": {},
},
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": {},
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": {},
},
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": {},
},
]
}
def test_openapi_schema(client: TestClient):

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
@@ -28,135 +27,73 @@ def test_post_body_form(client: TestClient):
def test_post_body_form_no_password(client: TestClient):
response = client.post("/login/", data={"username": "Foo"})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": None,
}
]
}
def test_post_body_form_no_username(client: TestClient):
response = client.post("/login/", data={"password": "secret"})
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": None,
}
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": None,
}
]
}
def test_post_body_form_no_data(client: TestClient):
response = client.post("/login/")
assert response.status_code == 422
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": None,
},
]
}
def test_post_body_json(client: TestClient):
response = client.post("/login/", json={"username": "Foo", "password": "secret"})
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "username"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": None,
},
]
}
def test_openapi_schema(client: TestClient):

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI
from fastapi.testclient import TestClient
@@ -28,140 +27,76 @@ def get_client(app: FastAPI):
def test_post_form_no_body(client: TestClient):
response = client.post("/files/")
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "fileb"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "token"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "file"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "fileb"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "fileb"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "token"],
"msg": "Field required",
"input": None,
},
]
}
def test_post_form_no_file(client: TestClient):
response = client.post("/files/", data={"token": "foo"})
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "fileb"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "file"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "fileb"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "fileb"],
"msg": "Field required",
"input": None,
},
]
}
def test_post_body_json(client: TestClient):
response = client.post("/files/", json={"file": "Foo", "token": "Bar"})
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "fileb"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "token"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "file"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "fileb"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "file"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "fileb"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "token"],
"msg": "Field required",
"input": None,
},
]
}
def test_post_file_no_token(tmp_path, app: FastAPI):
@@ -172,40 +107,22 @@ def test_post_file_no_token(tmp_path, app: FastAPI):
with path.open("rb") as file:
response = client.post("/files/", files={"file": file})
assert response.status_code == 422, response.text
assert response.json() == IsDict(
{
"detail": [
{
"type": "missing",
"loc": ["body", "fileb"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "token"],
"msg": "Field required",
"input": None,
},
]
}
) | IsDict(
# TODO: remove when deprecating Pydantic v1
{
"detail": [
{
"loc": ["body", "fileb"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
)
assert response.json() == {
"detail": [
{
"type": "missing",
"loc": ["body", "fileb"],
"msg": "Field required",
"input": None,
},
{
"type": "missing",
"loc": ["body", "token"],
"msg": "Field required",
"input": None,
},
]
}
def test_post_files_and_token(tmp_path, app: FastAPI):

View File

@@ -1,8 +1,8 @@
import importlib
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py310
@@ -42,125 +42,115 @@ def test_post_user(client: TestClient):
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/user/": {
"post": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/UserOut"}
}
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/user/": {
"post": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UserOut"
}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"422": {
"description": "Validation Error",
"summary": "Create User",
"operationId": "create_user_user__post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
"schema": {"$ref": "#/components/schemas/UserIn"}
}
},
"required": True,
},
}
}
},
"components": {
"schemas": {
"UserOut": {
"title": "UserOut",
"required": ["username", "email"],
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"email": {
"title": "Email",
"type": "string",
"format": "email",
},
"full_name": {
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
},
},
"summary": "Create User",
"operationId": "create_user_user__post",
"requestBody": {
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/UserIn"}
"UserIn": {
"title": "UserIn",
"required": ["username", "password", "email"],
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"password": {"title": "Password", "type": "string"},
"email": {
"title": "Email",
"type": "string",
"format": "email",
},
"full_name": {
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
"required": True,
},
}
}
},
"components": {
"schemas": {
"UserOut": {
"title": "UserOut",
"required": IsOneOf(
["username", "email", "full_name"],
# TODO: remove when deprecating Pydantic v1
["username", "email"],
),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"email": {
"title": "Email",
"type": "string",
"format": "email",
},
"full_name": IsDict(
{
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Full Name", "type": "string"}
),
},
},
"UserIn": {
"title": "UserIn",
"required": ["username", "password", "email"],
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"password": {"title": "Password", "type": "string"},
"email": {
"title": "Email",
"type": "string",
"format": "email",
},
"full_name": IsDict(
{
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Full Name", "type": "string"}
),
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
}
},
}
},
}
)

View File

@@ -1,8 +1,8 @@
import importlib
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py310
@@ -42,125 +42,115 @@ def test_post_user(client: TestClient):
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/user/": {
"post": {
"summary": "Create User",
"operationId": "create_user_user__post",
"requestBody": {
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/UserIn"}
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/user/": {
"post": {
"summary": "Create User",
"operationId": "create_user_user__post",
"requestBody": {
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/UserIn"}
}
},
"required": True,
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BaseUser"
}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
}
}
},
"components": {
"schemas": {
"BaseUser": {
"title": "BaseUser",
"required": ["username", "email"],
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"email": {
"title": "Email",
"type": "string",
"format": "email",
},
"full_name": {
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
"required": True,
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/BaseUser"}
}
"UserIn": {
"title": "UserIn",
"required": ["username", "email", "password"],
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"email": {
"title": "Email",
"type": "string",
"format": "email",
},
"full_name": {
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
"password": {"title": "Password", "type": "string"},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
}
}
},
"components": {
"schemas": {
"BaseUser": {
"title": "BaseUser",
"required": IsOneOf(
["username", "email", "full_name"],
# TODO: remove when deprecating Pydantic v1
["username", "email"],
),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"email": {
"title": "Email",
"type": "string",
"format": "email",
},
"full_name": IsDict(
{
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Full Name", "type": "string"}
),
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
"UserIn": {
"title": "UserIn",
"required": ["username", "email", "password"],
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"email": {
"title": "Email",
"type": "string",
"format": "email",
},
"full_name": IsDict(
{
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Full Name", "type": "string"}
),
"password": {"title": "Password", "type": "string"},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
}
},
}
},
}
)

View File

@@ -1,8 +1,8 @@
import importlib
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py310
@@ -50,104 +50,98 @@ def test_get(url, data, client: TestClient):
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
},
"summary": "Read Item",
"operationId": "read_item_items__item_id__get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
}
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": IsOneOf(
["name", "description", "price", "tax", "tags"],
# TODO: remove when deprecating Pydantic v1
["name", "price"],
),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": IsDict(
"summary": "Read Item",
"operationId": "read_item_items__item_id__get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
}
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"tax": {"title": "Tax", "type": "number", "default": 10.5},
"tags": {
"title": "Tags",
"type": "array",
"items": {"type": "string"},
"default": [],
},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
"tax": {"title": "Tax", "type": "number", "default": 10.5},
"tags": {
"title": "Tags",
"type": "array",
"items": {"type": "string"},
"default": [],
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
},
}
},
}
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
},
}
},
}
)

View File

@@ -1,8 +1,8 @@
import importlib
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py310
@@ -40,132 +40,126 @@ def test_read_item_public_data(client: TestClient):
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}/name": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}/name": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
}
},
},
},
},
"summary": "Read Item Name",
"operationId": "read_item_name_items__item_id__name_get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
},
"/items/{item_id}/public": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
},
},
},
},
"summary": "Read Item Public Data",
"operationId": "read_item_public_data_items__item_id__public_get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
},
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": IsOneOf(
["name", "description", "price", "tax"],
# TODO: remove when deprecating Pydantic v1
["name", "price"],
),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": IsDict(
"summary": "Read Item Name",
"operationId": "read_item_name_items__item_id__name_get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
},
"/items/{item_id}/public": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"summary": "Read Item Public Data",
"operationId": "read_item_public_data_items__item_id__public_get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
},
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"tax": {"title": "Tax", "type": "number", "default": 10.5},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
"tax": {"title": "Tax", "type": "number", "default": 10.5},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
},
}
},
}
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
},
}
},
}
)

View File

@@ -1,8 +1,8 @@
import importlib
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py310
@@ -40,132 +40,126 @@ def test_read_item_public_data(client: TestClient):
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}/name": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/{item_id}/name": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
}
},
},
},
},
"summary": "Read Item Name",
"operationId": "read_item_name_items__item_id__name_get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
},
"/items/{item_id}/public": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
},
},
},
},
"summary": "Read Item Public Data",
"operationId": "read_item_public_data_items__item_id__public_get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
},
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": IsOneOf(
["name", "description", "price", "tax"],
# TODO: remove when deprecating Pydantic v1
["name", "price"],
),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": IsDict(
"summary": "Read Item Name",
"operationId": "read_item_name_items__item_id__name_get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
},
"/items/{item_id}/public": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"summary": "Read Item Public Data",
"operationId": "read_item_public_data_items__item_id__public_get",
"parameters": [
{
"required": True,
"schema": {"title": "Item Id", "type": "string"},
"name": "item_id",
"in": "path",
}
],
}
},
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"tax": {"title": "Tax", "type": "number", "default": 10.5},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
"tax": {"title": "Tax", "type": "number", "default": 10.5},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
},
}
},
}
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
},
}
},
}
)

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -58,46 +57,22 @@ def test_openapi_schema(client: TestClient):
"requestBody": {
"content": {
"application/json": {
"schema": IsDict(
{
"$ref": "#/components/schemas/Item",
"examples": [
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
{"name": "Bar", "price": "35.4"},
{
"name": "Baz",
"price": "thirty five point four",
},
],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"allOf": [
{"$ref": "#/components/schemas/Item"}
],
"title": "Item",
"examples": [
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
{"name": "Bar", "price": "35.4"},
{
"name": "Baz",
"price": "thirty five point four",
},
],
}
)
"schema": {
"$ref": "#/components/schemas/Item",
"examples": [
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
{"name": "Bar", "price": "35.4"},
{
"name": "Baz",
"price": "thirty five point four",
},
],
}
}
},
"required": True,
@@ -140,27 +115,15 @@ def test_openapi_schema(client: TestClient):
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"description": IsDict(
{
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
"price": {"title": "Price", "type": "number"},
"tax": IsDict(
{
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Tax", "type": "number"}
),
"tax": {
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
},
},
},
"ValidationError": {

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -58,16 +57,7 @@ def test_openapi_schema(client: TestClient) -> None:
"requestBody": {
"content": {
"application/json": {
"schema": IsDict({"$ref": "#/components/schemas/Item"})
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"allOf": [
{"$ref": "#/components/schemas/Item"}
],
"title": "Item",
}
),
"schema": {"$ref": "#/components/schemas/Item"},
"examples": {
"normal": {
"summary": "A normal example",
@@ -134,27 +124,15 @@ def test_openapi_schema(client: TestClient) -> None:
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"description": IsDict(
{
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Description", "type": "string"}
),
"description": {
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
"price": {"title": "Price", "type": "number"},
"tax": IsDict(
{
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Tax", "type": "number"}
),
"tax": {
"title": "Tax",
"anyOf": [{"type": "number"}, {"type": "null"}],
},
},
},
"ValidationError": {

View File

@@ -1,7 +1,6 @@
import importlib
import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
from ...utils import needs_py310
@@ -144,23 +143,13 @@ def test_openapi_schema(client: TestClient):
"required": ["username", "password"],
"type": "object",
"properties": {
"grant_type": IsDict(
{
"title": "Grant Type",
"anyOf": [
{"pattern": "^password$", "type": "string"},
{"type": "null"},
],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Grant Type",
"pattern": "^password$",
"type": "string",
}
),
"grant_type": {
"title": "Grant Type",
"anyOf": [
{"pattern": "^password$", "type": "string"},
{"type": "null"},
],
},
"username": {"title": "Username", "type": "string"},
"password": {
"title": "Password",
@@ -168,31 +157,15 @@ def test_openapi_schema(client: TestClient):
"format": "password",
},
"scope": {"title": "Scope", "type": "string", "default": ""},
"client_id": IsDict(
{
"title": "Client Id",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Client Id", "type": "string"}
),
"client_secret": IsDict(
{
"title": "Client Secret",
"anyOf": [{"type": "string"}, {"type": "null"}],
"format": "password",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Client Secret",
"type": "string",
"format": "password",
}
),
"client_id": {
"title": "Client Id",
"anyOf": [{"type": "string"}, {"type": "null"}],
},
"client_secret": {
"title": "Client Secret",
"anyOf": [{"type": "string"}, {"type": "null"}],
"format": "password",
},
},
},
"ValidationError": {

View File

@@ -2,8 +2,8 @@ import importlib
from types import ModuleType
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py310
@@ -215,240 +215,200 @@ def test_openapi_schema(mod: ModuleType):
client = TestClient(mod.app)
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/token": {
"post": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Token"}
}
assert response.json() == snapshot(
{
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/token": {
"post": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Token"}
}
},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"422": {
"description": "Validation Error",
"summary": "Login For Access Token",
"operationId": "login_for_access_token_token_post",
"requestBody": {
"content": {
"application/json": {
"application/x-www-form-urlencoded": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
"$ref": "#/components/schemas/Body_login_for_access_token_token_post"
}
}
},
"required": True,
},
},
"summary": "Login For Access Token",
"operationId": "login_for_access_token_token_post",
"requestBody": {
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"$ref": "#/components/schemas/Body_login_for_access_token_token_post"
}
}
},
"/users/me/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/User"}
}
},
}
},
"required": True,
},
}
"summary": "Read Users Me",
"operationId": "read_users_me_users_me__get",
"security": [{"OAuth2PasswordBearer": ["me"]}],
}
},
"/users/me/items/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read Own Items",
"operationId": "read_own_items_users_me_items__get",
"security": [{"OAuth2PasswordBearer": ["items", "me"]}],
}
},
"/status/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read System Status",
"operationId": "read_system_status_status__get",
"security": [{"OAuth2PasswordBearer": []}],
}
},
},
"/users/me/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/User"}
}
},
}
},
"summary": "Read Users Me",
"operationId": "read_users_me_users_me__get",
"security": [{"OAuth2PasswordBearer": ["me"]}],
}
},
"/users/me/items/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read Own Items",
"operationId": "read_own_items_users_me_items__get",
"security": [{"OAuth2PasswordBearer": ["items", "me"]}],
}
},
"/status/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read System Status",
"operationId": "read_system_status_status__get",
"security": [{"OAuth2PasswordBearer": []}],
}
},
},
"components": {
"schemas": {
"User": {
"title": "User",
"required": IsOneOf(
["username", "email", "full_name", "disabled"],
# TODO: remove when deprecating Pydantic v1
["username"],
),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"email": IsDict(
{
"components": {
"schemas": {
"User": {
"title": "User",
"required": ["username"],
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
"email": {
"title": "Email",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Email", "type": "string"}
),
"full_name": IsDict(
{
},
"full_name": {
"title": "Full Name",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Full Name", "type": "string"}
),
"disabled": IsDict(
{
},
"disabled": {
"title": "Disabled",
"anyOf": [{"type": "boolean"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Disabled", "type": "boolean"}
),
},
},
},
},
"Token": {
"title": "Token",
"required": ["access_token", "token_type"],
"type": "object",
"properties": {
"access_token": {"title": "Access Token", "type": "string"},
"token_type": {"title": "Token Type", "type": "string"},
"Token": {
"title": "Token",
"required": ["access_token", "token_type"],
"type": "object",
"properties": {
"access_token": {"title": "Access Token", "type": "string"},
"token_type": {"title": "Token Type", "type": "string"},
},
},
},
"Body_login_for_access_token_token_post": {
"title": "Body_login_for_access_token_token_post",
"required": ["username", "password"],
"type": "object",
"properties": {
"grant_type": IsDict(
{
"Body_login_for_access_token_token_post": {
"title": "Body_login_for_access_token_token_post",
"required": ["username", "password"],
"type": "object",
"properties": {
"grant_type": {
"title": "Grant Type",
"anyOf": [
{"pattern": "^password$", "type": "string"},
{"type": "null"},
],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Grant Type",
"pattern": "^password$",
},
"username": {"title": "Username", "type": "string"},
"password": {
"title": "Password",
"type": "string",
}
),
"username": {"title": "Username", "type": "string"},
"password": {
"title": "Password",
"type": "string",
"format": "password",
},
"scope": {"title": "Scope", "type": "string", "default": ""},
"client_id": IsDict(
{
"format": "password",
},
"scope": {
"title": "Scope",
"type": "string",
"default": "",
},
"client_id": {
"title": "Client Id",
"anyOf": [{"type": "string"}, {"type": "null"}],
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{"title": "Client Id", "type": "string"}
),
"client_secret": IsDict(
{
},
"client_secret": {
"title": "Client Secret",
"anyOf": [{"type": "string"}, {"type": "null"}],
"format": "password",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"title": "Client Secret",
"type": "string",
"format": "password",
}
),
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
},
"securitySchemes": {
"OAuth2PasswordBearer": {
"type": "oauth2",
"flows": {
"password": {
"scopes": {
"me": "Read information about the current user.",
"items": "Read items.",
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"tokenUrl": "token",
}
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
}
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
},
},
"securitySchemes": {
"OAuth2PasswordBearer": {
"type": "oauth2",
"flows": {
"password": {
"scopes": {
"me": "Read information about the current user.",
"items": "Read items.",
},
"tokenUrl": "token",
}
},
}
},
},
},
}
}
)

View File

@@ -2,7 +2,7 @@ import importlib
import warnings
import pytest
from dirty_equals import IsDict, IsInt
from dirty_equals import IsInt
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from sqlalchemy import StaticPool
@@ -318,33 +318,15 @@ def test_openapi_schema(client: TestClient):
},
"Hero": {
"properties": {
"id": IsDict(
{
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Id",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "integer",
"title": "Id",
}
),
"id": {
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Id",
},
"name": {"type": "string", "title": "Name"},
"age": IsDict(
{
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Age",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "integer",
"title": "Age",
}
),
"age": {
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Age",
},
"secret_name": {"type": "string", "title": "Secret Name"},
},
"type": "object",

View File

@@ -2,7 +2,7 @@ import importlib
import warnings
import pytest
from dirty_equals import IsDict, IsInt
from dirty_equals import IsInt
from fastapi.testclient import TestClient
from inline_snapshot import Is, snapshot
from sqlalchemy import StaticPool
@@ -373,19 +373,10 @@ def test_openapi_schema(client: TestClient):
"HeroCreate": {
"properties": {
"name": {"type": "string", "title": "Name"},
"age": IsDict(
{
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Age",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "integer",
"title": "Age",
}
),
"age": {
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Age",
},
"secret_name": {"type": "string", "title": "Secret Name"},
},
"type": "object",
@@ -395,19 +386,10 @@ def test_openapi_schema(client: TestClient):
"HeroPublic": {
"properties": {
"name": {"type": "string", "title": "Name"},
"age": IsDict(
{
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Age",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "integer",
"title": "Age",
}
),
"age": {
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Age",
},
"id": {"type": "integer", "title": "Id"},
},
"type": "object",
@@ -416,45 +398,18 @@ def test_openapi_schema(client: TestClient):
},
"HeroUpdate": {
"properties": {
"name": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Name",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "Name",
}
),
"age": IsDict(
{
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Age",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "integer",
"title": "Age",
}
),
"secret_name": IsDict(
{
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Secret Name",
}
)
| IsDict(
# TODO: remove when deprecating Pydantic v1
{
"type": "string",
"title": "Secret Name",
}
),
"name": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Name",
},
"age": {
"anyOf": [{"type": "integer"}, {"type": "null"}],
"title": "Age",
},
"secret_name": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Secret Name",
},
},
"type": "object",
"title": "HeroUpdate",