Coverage for tests/test_tutorial/test_header_param_models/test_tutorial002.py: 100%
32 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-13 13:38 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-13 13:38 +0000
1import importlib 1abcde
3import pytest 1abcde
4from dirty_equals import IsDict 1abcde
5from fastapi.testclient import TestClient 1abcde
6from inline_snapshot import snapshot 1abcde
8from tests.utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2 1abcde
11@pytest.fixture( 1abcde
12 name="client",
13 params=[
14 pytest.param("tutorial002", marks=needs_pydanticv2),
15 pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
16 pytest.param("tutorial002_an", marks=needs_pydanticv2),
17 pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]),
18 pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
19 pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]),
20 pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
21 pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]),
22 pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]),
23 pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
24 ],
25)
26def get_client(request: pytest.FixtureRequest): 1abcde
27 mod = importlib.import_module(f"docs_src.header_param_models.{request.param}") 1abcde
29 client = TestClient(mod.app) 1abcde
30 client.headers.clear() 1abcde
31 return client 1abcde
34def test_header_param_model(client: TestClient): 1abcde
35 response = client.get( 1fghij
36 "/items/",
37 headers=[
38 ("save-data", "true"),
39 ("if-modified-since", "yesterday"),
40 ("traceparent", "123"),
41 ("x-tag", "one"),
42 ("x-tag", "two"),
43 ],
44 )
45 assert response.status_code == 200, response.text 1fghij
46 assert response.json() == { 1fghij
47 "host": "testserver",
48 "save_data": True,
49 "if_modified_since": "yesterday",
50 "traceparent": "123",
51 "x_tag": ["one", "two"],
52 }
55def test_header_param_model_defaults(client: TestClient): 1abcde
56 response = client.get("/items/", headers=[("save-data", "true")]) 1klmno
57 assert response.status_code == 200 1klmno
58 assert response.json() == { 1klmno
59 "host": "testserver",
60 "save_data": True,
61 "if_modified_since": None,
62 "traceparent": None,
63 "x_tag": [],
64 }
67def test_header_param_model_invalid(client: TestClient): 1abcde
68 response = client.get("/items/") 1pqrst
69 assert response.status_code == 422 1pqrst
70 assert response.json() == snapshot( 1pqrst
71 {
72 "detail": [
73 IsDict(
74 {
75 "type": "missing",
76 "loc": ["header", "save_data"],
77 "msg": "Field required",
78 "input": {"x_tag": [], "host": "testserver"},
79 }
80 )
81 | IsDict(
82 # TODO: remove when deprecating Pydantic v1
83 {
84 "type": "value_error.missing",
85 "loc": ["header", "save_data"],
86 "msg": "field required",
87 }
88 )
89 ]
90 }
91 )
94def test_header_param_model_extra(client: TestClient): 1abcde
95 response = client.get( 1uvwxy
96 "/items/", headers=[("save-data", "true"), ("tool", "plumbus")]
97 )
98 assert response.status_code == 422, response.text 1uvwxy
99 assert response.json() == snapshot( 1uvwxy
100 {
101 "detail": [
102 IsDict(
103 {
104 "type": "extra_forbidden",
105 "loc": ["header", "tool"],
106 "msg": "Extra inputs are not permitted",
107 "input": "plumbus",
108 }
109 )
110 | IsDict(
111 # TODO: remove when deprecating Pydantic v1
112 {
113 "type": "value_error.extra",
114 "loc": ["header", "tool"],
115 "msg": "extra fields not permitted",
116 }
117 )
118 ]
119 }
120 )
123def test_openapi_schema(client: TestClient): 1abcde
124 response = client.get("/openapi.json") 1zABCD
125 assert response.status_code == 200, response.text 1zABCD
126 assert response.json() == snapshot( 1zABCD
127 {
128 "openapi": "3.1.0",
129 "info": {"title": "FastAPI", "version": "0.1.0"},
130 "paths": {
131 "/items/": {
132 "get": {
133 "summary": "Read Items",
134 "operationId": "read_items_items__get",
135 "parameters": [
136 {
137 "name": "host",
138 "in": "header",
139 "required": True,
140 "schema": {"type": "string", "title": "Host"},
141 },
142 {
143 "name": "save_data",
144 "in": "header",
145 "required": True,
146 "schema": {"type": "boolean", "title": "Save Data"},
147 },
148 {
149 "name": "if_modified_since",
150 "in": "header",
151 "required": False,
152 "schema": IsDict(
153 {
154 "anyOf": [{"type": "string"}, {"type": "null"}],
155 "title": "If Modified Since",
156 }
157 )
158 | IsDict(
159 # TODO: remove when deprecating Pydantic v1
160 {
161 "type": "string",
162 "title": "If Modified Since",
163 }
164 ),
165 },
166 {
167 "name": "traceparent",
168 "in": "header",
169 "required": False,
170 "schema": IsDict(
171 {
172 "anyOf": [{"type": "string"}, {"type": "null"}],
173 "title": "Traceparent",
174 }
175 )
176 | IsDict(
177 # TODO: remove when deprecating Pydantic v1
178 {
179 "type": "string",
180 "title": "Traceparent",
181 }
182 ),
183 },
184 {
185 "name": "x_tag",
186 "in": "header",
187 "required": False,
188 "schema": {
189 "type": "array",
190 "items": {"type": "string"},
191 "default": [],
192 "title": "X Tag",
193 },
194 },
195 ],
196 "responses": {
197 "200": {
198 "description": "Successful Response",
199 "content": {"application/json": {"schema": {}}},
200 },
201 "422": {
202 "description": "Validation Error",
203 "content": {
204 "application/json": {
205 "schema": {
206 "$ref": "#/components/schemas/HTTPValidationError"
207 }
208 }
209 },
210 },
211 },
212 }
213 }
214 },
215 "components": {
216 "schemas": {
217 "HTTPValidationError": {
218 "properties": {
219 "detail": {
220 "items": {
221 "$ref": "#/components/schemas/ValidationError"
222 },
223 "type": "array",
224 "title": "Detail",
225 }
226 },
227 "type": "object",
228 "title": "HTTPValidationError",
229 },
230 "ValidationError": {
231 "properties": {
232 "loc": {
233 "items": {
234 "anyOf": [{"type": "string"}, {"type": "integer"}]
235 },
236 "type": "array",
237 "title": "Location",
238 },
239 "msg": {"type": "string", "title": "Message"},
240 "type": {"type": "string", "title": "Error Type"},
241 },
242 "type": "object",
243 "required": ["loc", "msg", "type"],
244 "title": "ValidationError",
245 },
246 }
247 },
248 }
249 )