Coverage for tests / test_request_params / test_form / test_required_str.py: 100%
132 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 1adbc
3import pytest 1adbc
4from dirty_equals import IsOneOf 1adbc
5from fastapi import FastAPI, Form 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, Form()]): 1adbc
19 return {"p": p} 1efgh
22class FormModelRequiredStr(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: Annotated[FormModelRequiredStr, Form()]): 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() 2kblbmbnbobpbqbrb
37 body_model_name = get_body_model_name(openapi, path) 2kblbmbnbobpbqbrb
39 assert app.openapi()["components"]["schemas"][body_model_name] == { 2kblbmbnbobpbqbrb
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( 1adbc
50 "path",
51 ["/required-str", "/model-required-str"],
52)
53def test_required_str_missing(path: str): 1adbc
54 client = TestClient(app) 1KLMNOPQR
55 response = client.post(path) 1KLMNOPQR
56 assert response.status_code == 422 1KLMNOPQR
57 assert response.json() == { 1KLMNOPQR
58 "detail": [
59 {
60 "type": "missing",
61 "loc": ["body", "p"],
62 "msg": "Field required",
63 "input": IsOneOf(None, {}),
64 }
65 ]
66 }
69@pytest.mark.parametrize( 1adbc
70 "path",
71 ["/required-str", "/model-required-str"],
72)
73def test_required_str(path: str): 1adbc
74 client = TestClient(app) 1iejfkglh
75 response = client.post(path, data={"p": "hello"}) 1iejfkglh
76 assert response.status_code == 200 1iejfkglh
77 assert response.json() == {"p": "hello"} 1iejfkglh
80# =====================================================================================
81# Alias
84@app.post("/required-alias", operation_id="required_alias") 1adbc
85async def read_required_alias(p: Annotated[str, Form(alias="p_alias")]): 1adbc
86 return {"p": p} 1mnop
89class FormModelRequiredAlias(BaseModel): 1adbc
90 p: str = Field(alias="p_alias") 1adbc
93@app.post("/model-required-alias", operation_id="model_required_alias") 1adbc
94async def read_model_required_alias(p: Annotated[FormModelRequiredAlias, Form()]): 1adbc
95 return {"p": p.p} 1qrst
98@pytest.mark.parametrize( 1adbc
99 "path",
100 [
101 "/required-alias",
102 "/model-required-alias",
103 ],
104)
105def test_required_str_alias_schema(path: str): 1adbc
106 openapi = app.openapi() 2sbtbubvbwbxbybzb
107 body_model_name = get_body_model_name(openapi, path) 2sbtbubvbwbxbybzb
109 assert app.openapi()["components"]["schemas"][body_model_name] == { 2sbtbubvbwbxbybzb
110 "properties": {
111 "p_alias": {"title": "P Alias", "type": "string"},
112 },
113 "required": ["p_alias"],
114 "title": body_model_name,
115 "type": "object",
116 }
119@pytest.mark.parametrize( 1adbc
120 "path",
121 ["/required-alias", "/model-required-alias"],
122)
123def test_required_alias_missing(path: str): 1adbc
124 client = TestClient(app) 1STUVWXYZ
125 response = client.post(path) 1STUVWXYZ
126 assert response.status_code == 422 1STUVWXYZ
127 assert response.json() == { 1STUVWXYZ
128 "detail": [
129 {
130 "type": "missing",
131 "loc": ["body", "p_alias"],
132 "msg": "Field required",
133 "input": IsOneOf(None, {}),
134 }
135 ]
136 }
139@pytest.mark.parametrize( 1adbc
140 "path",
141 ["/required-alias", "/model-required-alias"],
142)
143def test_required_alias_by_name(path: str): 1adbc
144 client = TestClient(app) 101234567
145 response = client.post(path, data={"p": "hello"}) 101234567
146 assert response.status_code == 422 101234567
147 assert response.json() == { 101234567
148 "detail": [
149 {
150 "type": "missing",
151 "loc": ["body", "p_alias"],
152 "msg": "Field required",
153 "input": IsOneOf(None, {"p": "hello"}),
154 }
155 ]
156 }
159@pytest.mark.parametrize( 1adbc
160 "path",
161 ["/required-alias", "/model-required-alias"],
162)
163def test_required_alias_by_alias(path: str): 1adbc
164 client = TestClient(app) 1qmrnsotp
165 response = client.post(path, data={"p_alias": "hello"}) 1qmrnsotp
166 assert response.status_code == 200, response.text 1qmrnsotp
167 assert response.json() == {"p": "hello"} 1qmrnsotp
170# =====================================================================================
171# Validation alias
174@app.post("/required-validation-alias", operation_id="required_validation_alias") 1adbc
175def read_required_validation_alias( 1adbc
176 p: Annotated[str, Form(validation_alias="p_val_alias")],
177):
178 return {"p": p} 1uvwx
181class FormModelRequiredValidationAlias(BaseModel): 1adbc
182 p: str = Field(validation_alias="p_val_alias") 1adbc
185@app.post( 1adbc
186 "/model-required-validation-alias", operation_id="model_required_validation_alias"
187)
188def read_model_required_validation_alias( 1adbc
189 p: Annotated[FormModelRequiredValidationAlias, Form()],
190):
191 return {"p": p.p} 1yzAB
194@pytest.mark.parametrize( 1adbc
195 "path",
196 ["/required-validation-alias", "/model-required-validation-alias"],
197)
198def test_required_validation_alias_schema(path: str): 1adbc
199 openapi = app.openapi() 2AbBbCbDbEbFbGb
200 body_model_name = get_body_model_name(openapi, path) 2AbBbCbDbEbFbGb
202 assert app.openapi()["components"]["schemas"][body_model_name] == { 2AbBbCbDbEbFbGb
203 "properties": {
204 "p_val_alias": {"title": "P Val Alias", "type": "string"},
205 },
206 "required": ["p_val_alias"],
207 "title": body_model_name,
208 "type": "object",
209 }
212@pytest.mark.parametrize( 1adbc
213 "path",
214 [
215 "/required-validation-alias",
216 "/model-required-validation-alias",
217 ],
218)
219def test_required_validation_alias_missing(path: str): 1adbc
220 client = TestClient(app) 189!#$%'(
221 response = client.post(path) 189!#$%'(
222 assert response.status_code == 422 189!#$%'(
223 assert response.json() == { 189!#$%'(
224 "detail": [
225 {
226 "type": "missing",
227 "loc": [
228 "body",
229 "p_val_alias",
230 ],
231 "msg": "Field required",
232 "input": IsOneOf(None, {}),
233 }
234 ]
235 }
238@pytest.mark.parametrize( 1adbc
239 "path",
240 [
241 "/required-validation-alias",
242 "/model-required-validation-alias",
243 ],
244)
245def test_required_validation_alias_by_name(path: str): 1adbc
246 client = TestClient(app) 1)*+,-./:
247 response = client.post(path, data={"p": "hello"}) 1)*+,-./:
248 assert response.status_code == 422, response.text 1)*+,-./:
250 assert response.json() == { 1)*+,-./:
251 "detail": [
252 {
253 "type": "missing",
254 "loc": ["body", "p_val_alias"],
255 "msg": "Field required",
256 "input": IsOneOf(None, {"p": "hello"}),
257 }
258 ]
259 }
262@pytest.mark.parametrize( 1adbc
263 "path",
264 [
265 "/required-validation-alias",
266 "/model-required-validation-alias",
267 ],
268)
269def test_required_validation_alias_by_validation_alias(path: str): 1adbc
270 client = TestClient(app) 1yuzvAwBx
271 response = client.post(path, data={"p_val_alias": "hello"}) 1yuzvAwBx
272 assert response.status_code == 200, response.text 1yuzvAwBx
274 assert response.json() == {"p": "hello"} 1yuzvAwBx
277# =====================================================================================
278# Alias and validation alias
281@app.post( 1adbc
282 "/required-alias-and-validation-alias",
283 operation_id="required_alias_and_validation_alias",
284)
285def read_required_alias_and_validation_alias( 1adbc
286 p: Annotated[str, Form(alias="p_alias", validation_alias="p_val_alias")],
287):
288 return {"p": p} 1CDEF
291class FormModelRequiredAliasAndValidationAlias(BaseModel): 1adbc
292 p: str = Field(alias="p_alias", validation_alias="p_val_alias") 1adbc
295@app.post( 1adbc
296 "/model-required-alias-and-validation-alias",
297 operation_id="model_required_alias_and_validation_alias",
298)
299def read_model_required_alias_and_validation_alias( 1adbc
300 p: Annotated[FormModelRequiredAliasAndValidationAlias, Form()],
301):
302 return {"p": p.p} 1GHIJ
305@pytest.mark.parametrize( 1adbc
306 "path",
307 [
308 "/required-alias-and-validation-alias",
309 "/model-required-alias-and-validation-alias",
310 ],
311)
312def test_required_alias_and_validation_alias_schema(path: str): 1adbc
313 openapi = app.openapi() 2HbIbJbKbLbMbNbOb
314 body_model_name = get_body_model_name(openapi, path) 2HbIbJbKbLbMbNbOb
316 assert app.openapi()["components"]["schemas"][body_model_name] == { 2HbIbJbKbLbMbNbOb
317 "properties": {
318 "p_val_alias": {"title": "P Val Alias", "type": "string"},
319 },
320 "required": ["p_val_alias"],
321 "title": body_model_name,
322 "type": "object",
323 }
326@pytest.mark.parametrize( 1adbc
327 "path",
328 [
329 "/required-alias-and-validation-alias",
330 "/model-required-alias-and-validation-alias",
331 ],
332)
333def test_required_alias_and_validation_alias_missing(path: str): 1adbc
334 client = TestClient(app) 1;=?@[]^_
335 response = client.post(path) 1;=?@[]^_
336 assert response.status_code == 422 1;=?@[]^_
337 assert response.json() == { 1;=?@[]^_
338 "detail": [
339 {
340 "type": "missing",
341 "loc": [
342 "body",
343 "p_val_alias",
344 ],
345 "msg": "Field required",
346 "input": IsOneOf(None, {}),
347 }
348 ]
349 }
352@pytest.mark.parametrize( 1adbc
353 "path",
354 [
355 "/required-alias-and-validation-alias",
356 "/model-required-alias-and-validation-alias",
357 ],
358)
359def test_required_alias_and_validation_alias_by_name(path: str): 1adbc
360 client = TestClient(app) 2` { | } ~ abbbcb
361 response = client.post(path, data={"p": "hello"}) 2` { | } ~ abbbcb
362 assert response.status_code == 422 2` { | } ~ abbbcb
364 assert response.json() == { 2` { | } ~ abbbcb
365 "detail": [
366 {
367 "type": "missing",
368 "loc": [
369 "body",
370 "p_val_alias",
371 ],
372 "msg": "Field required",
373 "input": IsOneOf(None, {"p": "hello"}),
374 }
375 ]
376 }
379@pytest.mark.parametrize( 1adbc
380 "path",
381 [
382 "/required-alias-and-validation-alias",
383 "/model-required-alias-and-validation-alias",
384 ],
385)
386def test_required_alias_and_validation_alias_by_alias(path: str): 1adbc
387 client = TestClient(app) 2dbebfbgbhbibjb
388 response = client.post(path, data={"p_alias": "hello"}) 2dbebfbgbhbibjb
389 assert response.status_code == 422, response.text 2dbebfbgbhbibjb
391 assert response.json() == { 2dbebfbgbhbibjb
392 "detail": [
393 {
394 "type": "missing",
395 "loc": ["body", "p_val_alias"],
396 "msg": "Field required",
397 "input": IsOneOf(None, {"p_alias": "hello"}),
398 }
399 ]
400 }
403@pytest.mark.parametrize( 1adbc
404 "path",
405 [
406 "/required-alias-and-validation-alias",
407 "/model-required-alias-and-validation-alias",
408 ],
409)
410def test_required_alias_and_validation_alias_by_validation_alias(path: str): 1adbc
411 client = TestClient(app) 1GCHDIEJF
412 response = client.post(path, data={"p_val_alias": "hello"}) 1GCHDIEJF
413 assert response.status_code == 200, response.text 1GCHDIEJF
415 assert response.json() == {"p": "hello"} 1GCHDIEJF