Coverage for tests / test_infer_param_optionality.py: 100%

62 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-04-06 01:24 +0000

1from fastapi import APIRouter, FastAPI 1abcd

2from fastapi.testclient import TestClient 1abcd

3from inline_snapshot import snapshot 1abcd

4 

5app = FastAPI() 1abcd

6 

7 

8user_router = APIRouter() 1abcd

9item_router = APIRouter() 1abcd

10 

11 

12@user_router.get("/") 1abcd

13def get_users(): 1abcd

14 return [{"user_id": "u1"}, {"user_id": "u2"}] 1yzAB

15 

16 

17@user_router.get("/{user_id}") 1abcd

18def get_user(user_id: str): 1abcd

19 return {"user_id": user_id} 1CDEF

20 

21 

22@item_router.get("/") 1abcd

23def get_items(user_id: str | None = None): 1abcd

24 if user_id is None: 1efghijklmn

25 return [{"item_id": "i1", "user_id": "u1"}, {"item_id": "i2", "user_id": "u2"}] 1ehil

26 else: 

27 return [{"item_id": "i2", "user_id": user_id}] 1fgGjkmn

28 

29 

30@item_router.get("/{item_id}") 1abcd

31def get_item(item_id: str, user_id: str | None = None): 1abcd

32 if user_id is None: 1opqrstuvwx

33 return {"item_id": item_id} 1orsv

34 else: 

35 return {"item_id": item_id, "user_id": user_id} 1pqHtuwx

36 

37 

38app.include_router(user_router, prefix="/users") 1abcd

39app.include_router(item_router, prefix="/items") 1abcd

40 

41app.include_router(item_router, prefix="/users/{user_id}/items") 1abcd

42 

43 

44client = TestClient(app) 1abcd

45 

46 

47def test_get_users(): 1abcd

48 """Check that /users returns expected data""" 

49 response = client.get("/users") 1yzAB

50 assert response.status_code == 200, response.text 1yzAB

51 assert response.json() == [{"user_id": "u1"}, {"user_id": "u2"}] 1yzAB

52 

53 

54def test_get_user(): 1abcd

55 """Check that /users/{user_id} returns expected data""" 

56 response = client.get("/users/abc123") 1CDEF

57 assert response.status_code == 200, response.text 1CDEF

58 assert response.json() == {"user_id": "abc123"} 1CDEF

59 

60 

61def test_get_items_1(): 1abcd

62 """Check that /items returns expected data""" 

63 response = client.get("/items") 1ehil

64 assert response.status_code == 200, response.text 1ehil

65 assert response.json() == [ 1ehil

66 {"item_id": "i1", "user_id": "u1"}, 

67 {"item_id": "i2", "user_id": "u2"}, 

68 ] 

69 

70 

71def test_get_items_2(): 1abcd

72 """Check that /items returns expected data with user_id specified""" 

73 response = client.get("/items?user_id=abc123") 1fGjm

74 assert response.status_code == 200, response.text 1fGjm

75 assert response.json() == [{"item_id": "i2", "user_id": "abc123"}] 1fGjm

76 

77 

78def test_get_item_1(): 1abcd

79 """Check that /items/{item_id} returns expected data""" 

80 response = client.get("/items/item01") 1orsv

81 assert response.status_code == 200, response.text 1orsv

82 assert response.json() == {"item_id": "item01"} 1orsv

83 

84 

85def test_get_item_2(): 1abcd

86 """Check that /items/{item_id} returns expected data with user_id specified""" 

87 response = client.get("/items/item01?user_id=abc123") 1pHtw

88 assert response.status_code == 200, response.text 1pHtw

89 assert response.json() == {"item_id": "item01", "user_id": "abc123"} 1pHtw

90 

91 

92def test_get_users_items(): 1abcd

93 """Check that /users/{user_id}/items returns expected data""" 

94 response = client.get("/users/abc123/items") 1gIkn

95 assert response.status_code == 200, response.text 1gIkn

96 assert response.json() == [{"item_id": "i2", "user_id": "abc123"}] 1gIkn

97 

98 

99def test_get_users_item(): 1abcd

100 """Check that /users/{user_id}/items returns expected data""" 

101 response = client.get("/users/abc123/items/item01") 1qJux

102 assert response.status_code == 200, response.text 1qJux

103 assert response.json() == {"item_id": "item01", "user_id": "abc123"} 1qJux

104 

105 

106def test_openapi_schema(): 1abcd

107 response = client.get("/openapi.json") 1KLMN

108 assert response.status_code == 200, response.text 1KLMN

109 assert response.json() == snapshot( 1KLMN

110 { 

111 "openapi": "3.1.0", 

112 "info": {"title": "FastAPI", "version": "0.1.0"}, 

113 "paths": { 

114 "/users/": { 

115 "get": { 

116 "summary": "Get Users", 

117 "operationId": "get_users_users__get", 

118 "responses": { 

119 "200": { 

120 "description": "Successful Response", 

121 "content": {"application/json": {"schema": {}}}, 

122 } 

123 }, 

124 } 

125 }, 

126 "/users/{user_id}": { 

127 "get": { 

128 "summary": "Get User", 

129 "operationId": "get_user_users__user_id__get", 

130 "parameters": [ 

131 { 

132 "required": True, 

133 "schema": {"title": "User Id", "type": "string"}, 

134 "name": "user_id", 

135 "in": "path", 

136 } 

137 ], 

138 "responses": { 

139 "200": { 

140 "description": "Successful Response", 

141 "content": {"application/json": {"schema": {}}}, 

142 }, 

143 "422": { 

144 "description": "Validation Error", 

145 "content": { 

146 "application/json": { 

147 "schema": { 

148 "$ref": "#/components/schemas/HTTPValidationError" 

149 } 

150 } 

151 }, 

152 }, 

153 }, 

154 } 

155 }, 

156 "/items/": { 

157 "get": { 

158 "summary": "Get Items", 

159 "operationId": "get_items_items__get", 

160 "parameters": [ 

161 { 

162 "required": False, 

163 "name": "user_id", 

164 "in": "query", 

165 "schema": { 

166 "anyOf": [{"type": "string"}, {"type": "null"}], 

167 "title": "User Id", 

168 }, 

169 } 

170 ], 

171 "responses": { 

172 "200": { 

173 "description": "Successful Response", 

174 "content": {"application/json": {"schema": {}}}, 

175 }, 

176 "422": { 

177 "description": "Validation Error", 

178 "content": { 

179 "application/json": { 

180 "schema": { 

181 "$ref": "#/components/schemas/HTTPValidationError" 

182 } 

183 } 

184 }, 

185 }, 

186 }, 

187 } 

188 }, 

189 "/items/{item_id}": { 

190 "get": { 

191 "summary": "Get Item", 

192 "operationId": "get_item_items__item_id__get", 

193 "parameters": [ 

194 { 

195 "required": True, 

196 "schema": {"title": "Item Id", "type": "string"}, 

197 "name": "item_id", 

198 "in": "path", 

199 }, 

200 { 

201 "required": False, 

202 "name": "user_id", 

203 "in": "query", 

204 "schema": { 

205 "anyOf": [{"type": "string"}, {"type": "null"}], 

206 "title": "User Id", 

207 }, 

208 }, 

209 ], 

210 "responses": { 

211 "200": { 

212 "description": "Successful Response", 

213 "content": {"application/json": {"schema": {}}}, 

214 }, 

215 "422": { 

216 "description": "Validation Error", 

217 "content": { 

218 "application/json": { 

219 "schema": { 

220 "$ref": "#/components/schemas/HTTPValidationError" 

221 } 

222 } 

223 }, 

224 }, 

225 }, 

226 } 

227 }, 

228 "/users/{user_id}/items/": { 

229 "get": { 

230 "summary": "Get Items", 

231 "operationId": "get_items_users__user_id__items__get", 

232 "parameters": [ 

233 { 

234 "required": True, 

235 "name": "user_id", 

236 "in": "path", 

237 "schema": { 

238 "anyOf": [{"type": "string"}, {"type": "null"}], 

239 "title": "User Id", 

240 }, 

241 } 

242 ], 

243 "responses": { 

244 "200": { 

245 "description": "Successful Response", 

246 "content": {"application/json": {"schema": {}}}, 

247 }, 

248 "422": { 

249 "description": "Validation Error", 

250 "content": { 

251 "application/json": { 

252 "schema": { 

253 "$ref": "#/components/schemas/HTTPValidationError" 

254 } 

255 } 

256 }, 

257 }, 

258 }, 

259 } 

260 }, 

261 "/users/{user_id}/items/{item_id}": { 

262 "get": { 

263 "summary": "Get Item", 

264 "operationId": "get_item_users__user_id__items__item_id__get", 

265 "parameters": [ 

266 { 

267 "required": True, 

268 "schema": {"title": "Item Id", "type": "string"}, 

269 "name": "item_id", 

270 "in": "path", 

271 }, 

272 { 

273 "required": True, 

274 "name": "user_id", 

275 "in": "path", 

276 "schema": { 

277 "anyOf": [{"type": "string"}, {"type": "null"}], 

278 "title": "User Id", 

279 }, 

280 }, 

281 ], 

282 "responses": { 

283 "200": { 

284 "description": "Successful Response", 

285 "content": {"application/json": {"schema": {}}}, 

286 }, 

287 "422": { 

288 "description": "Validation Error", 

289 "content": { 

290 "application/json": { 

291 "schema": { 

292 "$ref": "#/components/schemas/HTTPValidationError" 

293 } 

294 } 

295 }, 

296 }, 

297 }, 

298 } 

299 }, 

300 }, 

301 "components": { 

302 "schemas": { 

303 "HTTPValidationError": { 

304 "title": "HTTPValidationError", 

305 "type": "object", 

306 "properties": { 

307 "detail": { 

308 "title": "Detail", 

309 "type": "array", 

310 "items": { 

311 "$ref": "#/components/schemas/ValidationError" 

312 }, 

313 } 

314 }, 

315 }, 

316 "ValidationError": { 

317 "title": "ValidationError", 

318 "required": ["loc", "msg", "type"], 

319 "type": "object", 

320 "properties": { 

321 "loc": { 

322 "title": "Location", 

323 "type": "array", 

324 "items": { 

325 "anyOf": [{"type": "string"}, {"type": "integer"}] 

326 }, 

327 }, 

328 "msg": {"title": "Message", "type": "string"}, 

329 "type": {"title": "Error Type", "type": "string"}, 

330 "input": {"title": "Input"}, 

331 "ctx": {"title": "Context", "type": "object"}, 

332 }, 

333 }, 

334 } 

335 }, 

336 } 

337 )