Coverage for tests/test_tutorial/test_fastapi/test_update/test_tutorial001.py: 100%

45 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-09-09 00:02 +0000

1from dirty_equals import IsDict 1ghijkl

2from fastapi.testclient import TestClient 1ghijkl

3from sqlmodel import create_engine 1ghijkl

4from sqlmodel.pool import StaticPool 1ghijkl

5 

6 

7def test_tutorial(clear_sqlmodel): 1ghijkl

8 from docs_src.tutorial.fastapi.update import tutorial001 as mod 1fabcde

9 

10 mod.sqlite_url = "sqlite://" 1fabcde

11 mod.engine = create_engine( 1fabcde

12 mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool 

13 ) 

14 

15 with TestClient(mod.app) as client: 1fabcde

16 hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} 1fabcde

17 hero2_data = { 1abcde

18 "name": "Spider-Boy", 

19 "secret_name": "Pedro Parqueador", 

20 "id": 9000, 

21 } 

22 hero3_data = { 1abcde

23 "name": "Rusty-Man", 

24 "secret_name": "Tommy Sharp", 

25 "age": 48, 

26 } 

27 response = client.post("/heroes/", json=hero1_data) 1fabcde

28 assert response.status_code == 200, response.text 1fabcde

29 response = client.post("/heroes/", json=hero2_data) 1fabcde

30 assert response.status_code == 200, response.text 1fabcde

31 hero2 = response.json() 1fabcde

32 hero2_id = hero2["id"] 1fabcde

33 response = client.post("/heroes/", json=hero3_data) 1fabcde

34 assert response.status_code == 200, response.text 1fabcde

35 hero3 = response.json() 1fabcde

36 hero3_id = hero3["id"] 1fabcde

37 response = client.get(f"/heroes/{hero2_id}") 1fabcde

38 assert response.status_code == 200, response.text 1fabcde

39 response = client.get("/heroes/9000") 1fabcde

40 assert response.status_code == 404, response.text 1fabcde

41 response = client.get("/heroes/") 1fabcde

42 assert response.status_code == 200, response.text 1fabcde

43 data = response.json() 1fabcde

44 assert len(data) == 3 1fabcde

45 

46 response = client.patch( 1fabcde

47 f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"} 

48 ) 

49 data = response.json() 1fabcde

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

51 assert data["name"] == hero2_data["name"], "The name should not be set to none" 1fabcde

52 assert ( 1fabcde

53 data["secret_name"] == "Spider-Youngster" 

54 ), "The secret name should be updated" 

55 

56 response = client.patch(f"/heroes/{hero3_id}", json={"age": None}) 1fabcde

57 data = response.json() 1fabcde

58 assert response.status_code == 200, response.text 1fabcde

59 assert data["name"] == hero3_data["name"] 1fabcde

60 assert data["age"] is None, ( 1fabcde

61 "A field should be updatable to None, even if " "that's the default" 

62 ) 

63 

64 response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"}) 1fabcde

65 assert response.status_code == 404, response.text 1fabcde

66 

67 response = client.get("/openapi.json") 1fabcde

68 assert response.status_code == 200, response.text 1fabcde

69 assert response.json() == { 1fabcde

70 "openapi": "3.1.0", 

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

72 "paths": { 

73 "/heroes/": { 

74 "get": { 

75 "summary": "Read Heroes", 

76 "operationId": "read_heroes_heroes__get", 

77 "parameters": [ 

78 { 

79 "required": False, 

80 "schema": { 

81 "title": "Offset", 

82 "type": "integer", 

83 "default": 0, 

84 }, 

85 "name": "offset", 

86 "in": "query", 

87 }, 

88 { 

89 "required": False, 

90 "schema": { 

91 "title": "Limit", 

92 "maximum": 100.0, 

93 "type": "integer", 

94 "default": 100, 

95 }, 

96 "name": "limit", 

97 "in": "query", 

98 }, 

99 ], 

100 "responses": { 

101 "200": { 

102 "description": "Successful Response", 

103 "content": { 

104 "application/json": { 

105 "schema": { 

106 "title": "Response Read Heroes Heroes Get", 

107 "type": "array", 

108 "items": { 

109 "$ref": "#/components/schemas/HeroPublic" 

110 }, 

111 } 

112 } 

113 }, 

114 }, 

115 "422": { 

116 "description": "Validation Error", 

117 "content": { 

118 "application/json": { 

119 "schema": { 

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

121 } 

122 } 

123 }, 

124 }, 

125 }, 

126 }, 

127 "post": { 

128 "summary": "Create Hero", 

129 "operationId": "create_hero_heroes__post", 

130 "requestBody": { 

131 "content": { 

132 "application/json": { 

133 "schema": { 

134 "$ref": "#/components/schemas/HeroCreate" 

135 } 

136 } 

137 }, 

138 "required": True, 

139 }, 

140 "responses": { 

141 "200": { 

142 "description": "Successful Response", 

143 "content": { 

144 "application/json": { 

145 "schema": { 

146 "$ref": "#/components/schemas/HeroPublic" 

147 } 

148 } 

149 }, 

150 }, 

151 "422": { 

152 "description": "Validation Error", 

153 "content": { 

154 "application/json": { 

155 "schema": { 

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

157 } 

158 } 

159 }, 

160 }, 

161 }, 

162 }, 

163 }, 

164 "/heroes/{hero_id}": { 

165 "get": { 

166 "summary": "Read Hero", 

167 "operationId": "read_hero_heroes__hero_id__get", 

168 "parameters": [ 

169 { 

170 "required": True, 

171 "schema": {"title": "Hero Id", "type": "integer"}, 

172 "name": "hero_id", 

173 "in": "path", 

174 } 

175 ], 

176 "responses": { 

177 "200": { 

178 "description": "Successful Response", 

179 "content": { 

180 "application/json": { 

181 "schema": { 

182 "$ref": "#/components/schemas/HeroPublic" 

183 } 

184 } 

185 }, 

186 }, 

187 "422": { 

188 "description": "Validation Error", 

189 "content": { 

190 "application/json": { 

191 "schema": { 

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

193 } 

194 } 

195 }, 

196 }, 

197 }, 

198 }, 

199 "patch": { 

200 "summary": "Update Hero", 

201 "operationId": "update_hero_heroes__hero_id__patch", 

202 "parameters": [ 

203 { 

204 "required": True, 

205 "schema": {"title": "Hero Id", "type": "integer"}, 

206 "name": "hero_id", 

207 "in": "path", 

208 } 

209 ], 

210 "requestBody": { 

211 "content": { 

212 "application/json": { 

213 "schema": { 

214 "$ref": "#/components/schemas/HeroUpdate" 

215 } 

216 } 

217 }, 

218 "required": True, 

219 }, 

220 "responses": { 

221 "200": { 

222 "description": "Successful Response", 

223 "content": { 

224 "application/json": { 

225 "schema": { 

226 "$ref": "#/components/schemas/HeroPublic" 

227 } 

228 } 

229 }, 

230 }, 

231 "422": { 

232 "description": "Validation Error", 

233 "content": { 

234 "application/json": { 

235 "schema": { 

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

237 } 

238 } 

239 }, 

240 }, 

241 }, 

242 }, 

243 }, 

244 }, 

245 "components": { 

246 "schemas": { 

247 "HTTPValidationError": { 

248 "title": "HTTPValidationError", 

249 "type": "object", 

250 "properties": { 

251 "detail": { 

252 "title": "Detail", 

253 "type": "array", 

254 "items": { 

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

256 }, 

257 } 

258 }, 

259 }, 

260 "HeroCreate": { 

261 "title": "HeroCreate", 

262 "required": ["name", "secret_name"], 

263 "type": "object", 

264 "properties": { 

265 "name": {"title": "Name", "type": "string"}, 

266 "secret_name": {"title": "Secret Name", "type": "string"}, 

267 "age": IsDict( 

268 { 

269 "title": "Age", 

270 "anyOf": [{"type": "integer"}, {"type": "null"}], 

271 } 

272 ) 

273 | IsDict( 

274 # TODO: remove when deprecating Pydantic v1 

275 {"title": "Age", "type": "integer"} 

276 ), 

277 }, 

278 }, 

279 "HeroPublic": { 

280 "title": "HeroPublic", 

281 "required": ["name", "secret_name", "id"], 

282 "type": "object", 

283 "properties": { 

284 "name": {"title": "Name", "type": "string"}, 

285 "secret_name": {"title": "Secret Name", "type": "string"}, 

286 "age": IsDict( 

287 { 

288 "title": "Age", 

289 "anyOf": [{"type": "integer"}, {"type": "null"}], 

290 } 

291 ) 

292 | IsDict( 

293 # TODO: remove when deprecating Pydantic v1 

294 {"title": "Age", "type": "integer"} 

295 ), 

296 "id": {"title": "Id", "type": "integer"}, 

297 }, 

298 }, 

299 "HeroUpdate": { 

300 "title": "HeroUpdate", 

301 "type": "object", 

302 "properties": { 

303 "name": IsDict( 

304 { 

305 "title": "Name", 

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

307 } 

308 ) 

309 | IsDict( 

310 # TODO: remove when deprecating Pydantic v1 

311 {"title": "Name", "type": "string"} 

312 ), 

313 "secret_name": IsDict( 

314 { 

315 "title": "Secret Name", 

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

317 } 

318 ) 

319 | IsDict( 

320 # TODO: remove when deprecating Pydantic v1 

321 {"title": "Secret Name", "type": "string"} 

322 ), 

323 "age": IsDict( 

324 { 

325 "title": "Age", 

326 "anyOf": [{"type": "integer"}, {"type": "null"}], 

327 } 

328 ) 

329 | IsDict( 

330 # TODO: remove when deprecating Pydantic v1 

331 {"title": "Age", "type": "integer"} 

332 ), 

333 }, 

334 }, 

335 "ValidationError": { 

336 "title": "ValidationError", 

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

338 "type": "object", 

339 "properties": { 

340 "loc": { 

341 "title": "Location", 

342 "type": "array", 

343 "items": { 

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

345 }, 

346 }, 

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

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

349 }, 

350 }, 

351 } 

352 }, 

353 }