Coverage for tests / test_request_params / test_header / test_optional_str.py: 100%
123 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, Optional 1abcd
3import pytest 1abcd
4from fastapi import FastAPI, Header 1abcd
5from fastapi.testclient import TestClient 1abcd
6from inline_snapshot import snapshot 1abcd
7from pydantic import BaseModel, Field 1abcd
9app = FastAPI() 1abcd
11# =====================================================================================
12# Without aliases
15@app.get("/optional-str") 1abcd
16async def read_optional_str(p: Annotated[Optional[str], Header()] = None): 1abcd
17 return {"p": p} 1efghij
20class HeaderModelOptionalStr(BaseModel): 1abcd
21 p: Optional[str] = None 1abcd
24@app.get("/model-optional-str") 1abcd
25async def read_model_optional_str(p: Annotated[HeaderModelOptionalStr, Header()]): 1abcd
26 return {"p": p.p} 1efghij
29@pytest.mark.parametrize( 1abcd
30 "path",
31 ["/optional-str", "/model-optional-str"],
32)
33def test_optional_str_schema(path: str): 1abcd
34 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 1OPQ
35 [
36 {
37 "required": False,
38 "schema": {
39 "anyOf": [{"type": "string"}, {"type": "null"}],
40 "title": "P",
41 },
42 "name": "p",
43 "in": "header",
44 }
45 ]
46 )
49@pytest.mark.parametrize( 1abcd
50 "path",
51 ["/optional-str", "/model-optional-str"],
52)
53def test_optional_str_missing(path: str): 1abcd
54 client = TestClient(app) 1fhj
55 response = client.get(path) 1fhj
56 assert response.status_code == 200 1fhj
57 assert response.json() == {"p": None} 1fhj
60@pytest.mark.parametrize( 1abcd
61 "path",
62 ["/optional-str", "/model-optional-str"],
63)
64def test_optional_str(path: str): 1abcd
65 client = TestClient(app) 1egi
66 response = client.get(path, headers={"p": "hello"}) 1egi
67 assert response.status_code == 200 1egi
68 assert response.json() == {"p": "hello"} 1egi
71# =====================================================================================
72# Alias
75@app.get("/optional-alias") 1abcd
76async def read_optional_alias( 1abcd
77 p: Annotated[Optional[str], Header(alias="p_alias")] = None,
78):
79 return {"p": p} 1klmnopqrs
82class HeaderModelOptionalAlias(BaseModel): 1abcd
83 p: Optional[str] = Field(None, alias="p_alias") 1abcd
86@app.get("/model-optional-alias") 1abcd
87async def read_model_optional_alias(p: Annotated[HeaderModelOptionalAlias, Header()]): 1abcd
88 return {"p": p.p} 1klmnopqrs
91@pytest.mark.parametrize( 1abcd
92 "path",
93 ["/optional-alias", "/model-optional-alias"],
94)
95def test_optional_str_alias_schema(path: str): 1abcd
96 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 1RST
97 [
98 {
99 "required": False,
100 "schema": {
101 "anyOf": [{"type": "string"}, {"type": "null"}],
102 "title": "P Alias",
103 },
104 "name": "p_alias",
105 "in": "header",
106 }
107 ]
108 )
111@pytest.mark.parametrize( 1abcd
112 "path",
113 ["/optional-alias", "/model-optional-alias"],
114)
115def test_optional_alias_missing(path: str): 1abcd
116 client = TestClient(app) 1mps
117 response = client.get(path) 1mps
118 assert response.status_code == 200 1mps
119 assert response.json() == {"p": None} 1mps
122@pytest.mark.parametrize( 1abcd
123 "path",
124 ["/optional-alias", "/model-optional-alias"],
125)
126def test_optional_alias_by_name(path: str): 1abcd
127 client = TestClient(app) 1lor
128 response = client.get(path, headers={"p": "hello"}) 1lor
129 assert response.status_code == 200 1lor
130 assert response.json() == {"p": None} 1lor
133@pytest.mark.parametrize( 1abcd
134 "path",
135 [
136 "/optional-alias",
137 "/model-optional-alias",
138 ],
139)
140def test_optional_alias_by_alias(path: str): 1abcd
141 client = TestClient(app) 1knq
142 response = client.get(path, headers={"p_alias": "hello"}) 1knq
143 assert response.status_code == 200 1knq
144 assert response.json() == {"p": "hello"} 1knq
147# =====================================================================================
148# Validation alias
151@app.get("/optional-validation-alias") 1abcd
152def read_optional_validation_alias( 1abcd
153 p: Annotated[Optional[str], Header(validation_alias="p_val_alias")] = None,
154):
155 return {"p": p} 1tuvwxyzAB
158class HeaderModelOptionalValidationAlias(BaseModel): 1abcd
159 p: Optional[str] = Field(None, validation_alias="p_val_alias") 1abcd
162@app.get("/model-optional-validation-alias") 1abcd
163def read_model_optional_validation_alias( 1abcd
164 p: Annotated[HeaderModelOptionalValidationAlias, Header()],
165):
166 return {"p": p.p} 1tuvwxyzAB
169@pytest.mark.parametrize( 1abcd
170 "path",
171 ["/optional-validation-alias", "/model-optional-validation-alias"],
172)
173def test_optional_validation_alias_schema(path: str): 1abcd
174 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 1UVW
175 [
176 {
177 "required": False,
178 "schema": {
179 "anyOf": [{"type": "string"}, {"type": "null"}],
180 "title": "P Val Alias",
181 },
182 "name": "p_val_alias",
183 "in": "header",
184 }
185 ]
186 )
189@pytest.mark.parametrize( 1abcd
190 "path",
191 ["/optional-validation-alias", "/model-optional-validation-alias"],
192)
193def test_optional_validation_alias_missing(path: str): 1abcd
194 client = TestClient(app) 1vyB
195 response = client.get(path) 1vyB
196 assert response.status_code == 200 1vyB
197 assert response.json() == {"p": None} 1vyB
200@pytest.mark.parametrize( 1abcd
201 "path",
202 [
203 "/optional-validation-alias",
204 "/model-optional-validation-alias",
205 ],
206)
207def test_optional_validation_alias_by_name(path: str): 1abcd
208 client = TestClient(app) 1twz
209 response = client.get(path, headers={"p": "hello"}) 1twz
210 assert response.status_code == 200 1twz
211 assert response.json() == {"p": None} 1twz
214@pytest.mark.parametrize( 1abcd
215 "path",
216 [
217 "/optional-validation-alias",
218 "/model-optional-validation-alias",
219 ],
220)
221def test_optional_validation_alias_by_validation_alias(path: str): 1abcd
222 client = TestClient(app) 1uxA
223 response = client.get(path, headers={"p_val_alias": "hello"}) 1uxA
224 assert response.status_code == 200 1uxA
225 assert response.json() == {"p": "hello"} 1uxA
228# =====================================================================================
229# Alias and validation alias
232@app.get("/optional-alias-and-validation-alias") 1abcd
233def read_optional_alias_and_validation_alias( 1abcd
234 p: Annotated[
235 Optional[str], Header(alias="p_alias", validation_alias="p_val_alias")
236 ] = None,
237):
238 return {"p": p} 1CDEFGHIJKLMN
241class HeaderModelOptionalAliasAndValidationAlias(BaseModel): 1abcd
242 p: Optional[str] = Field(None, alias="p_alias", validation_alias="p_val_alias") 1abcd
245@app.get("/model-optional-alias-and-validation-alias") 1abcd
246def read_model_optional_alias_and_validation_alias( 1abcd
247 p: Annotated[HeaderModelOptionalAliasAndValidationAlias, Header()],
248):
249 return {"p": p.p} 1CDEFGHIJKLMN
252@pytest.mark.parametrize( 1abcd
253 "path",
254 [
255 "/optional-alias-and-validation-alias",
256 "/model-optional-alias-and-validation-alias",
257 ],
258)
259def test_optional_alias_and_validation_alias_schema(path: str): 1abcd
260 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 1XYZ
261 [
262 {
263 "required": False,
264 "schema": {
265 "anyOf": [{"type": "string"}, {"type": "null"}],
266 "title": "P Val Alias",
267 },
268 "name": "p_val_alias",
269 "in": "header",
270 }
271 ]
272 )
275@pytest.mark.parametrize( 1abcd
276 "path",
277 [
278 "/optional-alias-and-validation-alias",
279 "/model-optional-alias-and-validation-alias",
280 ],
281)
282def test_optional_alias_and_validation_alias_missing(path: str): 1abcd
283 client = TestClient(app) 1FJN
284 response = client.get(path) 1FJN
285 assert response.status_code == 200 1FJN
286 assert response.json() == {"p": None} 1FJN
289@pytest.mark.parametrize( 1abcd
290 "path",
291 [
292 "/optional-alias-and-validation-alias",
293 "/model-optional-alias-and-validation-alias",
294 ],
295)
296def test_optional_alias_and_validation_alias_by_name(path: str): 1abcd
297 client = TestClient(app) 1DHL
298 response = client.get(path, headers={"p": "hello"}) 1DHL
299 assert response.status_code == 200 1DHL
300 assert response.json() == {"p": None} 1DHL
303@pytest.mark.parametrize( 1abcd
304 "path",
305 [
306 "/optional-alias-and-validation-alias",
307 "/model-optional-alias-and-validation-alias",
308 ],
309)
310def test_optional_alias_and_validation_alias_by_alias(path: str): 1abcd
311 client = TestClient(app) 1CGK
312 response = client.get(path, headers={"p_alias": "hello"}) 1CGK
313 assert response.status_code == 200 1CGK
314 assert response.json() == {"p": None} 1CGK
317@pytest.mark.parametrize( 1abcd
318 "path",
319 [
320 "/optional-alias-and-validation-alias",
321 "/model-optional-alias-and-validation-alias",
322 ],
323)
324def test_optional_alias_and_validation_alias_by_validation_alias(path: str): 1abcd
325 client = TestClient(app) 1EIM
326 response = client.get(path, headers={"p_val_alias": "hello"}) 1EIM
327 assert response.status_code == 200 1EIM
328 assert response.json() == {"p": "hello"} 1EIM