Coverage for tests / test_tutorial / test_fastapi / test_update / test_tutorial001.py: 100%
51 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 sqlmodel import create_engine 1jklmnopqr
7from sqlmodel.pool import StaticPool 1jklmnopqr
9from tests.conftest import needs_py310 1jklmnopqr
12@pytest.fixture( 1jklmnopqr
13 name="module",
14 params=[
15 pytest.param("tutorial001_py39"),
16 pytest.param("tutorial001_py310", marks=needs_py310),
17 ],
18)
19def get_module(request: pytest.FixtureRequest) -> ModuleType: 1jklmnopqr
20 mod = importlib.import_module(f"docs_src.tutorial.fastapi.update.{request.param}") 1jklmnopqr
21 mod.sqlite_url = "sqlite://" 1jklmnopqr
22 mod.engine = create_engine( 1jklmnopqr
23 mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
24 )
25 return mod 1jklmnopqr
28def test_tutorial(module: ModuleType): 1jklmnopqr
29 with TestClient(module.app) as client: 1abcdefghi
30 hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} 1abcdefghi
31 hero2_data = { 1abcdefghi
32 "name": "Spider-Boy",
33 "secret_name": "Pedro Parqueador",
34 "id": 9000,
35 }
36 hero3_data = { 1abcdefghi
37 "name": "Rusty-Man",
38 "secret_name": "Tommy Sharp",
39 "age": 48,
40 }
41 response = client.post("/heroes/", json=hero1_data) 1abcdefghi
42 assert response.status_code == 200, response.text 1abcdefghi
43 response = client.post("/heroes/", json=hero2_data) 1abcdefghi
44 assert response.status_code == 200, response.text 1abcdefghi
45 hero2 = response.json() 1abcdefghi
46 hero2_id = hero2["id"] 1abcdefghi
47 response = client.post("/heroes/", json=hero3_data) 1abcdefghi
48 assert response.status_code == 200, response.text 1abcdefghi
49 hero3 = response.json() 1abcdefghi
50 hero3_id = hero3["id"] 1abcdefghi
51 response = client.get(f"/heroes/{hero2_id}") 1abcdefghi
52 assert response.status_code == 200, response.text 1abcdefghi
53 response = client.get("/heroes/9000") 1abcdefghi
54 assert response.status_code == 404, response.text 1abcdefghi
55 response = client.get("/heroes/") 1abcdefghi
56 assert response.status_code == 200, response.text 1abcdefghi
57 data = response.json() 1abcdefghi
58 assert len(data) == 3 1abcdefghi
60 response = client.patch( 1abcdefghi
61 f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"}
62 )
63 data = response.json() 1abcdefghi
64 assert response.status_code == 200, response.text 1abcdefghi
65 assert data["name"] == hero2_data["name"], "The name should not be set to none" 1abcdefghi
66 assert data["secret_name"] == "Spider-Youngster", ( 1abcdefghi
67 "The secret name should be updated"
68 )
70 response = client.patch(f"/heroes/{hero3_id}", json={"age": None}) 1abcdefghi
71 data = response.json() 1abcdefghi
72 assert response.status_code == 200, response.text 1abcdefghi
73 assert data["name"] == hero3_data["name"] 1abcdefghi
74 assert data["age"] is None, ( 1abcdefghi
75 "A field should be updatable to None, even if that's the default"
76 )
78 response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"}) 1abcdefghi
79 assert response.status_code == 404, response.text 1abcdefghi
81 response = client.get("/openapi.json") 1abcdefghi
82 assert response.status_code == 200, response.text 1abcdefghi
83 assert response.json() == { 1abcdefghi
84 "openapi": "3.1.0",
85 "info": {"title": "FastAPI", "version": "0.1.0"},
86 "paths": {
87 "/heroes/": {
88 "get": {
89 "summary": "Read Heroes",
90 "operationId": "read_heroes_heroes__get",
91 "parameters": [
92 {
93 "required": False,
94 "schema": {
95 "title": "Offset",
96 "type": "integer",
97 "default": 0,
98 },
99 "name": "offset",
100 "in": "query",
101 },
102 {
103 "required": False,
104 "schema": {
105 "title": "Limit",
106 "maximum": 100.0,
107 "type": "integer",
108 "default": 100,
109 },
110 "name": "limit",
111 "in": "query",
112 },
113 ],
114 "responses": {
115 "200": {
116 "description": "Successful Response",
117 "content": {
118 "application/json": {
119 "schema": {
120 "title": "Response Read Heroes Heroes Get",
121 "type": "array",
122 "items": {
123 "$ref": "#/components/schemas/HeroPublic"
124 },
125 }
126 }
127 },
128 },
129 "422": {
130 "description": "Validation Error",
131 "content": {
132 "application/json": {
133 "schema": {
134 "$ref": "#/components/schemas/HTTPValidationError"
135 }
136 }
137 },
138 },
139 },
140 },
141 "post": {
142 "summary": "Create Hero",
143 "operationId": "create_hero_heroes__post",
144 "requestBody": {
145 "content": {
146 "application/json": {
147 "schema": {
148 "$ref": "#/components/schemas/HeroCreate"
149 }
150 }
151 },
152 "required": True,
153 },
154 "responses": {
155 "200": {
156 "description": "Successful Response",
157 "content": {
158 "application/json": {
159 "schema": {
160 "$ref": "#/components/schemas/HeroPublic"
161 }
162 }
163 },
164 },
165 "422": {
166 "description": "Validation Error",
167 "content": {
168 "application/json": {
169 "schema": {
170 "$ref": "#/components/schemas/HTTPValidationError"
171 }
172 }
173 },
174 },
175 },
176 },
177 },
178 "/heroes/{hero_id}": {
179 "get": {
180 "summary": "Read Hero",
181 "operationId": "read_hero_heroes__hero_id__get",
182 "parameters": [
183 {
184 "required": True,
185 "schema": {"title": "Hero Id", "type": "integer"},
186 "name": "hero_id",
187 "in": "path",
188 }
189 ],
190 "responses": {
191 "200": {
192 "description": "Successful Response",
193 "content": {
194 "application/json": {
195 "schema": {
196 "$ref": "#/components/schemas/HeroPublic"
197 }
198 }
199 },
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 "patch": {
214 "summary": "Update Hero",
215 "operationId": "update_hero_heroes__hero_id__patch",
216 "parameters": [
217 {
218 "required": True,
219 "schema": {"title": "Hero Id", "type": "integer"},
220 "name": "hero_id",
221 "in": "path",
222 }
223 ],
224 "requestBody": {
225 "content": {
226 "application/json": {
227 "schema": {
228 "$ref": "#/components/schemas/HeroUpdate"
229 }
230 }
231 },
232 "required": True,
233 },
234 "responses": {
235 "200": {
236 "description": "Successful Response",
237 "content": {
238 "application/json": {
239 "schema": {
240 "$ref": "#/components/schemas/HeroPublic"
241 }
242 }
243 },
244 },
245 "422": {
246 "description": "Validation Error",
247 "content": {
248 "application/json": {
249 "schema": {
250 "$ref": "#/components/schemas/HTTPValidationError"
251 }
252 }
253 },
254 },
255 },
256 },
257 },
258 },
259 "components": {
260 "schemas": {
261 "HTTPValidationError": {
262 "title": "HTTPValidationError",
263 "type": "object",
264 "properties": {
265 "detail": {
266 "title": "Detail",
267 "type": "array",
268 "items": {
269 "$ref": "#/components/schemas/ValidationError"
270 },
271 }
272 },
273 },
274 "HeroCreate": {
275 "title": "HeroCreate",
276 "required": ["name", "secret_name"],
277 "type": "object",
278 "properties": {
279 "name": {"title": "Name", "type": "string"},
280 "secret_name": {"title": "Secret Name", "type": "string"},
281 "age": {
282 "title": "Age",
283 "anyOf": [{"type": "integer"}, {"type": "null"}],
284 },
285 },
286 },
287 "HeroPublic": {
288 "title": "HeroPublic",
289 "required": ["name", "secret_name", "id"],
290 "type": "object",
291 "properties": {
292 "name": {"title": "Name", "type": "string"},
293 "secret_name": {"title": "Secret Name", "type": "string"},
294 "age": {
295 "title": "Age",
296 "anyOf": [{"type": "integer"}, {"type": "null"}],
297 },
298 "id": {"title": "Id", "type": "integer"},
299 },
300 },
301 "HeroUpdate": {
302 "title": "HeroUpdate",
303 "type": "object",
304 "properties": {
305 "name": {
306 "title": "Name",
307 "anyOf": [{"type": "string"}, {"type": "null"}],
308 },
309 "secret_name": {
310 "title": "Secret Name",
311 "anyOf": [{"type": "string"}, {"type": "null"}],
312 },
313 "age": {
314 "title": "Age",
315 "anyOf": [{"type": "integer"}, {"type": "null"}],
316 },
317 },
318 },
319 "ValidationError": {
320 "title": "ValidationError",
321 "required": ["loc", "msg", "type"],
322 "type": "object",
323 "properties": {
324 "loc": {
325 "title": "Location",
326 "type": "array",
327 "items": {
328 "anyOf": [{"type": "string"}, {"type": "integer"}]
329 },
330 },
331 "msg": {"title": "Message", "type": "string"},
332 "type": {"title": "Error Type", "type": "string"},
333 },
334 },
335 }
336 },
337 }