Coverage for tests / test_multi_body_errors.py: 100%
30 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-12 18:15 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-12 18:15 +0000
1from decimal import Decimal 1abcd
3from dirty_equals import IsOneOf 1abcd
4from fastapi import FastAPI 1abcd
5from fastapi.testclient import TestClient 1abcd
6from inline_snapshot import snapshot 1abcd
7from pydantic import BaseModel, condecimal 1abcd
9app = FastAPI() 1abcd
12class Item(BaseModel): 1abcd
13 name: str 1abcd
14 age: condecimal(gt=Decimal(0.0)) # type: ignore 1abcd
17@app.post("/items/") 1abcd
18def save_item_no_body(item: list[Item]): 1abcd
19 return {"item": item} 1efg
22client = TestClient(app) 1abcd
25def test_put_correct_body(): 1abcd
26 response = client.post("/items/", json=[{"name": "Foo", "age": 5}]) 1efg
27 assert response.status_code == 200, response.text 1efg
28 assert response.json() == snapshot( 1efg
29 {
30 "item": [
31 {
32 "name": "Foo",
33 "age": "5",
34 }
35 ]
36 }
37 )
40def test_jsonable_encoder_requiring_error(): 1abcd
41 response = client.post("/items/", json=[{"name": "Foo", "age": -1.0}]) 1hij
42 assert response.status_code == 422, response.text 1hij
43 assert response.json() == { 1hij
44 "detail": [
45 {
46 "type": "greater_than",
47 "loc": ["body", 0, "age"],
48 "msg": "Input should be greater than 0",
49 "input": -1.0,
50 "ctx": {"gt": 0},
51 }
52 ]
53 }
56def test_put_incorrect_body_multiple(): 1abcd
57 response = client.post("/items/", json=[{"age": "five"}, {"age": "six"}]) 1klm
58 assert response.status_code == 422, response.text 1klm
59 assert response.json() == { 1klm
60 "detail": [
61 {
62 "type": "missing",
63 "loc": ["body", 0, "name"],
64 "msg": "Field required",
65 "input": {"age": "five"},
66 },
67 {
68 "type": "decimal_parsing",
69 "loc": ["body", 0, "age"],
70 "msg": "Input should be a valid decimal",
71 "input": "five",
72 },
73 {
74 "type": "missing",
75 "loc": ["body", 1, "name"],
76 "msg": "Field required",
77 "input": {"age": "six"},
78 },
79 {
80 "type": "decimal_parsing",
81 "loc": ["body", 1, "age"],
82 "msg": "Input should be a valid decimal",
83 "input": "six",
84 },
85 ]
86 }
89def test_openapi_schema(): 1abcd
90 response = client.get("/openapi.json") 1nop
91 assert response.status_code == 200, response.text 1nop
92 assert response.json() == snapshot( 1nop
93 {
94 "openapi": "3.1.0",
95 "info": {"title": "FastAPI", "version": "0.1.0"},
96 "paths": {
97 "/items/": {
98 "post": {
99 "responses": {
100 "200": {
101 "description": "Successful Response",
102 "content": {"application/json": {"schema": {}}},
103 },
104 "422": {
105 "description": "Validation Error",
106 "content": {
107 "application/json": {
108 "schema": {
109 "$ref": "#/components/schemas/HTTPValidationError"
110 }
111 }
112 },
113 },
114 },
115 "summary": "Save Item No Body",
116 "operationId": "save_item_no_body_items__post",
117 "requestBody": {
118 "content": {
119 "application/json": {
120 "schema": {
121 "title": "Item",
122 "type": "array",
123 "items": {"$ref": "#/components/schemas/Item"},
124 }
125 }
126 },
127 "required": True,
128 },
129 }
130 }
131 },
132 "components": {
133 "schemas": {
134 "Item": {
135 "title": "Item",
136 "required": ["name", "age"],
137 "type": "object",
138 "properties": {
139 "name": {"title": "Name", "type": "string"},
140 "age": {
141 "title": "Age",
142 "anyOf": [
143 {"exclusiveMinimum": 0.0, "type": "number"},
144 IsOneOf(
145 # pydantic < 2.12.0
146 {"type": "string"},
147 # pydantic >= 2.12.0
148 {
149 "type": "string",
150 "pattern": r"^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$",
151 },
152 ),
153 ],
154 },
155 },
156 },
157 "ValidationError": {
158 "title": "ValidationError",
159 "required": ["loc", "msg", "type"],
160 "type": "object",
161 "properties": {
162 "loc": {
163 "title": "Location",
164 "type": "array",
165 "items": {
166 "anyOf": [{"type": "string"}, {"type": "integer"}]
167 },
168 },
169 "msg": {"title": "Message", "type": "string"},
170 "type": {"title": "Error Type", "type": "string"},
171 "input": {"title": "Input"},
172 "ctx": {"title": "Context", "type": "object"},
173 },
174 },
175 "HTTPValidationError": {
176 "title": "HTTPValidationError",
177 "type": "object",
178 "properties": {
179 "detail": {
180 "title": "Detail",
181 "type": "array",
182 "items": {
183 "$ref": "#/components/schemas/ValidationError"
184 },
185 }
186 },
187 },
188 }
189 },
190 }
191 )