Coverage for tests / test_request_params / test_file / test_list.py: 100%
122 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 typing import Annotated 1abcd
3import pytest 1abcd
4from fastapi import FastAPI, File, UploadFile 1abcd
5from fastapi.testclient import TestClient 1abcd
7from .utils import get_body_model_name 1abcd
9app = FastAPI() 1abcd
11# =====================================================================================
12# Without aliases
15@app.post("/list-bytes", operation_id="list_bytes") 1abcd
16async def read_list_bytes(p: Annotated[list[bytes], File()]): 1abcd
17 return {"file_size": [len(file) for file in p]} 1efg
20@app.post("/list-uploadfile", operation_id="list_uploadfile") 1abcd
21async def read_list_uploadfile(p: Annotated[list[UploadFile], File()]): 1abcd
22 return {"file_size": [file.size for file in p]} 1efg
25@pytest.mark.parametrize( 1abcd
26 "path",
27 [
28 "/list-bytes",
29 "/list-uploadfile",
30 ],
31)
32def test_list_schema(path: str): 1abcd
33 openapi = app.openapi() 1OPQ
34 body_model_name = get_body_model_name(openapi, path) 1OPQ
36 assert app.openapi()["components"]["schemas"][body_model_name] == { 1OPQ
37 "properties": {
38 "p": {
39 "type": "array",
40 "items": {"type": "string", "format": "binary"},
41 "title": "P",
42 },
43 },
44 "required": ["p"],
45 "title": body_model_name,
46 "type": "object",
47 }
50@pytest.mark.parametrize( 1abcd
51 "path",
52 [
53 "/list-bytes",
54 "/list-uploadfile",
55 ],
56)
57def test_list_missing(path: str): 1abcd
58 client = TestClient(app) 1qrs
59 response = client.post(path) 1qrs
60 assert response.status_code == 422 1qrs
61 assert response.json() == { 1qrs
62 "detail": [
63 {
64 "type": "missing",
65 "loc": ["body", "p"],
66 "msg": "Field required",
67 "input": None,
68 }
69 ]
70 }
73@pytest.mark.parametrize( 1abcd
74 "path",
75 [
76 "/list-bytes",
77 "/list-uploadfile",
78 ],
79)
80def test_list(path: str): 1abcd
81 client = TestClient(app) 1efg
82 response = client.post(path, files=[("p", b"hello"), ("p", b"world")]) 1efg
83 assert response.status_code == 200 1efg
84 assert response.json() == {"file_size": [5, 5]} 1efg
87# =====================================================================================
88# Alias
91@app.post("/list-bytes-alias", operation_id="list_bytes_alias") 1abcd
92async def read_list_bytes_alias(p: Annotated[list[bytes], File(alias="p_alias")]): 1abcd
93 return {"file_size": [len(file) for file in p]} 1hij
96@app.post("/list-uploadfile-alias", operation_id="list_uploadfile_alias") 1abcd
97async def read_list_uploadfile_alias( 1abcd
98 p: Annotated[list[UploadFile], File(alias="p_alias")],
99):
100 return {"file_size": [file.size for file in p]} 1hij
103@pytest.mark.parametrize( 1abcd
104 "path",
105 [
106 "/list-bytes-alias",
107 "/list-uploadfile-alias",
108 ],
109)
110def test_list_alias_schema(path: str): 1abcd
111 openapi = app.openapi() 1RST
112 body_model_name = get_body_model_name(openapi, path) 1RST
114 assert app.openapi()["components"]["schemas"][body_model_name] == { 1RST
115 "properties": {
116 "p_alias": {
117 "type": "array",
118 "items": {"type": "string", "format": "binary"},
119 "title": "P Alias",
120 },
121 },
122 "required": ["p_alias"],
123 "title": body_model_name,
124 "type": "object",
125 }
128@pytest.mark.parametrize( 1abcd
129 "path",
130 [
131 "/list-bytes-alias",
132 "/list-uploadfile-alias",
133 ],
134)
135def test_list_alias_missing(path: str): 1abcd
136 client = TestClient(app) 1tuv
137 response = client.post(path) 1tuv
138 assert response.status_code == 422 1tuv
139 assert response.json() == { 1tuv
140 "detail": [
141 {
142 "type": "missing",
143 "loc": ["body", "p_alias"],
144 "msg": "Field required",
145 "input": None,
146 }
147 ]
148 }
151@pytest.mark.parametrize( 1abcd
152 "path",
153 [
154 "/list-bytes-alias",
155 "/list-uploadfile-alias",
156 ],
157)
158def test_list_alias_by_name(path: str): 1abcd
159 client = TestClient(app) 1wxy
160 response = client.post(path, files=[("p", b"hello"), ("p", b"world")]) 1wxy
161 assert response.status_code == 422 1wxy
162 assert response.json() == { 1wxy
163 "detail": [
164 {
165 "type": "missing",
166 "loc": ["body", "p_alias"],
167 "msg": "Field required",
168 "input": None,
169 }
170 ]
171 }
174@pytest.mark.parametrize( 1abcd
175 "path",
176 [
177 "/list-bytes-alias",
178 "/list-uploadfile-alias",
179 ],
180)
181def test_list_alias_by_alias(path: str): 1abcd
182 client = TestClient(app) 1hij
183 response = client.post(path, files=[("p_alias", b"hello"), ("p_alias", b"world")]) 1hij
184 assert response.status_code == 200, response.text 1hij
185 assert response.json() == {"file_size": [5, 5]} 1hij
188# =====================================================================================
189# Validation alias
192@app.post("/list-bytes-validation-alias", operation_id="list_bytes_validation_alias") 1abcd
193def read_list_bytes_validation_alias( 1abcd
194 p: Annotated[list[bytes], File(validation_alias="p_val_alias")],
195):
196 return {"file_size": [len(file) for file in p]} 1klm
199@app.post( 1abcd
200 "/list-uploadfile-validation-alias",
201 operation_id="list_uploadfile_validation_alias",
202)
203def read_list_uploadfile_validation_alias( 1abcd
204 p: Annotated[list[UploadFile], File(validation_alias="p_val_alias")],
205):
206 return {"file_size": [file.size for file in p]} 1klm
209@pytest.mark.parametrize( 1abcd
210 "path",
211 [
212 "/list-bytes-validation-alias",
213 "/list-uploadfile-validation-alias",
214 ],
215)
216def test_list_validation_alias_schema(path: str): 1abcd
217 openapi = app.openapi() 1UVW
218 body_model_name = get_body_model_name(openapi, path) 1UVW
220 assert app.openapi()["components"]["schemas"][body_model_name] == { 1UVW
221 "properties": {
222 "p_val_alias": {
223 "type": "array",
224 "items": {"type": "string", "format": "binary"},
225 "title": "P Val Alias",
226 },
227 },
228 "required": ["p_val_alias"],
229 "title": body_model_name,
230 "type": "object",
231 }
234@pytest.mark.parametrize( 1abcd
235 "path",
236 [
237 "/list-bytes-validation-alias",
238 "/list-uploadfile-validation-alias",
239 ],
240)
241def test_list_validation_alias_missing(path: str): 1abcd
242 client = TestClient(app) 1zAB
243 response = client.post(path) 1zAB
244 assert response.status_code == 422 1zAB
245 assert response.json() == { 1zAB
246 "detail": [
247 {
248 "type": "missing",
249 "loc": [
250 "body",
251 "p_val_alias",
252 ],
253 "msg": "Field required",
254 "input": None,
255 }
256 ]
257 }
260@pytest.mark.parametrize( 1abcd
261 "path",
262 [
263 "/list-bytes-validation-alias",
264 "/list-uploadfile-validation-alias",
265 ],
266)
267def test_list_validation_alias_by_name(path: str): 1abcd
268 client = TestClient(app) 1CDE
269 response = client.post(path, files=[("p", b"hello"), ("p", b"world")]) 1CDE
270 assert response.status_code == 422, response.text 1CDE
272 assert response.json() == { 1CDE
273 "detail": [
274 {
275 "type": "missing",
276 "loc": ["body", "p_val_alias"],
277 "msg": "Field required",
278 "input": None,
279 }
280 ]
281 }
284@pytest.mark.parametrize( 1abcd
285 "path",
286 [
287 "/list-bytes-validation-alias",
288 "/list-uploadfile-validation-alias",
289 ],
290)
291def test_list_validation_alias_by_validation_alias(path: str): 1abcd
292 client = TestClient(app) 1klm
293 response = client.post( 1klm
294 path, files=[("p_val_alias", b"hello"), ("p_val_alias", b"world")]
295 )
296 assert response.status_code == 200, response.text 1klm
297 assert response.json() == {"file_size": [5, 5]} 1klm
300# =====================================================================================
301# Alias and validation alias
304@app.post( 1abcd
305 "/list-bytes-alias-and-validation-alias",
306 operation_id="list_bytes_alias_and_validation_alias",
307)
308def read_list_bytes_alias_and_validation_alias( 1abcd
309 p: Annotated[list[bytes], File(alias="p_alias", validation_alias="p_val_alias")],
310):
311 return {"file_size": [len(file) for file in p]} 1nop
314@app.post( 1abcd
315 "/list-uploadfile-alias-and-validation-alias",
316 operation_id="list_uploadfile_alias_and_validation_alias",
317)
318def read_list_uploadfile_alias_and_validation_alias( 1abcd
319 p: Annotated[
320 list[UploadFile], File(alias="p_alias", validation_alias="p_val_alias")
321 ],
322):
323 return {"file_size": [file.size for file in p]} 1nop
326@pytest.mark.parametrize( 1abcd
327 "path",
328 [
329 "/list-bytes-alias-and-validation-alias",
330 "/list-uploadfile-alias-and-validation-alias",
331 ],
332)
333def test_list_alias_and_validation_alias_schema(path: str): 1abcd
334 openapi = app.openapi() 1XYZ
335 body_model_name = get_body_model_name(openapi, path) 1XYZ
337 assert app.openapi()["components"]["schemas"][body_model_name] == { 1XYZ
338 "properties": {
339 "p_val_alias": {
340 "type": "array",
341 "items": {"type": "string", "format": "binary"},
342 "title": "P Val Alias",
343 },
344 },
345 "required": ["p_val_alias"],
346 "title": body_model_name,
347 "type": "object",
348 }
351@pytest.mark.parametrize( 1abcd
352 "path",
353 [
354 "/list-bytes-alias-and-validation-alias",
355 "/list-uploadfile-alias-and-validation-alias",
356 ],
357)
358def test_list_alias_and_validation_alias_missing(path: str): 1abcd
359 client = TestClient(app) 1FGH
360 response = client.post(path) 1FGH
361 assert response.status_code == 422 1FGH
362 assert response.json() == { 1FGH
363 "detail": [
364 {
365 "type": "missing",
366 "loc": [
367 "body",
368 "p_val_alias",
369 ],
370 "msg": "Field required",
371 "input": None,
372 }
373 ]
374 }
377@pytest.mark.parametrize( 1abcd
378 "path",
379 [
380 "/list-bytes-alias-and-validation-alias",
381 "/list-uploadfile-alias-and-validation-alias",
382 ],
383)
384def test_list_alias_and_validation_alias_by_name(path: str): 1abcd
385 client = TestClient(app) 1IJK
386 response = client.post(path, files=[("p", "hello"), ("p", "world")]) 1IJK
387 assert response.status_code == 422 1IJK
389 assert response.json() == { 1IJK
390 "detail": [
391 {
392 "type": "missing",
393 "loc": [
394 "body",
395 "p_val_alias",
396 ],
397 "msg": "Field required",
398 "input": None,
399 }
400 ]
401 }
404@pytest.mark.parametrize( 1abcd
405 "path",
406 [
407 "/list-bytes-alias-and-validation-alias",
408 "/list-uploadfile-alias-and-validation-alias",
409 ],
410)
411def test_list_alias_and_validation_alias_by_alias(path: str): 1abcd
412 client = TestClient(app) 1LMN
413 response = client.post(path, files=[("p_alias", b"hello"), ("p_alias", b"world")]) 1LMN
414 assert response.status_code == 422, response.text 1LMN
416 assert response.json() == { 1LMN
417 "detail": [
418 {
419 "type": "missing",
420 "loc": ["body", "p_val_alias"],
421 "msg": "Field required",
422 "input": None,
423 }
424 ]
425 }
428@pytest.mark.parametrize( 1abcd
429 "path",
430 [
431 "/list-bytes-alias-and-validation-alias",
432 "/list-uploadfile-alias-and-validation-alias",
433 ],
434)
435def test_list_alias_and_validation_alias_by_validation_alias(path: str): 1abcd
436 client = TestClient(app) 1nop
437 response = client.post( 1nop
438 path, files=[("p_val_alias", b"hello"), ("p_val_alias", b"world")]
439 )
440 assert response.status_code == 200, response.text 1nop
441 assert response.json() == {"file_size": [5, 5]} 1nop