Add test for nested model with computed field in response model

This commit is contained in:
Yurii Motov 2025-12-10 17:06:38 +01:00
parent 71a17b5932
commit 0ee8db931f
1 changed files with 234 additions and 0 deletions

View File

@ -0,0 +1,234 @@
from typing import List
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
from .utils import needs_pydanticv2
@pytest.fixture(name="client")
def get_client():
from pydantic import computed_field
class MyModel(BaseModel):
id: int
name: str
age: int
@computed_field
@property
def is_adult(self) -> bool:
return self.age >= 18
app = FastAPI(separate_input_output_schemas=False)
@app.get("/item")
def get_item() -> MyModel:
return MyModel(id=1, name="Alice", age=30)
@app.get("/list")
def get_items() -> List[MyModel]:
return [MyModel(id=1, name="Alice", age=30), MyModel(id=2, name="Bob", age=17)]
@app.post("/item")
def create_item(item: MyModel) -> MyModel:
return item
yield TestClient(app)
@needs_pydanticv2
def test_openapi(client: TestClient):
response = client.get("/openapi.json")
openapi_schema = response.json()
expected_schema = {
"info": {
"title": "FastAPI",
"version": "0.1.0",
},
"openapi": "3.1.0",
"paths": {
"/item": {
"get": {
"operationId": "get_item_item_get",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MyModel-Output",
},
},
},
"description": "Successful Response",
},
},
"summary": "Get Item",
},
"post": {
"operationId": "create_item_item_post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MyModel-Input",
},
},
},
"required": True,
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MyModel-Output",
},
},
},
"description": "Successful Response",
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError",
},
},
},
"description": "Validation Error",
},
},
"summary": "Create Item",
},
},
"/list": {
"get": {
"operationId": "get_items_list_get",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/MyModel-Output",
},
"title": "Response Get Items List Get",
"type": "array",
},
},
},
"description": "Successful Response",
},
},
"summary": "Get Items",
},
},
},
"components": {
"schemas": {
"HTTPValidationError": {
"properties": {
"detail": {
"items": {
"$ref": "#/components/schemas/ValidationError",
},
"title": "Detail",
"type": "array",
},
},
"title": "HTTPValidationError",
"type": "object",
},
"MyModel-Input": {
"properties": {
"age": {
"title": "Age",
"type": "integer",
},
"id": {
"title": "Id",
"type": "integer",
},
"name": {
"title": "Name",
"type": "string",
},
},
"required": [
"id",
"name",
"age",
],
"title": "MyModel",
"type": "object",
},
"MyModel-Output": {
"properties": {
"age": {
"title": "Age",
"type": "integer",
},
"id": {
"title": "Id",
"type": "integer",
},
"is_adult": {
"readOnly": True,
"title": "Is Adult",
"type": "boolean",
},
"name": {
"title": "Name",
"type": "string",
},
},
"required": [
"id",
"name",
"age",
"is_adult",
],
"title": "MyModel",
"type": "object",
},
"ValidationError": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string",
},
{
"type": "integer",
},
],
},
"title": "Location",
"type": "array",
},
"msg": {
"title": "Message",
"type": "string",
},
"type": {
"title": "Error Type",
"type": "string",
},
},
"required": [
"loc",
"msg",
"type",
],
"title": "ValidationError",
"type": "object",
},
},
},
}
assert openapi_schema == expected_schema