Coverage for tests / test_request_params / test_form / test_list.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, IsPartialDict 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-list-str", operation_id="required_list_str") 1adbc
18async def read_required_list_str(p: Annotated[list[str], Form()]): 1adbc
19 return {"p": p} 1efgh
22class FormModelRequiredListStr(BaseModel): 1adbc
23 p: list[str] 1abc
26@app.post("/model-required-list-str", operation_id="model_required_list_str") 1adbc
27def read_model_required_list_str(p: Annotated[FormModelRequiredListStr, Form()]): 1adbc
28 return {"p": p.p} 2i Mbj k
31@pytest.mark.parametrize( 1adbc
32 "path",
33 ["/required-list-str", "/model-required-list-str"],
34)
35def test_required_list_str_schema(path: str): 1adbc
36 openapi = app.openapi() 2ibjbkblbmbnbob
37 body_model_name = get_body_model_name(openapi, path) 2ibjbkblbmbnbob
39 assert app.openapi()["components"]["schemas"][body_model_name] == { 2ibjbkblbmbnbob
40 "properties": {
41 "p": {
42 "items": {"type": "string"},
43 "title": "P",
44 "type": "array",
45 },
46 },
47 "required": ["p"],
48 "title": body_model_name,
49 "type": "object",
50 }
53@pytest.mark.parametrize( 1adbc
54 "path",
55 ["/required-list-str", "/model-required-list-str"],
56)
57def test_required_list_str_missing(path: str): 1adbc
58 client = TestClient(app) 1JKLMNOPQ
59 response = client.post(path) 1JKLMNOPQ
60 assert response.status_code == 422 1JKLMNOPQ
61 assert response.json() == { 1JKLMNOPQ
62 "detail": [
63 {
64 "type": "missing",
65 "loc": ["body", "p"],
66 "msg": "Field required",
67 "input": IsOneOf(None, {}),
68 }
69 ]
70 }
73@pytest.mark.parametrize( 1adbc
74 "path",
75 ["/required-list-str", "/model-required-list-str"],
76)
77def test_required_list_str(path: str): 1adbc
78 client = TestClient(app) 1iefjgkh
79 response = client.post(path, data={"p": ["hello", "world"]}) 1iefjgkh
80 assert response.status_code == 200 1iefjgkh
81 assert response.json() == {"p": ["hello", "world"]} 1iefjgkh
84# =====================================================================================
85# Alias
88@app.post("/required-list-alias", operation_id="required_list_alias") 1adbc
89async def read_required_list_alias(p: Annotated[list[str], Form(alias="p_alias")]): 1adbc
90 return {"p": p} 1lmno
93class FormModelRequiredListAlias(BaseModel): 1adbc
94 p: list[str] = Field(alias="p_alias") 1adbc
97@app.post("/model-required-list-alias", operation_id="model_required_list_alias") 1adbc
98async def read_model_required_list_alias( 1adbc
99 p: Annotated[FormModelRequiredListAlias, Form()],
100):
101 return {"p": p.p} 1pqrs
104@pytest.mark.parametrize( 1adbc
105 "path",
106 [
107 "/required-list-alias",
108 "/model-required-list-alias",
109 ],
110)
111def test_required_list_str_alias_schema(path: str): 1adbc
112 openapi = app.openapi() 2pbqbrbsbtbubvbwb
113 body_model_name = get_body_model_name(openapi, path) 2pbqbrbsbtbubvbwb
115 assert app.openapi()["components"]["schemas"][body_model_name] == { 2pbqbrbsbtbubvbwb
116 "properties": {
117 "p_alias": {
118 "items": {"type": "string"},
119 "title": "P Alias",
120 "type": "array",
121 },
122 },
123 "required": ["p_alias"],
124 "title": body_model_name,
125 "type": "object",
126 }
129@pytest.mark.parametrize( 1adbc
130 "path",
131 ["/required-list-alias", "/model-required-list-alias"],
132)
133def test_required_list_alias_missing(path: str): 1adbc
134 client = TestClient(app) 1RSTUVWXY
135 response = client.post(path) 1RSTUVWXY
136 assert response.status_code == 422 1RSTUVWXY
137 assert response.json() == { 1RSTUVWXY
138 "detail": [
139 {
140 "type": "missing",
141 "loc": ["body", "p_alias"],
142 "msg": "Field required",
143 "input": IsOneOf(None, {}),
144 }
145 ]
146 }
149@pytest.mark.parametrize( 1adbc
150 "path",
151 [
152 "/required-list-alias",
153 "/model-required-list-alias",
154 ],
155)
156def test_required_list_alias_by_name(path: str): 1adbc
157 client = TestClient(app) 1Z012345
158 response = client.post(path, data={"p": ["hello", "world"]}) 1Z012345
159 assert response.status_code == 422 1Z012345
160 assert response.json() == { 1Z012345
161 "detail": [
162 {
163 "type": "missing",
164 "loc": ["body", "p_alias"],
165 "msg": "Field required",
166 "input": IsOneOf(None, {"p": ["hello", "world"]}),
167 }
168 ]
169 }
172@pytest.mark.parametrize( 1adbc
173 "path",
174 ["/required-list-alias", "/model-required-list-alias"],
175)
176def test_required_list_alias_by_alias(path: str): 1adbc
177 client = TestClient(app) 1plqmrnso
178 response = client.post(path, data={"p_alias": ["hello", "world"]}) 1plqmrnso
179 assert response.status_code == 200, response.text 1plqmrnso
180 assert response.json() == {"p": ["hello", "world"]} 1plqmrnso
183# =====================================================================================
184# Validation alias
187@app.post( 1adbc
188 "/required-list-validation-alias", operation_id="required_list_validation_alias"
189)
190def read_required_list_validation_alias( 1adbc
191 p: Annotated[list[str], Form(validation_alias="p_val_alias")],
192):
193 return {"p": p} 1tuvw
196class FormModelRequiredListValidationAlias(BaseModel): 1adbc
197 p: list[str] = Field(validation_alias="p_val_alias") 1adbc
200@app.post( 1adbc
201 "/model-required-list-validation-alias",
202 operation_id="model_required_list_validation_alias",
203)
204async def read_model_required_list_validation_alias( 1adbc
205 p: Annotated[FormModelRequiredListValidationAlias, Form()],
206):
207 return {"p": p.p} 1xyzA
210@pytest.mark.parametrize( 1adbc
211 "path",
212 ["/required-list-validation-alias", "/model-required-list-validation-alias"],
213)
214def test_required_list_validation_alias_schema(path: str): 1adbc
215 openapi = app.openapi() 2xbybzbAbBbCbDb
216 body_model_name = get_body_model_name(openapi, path) 2xbybzbAbBbCbDb
218 assert app.openapi()["components"]["schemas"][body_model_name] == { 2xbybzbAbBbCbDb
219 "properties": {
220 "p_val_alias": {
221 "items": {"type": "string"},
222 "title": "P Val Alias",
223 "type": "array",
224 },
225 },
226 "required": ["p_val_alias"],
227 "title": body_model_name,
228 "type": "object",
229 }
232@pytest.mark.parametrize( 1adbc
233 "path",
234 [
235 "/required-list-validation-alias",
236 "/model-required-list-validation-alias",
237 ],
238)
239def test_required_list_validation_alias_missing(path: str): 1adbc
240 client = TestClient(app) 16789!#$%
241 response = client.post(path) 16789!#$%
242 assert response.status_code == 422 16789!#$%
243 assert response.json() == { 16789!#$%
244 "detail": [
245 {
246 "type": "missing",
247 "loc": [
248 "body",
249 "p_val_alias",
250 ],
251 "msg": "Field required",
252 "input": IsOneOf(None, {}),
253 }
254 ]
255 }
258@pytest.mark.parametrize( 1adbc
259 "path",
260 [
261 "/required-list-validation-alias",
262 "/model-required-list-validation-alias",
263 ],
264)
265def test_required_list_validation_alias_by_name(path: str): 1adbc
266 client = TestClient(app) 1'()*+,-.
267 response = client.post(path, data={"p": ["hello", "world"]}) 1'()*+,-.
268 assert response.status_code == 422, response.text 1'()*+,-.
270 assert response.json() == { 1'()*+,-.
271 "detail": [
272 {
273 "type": "missing",
274 "loc": ["body", "p_val_alias"],
275 "msg": "Field required",
276 "input": IsOneOf(None, IsPartialDict({"p": ["hello", "world"]})),
277 }
278 ]
279 }
282@pytest.mark.parametrize( 1adbc
283 "path",
284 ["/required-list-validation-alias", "/model-required-list-validation-alias"],
285)
286def test_required_list_validation_alias_by_validation_alias(path: str): 1adbc
287 client = TestClient(app) 1xtyuzvAw
288 response = client.post(path, data={"p_val_alias": ["hello", "world"]}) 1xtyuzvAw
289 assert response.status_code == 200, response.text 1xtyuzvAw
291 assert response.json() == {"p": ["hello", "world"]} 1xtyuzvAw
294# =====================================================================================
295# Alias and validation alias
298@app.post( 1adbc
299 "/required-list-alias-and-validation-alias",
300 operation_id="required_list_alias_and_validation_alias",
301)
302def read_required_list_alias_and_validation_alias( 1adbc
303 p: Annotated[list[str], Form(alias="p_alias", validation_alias="p_val_alias")],
304):
305 return {"p": p} 1BCDE
308class FormModelRequiredListAliasAndValidationAlias(BaseModel): 1adbc
309 p: list[str] = Field(alias="p_alias", validation_alias="p_val_alias") 1adbc
312@app.post( 1adbc
313 "/model-required-list-alias-and-validation-alias",
314 operation_id="model_required_list_alias_and_validation_alias",
315)
316def read_model_required_list_alias_and_validation_alias( 1adbc
317 p: Annotated[FormModelRequiredListAliasAndValidationAlias, Form()],
318):
319 return {"p": p.p} 1FGHI
322@pytest.mark.parametrize( 1adbc
323 "path",
324 [
325 "/required-list-alias-and-validation-alias",
326 "/model-required-list-alias-and-validation-alias",
327 ],
328)
329def test_required_list_alias_and_validation_alias_schema(path: str): 1adbc
330 openapi = app.openapi() 2EbFbGbHbIbJbKbLb
331 body_model_name = get_body_model_name(openapi, path) 2EbFbGbHbIbJbKbLb
333 assert app.openapi()["components"]["schemas"][body_model_name] == { 2EbFbGbHbIbJbKbLb
334 "properties": {
335 "p_val_alias": {
336 "items": {"type": "string"},
337 "title": "P Val Alias",
338 "type": "array",
339 },
340 },
341 "required": ["p_val_alias"],
342 "title": body_model_name,
343 "type": "object",
344 }
347@pytest.mark.parametrize( 1adbc
348 "path",
349 [
350 "/required-list-alias-and-validation-alias",
351 "/model-required-list-alias-and-validation-alias",
352 ],
353)
354def test_required_list_alias_and_validation_alias_missing(path: str): 1adbc
355 client = TestClient(app) 1/:;=?@[]
356 response = client.post(path) 1/:;=?@[]
357 assert response.status_code == 422 1/:;=?@[]
358 assert response.json() == { 1/:;=?@[]
359 "detail": [
360 {
361 "type": "missing",
362 "loc": [
363 "body",
364 "p_val_alias",
365 ],
366 "msg": "Field required",
367 "input": IsOneOf(None, {}),
368 }
369 ]
370 }
373@pytest.mark.parametrize( 1adbc
374 "path",
375 [
376 "/required-list-alias-and-validation-alias",
377 "/model-required-list-alias-and-validation-alias",
378 ],
379)
380def test_required_list_alias_and_validation_alias_by_name(path: str): 1adbc
381 client = TestClient(app) 2^ _ ` { | } ~ ab
382 response = client.post(path, data={"p": ["hello", "world"]}) 2^ _ ` { | } ~ ab
383 assert response.status_code == 422 2^ _ ` { | } ~ ab
384 assert response.json() == { 2^ _ ` { | } ~ ab
385 "detail": [
386 {
387 "type": "missing",
388 "loc": [
389 "body",
390 "p_val_alias",
391 ],
392 "msg": "Field required",
393 "input": IsOneOf(
394 None,
395 {"p": ["hello", "world"]},
396 ),
397 }
398 ]
399 }
402@pytest.mark.parametrize( 1adbc
403 "path",
404 [
405 "/required-list-alias-and-validation-alias",
406 "/model-required-list-alias-and-validation-alias",
407 ],
408)
409def test_required_list_alias_and_validation_alias_by_alias(path: str): 1adbc
410 client = TestClient(app) 2bbcbdbebfbgbhb
411 response = client.post(path, data={"p_alias": ["hello", "world"]}) 2bbcbdbebfbgbhb
412 assert response.status_code == 422 2bbcbdbebfbgbhb
413 assert response.json() == { 2bbcbdbebfbgbhb
414 "detail": [
415 {
416 "type": "missing",
417 "loc": ["body", "p_val_alias"],
418 "msg": "Field required",
419 "input": IsOneOf(None, {"p_alias": ["hello", "world"]}),
420 }
421 ]
422 }
425@pytest.mark.parametrize( 1adbc
426 "path",
427 [
428 "/required-list-alias-and-validation-alias",
429 "/model-required-list-alias-and-validation-alias",
430 ],
431)
432def test_required_list_alias_and_validation_alias_by_validation_alias(path: str): 1adbc
433 client = TestClient(app) 1FBGCHDIE
434 response = client.post(path, data={"p_val_alias": ["hello", "world"]}) 1FBGCHDIE
435 assert response.status_code == 200, response.text 1FBGCHDIE
436 assert response.json() == {"p": ["hello", "world"]} 1FBGCHDIE