Browse Source

Add tests for dicts in models in pydantic.v1 for coverage

pull/14575/head
Sebastián Ramírez 7 months ago
parent
commit
6a438d7882
  1. 8
      tests/test_filter_pydantic_sub_model/app_pv1.py
  2. 170
      tests/test_filter_pydantic_sub_model/test_filter_pydantic_sub_model_pv1.py
  3. 202
      tests/test_filter_pydantic_sub_model_pv2.py

8
tests/test_filter_pydantic_sub_model/app_pv1.py

@ -18,6 +18,7 @@ class ModelA(BaseModel):
name: str name: str
description: Optional[str] = None description: Optional[str] = None
model_b: ModelB model_b: ModelB
tags: dict[str, str] = {}
@validator("name") @validator("name")
def lower_username(cls, name: str, values): def lower_username(cls, name: str, values):
@ -32,4 +33,9 @@ async def get_model_c() -> ModelC:
@app.get("/model/{name}", response_model=ModelA) @app.get("/model/{name}", response_model=ModelA)
async def get_model_a(name: str, model_c=Depends(get_model_c)): async def get_model_a(name: str, model_c=Depends(get_model_c)):
return {"name": name, "description": "model-a-desc", "model_b": model_c} return {
"name": name,
"description": "model-a-desc",
"model_b": model_c,
"tags": {"key1": "value1", "key2": "value2"},
}

170
tests/test_filter_pydantic_sub_model/test_filter_pydantic_sub_model_pv1.py

@ -1,6 +1,7 @@
import pytest import pytest
from fastapi.exceptions import ResponseValidationError from fastapi.exceptions import ResponseValidationError
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ..utils import needs_pydanticv1 from ..utils import needs_pydanticv1
@ -21,6 +22,7 @@ def test_filter_sub_model(client: TestClient):
"name": "modelA", "name": "modelA",
"description": "model-a-desc", "description": "model-a-desc",
"model_b": {"username": "test-user"}, "model_b": {"username": "test-user"},
"tags": {"key1": "value1", "key2": "value2"},
} }
@ -41,90 +43,104 @@ def test_validator_is_cloned(client: TestClient):
def test_openapi_schema(client: TestClient): def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json") response = client.get("/openapi.json")
assert response.status_code == 200, response.text assert response.status_code == 200, response.text
assert response.json() == { assert response.json() == snapshot(
"openapi": "3.1.0", {
"info": {"title": "FastAPI", "version": "0.1.0"}, "openapi": "3.1.0",
"paths": { "info": {"title": "FastAPI", "version": "0.1.0"},
"/model/{name}": { "paths": {
"get": { "/model/{name}": {
"summary": "Get Model A", "get": {
"operationId": "get_model_a_model__name__get", "summary": "Get Model A",
"parameters": [ "operationId": "get_model_a_model__name__get",
{ "parameters": [
"required": True, {
"schema": {"title": "Name", "type": "string"}, "required": True,
"name": "name", "schema": {"title": "Name", "type": "string"},
"in": "path", "name": "name",
} "in": "path",
], }
"responses": { ],
"200": { "responses": {
"description": "Successful Response", "200": {
"content": { "description": "Successful Response",
"application/json": { "content": {
"schema": {"$ref": "#/components/schemas/ModelA"} "application/json": {
} "schema": {
"$ref": "#/components/schemas/ModelA"
}
}
},
}, },
}, "422": {
"422": { "description": "Validation Error",
"description": "Validation Error", "content": {
"content": { "application/json": {
"application/json": { "schema": {
"schema": { "$ref": "#/components/schemas/HTTPValidationError"
"$ref": "#/components/schemas/HTTPValidationError" }
} }
} },
}, },
}, },
}, }
} }
} },
}, "components": {
"components": { "schemas": {
"schemas": { "HTTPValidationError": {
"HTTPValidationError": { "title": "HTTPValidationError",
"title": "HTTPValidationError", "type": "object",
"type": "object", "properties": {
"properties": { "detail": {
"detail": { "title": "Detail",
"title": "Detail", "type": "array",
"type": "array", "items": {
"items": {"$ref": "#/components/schemas/ValidationError"}, "$ref": "#/components/schemas/ValidationError"
} },
}
},
}, },
}, "ModelA": {
"ModelA": { "title": "ModelA",
"title": "ModelA", "required": ["name", "model_b"],
"required": ["name", "model_b"], "type": "object",
"type": "object", "properties": {
"properties": { "name": {"title": "Name", "type": "string"},
"name": {"title": "Name", "type": "string"}, "description": {"title": "Description", "type": "string"},
"description": {"title": "Description", "type": "string"}, "model_b": {"$ref": "#/components/schemas/ModelB"},
"model_b": {"$ref": "#/components/schemas/ModelB"}, "tags": {
"additionalProperties": {"type": "string"},
"type": "object",
"title": "Tags",
"default": {},
},
},
},
"ModelB": {
"title": "ModelB",
"required": ["username"],
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"}
},
}, },
}, "ValidationError": {
"ModelB": { "title": "ValidationError",
"title": "ModelB", "required": ["loc", "msg", "type"],
"required": ["username"], "type": "object",
"type": "object", "properties": {
"properties": {"username": {"title": "Username", "type": "string"}}, "loc": {
}, "title": "Location",
"ValidationError": { "type": "array",
"title": "ValidationError", "items": {
"required": ["loc", "msg", "type"], "anyOf": [{"type": "string"}, {"type": "integer"}]
"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"},
}, },
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
}, },
}, }
} },
}, }
} )

202
tests/test_filter_pydantic_sub_model_pv2.py

@ -5,6 +5,7 @@ from dirty_equals import HasRepr, IsDict, IsOneOf
from fastapi import Depends, FastAPI from fastapi import Depends, FastAPI
from fastapi.exceptions import ResponseValidationError from fastapi.exceptions import ResponseValidationError
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from inline_snapshot import snapshot
@pytest.fixture(name="client") @pytest.fixture(name="client")
@ -23,6 +24,7 @@ def get_client():
name: str name: str
description: Optional[str] = None description: Optional[str] = None
foo: ModelB foo: ModelB
tags: dict[str, str] = {}
@field_validator("name") @field_validator("name")
def lower_username(cls, name: str, info: ValidationInfo): def lower_username(cls, name: str, info: ValidationInfo):
@ -35,7 +37,12 @@ def get_client():
@app.get("/model/{name}", response_model=ModelA) @app.get("/model/{name}", response_model=ModelA)
async def get_model_a(name: str, model_c=Depends(get_model_c)): async def get_model_a(name: str, model_c=Depends(get_model_c)):
return {"name": name, "description": "model-a-desc", "foo": model_c} return {
"name": name,
"description": "model-a-desc",
"foo": model_c,
"tags": {"key1": "value1", "key2": "value2"},
}
client = TestClient(app) client = TestClient(app)
return client return client
@ -48,6 +55,7 @@ def test_filter_sub_model(client: TestClient):
"name": "modelA", "name": "modelA",
"description": "model-a-desc", "description": "model-a-desc",
"foo": {"username": "test-user"}, "foo": {"username": "test-user"},
"tags": {"key1": "value1", "key2": "value2"},
} }
@ -78,102 +86,116 @@ def test_validator_is_cloned(client: TestClient):
def test_openapi_schema(client: TestClient): def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json") response = client.get("/openapi.json")
assert response.status_code == 200, response.text assert response.status_code == 200, response.text
assert response.json() == { assert response.json() == snapshot(
"openapi": "3.1.0", {
"info": {"title": "FastAPI", "version": "0.1.0"}, "openapi": "3.1.0",
"paths": { "info": {"title": "FastAPI", "version": "0.1.0"},
"/model/{name}": { "paths": {
"get": { "/model/{name}": {
"summary": "Get Model A", "get": {
"operationId": "get_model_a_model__name__get", "summary": "Get Model A",
"parameters": [ "operationId": "get_model_a_model__name__get",
{ "parameters": [
"required": True, {
"schema": {"title": "Name", "type": "string"}, "required": True,
"name": "name", "schema": {"title": "Name", "type": "string"},
"in": "path", "name": "name",
} "in": "path",
], }
"responses": { ],
"200": { "responses": {
"description": "Successful Response", "200": {
"content": { "description": "Successful Response",
"application/json": { "content": {
"schema": {"$ref": "#/components/schemas/ModelA"} "application/json": {
} "schema": {
"$ref": "#/components/schemas/ModelA"
}
}
},
}, },
}, "422": {
"422": { "description": "Validation Error",
"description": "Validation Error", "content": {
"content": { "application/json": {
"application/json": { "schema": {
"schema": { "$ref": "#/components/schemas/HTTPValidationError"
"$ref": "#/components/schemas/HTTPValidationError" }
} }
} },
}, },
}, },
}, }
} }
} },
}, "components": {
"components": { "schemas": {
"schemas": { "HTTPValidationError": {
"HTTPValidationError": { "title": "HTTPValidationError",
"title": "HTTPValidationError", "type": "object",
"type": "object", "properties": {
"properties": { "detail": {
"detail": { "title": "Detail",
"title": "Detail", "type": "array",
"type": "array", "items": {
"items": {"$ref": "#/components/schemas/ValidationError"}, "$ref": "#/components/schemas/ValidationError"
} },
},
},
"ModelA": {
"title": "ModelA",
"required": IsOneOf(
["name", "description", "foo"],
# TODO remove when deprecating Pydantic v1
["name", "foo"],
),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"description": IsDict(
{
"title": "Description",
"anyOf": [{"type": "string"}, {"type": "null"}],
} }
) },
|
# TODO remove when deprecating Pydantic v1
IsDict({"title": "Description", "type": "string"}),
"foo": {"$ref": "#/components/schemas/ModelB"},
}, },
}, "ModelA": {
"ModelB": { "title": "ModelA",
"title": "ModelB", "required": IsOneOf(
"required": ["username"], ["name", "description", "foo"],
"type": "object", # TODO remove when deprecating Pydantic v1
"properties": {"username": {"title": "Username", "type": "string"}}, ["name", "foo"],
}, ),
"ValidationError": { "type": "object",
"title": "ValidationError", "properties": {
"required": ["loc", "msg", "type"], "name": {"title": "Name", "type": "string"},
"type": "object", "description": IsDict(
"properties": { {
"loc": { "title": "Description",
"title": "Location", "anyOf": [{"type": "string"}, {"type": "null"}],
"type": "array", }
"items": { )
"anyOf": [{"type": "string"}, {"type": "integer"}] |
# TODO remove when deprecating Pydantic v1
IsDict({"title": "Description", "type": "string"}),
"foo": {"$ref": "#/components/schemas/ModelB"},
"tags": {
"additionalProperties": {"type": "string"},
"type": "object",
"title": "Tags",
"default": {},
}, },
}, },
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
}, },
}, "ModelB": {
} "title": "ModelB",
}, "required": ["username"],
} "type": "object",
"properties": {
"username": {"title": "Username", "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"},
},
},
}
},
}
)

Loading…
Cancel
Save