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