Coverage for tests / test_request_params / test_header / test_list.py: 100%
124 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 AnyThing, IsOneOf, IsPartialDict 1adbc
5from fastapi import FastAPI, Header 1adbc
6from fastapi.testclient import TestClient 1adbc
7from inline_snapshot import snapshot 1adbc
8from pydantic import BaseModel, Field 1adbc
10app = FastAPI() 1adbc
12# =====================================================================================
13# Without aliases
16@app.get("/required-list-str") 1adbc
17async def read_required_list_str(p: Annotated[list[str], Header()]): 1adbc
18 return {"p": p} 1efgh
21class HeaderModelRequiredListStr(BaseModel): 1adbc
22 p: list[str] 1abc
25@app.get("/model-required-list-str") 1adbc
26def read_model_required_list_str(p: Annotated[HeaderModelRequiredListStr, Header()]): 1adbc
27 return {"p": p.p} 1ijkl
30@pytest.mark.parametrize( 1adbc
31 "path",
32 ["/required-list-str", "/model-required-list-str"],
33)
34def test_required_list_str_schema(path: str): 1adbc
35 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 2kblbmbnbobpbqbrb
36 [
37 {
38 "required": True,
39 "schema": {
40 "title": "P",
41 "type": "array",
42 "items": {"type": "string"},
43 },
44 "name": "p",
45 "in": "header",
46 }
47 ]
48 )
51@pytest.mark.parametrize( 1adbc
52 "path",
53 ["/required-list-str", "/model-required-list-str"],
54)
55def test_required_list_str_missing(path: str): 1adbc
56 client = TestClient(app) 1KLMNOPQR
57 response = client.get(path) 1KLMNOPQR
58 assert response.status_code == 422 1KLMNOPQR
59 assert response.json() == { 1KLMNOPQR
60 "detail": [
61 {
62 "type": "missing",
63 "loc": ["header", "p"],
64 "msg": "Field required",
65 "input": AnyThing,
66 }
67 ]
68 }
71@pytest.mark.parametrize( 1adbc
72 "path",
73 ["/required-list-str", "/model-required-list-str"],
74)
75def test_required_list_str(path: str): 1adbc
76 client = TestClient(app) 1iejfkglh
77 response = client.get(path, headers=[("p", "hello"), ("p", "world")]) 1iejfkglh
78 assert response.status_code == 200 1iejfkglh
79 assert response.json() == {"p": ["hello", "world"]} 1iejfkglh
82# =====================================================================================
83# Alias
86@app.get("/required-list-alias") 1adbc
87async def read_required_list_alias(p: Annotated[list[str], Header(alias="p_alias")]): 1adbc
88 return {"p": p} 1mnop
91class HeaderModelRequiredListAlias(BaseModel): 1adbc
92 p: list[str] = Field(alias="p_alias") 1adbc
95@app.get("/model-required-list-alias") 1adbc
96async def read_model_required_list_alias( 1adbc
97 p: Annotated[HeaderModelRequiredListAlias, Header()],
98):
99 return {"p": p.p} 1qrst
102@pytest.mark.parametrize( 1adbc
103 "path",
104 ["/required-list-alias", "/model-required-list-alias"],
105)
106def test_required_list_str_alias_schema(path: str): 1adbc
107 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 2sbtbubvbwbxbybzb
108 [
109 {
110 "required": True,
111 "schema": {
112 "title": "P Alias",
113 "type": "array",
114 "items": {"type": "string"},
115 },
116 "name": "p_alias",
117 "in": "header",
118 }
119 ]
120 )
123@pytest.mark.parametrize( 1adbc
124 "path",
125 ["/required-list-alias", "/model-required-list-alias"],
126)
127def test_required_list_alias_missing(path: str): 1adbc
128 client = TestClient(app) 1STUVWXYZ
129 response = client.get(path) 1STUVWXYZ
130 assert response.status_code == 422 1STUVWXYZ
131 assert response.json() == { 1STUVWXYZ
132 "detail": [
133 {
134 "type": "missing",
135 "loc": ["header", "p_alias"],
136 "msg": "Field required",
137 "input": AnyThing,
138 }
139 ]
140 }
143@pytest.mark.parametrize( 1adbc
144 "path",
145 [
146 "/required-list-alias",
147 "/model-required-list-alias",
148 ],
149)
150def test_required_list_alias_by_name(path: str): 1adbc
151 client = TestClient(app) 101234567
152 response = client.get(path, headers=[("p", "hello"), ("p", "world")]) 101234567
153 assert response.status_code == 422 101234567
154 assert response.json() == { 101234567
155 "detail": [
156 {
157 "type": "missing",
158 "loc": ["header", "p_alias"],
159 "msg": "Field required",
160 "input": IsOneOf(None, IsPartialDict({"p": ["hello", "world"]})),
161 }
162 ]
163 }
166@pytest.mark.parametrize( 1adbc
167 "path",
168 [
169 "/required-list-alias",
170 "/model-required-list-alias",
171 ],
172)
173def test_required_list_alias_by_alias(path: str): 1adbc
174 client = TestClient(app) 1qmrnsotp
175 response = client.get(path, headers=[("p_alias", "hello"), ("p_alias", "world")]) 1qmrnsotp
176 assert response.status_code == 200, response.text 1qmrnsotp
177 assert response.json() == {"p": ["hello", "world"]} 1qmrnsotp
180# =====================================================================================
181# Validation alias
184@app.get("/required-list-validation-alias") 1adbc
185def read_required_list_validation_alias( 1adbc
186 p: Annotated[list[str], Header(validation_alias="p_val_alias")],
187):
188 return {"p": p} 1uvwx
191class HeaderModelRequiredListValidationAlias(BaseModel): 1adbc
192 p: list[str] = Field(validation_alias="p_val_alias") 1adbc
195@app.get("/model-required-list-validation-alias") 1adbc
196async def read_model_required_list_validation_alias( 1adbc
197 p: Annotated[HeaderModelRequiredListValidationAlias, Header()],
198):
199 return {"p": p.p} 1yzAB
202@pytest.mark.parametrize( 1adbc
203 "path",
204 ["/required-list-validation-alias", "/model-required-list-validation-alias"],
205)
206def test_required_list_validation_alias_schema(path: str): 1adbc
207 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 2AbBbCbDbEbFbGbHb
208 [
209 {
210 "required": True,
211 "schema": {
212 "title": "P Val Alias",
213 "type": "array",
214 "items": {"type": "string"},
215 },
216 "name": "p_val_alias",
217 "in": "header",
218 }
219 ]
220 )
223@pytest.mark.parametrize( 1adbc
224 "path",
225 [
226 "/required-list-validation-alias",
227 "/model-required-list-validation-alias",
228 ],
229)
230def test_required_list_validation_alias_missing(path: str): 1adbc
231 client = TestClient(app) 189!#$%'(
232 response = client.get(path) 189!#$%'(
233 assert response.status_code == 422 189!#$%'(
234 assert response.json() == { 189!#$%'(
235 "detail": [
236 {
237 "type": "missing",
238 "loc": [
239 "header",
240 "p_val_alias",
241 ],
242 "msg": "Field required",
243 "input": AnyThing,
244 }
245 ]
246 }
249@pytest.mark.parametrize( 1adbc
250 "path",
251 [
252 "/required-list-validation-alias",
253 "/model-required-list-validation-alias",
254 ],
255)
256def test_required_list_validation_alias_by_name(path: str): 1adbc
257 client = TestClient(app) 1)*+,-./
258 response = client.get(path, headers=[("p", "hello"), ("p", "world")]) 1)*+,-./
259 assert response.status_code == 422 1)*+,-./
261 assert response.json() == { 1)*+,-./
262 "detail": [
263 {
264 "type": "missing",
265 "loc": ["header", "p_val_alias"],
266 "msg": "Field required",
267 "input": IsOneOf(None, IsPartialDict({"p": ["hello", "world"]})),
268 }
269 ]
270 }
273@pytest.mark.parametrize( 1adbc
274 "path",
275 ["/required-list-validation-alias", "/model-required-list-validation-alias"],
276)
277def test_required_list_validation_alias_by_validation_alias(path: str): 1adbc
278 client = TestClient(app) 1yuzvAwBx
279 response = client.get( 1yuzvAwBx
280 path, headers=[("p_val_alias", "hello"), ("p_val_alias", "world")]
281 )
282 assert response.status_code == 200, response.text 1yuzvAwBx
284 assert response.json() == {"p": ["hello", "world"]} 1yuzvAwBx
287# =====================================================================================
288# Alias and validation alias
291@app.get("/required-list-alias-and-validation-alias") 1adbc
292def read_required_list_alias_and_validation_alias( 1adbc
293 p: Annotated[list[str], Header(alias="p_alias", validation_alias="p_val_alias")],
294):
295 return {"p": p} 1CDEF
298class HeaderModelRequiredListAliasAndValidationAlias(BaseModel): 1adbc
299 p: list[str] = Field(alias="p_alias", validation_alias="p_val_alias") 1adbc
302@app.get("/model-required-list-alias-and-validation-alias") 1adbc
303def read_model_required_list_alias_and_validation_alias( 1adbc
304 p: Annotated[HeaderModelRequiredListAliasAndValidationAlias, Header()],
305):
306 return {"p": p.p} 1GHIJ
309@pytest.mark.parametrize( 1adbc
310 "path",
311 [
312 "/required-list-alias-and-validation-alias",
313 "/model-required-list-alias-and-validation-alias",
314 ],
315)
316def test_required_list_alias_and_validation_alias_schema(path: str): 1adbc
317 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 2IbJbKbLbMbNbObPb
318 [
319 {
320 "required": True,
321 "schema": {
322 "title": "P Val Alias",
323 "type": "array",
324 "items": {"type": "string"},
325 },
326 "name": "p_val_alias",
327 "in": "header",
328 }
329 ]
330 )
333@pytest.mark.parametrize( 1adbc
334 "path",
335 [
336 "/required-list-alias-and-validation-alias",
337 "/model-required-list-alias-and-validation-alias",
338 ],
339)
340def test_required_list_alias_and_validation_alias_missing(path: str): 1adbc
341 client = TestClient(app) 1:;=?@[]^
342 response = client.get(path) 1:;=?@[]^
343 assert response.status_code == 422 1:;=?@[]^
344 assert response.json() == { 1:;=?@[]^
345 "detail": [
346 {
347 "type": "missing",
348 "loc": [
349 "header",
350 "p_val_alias",
351 ],
352 "msg": "Field required",
353 "input": AnyThing,
354 }
355 ]
356 }
359@pytest.mark.parametrize( 1adbc
360 "path",
361 [
362 "/required-list-alias-and-validation-alias",
363 "/model-required-list-alias-and-validation-alias",
364 ],
365)
366def test_required_list_alias_and_validation_alias_by_name(path: str): 1adbc
367 client = TestClient(app) 2_ ` { | } ~ abbb
368 response = client.get(path, headers=[("p", "hello"), ("p", "world")]) 2_ ` { | } ~ abbb
369 assert response.status_code == 422 2_ ` { | } ~ abbb
370 assert response.json() == { 2_ ` { | } ~ abbb
371 "detail": [
372 {
373 "type": "missing",
374 "loc": [
375 "header",
376 "p_val_alias",
377 ],
378 "msg": "Field required",
379 "input": IsOneOf(
380 None,
381 IsPartialDict({"p": ["hello", "world"]}),
382 ),
383 }
384 ]
385 }
388@pytest.mark.parametrize( 1adbc
389 "path",
390 [
391 "/required-list-alias-and-validation-alias",
392 "/model-required-list-alias-and-validation-alias",
393 ],
394)
395def test_required_list_alias_and_validation_alias_by_alias(path: str): 1adbc
396 client = TestClient(app) 2cbdbebfbgbhbibjb
397 response = client.get(path, headers=[("p_alias", "hello"), ("p_alias", "world")]) 2cbdbebfbgbhbibjb
398 assert response.status_code == 422 2cbdbebfbgbhbibjb
399 assert response.json() == { 2cbdbebfbgbhbibjb
400 "detail": [
401 {
402 "type": "missing",
403 "loc": ["header", "p_val_alias"],
404 "msg": "Field required",
405 "input": IsOneOf(
406 None,
407 IsPartialDict({"p_alias": ["hello", "world"]}),
408 ),
409 }
410 ]
411 }
414@pytest.mark.parametrize( 1adbc
415 "path",
416 [
417 "/required-list-alias-and-validation-alias",
418 "/model-required-list-alias-and-validation-alias",
419 ],
420)
421def test_required_list_alias_and_validation_alias_by_validation_alias(path: str): 1adbc
422 client = TestClient(app) 1GCHDIEJF
423 response = client.get( 1GCHDIEJF
424 path, headers=[("p_val_alias", "hello"), ("p_val_alias", "world")]
425 )
426 assert response.status_code == 200, response.text 1GCHDIEJF
427 assert response.json() == {"p": ["hello", "world"]} 1GCHDIEJF