Coverage for tests / test_tutorial / test_body_multiple_params / test_tutorial002.py: 100%
46 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
1import importlib 1abdc
3import pytest 1abdc
4from fastapi.testclient import TestClient 1abdc
5from inline_snapshot import snapshot 1abdc
7from ...utils import needs_py310 1abdc
10@pytest.fixture( 1abdc
11 name="client",
12 params=[
13 pytest.param("tutorial002_py310", marks=needs_py310),
14 ],
15)
16def get_client(request: pytest.FixtureRequest): 1abdc
17 mod = importlib.import_module(f"docs_src.body_multiple_params.{request.param}") 1abc
19 client = TestClient(mod.app) 1abc
20 return client 1abc
23def test_post_all(client: TestClient): 1abdc
24 response = client.put( 1efg
25 "/items/5",
26 json={
27 "item": {
28 "name": "Foo",
29 "price": 50.5,
30 "description": "Some Foo",
31 "tax": 0.1,
32 },
33 "user": {"username": "johndoe", "full_name": "John Doe"},
34 },
35 )
36 assert response.status_code == 200 1efg
37 assert response.json() == { 1efg
38 "item_id": 5,
39 "item": {
40 "name": "Foo",
41 "price": 50.5,
42 "description": "Some Foo",
43 "tax": 0.1,
44 },
45 "user": {"username": "johndoe", "full_name": "John Doe"},
46 }
49def test_post_required(client: TestClient): 1abdc
50 response = client.put( 1hij
51 "/items/5",
52 json={
53 "item": {"name": "Foo", "price": 50.5},
54 "user": {"username": "johndoe"},
55 },
56 )
57 assert response.status_code == 200 1hij
58 assert response.json() == { 1hij
59 "item_id": 5,
60 "item": {
61 "name": "Foo",
62 "price": 50.5,
63 "description": None,
64 "tax": None,
65 },
66 "user": {"username": "johndoe", "full_name": None},
67 }
70def test_post_no_body(client: TestClient): 1abdc
71 response = client.put("/items/5", json=None) 1klm
72 assert response.status_code == 422 1klm
73 assert response.json() == { 1klm
74 "detail": [
75 {
76 "input": None,
77 "loc": [
78 "body",
79 "item",
80 ],
81 "msg": "Field required",
82 "type": "missing",
83 },
84 {
85 "input": None,
86 "loc": [
87 "body",
88 "user",
89 ],
90 "msg": "Field required",
91 "type": "missing",
92 },
93 ],
94 }
97def test_post_no_item(client: TestClient): 1abdc
98 response = client.put("/items/5", json={"user": {"username": "johndoe"}}) 1nop
99 assert response.status_code == 422 1nop
100 assert response.json() == { 1nop
101 "detail": [
102 {
103 "input": None,
104 "loc": [
105 "body",
106 "item",
107 ],
108 "msg": "Field required",
109 "type": "missing",
110 },
111 ],
112 }
115def test_post_no_user(client: TestClient): 1abdc
116 response = client.put("/items/5", json={"item": {"name": "Foo", "price": 50.5}}) 1qrs
117 assert response.status_code == 422 1qrs
118 assert response.json() == { 1qrs
119 "detail": [
120 {
121 "input": None,
122 "loc": [
123 "body",
124 "user",
125 ],
126 "msg": "Field required",
127 "type": "missing",
128 },
129 ],
130 }
133def test_post_missing_required_field_in_item(client: TestClient): 1abdc
134 response = client.put( 1tuv
135 "/items/5", json={"item": {"name": "Foo"}, "user": {"username": "johndoe"}}
136 )
137 assert response.status_code == 422 1tuv
138 assert response.json() == { 1tuv
139 "detail": [
140 {
141 "input": {"name": "Foo"},
142 "loc": [
143 "body",
144 "item",
145 "price",
146 ],
147 "msg": "Field required",
148 "type": "missing",
149 },
150 ],
151 }
154def test_post_missing_required_field_in_user(client: TestClient): 1abdc
155 response = client.put( 1wxy
156 "/items/5",
157 json={"item": {"name": "Foo", "price": 50.5}, "user": {"ful_name": "John Doe"}},
158 )
159 assert response.status_code == 422 1wxy
160 assert response.json() == { 1wxy
161 "detail": [
162 {
163 "input": {"ful_name": "John Doe"},
164 "loc": [
165 "body",
166 "user",
167 "username",
168 ],
169 "msg": "Field required",
170 "type": "missing",
171 },
172 ],
173 }
176def test_post_id_foo(client: TestClient): 1abdc
177 response = client.put( 1zAB
178 "/items/foo",
179 json={
180 "item": {"name": "Foo", "price": 50.5},
181 "user": {"username": "johndoe"},
182 },
183 )
184 assert response.status_code == 422 1zAB
185 assert response.json() == { 1zAB
186 "detail": [
187 {
188 "type": "int_parsing",
189 "loc": ["path", "item_id"],
190 "msg": "Input should be a valid integer, unable to parse string as an integer",
191 "input": "foo",
192 }
193 ]
194 }
197def test_openapi_schema(client: TestClient): 1abdc
198 response = client.get("/openapi.json") 1CDE
199 assert response.status_code == 200, response.text 1CDE
200 assert response.json() == snapshot( 1CDE
201 {
202 "info": {
203 "title": "FastAPI",
204 "version": "0.1.0",
205 },
206 "openapi": "3.1.0",
207 "paths": {
208 "/items/{item_id}": {
209 "put": {
210 "operationId": "update_item_items__item_id__put",
211 "parameters": [
212 {
213 "in": "path",
214 "name": "item_id",
215 "required": True,
216 "schema": {
217 "title": "Item Id",
218 "type": "integer",
219 },
220 },
221 ],
222 "requestBody": {
223 "content": {
224 "application/json": {
225 "schema": {
226 "$ref": "#/components/schemas/Body_update_item_items__item_id__put",
227 },
228 },
229 },
230 "required": True,
231 },
232 "responses": {
233 "200": {
234 "content": {
235 "application/json": {
236 "schema": {},
237 },
238 },
239 "description": "Successful Response",
240 },
241 "422": {
242 "content": {
243 "application/json": {
244 "schema": {
245 "$ref": "#/components/schemas/HTTPValidationError",
246 },
247 },
248 },
249 "description": "Validation Error",
250 },
251 },
252 "summary": "Update Item",
253 },
254 },
255 },
256 "components": {
257 "schemas": {
258 "Body_update_item_items__item_id__put": {
259 "properties": {
260 "item": {
261 "$ref": "#/components/schemas/Item",
262 },
263 "user": {
264 "$ref": "#/components/schemas/User",
265 },
266 },
267 "required": [
268 "item",
269 "user",
270 ],
271 "title": "Body_update_item_items__item_id__put",
272 "type": "object",
273 },
274 "HTTPValidationError": {
275 "properties": {
276 "detail": {
277 "items": {
278 "$ref": "#/components/schemas/ValidationError",
279 },
280 "title": "Detail",
281 "type": "array",
282 },
283 },
284 "title": "HTTPValidationError",
285 "type": "object",
286 },
287 "Item": {
288 "properties": {
289 "name": {
290 "title": "Name",
291 "type": "string",
292 },
293 "description": {
294 "title": "Description",
295 "anyOf": [{"type": "string"}, {"type": "null"}],
296 },
297 "price": {"title": "Price", "type": "number"},
298 "tax": {
299 "title": "Tax",
300 "anyOf": [{"type": "number"}, {"type": "null"}],
301 },
302 },
303 "required": [
304 "name",
305 "price",
306 ],
307 "title": "Item",
308 "type": "object",
309 },
310 "User": {
311 "properties": {
312 "username": {
313 "title": "Username",
314 "type": "string",
315 },
316 "full_name": {
317 "title": "Full Name",
318 "anyOf": [{"type": "string"}, {"type": "null"}],
319 },
320 },
321 "required": [
322 "username",
323 ],
324 "title": "User",
325 "type": "object",
326 },
327 "ValidationError": {
328 "properties": {
329 "ctx": {"title": "Context", "type": "object"},
330 "input": {"title": "Input"},
331 "loc": {
332 "items": {
333 "anyOf": [
334 {
335 "type": "string",
336 },
337 {
338 "type": "integer",
339 },
340 ],
341 },
342 "title": "Location",
343 "type": "array",
344 },
345 "msg": {
346 "title": "Message",
347 "type": "string",
348 },
349 "type": {
350 "title": "Error Type",
351 "type": "string",
352 },
353 },
354 "required": [
355 "loc",
356 "msg",
357 "type",
358 ],
359 "title": "ValidationError",
360 "type": "object",
361 },
362 },
363 },
364 }
365 )