Coverage for tests / test_tutorial / test_fastapi / test_multiple_models / test_tutorial001.py: 100%
52 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-01-06 21:09 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-01-06 21:09 +0000
1import importlib 1jklmnopqr
2from types import ModuleType 1jklmnopqr
4import pytest 1jklmnopqr
5from fastapi.testclient import TestClient 1jklmnopqr
6from sqlalchemy import inspect 1jklmnopqr
7from sqlalchemy.engine.reflection import Inspector 1jklmnopqr
8from sqlmodel import create_engine 1jklmnopqr
9from sqlmodel.pool import StaticPool 1jklmnopqr
11from tests.conftest import needs_py310 1jklmnopqr
14@pytest.fixture( 1jklmnopqr
15 name="module",
16 params=[
17 pytest.param("tutorial001_py39"),
18 pytest.param("tutorial001_py310", marks=needs_py310),
19 ],
20)
21def get_module(request: pytest.FixtureRequest) -> ModuleType: 1jklmnopqr
22 mod = importlib.import_module( 1jklmnopqr
23 f"docs_src.tutorial.fastapi.multiple_models.{request.param}"
24 )
25 mod.sqlite_url = "sqlite://" 1jklmnopqr
26 mod.engine = create_engine( 1jklmnopqr
27 mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
28 )
29 return mod 1jklmnopqr
32def test_tutorial(module: ModuleType): 1jklmnopqr
33 with TestClient(module.app) as client: 1abcdefghi
34 hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} 1abcdefghi
35 hero2_data = { 1abcdefghi
36 "name": "Spider-Boy",
37 "secret_name": "Pedro Parqueador",
38 "id": 9000,
39 }
40 response = client.post("/heroes/", json=hero1_data) 1abcdefghi
41 data = response.json() 1abcdefghi
43 assert response.status_code == 200, response.text 1abcdefghi
44 assert data["name"] == hero1_data["name"] 1abcdefghi
45 assert data["secret_name"] == hero1_data["secret_name"] 1abcdefghi
46 assert data["id"] is not None 1abcdefghi
47 assert data["age"] is None 1abcdefghi
49 response = client.post("/heroes/", json=hero2_data) 1abcdefghi
50 data = response.json() 1abcdefghi
52 assert response.status_code == 200, response.text 1abcdefghi
53 assert data["name"] == hero2_data["name"] 1abcdefghi
54 assert data["secret_name"] == hero2_data["secret_name"] 1abcdefghi
55 assert data["id"] != hero2_data["id"], ( 1abcdefghi
56 "Now it's not possible to predefine the ID from the request, "
57 "it's now set by the database"
58 )
59 assert data["age"] is None 1abcdefghi
61 response = client.get("/heroes/") 1abcdefghi
62 data = response.json() 1abcdefghi
64 assert response.status_code == 200, response.text 1abcdefghi
65 assert len(data) == 2 1abcdefghi
66 assert data[0]["name"] == hero1_data["name"] 1abcdefghi
67 assert data[0]["secret_name"] == hero1_data["secret_name"] 1abcdefghi
68 assert data[1]["name"] == hero2_data["name"] 1abcdefghi
69 assert data[1]["secret_name"] == hero2_data["secret_name"] 1abcdefghi
70 assert data[1]["id"] != hero2_data["id"] 1abcdefghi
72 response = client.get("/openapi.json") 1abcdefghi
74 assert response.status_code == 200, response.text 1abcdefghi
76 assert response.json() == { 1abcdefghi
77 "openapi": "3.1.0",
78 "info": {"title": "FastAPI", "version": "0.1.0"},
79 "paths": {
80 "/heroes/": {
81 "get": {
82 "summary": "Read Heroes",
83 "operationId": "read_heroes_heroes__get",
84 "responses": {
85 "200": {
86 "description": "Successful Response",
87 "content": {
88 "application/json": {
89 "schema": {
90 "title": "Response Read Heroes Heroes Get",
91 "type": "array",
92 "items": {
93 "$ref": "#/components/schemas/HeroPublic"
94 },
95 }
96 }
97 },
98 }
99 },
100 },
101 "post": {
102 "summary": "Create Hero",
103 "operationId": "create_hero_heroes__post",
104 "requestBody": {
105 "content": {
106 "application/json": {
107 "schema": {
108 "$ref": "#/components/schemas/HeroCreate"
109 }
110 }
111 },
112 "required": True,
113 },
114 "responses": {
115 "200": {
116 "description": "Successful Response",
117 "content": {
118 "application/json": {
119 "schema": {
120 "$ref": "#/components/schemas/HeroPublic"
121 }
122 }
123 },
124 },
125 "422": {
126 "description": "Validation Error",
127 "content": {
128 "application/json": {
129 "schema": {
130 "$ref": "#/components/schemas/HTTPValidationError"
131 }
132 }
133 },
134 },
135 },
136 },
137 }
138 },
139 "components": {
140 "schemas": {
141 "HTTPValidationError": {
142 "title": "HTTPValidationError",
143 "type": "object",
144 "properties": {
145 "detail": {
146 "title": "Detail",
147 "type": "array",
148 "items": {
149 "$ref": "#/components/schemas/ValidationError"
150 },
151 }
152 },
153 },
154 "HeroCreate": {
155 "title": "HeroCreate",
156 "required": ["name", "secret_name"],
157 "type": "object",
158 "properties": {
159 "name": {"title": "Name", "type": "string"},
160 "secret_name": {"title": "Secret Name", "type": "string"},
161 "age": {
162 "title": "Age",
163 "anyOf": [{"type": "integer"}, {"type": "null"}],
164 },
165 },
166 },
167 "HeroPublic": {
168 "title": "HeroPublic",
169 "required": ["id", "name", "secret_name"],
170 "type": "object",
171 "properties": {
172 "id": {"title": "Id", "type": "integer"},
173 "name": {"title": "Name", "type": "string"},
174 "secret_name": {"title": "Secret Name", "type": "string"},
175 "age": {
176 "title": "Age",
177 "anyOf": [{"type": "integer"}, {"type": "null"}],
178 },
179 },
180 },
181 "ValidationError": {
182 "title": "ValidationError",
183 "required": ["loc", "msg", "type"],
184 "type": "object",
185 "properties": {
186 "loc": {
187 "title": "Location",
188 "type": "array",
189 "items": {
190 "anyOf": [{"type": "string"}, {"type": "integer"}]
191 },
192 },
193 "msg": {"title": "Message", "type": "string"},
194 "type": {"title": "Error Type", "type": "string"},
195 },
196 },
197 }
198 },
199 }
201 # Test inherited indexes
202 insp: Inspector = inspect(module.engine) 1abcdefghi
203 indexes = insp.get_indexes(str(module.Hero.__tablename__)) 1abcdefghi
204 expected_indexes = [ 1abcdefghi
205 {
206 "name": "ix_hero_name",
207 "dialect_options": {},
208 "column_names": ["name"],
209 "unique": 0,
210 },
211 {
212 "name": "ix_hero_age",
213 "dialect_options": {},
214 "column_names": ["age"],
215 "unique": 0,
216 },
217 ]
218 for index in expected_indexes: 1abcdefghi
219 assert index in indexes, "This expected index should be in the indexes in DB" 1abcdefghi
220 # Now that this index was checked, remove it from the list of indexes
221 indexes.pop(indexes.index(index)) 1abcdefghi
222 assert len(indexes) == 0, "The database should only have the expected indexes" 1abcdefghi