Coverage for tests/test_tutorial/test_header_param_models/test_tutorial003.py: 100%
35 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-05 00:03 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-05 00:03 +0000
1import importlib 1abcdef
3import pytest 1abcdef
4from dirty_equals import IsDict 1abcdef
5from fastapi.testclient import TestClient 1abcdef
6from inline_snapshot import snapshot 1abcdef
8from tests.utils import needs_py39, needs_py310 1abcdef
11@pytest.fixture( 1abcdef
12 name="client",
13 params=[
14 "tutorial003",
15 pytest.param("tutorial003_py39", marks=needs_py39),
16 pytest.param("tutorial003_py310", marks=needs_py310),
17 "tutorial003_an",
18 pytest.param("tutorial003_an_py39", marks=needs_py39),
19 pytest.param("tutorial003_an_py310", marks=needs_py310),
20 ],
21)
22def get_client(request: pytest.FixtureRequest): 1abcdef
23 mod = importlib.import_module(f"docs_src.header_param_models.{request.param}") 1abcdef
25 client = TestClient(mod.app) 1abcdef
26 return client 1abcdef
29def test_header_param_model(client: TestClient): 1abcdef
30 response = client.get( 1ghijkl
31 "/items/",
32 headers=[
33 ("save_data", "true"),
34 ("if_modified_since", "yesterday"),
35 ("traceparent", "123"),
36 ("x_tag", "one"),
37 ("x_tag", "two"),
38 ],
39 )
40 assert response.status_code == 200 1ghijkl
41 assert response.json() == { 1ghijkl
42 "host": "testserver",
43 "save_data": True,
44 "if_modified_since": "yesterday",
45 "traceparent": "123",
46 "x_tag": ["one", "two"],
47 }
50def test_header_param_model_no_underscore(client: TestClient): 1abcdef
51 response = client.get( 1mnopqr
52 "/items/",
53 headers=[
54 ("save-data", "true"),
55 ("if-modified-since", "yesterday"),
56 ("traceparent", "123"),
57 ("x-tag", "one"),
58 ("x-tag", "two"),
59 ],
60 )
61 assert response.status_code == 422 1mnopqr
62 assert response.json() == snapshot( 1mnopqr
63 {
64 "detail": [
65 IsDict(
66 {
67 "type": "missing",
68 "loc": ["header", "save_data"],
69 "msg": "Field required",
70 "input": {
71 "host": "testserver",
72 "traceparent": "123",
73 "x_tag": [],
74 "accept": "*/*",
75 "accept-encoding": "gzip, deflate",
76 "connection": "keep-alive",
77 "user-agent": "testclient",
78 "save-data": "true",
79 "if-modified-since": "yesterday",
80 "x-tag": "two",
81 },
82 }
83 )
84 | IsDict(
85 # TODO: remove when deprecating Pydantic v1
86 {
87 "type": "value_error.missing",
88 "loc": ["header", "save_data"],
89 "msg": "field required",
90 }
91 )
92 ]
93 }
94 )
97def test_header_param_model_defaults(client: TestClient): 1abcdef
98 response = client.get("/items/", headers=[("save_data", "true")]) 1stuvwx
99 assert response.status_code == 200 1stuvwx
100 assert response.json() == { 1stuvwx
101 "host": "testserver",
102 "save_data": True,
103 "if_modified_since": None,
104 "traceparent": None,
105 "x_tag": [],
106 }
109def test_header_param_model_invalid(client: TestClient): 1abcdef
110 response = client.get("/items/") 1yzABCD
111 assert response.status_code == 422 1yzABCD
112 assert response.json() == snapshot( 1yzABCD
113 {
114 "detail": [
115 IsDict(
116 {
117 "type": "missing",
118 "loc": ["header", "save_data"],
119 "msg": "Field required",
120 "input": {
121 "x_tag": [],
122 "host": "testserver",
123 "accept": "*/*",
124 "accept-encoding": "gzip, deflate",
125 "connection": "keep-alive",
126 "user-agent": "testclient",
127 },
128 }
129 )
130 | IsDict(
131 # TODO: remove when deprecating Pydantic v1
132 {
133 "type": "value_error.missing",
134 "loc": ["header", "save_data"],
135 "msg": "field required",
136 }
137 )
138 ]
139 }
140 )
143def test_header_param_model_extra(client: TestClient): 1abcdef
144 response = client.get( 1EFGHIJ
145 "/items/", headers=[("save_data", "true"), ("tool", "plumbus")]
146 )
147 assert response.status_code == 200, response.text 1EFGHIJ
148 assert response.json() == snapshot( 1EFGHIJ
149 {
150 "host": "testserver",
151 "save_data": True,
152 "if_modified_since": None,
153 "traceparent": None,
154 "x_tag": [],
155 }
156 )
159def test_openapi_schema(client: TestClient): 1abcdef
160 response = client.get("/openapi.json") 1KLMNOP
161 assert response.status_code == 200, response.text 1KLMNOP
162 assert response.json() == snapshot( 1KLMNOP
163 {
164 "openapi": "3.1.0",
165 "info": {"title": "FastAPI", "version": "0.1.0"},
166 "paths": {
167 "/items/": {
168 "get": {
169 "summary": "Read Items",
170 "operationId": "read_items_items__get",
171 "parameters": [
172 {
173 "name": "host",
174 "in": "header",
175 "required": True,
176 "schema": {"type": "string", "title": "Host"},
177 },
178 {
179 "name": "save_data",
180 "in": "header",
181 "required": True,
182 "schema": {"type": "boolean", "title": "Save Data"},
183 },
184 {
185 "name": "if_modified_since",
186 "in": "header",
187 "required": False,
188 "schema": IsDict(
189 {
190 "anyOf": [{"type": "string"}, {"type": "null"}],
191 "title": "If Modified Since",
192 }
193 )
194 | IsDict(
195 # TODO: remove when deprecating Pydantic v1
196 {
197 "type": "string",
198 "title": "If Modified Since",
199 }
200 ),
201 },
202 {
203 "name": "traceparent",
204 "in": "header",
205 "required": False,
206 "schema": IsDict(
207 {
208 "anyOf": [{"type": "string"}, {"type": "null"}],
209 "title": "Traceparent",
210 }
211 )
212 | IsDict(
213 # TODO: remove when deprecating Pydantic v1
214 {
215 "type": "string",
216 "title": "Traceparent",
217 }
218 ),
219 },
220 {
221 "name": "x_tag",
222 "in": "header",
223 "required": False,
224 "schema": {
225 "type": "array",
226 "items": {"type": "string"},
227 "default": [],
228 "title": "X Tag",
229 },
230 },
231 ],
232 "responses": {
233 "200": {
234 "description": "Successful Response",
235 "content": {"application/json": {"schema": {}}},
236 },
237 "422": {
238 "description": "Validation Error",
239 "content": {
240 "application/json": {
241 "schema": {
242 "$ref": "#/components/schemas/HTTPValidationError"
243 }
244 }
245 },
246 },
247 },
248 }
249 }
250 },
251 "components": {
252 "schemas": {
253 "HTTPValidationError": {
254 "properties": {
255 "detail": {
256 "items": {
257 "$ref": "#/components/schemas/ValidationError"
258 },
259 "type": "array",
260 "title": "Detail",
261 }
262 },
263 "type": "object",
264 "title": "HTTPValidationError",
265 },
266 "ValidationError": {
267 "properties": {
268 "loc": {
269 "items": {
270 "anyOf": [{"type": "string"}, {"type": "integer"}]
271 },
272 "type": "array",
273 "title": "Location",
274 },
275 "msg": {"type": "string", "title": "Message"},
276 "type": {"type": "string", "title": "Error Type"},
277 },
278 "type": "object",
279 "required": ["loc", "msg", "type"],
280 "title": "ValidationError",
281 },
282 }
283 },
284 }
285 )