Coverage for tests/test_computed_fields.py: 100%
37 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-12-04 08:29 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-12-04 08:29 +0000
1import pytest 1abcdefg
2from fastapi import FastAPI 1abcdefg
3from fastapi.testclient import TestClient 1abcdefg
5from .utils import needs_pydanticv2 1abcdefg
8@pytest.fixture(name="client") 1abcdefg
9def get_client(request): 1abcdefg
10 separate_input_output_schemas = request.param 1abcdefg
11 app = FastAPI(separate_input_output_schemas=separate_input_output_schemas) 1abcdefg
13 from pydantic import BaseModel, computed_field 1abcdefg
15 class Rectangle(BaseModel): 1abcdefg
16 width: int 1abcdefg
17 length: int 1abcdefg
19 @computed_field 1abcdefg
20 @property 1abcdefg
21 def area(self) -> int: 1abcdefg
22 return self.width * self.length 1hijklmn
24 @app.get("/") 1abcdefg
25 def read_root() -> Rectangle: 1abcdefg
26 return Rectangle(width=3, length=4) 1hijklmn
28 @app.get("/responses", responses={200: {"model": Rectangle}}) 1abcdefg
29 def read_responses() -> Rectangle: 1abcdefg
30 return Rectangle(width=3, length=4) 1hijklmn
32 client = TestClient(app) 1abcdefg
33 return client 1abcdefg
36@pytest.mark.parametrize("client", [True, False], indirect=True) 1abcdefg
37@pytest.mark.parametrize("path", ["/", "/responses"]) 1abcdefg
38@needs_pydanticv2 1abcdefg
39def test_get(client: TestClient, path: str): 1abcdefg
40 response = client.get(path) 1hijklmn
41 assert response.status_code == 200, response.text 1hijklmn
42 assert response.json() == {"width": 3, "length": 4, "area": 12} 1hijklmn
45@pytest.mark.parametrize("client", [True, False], indirect=True) 1abcdefg
46@needs_pydanticv2 1abcdefg
47def test_openapi_schema(client: TestClient): 1abcdefg
48 response = client.get("/openapi.json") 1opqrstu
49 assert response.status_code == 200, response.text 1opqrstu
50 assert response.json() == { 1opqrstu
51 "openapi": "3.1.0",
52 "info": {"title": "FastAPI", "version": "0.1.0"},
53 "paths": {
54 "/": {
55 "get": {
56 "summary": "Read Root",
57 "operationId": "read_root__get",
58 "responses": {
59 "200": {
60 "description": "Successful Response",
61 "content": {
62 "application/json": {
63 "schema": {"$ref": "#/components/schemas/Rectangle"}
64 }
65 },
66 }
67 },
68 }
69 },
70 "/responses": {
71 "get": {
72 "summary": "Read Responses",
73 "operationId": "read_responses_responses_get",
74 "responses": {
75 "200": {
76 "description": "Successful Response",
77 "content": {
78 "application/json": {
79 "schema": {"$ref": "#/components/schemas/Rectangle"}
80 }
81 },
82 }
83 },
84 }
85 },
86 },
87 "components": {
88 "schemas": {
89 "Rectangle": {
90 "properties": {
91 "width": {"type": "integer", "title": "Width"},
92 "length": {"type": "integer", "title": "Length"},
93 "area": {"type": "integer", "title": "Area", "readOnly": True},
94 },
95 "type": "object",
96 "required": ["width", "length", "area"],
97 "title": "Rectangle",
98 }
99 }
100 },
101 }