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

47 statements  

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

1from dirty_equals import IsDict 1idefgh

2from fastapi.testclient import TestClient 1idefgh

3from sqlmodel import create_engine 1idefgh

4from sqlmodel.pool import StaticPool 1idefgh

5 

6from ....conftest import needs_py310 1idefgh

7 

8 

9@needs_py310 1idefgh

10def test_tutorial(clear_sqlmodel): 1defgh

11 from docs_src.tutorial.fastapi.update import tutorial001_py310 as mod 1abc

12 

13 mod.sqlite_url = "sqlite://" 1abc

14 mod.engine = create_engine( 1abc

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

16 ) 

17 

18 with TestClient(mod.app) as client: 1abc

19 hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} 1abc

20 hero2_data = { 1abc

21 "name": "Spider-Boy", 

22 "secret_name": "Pedro Parqueador", 

23 "id": 9000, 

24 } 

25 hero3_data = { 1abc

26 "name": "Rusty-Man", 

27 "secret_name": "Tommy Sharp", 

28 "age": 48, 

29 } 

30 response = client.post("/heroes/", json=hero1_data) 1abc

31 assert response.status_code == 200, response.text 1abc

32 response = client.post("/heroes/", json=hero2_data) 1abc

33 assert response.status_code == 200, response.text 1abc

34 hero2 = response.json() 1abc

35 hero2_id = hero2["id"] 1abc

36 response = client.post("/heroes/", json=hero3_data) 1abc

37 assert response.status_code == 200, response.text 1abc

38 hero3 = response.json() 1abc

39 hero3_id = hero3["id"] 1abc

40 response = client.get(f"/heroes/{hero2_id}") 1abc

41 assert response.status_code == 200, response.text 1abc

42 response = client.get("/heroes/9000") 1abc

43 assert response.status_code == 404, response.text 1abc

44 response = client.get("/heroes/") 1abc

45 assert response.status_code == 200, response.text 1abc

46 data = response.json() 1abc

47 assert len(data) == 3 1abc

48 

49 response = client.patch( 1abc

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

51 ) 

52 data = response.json() 1abc

53 assert response.status_code == 200, response.text 1abc

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

55 assert ( 1abc

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

57 ), "The secret name should be updated" 

58 

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

60 data = response.json() 1abc

61 assert response.status_code == 200, response.text 1abc

62 assert data["name"] == hero3_data["name"] 1abc

63 assert data["age"] is None, ( 1abc

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

65 ) 

66 

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

68 assert response.status_code == 404, response.text 1abc

69 

70 response = client.get("/openapi.json") 1abc

71 assert response.status_code == 200, response.text 1abc

72 assert response.json() == { 1abc

73 "openapi": "3.1.0", 

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

75 "paths": { 

76 "/heroes/": { 

77 "get": { 

78 "summary": "Read Heroes", 

79 "operationId": "read_heroes_heroes__get", 

80 "parameters": [ 

81 { 

82 "required": False, 

83 "schema": { 

84 "title": "Offset", 

85 "type": "integer", 

86 "default": 0, 

87 }, 

88 "name": "offset", 

89 "in": "query", 

90 }, 

91 { 

92 "required": False, 

93 "schema": { 

94 "title": "Limit", 

95 "maximum": 100.0, 

96 "type": "integer", 

97 "default": 100, 

98 }, 

99 "name": "limit", 

100 "in": "query", 

101 }, 

102 ], 

103 "responses": { 

104 "200": { 

105 "description": "Successful Response", 

106 "content": { 

107 "application/json": { 

108 "schema": { 

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

110 "type": "array", 

111 "items": { 

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

113 }, 

114 } 

115 } 

116 }, 

117 }, 

118 "422": { 

119 "description": "Validation Error", 

120 "content": { 

121 "application/json": { 

122 "schema": { 

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

124 } 

125 } 

126 }, 

127 }, 

128 }, 

129 }, 

130 "post": { 

131 "summary": "Create Hero", 

132 "operationId": "create_hero_heroes__post", 

133 "requestBody": { 

134 "content": { 

135 "application/json": { 

136 "schema": { 

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

138 } 

139 } 

140 }, 

141 "required": True, 

142 }, 

143 "responses": { 

144 "200": { 

145 "description": "Successful Response", 

146 "content": { 

147 "application/json": { 

148 "schema": { 

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

150 } 

151 } 

152 }, 

153 }, 

154 "422": { 

155 "description": "Validation Error", 

156 "content": { 

157 "application/json": { 

158 "schema": { 

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

160 } 

161 } 

162 }, 

163 }, 

164 }, 

165 }, 

166 }, 

167 "/heroes/{hero_id}": { 

168 "get": { 

169 "summary": "Read Hero", 

170 "operationId": "read_hero_heroes__hero_id__get", 

171 "parameters": [ 

172 { 

173 "required": True, 

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

175 "name": "hero_id", 

176 "in": "path", 

177 } 

178 ], 

179 "responses": { 

180 "200": { 

181 "description": "Successful Response", 

182 "content": { 

183 "application/json": { 

184 "schema": { 

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

186 } 

187 } 

188 }, 

189 }, 

190 "422": { 

191 "description": "Validation Error", 

192 "content": { 

193 "application/json": { 

194 "schema": { 

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

196 } 

197 } 

198 }, 

199 }, 

200 }, 

201 }, 

202 "patch": { 

203 "summary": "Update Hero", 

204 "operationId": "update_hero_heroes__hero_id__patch", 

205 "parameters": [ 

206 { 

207 "required": True, 

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

209 "name": "hero_id", 

210 "in": "path", 

211 } 

212 ], 

213 "requestBody": { 

214 "content": { 

215 "application/json": { 

216 "schema": { 

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

218 } 

219 } 

220 }, 

221 "required": True, 

222 }, 

223 "responses": { 

224 "200": { 

225 "description": "Successful Response", 

226 "content": { 

227 "application/json": { 

228 "schema": { 

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

230 } 

231 } 

232 }, 

233 }, 

234 "422": { 

235 "description": "Validation Error", 

236 "content": { 

237 "application/json": { 

238 "schema": { 

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

240 } 

241 } 

242 }, 

243 }, 

244 }, 

245 }, 

246 }, 

247 }, 

248 "components": { 

249 "schemas": { 

250 "HTTPValidationError": { 

251 "title": "HTTPValidationError", 

252 "type": "object", 

253 "properties": { 

254 "detail": { 

255 "title": "Detail", 

256 "type": "array", 

257 "items": { 

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

259 }, 

260 } 

261 }, 

262 }, 

263 "HeroCreate": { 

264 "title": "HeroCreate", 

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

266 "type": "object", 

267 "properties": { 

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

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

270 "age": IsDict( 

271 { 

272 "title": "Age", 

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

274 } 

275 ) 

276 | IsDict( 

277 # TODO: remove when deprecating Pydantic v1 

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

279 ), 

280 }, 

281 }, 

282 "HeroPublic": { 

283 "title": "HeroPublic", 

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

285 "type": "object", 

286 "properties": { 

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

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

289 "age": IsDict( 

290 { 

291 "title": "Age", 

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

293 } 

294 ) 

295 | IsDict( 

296 # TODO: remove when deprecating Pydantic v1 

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

298 ), 

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

300 }, 

301 }, 

302 "HeroUpdate": { 

303 "title": "HeroUpdate", 

304 "type": "object", 

305 "properties": { 

306 "name": IsDict( 

307 { 

308 "title": "Name", 

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

310 } 

311 ) 

312 | IsDict( 

313 # TODO: remove when deprecating Pydantic v1 

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

315 ), 

316 "secret_name": IsDict( 

317 { 

318 "title": "Secret Name", 

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

320 } 

321 ) 

322 | IsDict( 

323 # TODO: remove when deprecating Pydantic v1 

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

325 ), 

326 "age": IsDict( 

327 { 

328 "title": "Age", 

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

330 } 

331 ) 

332 | IsDict( 

333 # TODO: remove when deprecating Pydantic v1 

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

335 ), 

336 }, 

337 }, 

338 "ValidationError": { 

339 "title": "ValidationError", 

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

341 "type": "object", 

342 "properties": { 

343 "loc": { 

344 "title": "Location", 

345 "type": "array", 

346 "items": { 

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

348 }, 

349 }, 

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

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

352 }, 

353 }, 

354 } 

355 }, 

356 }