Coverage for tests / test_infer_param_optionality.py: 100%
63 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
1from typing import Optional 1abcd
3from fastapi import APIRouter, FastAPI 1abcd
4from fastapi.testclient import TestClient 1abcd
5from inline_snapshot import snapshot 1abcd
7app = FastAPI() 1abcd
10user_router = APIRouter() 1abcd
11item_router = APIRouter() 1abcd
14@user_router.get("/") 1abcd
15def get_users(): 1abcd
16 return [{"user_id": "u1"}, {"user_id": "u2"}] 1wxy
19@user_router.get("/{user_id}") 1abcd
20def get_user(user_id: str): 1abcd
21 return {"user_id": user_id} 1zAB
24@item_router.get("/") 1abcd
25def get_items(user_id: Optional[str] = None): 1abcd
26 if user_id is None: 1efghijklm
27 return [{"item_id": "i1", "user_id": "u1"}, {"item_id": "i2", "user_id": "u2"}] 1ehk
28 else:
29 return [{"item_id": "i2", "user_id": user_id}] 1fgijlm
32@item_router.get("/{item_id}") 1abcd
33def get_item(item_id: str, user_id: Optional[str] = None): 1abcd
34 if user_id is None: 1nopqrstuv
35 return {"item_id": item_id} 1nqt
36 else:
37 return {"item_id": item_id, "user_id": user_id} 1oprsuv
40app.include_router(user_router, prefix="/users") 1abcd
41app.include_router(item_router, prefix="/items") 1abcd
43app.include_router(item_router, prefix="/users/{user_id}/items") 1abcd
46client = TestClient(app) 1abcd
49def test_get_users(): 1abcd
50 """Check that /users returns expected data"""
51 response = client.get("/users") 1wxy
52 assert response.status_code == 200, response.text 1wxy
53 assert response.json() == [{"user_id": "u1"}, {"user_id": "u2"}] 1wxy
56def test_get_user(): 1abcd
57 """Check that /users/{user_id} returns expected data"""
58 response = client.get("/users/abc123") 1zAB
59 assert response.status_code == 200, response.text 1zAB
60 assert response.json() == {"user_id": "abc123"} 1zAB
63def test_get_items_1(): 1abcd
64 """Check that /items returns expected data"""
65 response = client.get("/items") 1ehk
66 assert response.status_code == 200, response.text 1ehk
67 assert response.json() == [ 1ehk
68 {"item_id": "i1", "user_id": "u1"},
69 {"item_id": "i2", "user_id": "u2"},
70 ]
73def test_get_items_2(): 1abcd
74 """Check that /items returns expected data with user_id specified"""
75 response = client.get("/items?user_id=abc123") 1fil
76 assert response.status_code == 200, response.text 1fil
77 assert response.json() == [{"item_id": "i2", "user_id": "abc123"}] 1fil
80def test_get_item_1(): 1abcd
81 """Check that /items/{item_id} returns expected data"""
82 response = client.get("/items/item01") 1nqt
83 assert response.status_code == 200, response.text 1nqt
84 assert response.json() == {"item_id": "item01"} 1nqt
87def test_get_item_2(): 1abcd
88 """Check that /items/{item_id} returns expected data with user_id specified"""
89 response = client.get("/items/item01?user_id=abc123") 1oru
90 assert response.status_code == 200, response.text 1oru
91 assert response.json() == {"item_id": "item01", "user_id": "abc123"} 1oru
94def test_get_users_items(): 1abcd
95 """Check that /users/{user_id}/items returns expected data"""
96 response = client.get("/users/abc123/items") 1gjm
97 assert response.status_code == 200, response.text 1gjm
98 assert response.json() == [{"item_id": "i2", "user_id": "abc123"}] 1gjm
101def test_get_users_item(): 1abcd
102 """Check that /users/{user_id}/items returns expected data"""
103 response = client.get("/users/abc123/items/item01") 1psv
104 assert response.status_code == 200, response.text 1psv
105 assert response.json() == {"item_id": "item01", "user_id": "abc123"} 1psv
108def test_openapi_schema(): 1abcd
109 response = client.get("/openapi.json") 1CDE
110 assert response.status_code == 200, response.text 1CDE
111 assert response.json() == snapshot( 1CDE
112 {
113 "openapi": "3.1.0",
114 "info": {"title": "FastAPI", "version": "0.1.0"},
115 "paths": {
116 "/users/": {
117 "get": {
118 "summary": "Get Users",
119 "operationId": "get_users_users__get",
120 "responses": {
121 "200": {
122 "description": "Successful Response",
123 "content": {"application/json": {"schema": {}}},
124 }
125 },
126 }
127 },
128 "/users/{user_id}": {
129 "get": {
130 "summary": "Get User",
131 "operationId": "get_user_users__user_id__get",
132 "parameters": [
133 {
134 "required": True,
135 "schema": {"title": "User Id", "type": "string"},
136 "name": "user_id",
137 "in": "path",
138 }
139 ],
140 "responses": {
141 "200": {
142 "description": "Successful Response",
143 "content": {"application/json": {"schema": {}}},
144 },
145 "422": {
146 "description": "Validation Error",
147 "content": {
148 "application/json": {
149 "schema": {
150 "$ref": "#/components/schemas/HTTPValidationError"
151 }
152 }
153 },
154 },
155 },
156 }
157 },
158 "/items/": {
159 "get": {
160 "summary": "Get Items",
161 "operationId": "get_items_items__get",
162 "parameters": [
163 {
164 "required": False,
165 "name": "user_id",
166 "in": "query",
167 "schema": {
168 "anyOf": [{"type": "string"}, {"type": "null"}],
169 "title": "User Id",
170 },
171 }
172 ],
173 "responses": {
174 "200": {
175 "description": "Successful Response",
176 "content": {"application/json": {"schema": {}}},
177 },
178 "422": {
179 "description": "Validation Error",
180 "content": {
181 "application/json": {
182 "schema": {
183 "$ref": "#/components/schemas/HTTPValidationError"
184 }
185 }
186 },
187 },
188 },
189 }
190 },
191 "/items/{item_id}": {
192 "get": {
193 "summary": "Get Item",
194 "operationId": "get_item_items__item_id__get",
195 "parameters": [
196 {
197 "required": True,
198 "schema": {"title": "Item Id", "type": "string"},
199 "name": "item_id",
200 "in": "path",
201 },
202 {
203 "required": False,
204 "name": "user_id",
205 "in": "query",
206 "schema": {
207 "anyOf": [{"type": "string"}, {"type": "null"}],
208 "title": "User Id",
209 },
210 },
211 ],
212 "responses": {
213 "200": {
214 "description": "Successful Response",
215 "content": {"application/json": {"schema": {}}},
216 },
217 "422": {
218 "description": "Validation Error",
219 "content": {
220 "application/json": {
221 "schema": {
222 "$ref": "#/components/schemas/HTTPValidationError"
223 }
224 }
225 },
226 },
227 },
228 }
229 },
230 "/users/{user_id}/items/": {
231 "get": {
232 "summary": "Get Items",
233 "operationId": "get_items_users__user_id__items__get",
234 "parameters": [
235 {
236 "required": True,
237 "name": "user_id",
238 "in": "path",
239 "schema": {
240 "anyOf": [{"type": "string"}, {"type": "null"}],
241 "title": "User Id",
242 },
243 }
244 ],
245 "responses": {
246 "200": {
247 "description": "Successful Response",
248 "content": {"application/json": {"schema": {}}},
249 },
250 "422": {
251 "description": "Validation Error",
252 "content": {
253 "application/json": {
254 "schema": {
255 "$ref": "#/components/schemas/HTTPValidationError"
256 }
257 }
258 },
259 },
260 },
261 }
262 },
263 "/users/{user_id}/items/{item_id}": {
264 "get": {
265 "summary": "Get Item",
266 "operationId": "get_item_users__user_id__items__item_id__get",
267 "parameters": [
268 {
269 "required": True,
270 "schema": {"title": "Item Id", "type": "string"},
271 "name": "item_id",
272 "in": "path",
273 },
274 {
275 "required": True,
276 "name": "user_id",
277 "in": "path",
278 "schema": {
279 "anyOf": [{"type": "string"}, {"type": "null"}],
280 "title": "User Id",
281 },
282 },
283 ],
284 "responses": {
285 "200": {
286 "description": "Successful Response",
287 "content": {"application/json": {"schema": {}}},
288 },
289 "422": {
290 "description": "Validation Error",
291 "content": {
292 "application/json": {
293 "schema": {
294 "$ref": "#/components/schemas/HTTPValidationError"
295 }
296 }
297 },
298 },
299 },
300 }
301 },
302 },
303 "components": {
304 "schemas": {
305 "HTTPValidationError": {
306 "title": "HTTPValidationError",
307 "type": "object",
308 "properties": {
309 "detail": {
310 "title": "Detail",
311 "type": "array",
312 "items": {
313 "$ref": "#/components/schemas/ValidationError"
314 },
315 }
316 },
317 },
318 "ValidationError": {
319 "title": "ValidationError",
320 "required": ["loc", "msg", "type"],
321 "type": "object",
322 "properties": {
323 "loc": {
324 "title": "Location",
325 "type": "array",
326 "items": {
327 "anyOf": [{"type": "string"}, {"type": "integer"}]
328 },
329 },
330 "msg": {"title": "Message", "type": "string"},
331 "type": {"title": "Error Type", "type": "string"},
332 "input": {"title": "Input"},
333 "ctx": {"title": "Context", "type": "object"},
334 },
335 },
336 }
337 },
338 }
339 )