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-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 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]} 1efgh
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]} 2i Nbj k
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() 2ibjbkblbmbnbob
34 body_model_name = get_body_model_name(openapi, path) 2ibjbkblbmbnbob
36 assert app.openapi()["components"]["schemas"][body_model_name] == { 2ibjbkblbmbnbob
37 "properties": {
38 "p": {
39 "type": "array",
40 "items": {
41 "type": "string",
42 "contentMediaType": "application/octet-stream",
43 },
44 "title": "P",
45 },
46 },
47 "required": ["p"],
48 "title": body_model_name,
49 "type": "object",
50 }
53@pytest.mark.parametrize( 1abcd
54 "path",
55 [
56 "/list-bytes",
57 "/list-uploadfile",
58 ],
59)
60def test_list_missing(path: str): 1abcd
61 client = TestClient(app) 1IJKLMNOP
62 response = client.post(path) 1IJKLMNOP
63 assert response.status_code == 422 1IJKLMNOP
64 assert response.json() == { 1IJKLMNOP
65 "detail": [
66 {
67 "type": "missing",
68 "loc": ["body", "p"],
69 "msg": "Field required",
70 "input": None,
71 }
72 ]
73 }
76@pytest.mark.parametrize( 1abcd
77 "path",
78 [
79 "/list-bytes",
80 "/list-uploadfile",
81 ],
82)
83def test_list(path: str): 1abcd
84 client = TestClient(app) 1eifgjhk
85 response = client.post(path, files=[("p", b"hello"), ("p", b"world")]) 1eifgjhk
86 assert response.status_code == 200 1eifgjhk
87 assert response.json() == {"file_size": [5, 5]} 1eifgjhk
90# =====================================================================================
91# Alias
94@app.post("/list-bytes-alias", operation_id="list_bytes_alias") 1abcd
95async def read_list_bytes_alias(p: Annotated[list[bytes], File(alias="p_alias")]): 1abcd
96 return {"file_size": [len(file) for file in p]} 1lmno
99@app.post("/list-uploadfile-alias", operation_id="list_uploadfile_alias") 1abcd
100async def read_list_uploadfile_alias( 1abcd
101 p: Annotated[list[UploadFile], File(alias="p_alias")],
102):
103 return {"file_size": [file.size for file in p]} 2p Obq r
106@pytest.mark.parametrize( 1abcd
107 "path",
108 [
109 "/list-bytes-alias",
110 "/list-uploadfile-alias",
111 ],
112)
113def test_list_alias_schema(path: str): 1abcd
114 openapi = app.openapi() 2pbqbrbsbtbubvbwb
115 body_model_name = get_body_model_name(openapi, path) 2pbqbrbsbtbubvbwb
117 assert app.openapi()["components"]["schemas"][body_model_name] == { 2pbqbrbsbtbubvbwb
118 "properties": {
119 "p_alias": {
120 "type": "array",
121 "items": {
122 "type": "string",
123 "contentMediaType": "application/octet-stream",
124 },
125 "title": "P Alias",
126 },
127 },
128 "required": ["p_alias"],
129 "title": body_model_name,
130 "type": "object",
131 }
134@pytest.mark.parametrize( 1abcd
135 "path",
136 [
137 "/list-bytes-alias",
138 "/list-uploadfile-alias",
139 ],
140)
141def test_list_alias_missing(path: str): 1abcd
142 client = TestClient(app) 1QRSTUVWX
143 response = client.post(path) 1QRSTUVWX
144 assert response.status_code == 422 1QRSTUVWX
145 assert response.json() == { 1QRSTUVWX
146 "detail": [
147 {
148 "type": "missing",
149 "loc": ["body", "p_alias"],
150 "msg": "Field required",
151 "input": None,
152 }
153 ]
154 }
157@pytest.mark.parametrize( 1abcd
158 "path",
159 [
160 "/list-bytes-alias",
161 "/list-uploadfile-alias",
162 ],
163)
164def test_list_alias_by_name(path: str): 1abcd
165 client = TestClient(app) 1YZ01234
166 response = client.post(path, files=[("p", b"hello"), ("p", b"world")]) 1YZ01234
167 assert response.status_code == 422 1YZ01234
168 assert response.json() == { 1YZ01234
169 "detail": [
170 {
171 "type": "missing",
172 "loc": ["body", "p_alias"],
173 "msg": "Field required",
174 "input": None,
175 }
176 ]
177 }
180@pytest.mark.parametrize( 1abcd
181 "path",
182 [
183 "/list-bytes-alias",
184 "/list-uploadfile-alias",
185 ],
186)
187def test_list_alias_by_alias(path: str): 1abcd
188 client = TestClient(app) 1lpmnqor
189 response = client.post(path, files=[("p_alias", b"hello"), ("p_alias", b"world")]) 1lpmnqor
190 assert response.status_code == 200, response.text 1lpmnqor
191 assert response.json() == {"file_size": [5, 5]} 1lpmnqor
194# =====================================================================================
195# Validation alias
198@app.post("/list-bytes-validation-alias", operation_id="list_bytes_validation_alias") 1abcd
199def read_list_bytes_validation_alias( 1abcd
200 p: Annotated[list[bytes], File(validation_alias="p_val_alias")],
201):
202 return {"file_size": [len(file) for file in p]} 1stuv
205@app.post( 1abcd
206 "/list-uploadfile-validation-alias",
207 operation_id="list_uploadfile_validation_alias",
208)
209def read_list_uploadfile_validation_alias( 1abcd
210 p: Annotated[list[UploadFile], File(validation_alias="p_val_alias")],
211):
212 return {"file_size": [file.size for file in p]} 1wxyz
215@pytest.mark.parametrize( 1abcd
216 "path",
217 [
218 "/list-bytes-validation-alias",
219 "/list-uploadfile-validation-alias",
220 ],
221)
222def test_list_validation_alias_schema(path: str): 1abcd
223 openapi = app.openapi() 2xbybzbAbBbCbDbEb
224 body_model_name = get_body_model_name(openapi, path) 2xbybzbAbBbCbDbEb
226 assert app.openapi()["components"]["schemas"][body_model_name] == { 2xbybzbAbBbCbDbEb
227 "properties": {
228 "p_val_alias": {
229 "type": "array",
230 "items": {
231 "type": "string",
232 "contentMediaType": "application/octet-stream",
233 },
234 "title": "P Val Alias",
235 },
236 },
237 "required": ["p_val_alias"],
238 "title": body_model_name,
239 "type": "object",
240 }
243@pytest.mark.parametrize( 1abcd
244 "path",
245 [
246 "/list-bytes-validation-alias",
247 "/list-uploadfile-validation-alias",
248 ],
249)
250def test_list_validation_alias_missing(path: str): 1abcd
251 client = TestClient(app) 156789!#$
252 response = client.post(path) 156789!#$
253 assert response.status_code == 422 156789!#$
254 assert response.json() == { 156789!#$
255 "detail": [
256 {
257 "type": "missing",
258 "loc": [
259 "body",
260 "p_val_alias",
261 ],
262 "msg": "Field required",
263 "input": None,
264 }
265 ]
266 }
269@pytest.mark.parametrize( 1abcd
270 "path",
271 [
272 "/list-bytes-validation-alias",
273 "/list-uploadfile-validation-alias",
274 ],
275)
276def test_list_validation_alias_by_name(path: str): 1abcd
277 client = TestClient(app) 1%'()*+,-
278 response = client.post(path, files=[("p", b"hello"), ("p", b"world")]) 1%'()*+,-
279 assert response.status_code == 422, response.text 1%'()*+,-
281 assert response.json() == { 1%'()*+,-
282 "detail": [
283 {
284 "type": "missing",
285 "loc": ["body", "p_val_alias"],
286 "msg": "Field required",
287 "input": None,
288 }
289 ]
290 }
293@pytest.mark.parametrize( 1abcd
294 "path",
295 [
296 "/list-bytes-validation-alias",
297 "/list-uploadfile-validation-alias",
298 ],
299)
300def test_list_validation_alias_by_validation_alias(path: str): 1abcd
301 client = TestClient(app) 1swtxuyvz
302 response = client.post( 1swtxuyvz
303 path, files=[("p_val_alias", b"hello"), ("p_val_alias", b"world")]
304 )
305 assert response.status_code == 200, response.text 1swtxuyvz
306 assert response.json() == {"file_size": [5, 5]} 1swtxuyvz
309# =====================================================================================
310# Alias and validation alias
313@app.post( 1abcd
314 "/list-bytes-alias-and-validation-alias",
315 operation_id="list_bytes_alias_and_validation_alias",
316)
317def read_list_bytes_alias_and_validation_alias( 1abcd
318 p: Annotated[list[bytes], File(alias="p_alias", validation_alias="p_val_alias")],
319):
320 return {"file_size": [len(file) for file in p]} 1ABCD
323@app.post( 1abcd
324 "/list-uploadfile-alias-and-validation-alias",
325 operation_id="list_uploadfile_alias_and_validation_alias",
326)
327def read_list_uploadfile_alias_and_validation_alias( 1abcd
328 p: Annotated[
329 list[UploadFile], File(alias="p_alias", validation_alias="p_val_alias")
330 ],
331):
332 return {"file_size": [file.size for file in p]} 1EFGH
335@pytest.mark.parametrize( 1abcd
336 "path",
337 [
338 "/list-bytes-alias-and-validation-alias",
339 "/list-uploadfile-alias-and-validation-alias",
340 ],
341)
342def test_list_alias_and_validation_alias_schema(path: str): 1abcd
343 openapi = app.openapi() 2FbGbHbIbJbKbLbMb
344 body_model_name = get_body_model_name(openapi, path) 2FbGbHbIbJbKbLbMb
346 assert app.openapi()["components"]["schemas"][body_model_name] == { 2FbGbHbIbJbKbLbMb
347 "properties": {
348 "p_val_alias": {
349 "type": "array",
350 "items": {
351 "type": "string",
352 "contentMediaType": "application/octet-stream",
353 },
354 "title": "P Val Alias",
355 },
356 },
357 "required": ["p_val_alias"],
358 "title": body_model_name,
359 "type": "object",
360 }
363@pytest.mark.parametrize( 1abcd
364 "path",
365 [
366 "/list-bytes-alias-and-validation-alias",
367 "/list-uploadfile-alias-and-validation-alias",
368 ],
369)
370def test_list_alias_and_validation_alias_missing(path: str): 1abcd
371 client = TestClient(app) 1./:;=?@[
372 response = client.post(path) 1./:;=?@[
373 assert response.status_code == 422 1./:;=?@[
374 assert response.json() == { 1./:;=?@[
375 "detail": [
376 {
377 "type": "missing",
378 "loc": [
379 "body",
380 "p_val_alias",
381 ],
382 "msg": "Field required",
383 "input": None,
384 }
385 ]
386 }
389@pytest.mark.parametrize( 1abcd
390 "path",
391 [
392 "/list-bytes-alias-and-validation-alias",
393 "/list-uploadfile-alias-and-validation-alias",
394 ],
395)
396def test_list_alias_and_validation_alias_by_name(path: str): 1abcd
397 client = TestClient(app) 1]^_`{|}~
398 response = client.post(path, files=[("p", "hello"), ("p", "world")]) 1]^_`{|}~
399 assert response.status_code == 422 1]^_`{|}~
401 assert response.json() == { 1]^_`{|}~
402 "detail": [
403 {
404 "type": "missing",
405 "loc": [
406 "body",
407 "p_val_alias",
408 ],
409 "msg": "Field required",
410 "input": None,
411 }
412 ]
413 }
416@pytest.mark.parametrize( 1abcd
417 "path",
418 [
419 "/list-bytes-alias-and-validation-alias",
420 "/list-uploadfile-alias-and-validation-alias",
421 ],
422)
423def test_list_alias_and_validation_alias_by_alias(path: str): 1abcd
424 client = TestClient(app) 2abbbcbdbebfbgbhb
425 response = client.post(path, files=[("p_alias", b"hello"), ("p_alias", b"world")]) 2abbbcbdbebfbgbhb
426 assert response.status_code == 422, response.text 2abbbcbdbebfbgbhb
428 assert response.json() == { 2abbbcbdbebfbgbhb
429 "detail": [
430 {
431 "type": "missing",
432 "loc": ["body", "p_val_alias"],
433 "msg": "Field required",
434 "input": None,
435 }
436 ]
437 }
440@pytest.mark.parametrize( 1abcd
441 "path",
442 [
443 "/list-bytes-alias-and-validation-alias",
444 "/list-uploadfile-alias-and-validation-alias",
445 ],
446)
447def test_list_alias_and_validation_alias_by_validation_alias(path: str): 1abcd
448 client = TestClient(app) 1AEBFCGDH
449 response = client.post( 1AEBFCGDH
450 path, files=[("p_val_alias", b"hello"), ("p_val_alias", b"world")]
451 )
452 assert response.status_code == 200, response.text 1AEBFCGDH
453 assert response.json() == {"file_size": [5, 5]} 1AEBFCGDH