Coverage for tests / test_tutorial / test_fastapi / test_relationships / test_tutorial001.py: 100%
89 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-06-10 09:40 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-06-10 09:40 +0000
1import importlib 1ijklmnop
2from types import ModuleType 1ijklmnop
4import pytest 1ijklmnop
5from dirty_equals import IsOneOf 1ijklmnop
6from fastapi.testclient import TestClient 1ijklmnop
7from sqlmodel import create_engine 1ijklmnop
8from sqlmodel.pool import StaticPool 1ijklmnop
11@pytest.fixture( 1ijklmnop
12 name="module",
13 params=[
14 pytest.param("tutorial001_py310"),
15 ],
16)
17def get_module(request: pytest.FixtureRequest) -> ModuleType: 1ijklmnop
18 mod = importlib.import_module( 1ijklmnop
19 f"docs_src.tutorial.fastapi.relationships.{request.param}"
20 )
21 mod.sqlite_url = "sqlite://" 1ijklmnop
22 mod.engine = create_engine( 1ijklmnop
23 mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
24 )
25 return mod 1ijklmnop
28def test_tutorial(module: ModuleType): 1ijklmnop
29 with TestClient(module.app) as client: 1abcdefgh
30 team_preventers = {"name": "Preventers", "headquarters": "Sharp Tower"} 1abcdefgh
31 team_z_force = {"name": "Z-Force", "headquarters": "Sister Margaret's Bar"} 1abcdefgh
32 response = client.post("/teams/", json=team_preventers) 1abcdefgh
33 assert response.status_code == 200, response.text 1abcdefgh
34 team_preventers_data = response.json() 1abcdefgh
35 team_preventers_id = team_preventers_data["id"] 1abcdefgh
36 response = client.post("/teams/", json=team_z_force) 1abcdefgh
37 assert response.status_code == 200, response.text 1abcdefgh
38 team_z_force_data = response.json() 1abcdefgh
39 team_z_force_id = team_z_force_data["id"] 1abcdefgh
40 response = client.get("/teams/") 1abcdefgh
41 data = response.json() 1abcdefgh
42 assert len(data) == 2 1abcdefgh
43 response = client.get("/teams/9000") 1abcdefgh
44 assert response.status_code == 404, response.text 1abcdefgh
45 response = client.patch( 1abcdefgh
46 f"/teams/{team_preventers_id}", json={"headquarters": "Preventers Tower"}
47 )
48 data = response.json() 1abcdefgh
49 assert response.status_code == 200, response.text 1abcdefgh
50 assert data["name"] == team_preventers["name"] 1abcdefgh
51 assert data["headquarters"] == "Preventers Tower" 1abcdefgh
52 response = client.patch("/teams/9000", json={"name": "Freedom League"}) 1abcdefgh
53 assert response.status_code == 404, response.text 1abcdefgh
55 hero1_data = { 1abcdefgh
56 "name": "Deadpond",
57 "secret_name": "Dive Wilson",
58 "team_id": team_z_force_id,
59 }
60 hero2_data = { 1abcdefgh
61 "name": "Spider-Boy",
62 "secret_name": "Pedro Parqueador",
63 "id": 9000,
64 }
65 hero3_data = { 1abcdefgh
66 "name": "Rusty-Man",
67 "secret_name": "Tommy Sharp",
68 "age": 48,
69 "team_id": team_preventers_id,
70 }
71 response = client.post("/heroes/", json=hero1_data) 1abcdefgh
72 assert response.status_code == 200, response.text 1abcdefgh
73 hero1 = response.json() 1abcdefgh
74 hero1_id = hero1["id"] 1abcdefgh
75 response = client.post("/heroes/", json=hero2_data) 1abcdefgh
76 assert response.status_code == 200, response.text 1abcdefgh
77 hero2 = response.json() 1abcdefgh
78 hero2_id = hero2["id"] 1abcdefgh
79 response = client.post("/heroes/", json=hero3_data) 1abcdefgh
80 assert response.status_code == 200, response.text 1abcdefgh
81 response = client.get("/heroes/9000") 1abcdefgh
82 assert response.status_code == 404, response.text 1abcdefgh
83 response = client.get("/heroes/") 1abcdefgh
84 assert response.status_code == 200, response.text 1abcdefgh
85 data = response.json() 1abcdefgh
86 assert len(data) == 3 1abcdefgh
87 response = client.get(f"/heroes/{hero1_id}") 1abcdefgh
88 assert response.status_code == 200, response.text 1abcdefgh
89 data = response.json() 1abcdefgh
90 assert data["name"] == hero1_data["name"] 1abcdefgh
91 assert data["team"]["name"] == team_z_force["name"] 1abcdefgh
92 response = client.patch( 1abcdefgh
93 f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
94 )
95 assert response.status_code == 200, response.text 1abcdefgh
96 response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"}) 1abcdefgh
97 assert response.status_code == 404, response.text 1abcdefgh
98 response = client.delete(f"/heroes/{hero2_id}") 1abcdefgh
99 assert response.status_code == 200, response.text 1abcdefgh
100 response = client.get("/heroes/") 1abcdefgh
101 assert response.status_code == 200, response.text 1abcdefgh
102 data = response.json() 1abcdefgh
103 assert len(data) == 2 1abcdefgh
104 response = client.delete("/heroes/9000") 1abcdefgh
105 assert response.status_code == 404, response.text 1abcdefgh
107 response = client.get(f"/teams/{team_preventers_id}") 1abcdefgh
108 data = response.json() 1abcdefgh
109 assert response.status_code == 200, response.text 1abcdefgh
110 assert data["name"] == team_preventers_data["name"] 1abcdefgh
111 assert data["heroes"][0]["name"] == hero3_data["name"] 1abcdefgh
113 response = client.delete(f"/teams/{team_preventers_id}") 1abcdefgh
114 assert response.status_code == 200, response.text 1abcdefgh
115 response = client.delete("/teams/9000") 1abcdefgh
116 assert response.status_code == 404, response.text 1abcdefgh
117 response = client.get("/teams/") 1abcdefgh
118 assert response.status_code == 200, response.text 1abcdefgh
119 data = response.json() 1abcdefgh
120 assert len(data) == 1 1abcdefgh
122 response = client.get("/openapi.json") 1abcdefgh
123 assert response.status_code == 200, response.text 1abcdefgh
124 assert response.json() == { 1abcdefgh
125 "openapi": "3.1.0",
126 "info": {"title": "FastAPI", "version": "0.1.0"},
127 "paths": {
128 "/heroes/": {
129 "get": {
130 "summary": "Read Heroes",
131 "operationId": "read_heroes_heroes__get",
132 "parameters": [
133 {
134 "required": False,
135 "schema": {
136 "title": "Offset",
137 "type": "integer",
138 "default": 0,
139 },
140 "name": "offset",
141 "in": "query",
142 },
143 {
144 "required": False,
145 "schema": {
146 "title": "Limit",
147 "maximum": 100.0,
148 "type": "integer",
149 "default": 100,
150 },
151 "name": "limit",
152 "in": "query",
153 },
154 ],
155 "responses": {
156 "200": {
157 "description": "Successful Response",
158 "content": {
159 "application/json": {
160 "schema": {
161 "title": "Response Read Heroes Heroes Get",
162 "type": "array",
163 "items": {
164 "$ref": "#/components/schemas/HeroPublic"
165 },
166 }
167 }
168 },
169 },
170 "422": {
171 "description": "Validation Error",
172 "content": {
173 "application/json": {
174 "schema": {
175 "$ref": "#/components/schemas/HTTPValidationError"
176 }
177 }
178 },
179 },
180 },
181 },
182 "post": {
183 "summary": "Create Hero",
184 "operationId": "create_hero_heroes__post",
185 "requestBody": {
186 "content": {
187 "application/json": {
188 "schema": {
189 "$ref": "#/components/schemas/HeroCreate"
190 }
191 }
192 },
193 "required": True,
194 },
195 "responses": {
196 "200": {
197 "description": "Successful Response",
198 "content": {
199 "application/json": {
200 "schema": {
201 "$ref": "#/components/schemas/HeroPublic"
202 }
203 }
204 },
205 },
206 "422": {
207 "description": "Validation Error",
208 "content": {
209 "application/json": {
210 "schema": {
211 "$ref": "#/components/schemas/HTTPValidationError"
212 }
213 }
214 },
215 },
216 },
217 },
218 },
219 "/heroes/{hero_id}": {
220 "get": {
221 "summary": "Read Hero",
222 "operationId": "read_hero_heroes__hero_id__get",
223 "parameters": [
224 {
225 "required": True,
226 "schema": {"title": "Hero Id", "type": "integer"},
227 "name": "hero_id",
228 "in": "path",
229 }
230 ],
231 "responses": {
232 "200": {
233 "description": "Successful Response",
234 "content": {
235 "application/json": {
236 "schema": {
237 "$ref": "#/components/schemas/HeroPublicWithTeam"
238 }
239 }
240 },
241 },
242 "422": {
243 "description": "Validation Error",
244 "content": {
245 "application/json": {
246 "schema": {
247 "$ref": "#/components/schemas/HTTPValidationError"
248 }
249 }
250 },
251 },
252 },
253 },
254 "delete": {
255 "summary": "Delete Hero",
256 "operationId": "delete_hero_heroes__hero_id__delete",
257 "parameters": [
258 {
259 "required": True,
260 "schema": {"title": "Hero Id", "type": "integer"},
261 "name": "hero_id",
262 "in": "path",
263 }
264 ],
265 "responses": {
266 "200": {
267 "description": "Successful Response",
268 "content": {"application/json": {"schema": {}}},
269 },
270 "422": {
271 "description": "Validation Error",
272 "content": {
273 "application/json": {
274 "schema": {
275 "$ref": "#/components/schemas/HTTPValidationError"
276 }
277 }
278 },
279 },
280 },
281 },
282 "patch": {
283 "summary": "Update Hero",
284 "operationId": "update_hero_heroes__hero_id__patch",
285 "parameters": [
286 {
287 "required": True,
288 "schema": {"title": "Hero Id", "type": "integer"},
289 "name": "hero_id",
290 "in": "path",
291 }
292 ],
293 "requestBody": {
294 "content": {
295 "application/json": {
296 "schema": {
297 "$ref": "#/components/schemas/HeroUpdate"
298 }
299 }
300 },
301 "required": True,
302 },
303 "responses": {
304 "200": {
305 "description": "Successful Response",
306 "content": {
307 "application/json": {
308 "schema": {
309 "$ref": "#/components/schemas/HeroPublic"
310 }
311 }
312 },
313 },
314 "422": {
315 "description": "Validation Error",
316 "content": {
317 "application/json": {
318 "schema": {
319 "$ref": "#/components/schemas/HTTPValidationError"
320 }
321 }
322 },
323 },
324 },
325 },
326 },
327 "/teams/": {
328 "get": {
329 "summary": "Read Teams",
330 "operationId": "read_teams_teams__get",
331 "parameters": [
332 {
333 "required": False,
334 "schema": {
335 "title": "Offset",
336 "type": "integer",
337 "default": 0,
338 },
339 "name": "offset",
340 "in": "query",
341 },
342 {
343 "required": False,
344 "schema": {
345 "title": "Limit",
346 "maximum": 100.0,
347 "type": "integer",
348 "default": 100,
349 },
350 "name": "limit",
351 "in": "query",
352 },
353 ],
354 "responses": {
355 "200": {
356 "description": "Successful Response",
357 "content": {
358 "application/json": {
359 "schema": {
360 "title": "Response Read Teams Teams Get",
361 "type": "array",
362 "items": {
363 "$ref": "#/components/schemas/TeamPublic"
364 },
365 }
366 }
367 },
368 },
369 "422": {
370 "description": "Validation Error",
371 "content": {
372 "application/json": {
373 "schema": {
374 "$ref": "#/components/schemas/HTTPValidationError"
375 }
376 }
377 },
378 },
379 },
380 },
381 "post": {
382 "summary": "Create Team",
383 "operationId": "create_team_teams__post",
384 "requestBody": {
385 "content": {
386 "application/json": {
387 "schema": {
388 "$ref": "#/components/schemas/TeamCreate"
389 }
390 }
391 },
392 "required": True,
393 },
394 "responses": {
395 "200": {
396 "description": "Successful Response",
397 "content": {
398 "application/json": {
399 "schema": {
400 "$ref": "#/components/schemas/TeamPublic"
401 }
402 }
403 },
404 },
405 "422": {
406 "description": "Validation Error",
407 "content": {
408 "application/json": {
409 "schema": {
410 "$ref": "#/components/schemas/HTTPValidationError"
411 }
412 }
413 },
414 },
415 },
416 },
417 },
418 "/teams/{team_id}": {
419 "get": {
420 "summary": "Read Team",
421 "operationId": "read_team_teams__team_id__get",
422 "parameters": [
423 {
424 "required": True,
425 "schema": {"title": "Team Id", "type": "integer"},
426 "name": "team_id",
427 "in": "path",
428 }
429 ],
430 "responses": {
431 "200": {
432 "description": "Successful Response",
433 "content": {
434 "application/json": {
435 "schema": {
436 "$ref": "#/components/schemas/TeamPublicWithHeroes"
437 }
438 }
439 },
440 },
441 "422": {
442 "description": "Validation Error",
443 "content": {
444 "application/json": {
445 "schema": {
446 "$ref": "#/components/schemas/HTTPValidationError"
447 }
448 }
449 },
450 },
451 },
452 },
453 "delete": {
454 "summary": "Delete Team",
455 "operationId": "delete_team_teams__team_id__delete",
456 "parameters": [
457 {
458 "required": True,
459 "schema": {"title": "Team Id", "type": "integer"},
460 "name": "team_id",
461 "in": "path",
462 }
463 ],
464 "responses": {
465 "200": {
466 "description": "Successful Response",
467 "content": {"application/json": {"schema": {}}},
468 },
469 "422": {
470 "description": "Validation Error",
471 "content": {
472 "application/json": {
473 "schema": {
474 "$ref": "#/components/schemas/HTTPValidationError"
475 }
476 }
477 },
478 },
479 },
480 },
481 "patch": {
482 "summary": "Update Team",
483 "operationId": "update_team_teams__team_id__patch",
484 "parameters": [
485 {
486 "required": True,
487 "schema": {"title": "Team Id", "type": "integer"},
488 "name": "team_id",
489 "in": "path",
490 }
491 ],
492 "requestBody": {
493 "content": {
494 "application/json": {
495 "schema": {
496 "$ref": "#/components/schemas/TeamUpdate"
497 }
498 }
499 },
500 "required": True,
501 },
502 "responses": {
503 "200": {
504 "description": "Successful Response",
505 "content": {
506 "application/json": {
507 "schema": {
508 "$ref": "#/components/schemas/TeamPublic"
509 }
510 }
511 },
512 },
513 "422": {
514 "description": "Validation Error",
515 "content": {
516 "application/json": {
517 "schema": {
518 "$ref": "#/components/schemas/HTTPValidationError"
519 }
520 }
521 },
522 },
523 },
524 },
525 },
526 },
527 "components": {
528 "schemas": {
529 "HTTPValidationError": {
530 "title": "HTTPValidationError",
531 "type": "object",
532 "properties": {
533 "detail": {
534 "title": "Detail",
535 "type": "array",
536 "items": {
537 "$ref": "#/components/schemas/ValidationError"
538 },
539 }
540 },
541 },
542 "HeroCreate": {
543 "title": "HeroCreate",
544 "required": ["name", "secret_name"],
545 "type": "object",
546 "properties": {
547 "name": {"title": "Name", "type": "string"},
548 "secret_name": {"title": "Secret Name", "type": "string"},
549 "age": {
550 "title": "Age",
551 "anyOf": [{"type": "integer"}, {"type": "null"}],
552 },
553 "team_id": {
554 "title": "Team Id",
555 "anyOf": [{"type": "integer"}, {"type": "null"}],
556 },
557 },
558 },
559 "HeroPublic": {
560 "title": "HeroPublic",
561 "required": ["name", "secret_name", "id"],
562 "type": "object",
563 "properties": {
564 "name": {"title": "Name", "type": "string"},
565 "secret_name": {"title": "Secret Name", "type": "string"},
566 "age": {
567 "title": "Age",
568 "anyOf": [{"type": "integer"}, {"type": "null"}],
569 },
570 "team_id": {
571 "title": "Team Id",
572 "anyOf": [{"type": "integer"}, {"type": "null"}],
573 },
574 "id": {"title": "Id", "type": "integer"},
575 },
576 },
577 "HeroPublicWithTeam": {
578 "title": "HeroPublicWithTeam",
579 "required": ["name", "secret_name", "id"],
580 "type": "object",
581 "properties": {
582 "name": {"title": "Name", "type": "string"},
583 "secret_name": {"title": "Secret Name", "type": "string"},
584 "age": {
585 "title": "Age",
586 "anyOf": [{"type": "integer"}, {"type": "null"}],
587 },
588 "team_id": {
589 "title": "Team Id",
590 "anyOf": [{"type": "integer"}, {"type": "null"}],
591 },
592 "id": {"title": "Id", "type": "integer"},
593 "team": {
594 "anyOf": [
595 {"$ref": "#/components/schemas/TeamPublic"},
596 {"type": "null"},
597 ]
598 },
599 },
600 },
601 "HeroUpdate": {
602 "title": "HeroUpdate",
603 "type": "object",
604 "properties": {
605 "name": {
606 "title": "Name",
607 "anyOf": [{"type": "string"}, {"type": "null"}],
608 },
609 "secret_name": {
610 "title": "Secret Name",
611 "anyOf": [{"type": "string"}, {"type": "null"}],
612 },
613 "age": {
614 "title": "Age",
615 "anyOf": [{"type": "integer"}, {"type": "null"}],
616 },
617 "team_id": {
618 "title": "Team Id",
619 "anyOf": [{"type": "integer"}, {"type": "null"}],
620 },
621 },
622 },
623 "TeamCreate": {
624 "title": "TeamCreate",
625 "required": ["name", "headquarters"],
626 "type": "object",
627 "properties": {
628 "name": {"title": "Name", "type": "string"},
629 "headquarters": {"title": "Headquarters", "type": "string"},
630 },
631 },
632 "TeamPublic": {
633 "title": "TeamPublic",
634 "required": ["name", "headquarters", "id"],
635 "type": "object",
636 "properties": {
637 "name": {"title": "Name", "type": "string"},
638 "headquarters": {"title": "Headquarters", "type": "string"},
639 "id": {"title": "Id", "type": "integer"},
640 },
641 },
642 "TeamPublicWithHeroes": {
643 "title": "TeamPublicWithHeroes",
644 "required": ["name", "headquarters", "id"],
645 "type": "object",
646 "properties": {
647 "name": {"title": "Name", "type": "string"},
648 "headquarters": {"title": "Headquarters", "type": "string"},
649 "id": {"title": "Id", "type": "integer"},
650 "heroes": {
651 "title": "Heroes",
652 "type": "array",
653 "items": {"$ref": "#/components/schemas/HeroPublic"},
654 "default": [],
655 },
656 },
657 },
658 "TeamUpdate": {
659 "title": "TeamUpdate",
660 "type": "object",
661 "properties": {
662 "id": {
663 "title": "Id",
664 "anyOf": [{"type": "integer"}, {"type": "null"}],
665 },
666 "name": {
667 "title": "Name",
668 "anyOf": [{"type": "string"}, {"type": "null"}],
669 },
670 "headquarters": {
671 "title": "Headquarters",
672 "anyOf": [{"type": "string"}, {"type": "null"}],
673 },
674 },
675 },
676 "ValidationError": {
677 "title": "ValidationError",
678 "required": ["loc", "msg", "type"],
679 "type": "object",
680 "properties": IsOneOf(
681 {
682 "loc": {
683 "title": "Location",
684 "type": "array",
685 "items": {
686 "anyOf": [
687 {"type": "string"},
688 {"type": "integer"},
689 ]
690 },
691 },
692 "msg": {"title": "Message", "type": "string"},
693 "type": {"title": "Error Type", "type": "string"},
694 },
695 {
696 "loc": {
697 "title": "Location",
698 "type": "array",
699 "items": {
700 "anyOf": [
701 {"type": "string"},
702 {"type": "integer"},
703 ]
704 },
705 },
706 "msg": {"title": "Message", "type": "string"},
707 "type": {"title": "Error Type", "type": "string"},
708 "ctx": {"title": "Context", "type": "object"},
709 "input": {"title": "Input"},
710 },
711 ),
712 },
713 }
714 },
715 }