Coverage for tests / test_request_params / test_body / test_required_str.py: 100%
136 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-04-06 01:24 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-04-06 01:24 +0000
1from typing import Annotated, Any 1adbc
3import pytest 1adbc
4from dirty_equals import IsOneOf 1adbc
5from fastapi import Body, FastAPI 1adbc
6from fastapi.testclient import TestClient 1adbc
7from pydantic import BaseModel, Field 1adbc
9from .utils import get_body_model_name 1adbc
11app = FastAPI() 1adbc
13# =====================================================================================
14# Without aliases
17@app.post("/required-str", operation_id="required_str") 1adbc
18async def read_required_str(p: Annotated[str, Body(embed=True)]): 1adbc
19 return {"p": p} 1efgh
22class BodyModelRequiredStr(BaseModel): 1adbc
23 p: str 1abc
26@app.post("/model-required-str", operation_id="model_required_str") 1adbc
27async def read_model_required_str(p: BodyModelRequiredStr): 1adbc
28 return {"p": p.p} 1ijkl
31@pytest.mark.parametrize( 1adbc
32 "path",
33 ["/required-str", "/model-required-str"],
34)
35def test_required_str_schema(path: str): 1adbc
36 openapi = app.openapi() 2JbKbLbMbNbObPbQb
37 body_model_name = get_body_model_name(openapi, path) 2JbKbLbMbNbObPbQb
39 assert app.openapi()["components"]["schemas"][body_model_name] == { 2JbKbLbMbNbObPbQb
40 "properties": {
41 "p": {"title": "P", "type": "string"},
42 },
43 "required": ["p"],
44 "title": body_model_name,
45 "type": "object",
46 }
49@pytest.mark.parametrize("json", [None, {}]) 1adbc
50@pytest.mark.parametrize( 1adbc
51 "path",
52 ["/required-str", "/model-required-str"],
53)
54def test_required_str_missing(path: str, json: dict[str, Any] | None): 1adbc
55 client = TestClient(app) 1KLMNOPQRSTUVWX
56 response = client.post(path, json=json) 1KLMNOPQRSTUVWX
57 assert response.status_code == 422 1KLMNOPQRSTUVWX
58 assert response.json() == { 1KLMNOPQRSTUVWX
59 "detail": [
60 {
61 "type": "missing",
62 "loc": IsOneOf(["body"], ["body", "p"]),
63 "msg": "Field required",
64 "input": IsOneOf(None, {}),
65 }
66 ]
67 }
70@pytest.mark.parametrize( 1adbc
71 "path",
72 ["/required-str", "/model-required-str"],
73)
74def test_required_str(path: str): 1adbc
75 client = TestClient(app) 1iejfkglh
76 response = client.post(path, json={"p": "hello"}) 1iejfkglh
77 assert response.status_code == 200 1iejfkglh
78 assert response.json() == {"p": "hello"} 1iejfkglh
81# =====================================================================================
82# Alias
85@app.post("/required-alias", operation_id="required_alias") 1adbc
86async def read_required_alias( 1adbc
87 p: Annotated[str, Body(embed=True, alias="p_alias")],
88):
89 return {"p": p} 1mnop
92class BodyModelRequiredAlias(BaseModel): 1adbc
93 p: str = Field(alias="p_alias") 1adbc
96@app.post("/model-required-alias", operation_id="model_required_alias") 1adbc
97async def read_model_required_alias(p: BodyModelRequiredAlias): 1adbc
98 return {"p": p.p} 1qrst
101@pytest.mark.parametrize( 1adbc
102 "path",
103 [
104 "/required-alias",
105 "/model-required-alias",
106 ],
107)
108def test_required_str_alias_schema(path: str): 1adbc
109 openapi = app.openapi() 2RbSbTbUbVbWbXbYb
110 body_model_name = get_body_model_name(openapi, path) 2RbSbTbUbVbWbXbYb
112 assert app.openapi()["components"]["schemas"][body_model_name] == { 2RbSbTbUbVbWbXbYb
113 "properties": {
114 "p_alias": {"title": "P Alias", "type": "string"},
115 },
116 "required": ["p_alias"],
117 "title": body_model_name,
118 "type": "object",
119 }
122@pytest.mark.parametrize("json", [None, {}]) 1adbc
123@pytest.mark.parametrize( 1adbc
124 "path",
125 ["/required-alias", "/model-required-alias"],
126)
127def test_required_alias_missing(path: str, json: dict[str, Any] | None): 1adbc
128 client = TestClient(app) 1YZ0123456789!#
129 response = client.post(path, json=json) 1YZ0123456789!#
130 assert response.status_code == 422 1YZ0123456789!#
131 assert response.json() == { 1YZ0123456789!#
132 "detail": [
133 {
134 "type": "missing",
135 "loc": IsOneOf(["body", "p_alias"], ["body"]),
136 "msg": "Field required",
137 "input": IsOneOf(None, {}),
138 }
139 ]
140 }
143@pytest.mark.parametrize( 1adbc
144 "path",
145 ["/required-alias", "/model-required-alias"],
146)
147def test_required_alias_by_name(path: str): 1adbc
148 client = TestClient(app) 1$%'()*+,
149 response = client.post(path, json={"p": "hello"}) 1$%'()*+,
150 assert response.status_code == 422 1$%'()*+,
151 assert response.json() == { 1$%'()*+,
152 "detail": [
153 {
154 "type": "missing",
155 "loc": ["body", "p_alias"],
156 "msg": "Field required",
157 "input": IsOneOf(None, {"p": "hello"}),
158 }
159 ]
160 }
163@pytest.mark.parametrize( 1adbc
164 "path",
165 ["/required-alias", "/model-required-alias"],
166)
167def test_required_alias_by_alias(path: str): 1adbc
168 client = TestClient(app) 1qmrnsotp
169 response = client.post(path, json={"p_alias": "hello"}) 1qmrnsotp
170 assert response.status_code == 200, response.text 1qmrnsotp
171 assert response.json() == {"p": "hello"} 1qmrnsotp
174# =====================================================================================
175# Validation alias
178@app.post("/required-validation-alias", operation_id="required_validation_alias") 1adbc
179def read_required_validation_alias( 1adbc
180 p: Annotated[str, Body(embed=True, validation_alias="p_val_alias")],
181):
182 return {"p": p} 1uvwx
185class BodyModelRequiredValidationAlias(BaseModel): 1adbc
186 p: str = Field(validation_alias="p_val_alias") 1adbc
189@app.post( 1adbc
190 "/model-required-validation-alias", operation_id="model_required_validation_alias"
191)
192def read_model_required_validation_alias( 1adbc
193 p: BodyModelRequiredValidationAlias,
194):
195 return {"p": p.p} 1yzAB
198@pytest.mark.parametrize( 1adbc
199 "path",
200 ["/required-validation-alias", "/model-required-validation-alias"],
201)
202def test_required_validation_alias_schema(path: str): 1adbc
203 openapi = app.openapi() 2Zb0b1b2b3b4b5b6b
204 body_model_name = get_body_model_name(openapi, path) 2Zb0b1b2b3b4b5b6b
206 assert app.openapi()["components"]["schemas"][body_model_name] == { 2Zb0b1b2b3b4b5b6b
207 "properties": {
208 "p_val_alias": {"title": "P Val Alias", "type": "string"},
209 },
210 "required": ["p_val_alias"],
211 "title": body_model_name,
212 "type": "object",
213 }
216@pytest.mark.parametrize("json", [None, {}]) 1adbc
217@pytest.mark.parametrize( 1adbc
218 "path",
219 [
220 "/required-validation-alias",
221 "/model-required-validation-alias",
222 ],
223)
224def test_required_validation_alias_missing(path: str, json: dict[str, Any] | None): 1adbc
225 client = TestClient(app) 1-./:;=?@[]^_`{
226 response = client.post(path, json=json) 1-./:;=?@[]^_`{
227 assert response.status_code == 422 1-./:;=?@[]^_`{
228 assert response.json() == { 1-./:;=?@[]^_`{
229 "detail": [
230 {
231 "type": "missing",
232 "loc": IsOneOf(["body", "p_val_alias"], ["body"]),
233 "msg": "Field required",
234 "input": IsOneOf(None, {}),
235 }
236 ]
237 }
240@pytest.mark.parametrize( 1adbc
241 "path",
242 [
243 "/required-validation-alias",
244 "/model-required-validation-alias",
245 ],
246)
247def test_required_validation_alias_by_name(path: str): 1adbc
248 client = TestClient(app) 2| } ~ abbbcbdbeb
249 response = client.post(path, json={"p": "hello"}) 2| } ~ abbbcbdbeb
250 assert response.status_code == 422, response.text 2| } ~ abbbcbdbeb
252 assert response.json() == { 2| } ~ abbbcbdbeb
253 "detail": [
254 {
255 "type": "missing",
256 "loc": ["body", "p_val_alias"],
257 "msg": "Field required",
258 "input": IsOneOf(None, {"p": "hello"}),
259 }
260 ]
261 }
264@pytest.mark.parametrize( 1adbc
265 "path",
266 [
267 "/required-validation-alias",
268 "/model-required-validation-alias",
269 ],
270)
271def test_required_validation_alias_by_validation_alias(path: str): 1adbc
272 client = TestClient(app) 1yuzvAwBx
273 response = client.post(path, json={"p_val_alias": "hello"}) 1yuzvAwBx
274 assert response.status_code == 200, response.text 1yuzvAwBx
276 assert response.json() == {"p": "hello"} 1yuzvAwBx
279# =====================================================================================
280# Alias and validation alias
283@app.post( 1adbc
284 "/required-alias-and-validation-alias",
285 operation_id="required_alias_and_validation_alias",
286)
287def read_required_alias_and_validation_alias( 1adbc
288 p: Annotated[
289 str, Body(embed=True, alias="p_alias", validation_alias="p_val_alias")
290 ],
291):
292 return {"p": p} 1CDEF
295class BodyModelRequiredAliasAndValidationAlias(BaseModel): 1adbc
296 p: str = Field(alias="p_alias", validation_alias="p_val_alias") 1adbc
299@app.post( 1adbc
300 "/model-required-alias-and-validation-alias",
301 operation_id="model_required_alias_and_validation_alias",
302)
303def read_model_required_alias_and_validation_alias( 1adbc
304 p: BodyModelRequiredAliasAndValidationAlias,
305):
306 return {"p": p.p} 1GHIJ
309@pytest.mark.parametrize( 1adbc
310 "path",
311 [
312 "/required-alias-and-validation-alias",
313 "/model-required-alias-and-validation-alias",
314 ],
315)
316def test_required_alias_and_validation_alias_schema(path: str): 1adbc
317 openapi = app.openapi() 27b8b9b!b#b$b%b'b
318 body_model_name = get_body_model_name(openapi, path) 27b8b9b!b#b$b%b'b
320 assert app.openapi()["components"]["schemas"][body_model_name] == { 27b8b9b!b#b$b%b'b
321 "properties": {
322 "p_val_alias": {"title": "P Val Alias", "type": "string"},
323 },
324 "required": ["p_val_alias"],
325 "title": body_model_name,
326 "type": "object",
327 }
330@pytest.mark.parametrize("json", [None, {}]) 1adbc
331@pytest.mark.parametrize( 1adbc
332 "path",
333 [
334 "/required-alias-and-validation-alias",
335 "/model-required-alias-and-validation-alias",
336 ],
337)
338def test_required_alias_and_validation_alias_missing( 1adbc
339 path: str, json: dict[str, Any] | None
340):
341 client = TestClient(app) 2fbgbhbibjbkblbmbnbobpbqbrbsb
342 response = client.post(path, json=json) 2fbgbhbibjbkblbmbnbobpbqbrbsb
343 assert response.status_code == 422 2fbgbhbibjbkblbmbnbobpbqbrbsb
344 assert response.json() == { 2fbgbhbibjbkblbmbnbobpbqbrbsb
345 "detail": [
346 {
347 "type": "missing",
348 "loc": IsOneOf(["body"], ["body", "p_val_alias"]),
349 "msg": "Field required",
350 "input": IsOneOf(None, {}),
351 }
352 ]
353 }
356@pytest.mark.parametrize( 1adbc
357 "path",
358 [
359 "/required-alias-and-validation-alias",
360 "/model-required-alias-and-validation-alias",
361 ],
362)
363def test_required_alias_and_validation_alias_by_name(path: str): 1adbc
364 client = TestClient(app) 2tbubvbwbxbybzbAb
365 response = client.post(path, json={"p": "hello"}) 2tbubvbwbxbybzbAb
366 assert response.status_code == 422 2tbubvbwbxbybzbAb
368 assert response.json() == { 2tbubvbwbxbybzbAb
369 "detail": [
370 {
371 "type": "missing",
372 "loc": [
373 "body",
374 "p_val_alias",
375 ],
376 "msg": "Field required",
377 "input": IsOneOf(None, {"p": "hello"}),
378 }
379 ]
380 }
383@pytest.mark.parametrize( 1adbc
384 "path",
385 [
386 "/required-alias-and-validation-alias",
387 "/model-required-alias-and-validation-alias",
388 ],
389)
390def test_required_alias_and_validation_alias_by_alias(path: str): 1adbc
391 client = TestClient(app) 2BbCbDbEbFbGbHbIb
392 response = client.post(path, json={"p_alias": "hello"}) 2BbCbDbEbFbGbHbIb
393 assert response.status_code == 422, response.text 2BbCbDbEbFbGbHbIb
395 assert response.json() == { 2BbCbDbEbFbGbHbIb
396 "detail": [
397 {
398 "type": "missing",
399 "loc": ["body", "p_val_alias"],
400 "msg": "Field required",
401 "input": IsOneOf(None, {"p_alias": "hello"}),
402 }
403 ]
404 }
407@pytest.mark.parametrize( 1adbc
408 "path",
409 [
410 "/required-alias-and-validation-alias",
411 "/model-required-alias-and-validation-alias",
412 ],
413)
414def test_required_alias_and_validation_alias_by_validation_alias(path: str): 1adbc
415 client = TestClient(app) 1GCHDIEJF
416 response = client.post(path, json={"p_val_alias": "hello"}) 1GCHDIEJF
417 assert response.status_code == 200, response.text 1GCHDIEJF
419 assert response.json() == {"p": "hello"} 1GCHDIEJF