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

89 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-01-06 21:09 +0000

1import importlib 1jklmnopqr

2from types import ModuleType 1jklmnopqr

3 

4import pytest 1jklmnopqr

5from fastapi.testclient import TestClient 1jklmnopqr

6from sqlmodel import create_engine 1jklmnopqr

7from sqlmodel.pool import StaticPool 1jklmnopqr

8 

9from tests.conftest import needs_py310 1jklmnopqr

10 

11 

12@pytest.fixture( 1jklmnopqr

13 name="module", 

14 params=[ 

15 pytest.param("tutorial001_py39"), 

16 pytest.param("tutorial001_py310", marks=needs_py310), 

17 ], 

18) 

19def get_module(request: pytest.FixtureRequest) -> ModuleType: 1jklmnopqr

20 mod = importlib.import_module( 1jklmnopqr

21 f"docs_src.tutorial.fastapi.relationships.{request.param}" 

22 ) 

23 mod.sqlite_url = "sqlite://" 1jklmnopqr

24 mod.engine = create_engine( 1jklmnopqr

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

26 ) 

27 return mod 1jklmnopqr

28 

29 

30def test_tutorial(module: ModuleType): 1jklmnopqr

31 with TestClient(module.app) as client: 1abcdefghi

32 team_preventers = {"name": "Preventers", "headquarters": "Sharp Tower"} 1abcdefghi

33 team_z_force = {"name": "Z-Force", "headquarters": "Sister Margaret's Bar"} 1abcdefghi

34 response = client.post("/teams/", json=team_preventers) 1abcdefghi

35 assert response.status_code == 200, response.text 1abcdefghi

36 team_preventers_data = response.json() 1abcdefghi

37 team_preventers_id = team_preventers_data["id"] 1abcdefghi

38 response = client.post("/teams/", json=team_z_force) 1abcdefghi

39 assert response.status_code == 200, response.text 1abcdefghi

40 team_z_force_data = response.json() 1abcdefghi

41 team_z_force_id = team_z_force_data["id"] 1abcdefghi

42 response = client.get("/teams/") 1abcdefghi

43 data = response.json() 1abcdefghi

44 assert len(data) == 2 1abcdefghi

45 response = client.get("/teams/9000") 1abcdefghi

46 assert response.status_code == 404, response.text 1abcdefghi

47 response = client.patch( 1abcdefghi

48 f"/teams/{team_preventers_id}", json={"headquarters": "Preventers Tower"} 

49 ) 

50 data = response.json() 1abcdefghi

51 assert response.status_code == 200, response.text 1abcdefghi

52 assert data["name"] == team_preventers["name"] 1abcdefghi

53 assert data["headquarters"] == "Preventers Tower" 1abcdefghi

54 response = client.patch("/teams/9000", json={"name": "Freedom League"}) 1abcdefghi

55 assert response.status_code == 404, response.text 1abcdefghi

56 

57 hero1_data = { 1abcdefghi

58 "name": "Deadpond", 

59 "secret_name": "Dive Wilson", 

60 "team_id": team_z_force_id, 

61 } 

62 hero2_data = { 1abcdefghi

63 "name": "Spider-Boy", 

64 "secret_name": "Pedro Parqueador", 

65 "id": 9000, 

66 } 

67 hero3_data = { 1abcdefghi

68 "name": "Rusty-Man", 

69 "secret_name": "Tommy Sharp", 

70 "age": 48, 

71 "team_id": team_preventers_id, 

72 } 

73 response = client.post("/heroes/", json=hero1_data) 1abcdefghi

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

75 hero1 = response.json() 1abcdefghi

76 hero1_id = hero1["id"] 1abcdefghi

77 response = client.post("/heroes/", json=hero2_data) 1abcdefghi

78 assert response.status_code == 200, response.text 1abcdefghi

79 hero2 = response.json() 1abcdefghi

80 hero2_id = hero2["id"] 1abcdefghi

81 response = client.post("/heroes/", json=hero3_data) 1abcdefghi

82 assert response.status_code == 200, response.text 1abcdefghi

83 response = client.get("/heroes/9000") 1abcdefghi

84 assert response.status_code == 404, response.text 1abcdefghi

85 response = client.get("/heroes/") 1abcdefghi

86 assert response.status_code == 200, response.text 1abcdefghi

87 data = response.json() 1abcdefghi

88 assert len(data) == 3 1abcdefghi

89 response = client.get(f"/heroes/{hero1_id}") 1abcdefghi

90 assert response.status_code == 200, response.text 1abcdefghi

91 data = response.json() 1abcdefghi

92 assert data["name"] == hero1_data["name"] 1abcdefghi

93 assert data["team"]["name"] == team_z_force["name"] 1abcdefghi

94 response = client.patch( 1abcdefghi

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

96 ) 

97 assert response.status_code == 200, response.text 1abcdefghi

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

99 assert response.status_code == 404, response.text 1abcdefghi

100 response = client.delete(f"/heroes/{hero2_id}") 1abcdefghi

101 assert response.status_code == 200, response.text 1abcdefghi

102 response = client.get("/heroes/") 1abcdefghi

103 assert response.status_code == 200, response.text 1abcdefghi

104 data = response.json() 1abcdefghi

105 assert len(data) == 2 1abcdefghi

106 response = client.delete("/heroes/9000") 1abcdefghi

107 assert response.status_code == 404, response.text 1abcdefghi

108 

109 response = client.get(f"/teams/{team_preventers_id}") 1abcdefghi

110 data = response.json() 1abcdefghi

111 assert response.status_code == 200, response.text 1abcdefghi

112 assert data["name"] == team_preventers_data["name"] 1abcdefghi

113 assert data["heroes"][0]["name"] == hero3_data["name"] 1abcdefghi

114 

115 response = client.delete(f"/teams/{team_preventers_id}") 1abcdefghi

116 assert response.status_code == 200, response.text 1abcdefghi

117 response = client.delete("/teams/9000") 1abcdefghi

118 assert response.status_code == 404, response.text 1abcdefghi

119 response = client.get("/teams/") 1abcdefghi

120 assert response.status_code == 200, response.text 1abcdefghi

121 data = response.json() 1abcdefghi

122 assert len(data) == 1 1abcdefghi

123 

124 response = client.get("/openapi.json") 1abcdefghi

125 assert response.status_code == 200, response.text 1abcdefghi

126 assert response.json() == { 1abcdefghi

127 "openapi": "3.1.0", 

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

129 "paths": { 

130 "/heroes/": { 

131 "get": { 

132 "summary": "Read Heroes", 

133 "operationId": "read_heroes_heroes__get", 

134 "parameters": [ 

135 { 

136 "required": False, 

137 "schema": { 

138 "title": "Offset", 

139 "type": "integer", 

140 "default": 0, 

141 }, 

142 "name": "offset", 

143 "in": "query", 

144 }, 

145 { 

146 "required": False, 

147 "schema": { 

148 "title": "Limit", 

149 "maximum": 100.0, 

150 "type": "integer", 

151 "default": 100, 

152 }, 

153 "name": "limit", 

154 "in": "query", 

155 }, 

156 ], 

157 "responses": { 

158 "200": { 

159 "description": "Successful Response", 

160 "content": { 

161 "application/json": { 

162 "schema": { 

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

164 "type": "array", 

165 "items": { 

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

167 }, 

168 } 

169 } 

170 }, 

171 }, 

172 "422": { 

173 "description": "Validation Error", 

174 "content": { 

175 "application/json": { 

176 "schema": { 

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

178 } 

179 } 

180 }, 

181 }, 

182 }, 

183 }, 

184 "post": { 

185 "summary": "Create Hero", 

186 "operationId": "create_hero_heroes__post", 

187 "requestBody": { 

188 "content": { 

189 "application/json": { 

190 "schema": { 

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

192 } 

193 } 

194 }, 

195 "required": True, 

196 }, 

197 "responses": { 

198 "200": { 

199 "description": "Successful Response", 

200 "content": { 

201 "application/json": { 

202 "schema": { 

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

204 } 

205 } 

206 }, 

207 }, 

208 "422": { 

209 "description": "Validation Error", 

210 "content": { 

211 "application/json": { 

212 "schema": { 

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

214 } 

215 } 

216 }, 

217 }, 

218 }, 

219 }, 

220 }, 

221 "/heroes/{hero_id}": { 

222 "get": { 

223 "summary": "Read Hero", 

224 "operationId": "read_hero_heroes__hero_id__get", 

225 "parameters": [ 

226 { 

227 "required": True, 

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

229 "name": "hero_id", 

230 "in": "path", 

231 } 

232 ], 

233 "responses": { 

234 "200": { 

235 "description": "Successful Response", 

236 "content": { 

237 "application/json": { 

238 "schema": { 

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

240 } 

241 } 

242 }, 

243 }, 

244 "422": { 

245 "description": "Validation Error", 

246 "content": { 

247 "application/json": { 

248 "schema": { 

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

250 } 

251 } 

252 }, 

253 }, 

254 }, 

255 }, 

256 "delete": { 

257 "summary": "Delete Hero", 

258 "operationId": "delete_hero_heroes__hero_id__delete", 

259 "parameters": [ 

260 { 

261 "required": True, 

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

263 "name": "hero_id", 

264 "in": "path", 

265 } 

266 ], 

267 "responses": { 

268 "200": { 

269 "description": "Successful Response", 

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

271 }, 

272 "422": { 

273 "description": "Validation Error", 

274 "content": { 

275 "application/json": { 

276 "schema": { 

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

278 } 

279 } 

280 }, 

281 }, 

282 }, 

283 }, 

284 "patch": { 

285 "summary": "Update Hero", 

286 "operationId": "update_hero_heroes__hero_id__patch", 

287 "parameters": [ 

288 { 

289 "required": True, 

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

291 "name": "hero_id", 

292 "in": "path", 

293 } 

294 ], 

295 "requestBody": { 

296 "content": { 

297 "application/json": { 

298 "schema": { 

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

300 } 

301 } 

302 }, 

303 "required": True, 

304 }, 

305 "responses": { 

306 "200": { 

307 "description": "Successful Response", 

308 "content": { 

309 "application/json": { 

310 "schema": { 

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

312 } 

313 } 

314 }, 

315 }, 

316 "422": { 

317 "description": "Validation Error", 

318 "content": { 

319 "application/json": { 

320 "schema": { 

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

322 } 

323 } 

324 }, 

325 }, 

326 }, 

327 }, 

328 }, 

329 "/teams/": { 

330 "get": { 

331 "summary": "Read Teams", 

332 "operationId": "read_teams_teams__get", 

333 "parameters": [ 

334 { 

335 "required": False, 

336 "schema": { 

337 "title": "Offset", 

338 "type": "integer", 

339 "default": 0, 

340 }, 

341 "name": "offset", 

342 "in": "query", 

343 }, 

344 { 

345 "required": False, 

346 "schema": { 

347 "title": "Limit", 

348 "maximum": 100.0, 

349 "type": "integer", 

350 "default": 100, 

351 }, 

352 "name": "limit", 

353 "in": "query", 

354 }, 

355 ], 

356 "responses": { 

357 "200": { 

358 "description": "Successful Response", 

359 "content": { 

360 "application/json": { 

361 "schema": { 

362 "title": "Response Read Teams Teams Get", 

363 "type": "array", 

364 "items": { 

365 "$ref": "#/components/schemas/TeamPublic" 

366 }, 

367 } 

368 } 

369 }, 

370 }, 

371 "422": { 

372 "description": "Validation Error", 

373 "content": { 

374 "application/json": { 

375 "schema": { 

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

377 } 

378 } 

379 }, 

380 }, 

381 }, 

382 }, 

383 "post": { 

384 "summary": "Create Team", 

385 "operationId": "create_team_teams__post", 

386 "requestBody": { 

387 "content": { 

388 "application/json": { 

389 "schema": { 

390 "$ref": "#/components/schemas/TeamCreate" 

391 } 

392 } 

393 }, 

394 "required": True, 

395 }, 

396 "responses": { 

397 "200": { 

398 "description": "Successful Response", 

399 "content": { 

400 "application/json": { 

401 "schema": { 

402 "$ref": "#/components/schemas/TeamPublic" 

403 } 

404 } 

405 }, 

406 }, 

407 "422": { 

408 "description": "Validation Error", 

409 "content": { 

410 "application/json": { 

411 "schema": { 

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

413 } 

414 } 

415 }, 

416 }, 

417 }, 

418 }, 

419 }, 

420 "/teams/{team_id}": { 

421 "get": { 

422 "summary": "Read Team", 

423 "operationId": "read_team_teams__team_id__get", 

424 "parameters": [ 

425 { 

426 "required": True, 

427 "schema": {"title": "Team Id", "type": "integer"}, 

428 "name": "team_id", 

429 "in": "path", 

430 } 

431 ], 

432 "responses": { 

433 "200": { 

434 "description": "Successful Response", 

435 "content": { 

436 "application/json": { 

437 "schema": { 

438 "$ref": "#/components/schemas/TeamPublicWithHeroes" 

439 } 

440 } 

441 }, 

442 }, 

443 "422": { 

444 "description": "Validation Error", 

445 "content": { 

446 "application/json": { 

447 "schema": { 

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

449 } 

450 } 

451 }, 

452 }, 

453 }, 

454 }, 

455 "delete": { 

456 "summary": "Delete Team", 

457 "operationId": "delete_team_teams__team_id__delete", 

458 "parameters": [ 

459 { 

460 "required": True, 

461 "schema": {"title": "Team Id", "type": "integer"}, 

462 "name": "team_id", 

463 "in": "path", 

464 } 

465 ], 

466 "responses": { 

467 "200": { 

468 "description": "Successful Response", 

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

470 }, 

471 "422": { 

472 "description": "Validation Error", 

473 "content": { 

474 "application/json": { 

475 "schema": { 

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

477 } 

478 } 

479 }, 

480 }, 

481 }, 

482 }, 

483 "patch": { 

484 "summary": "Update Team", 

485 "operationId": "update_team_teams__team_id__patch", 

486 "parameters": [ 

487 { 

488 "required": True, 

489 "schema": {"title": "Team Id", "type": "integer"}, 

490 "name": "team_id", 

491 "in": "path", 

492 } 

493 ], 

494 "requestBody": { 

495 "content": { 

496 "application/json": { 

497 "schema": { 

498 "$ref": "#/components/schemas/TeamUpdate" 

499 } 

500 } 

501 }, 

502 "required": True, 

503 }, 

504 "responses": { 

505 "200": { 

506 "description": "Successful Response", 

507 "content": { 

508 "application/json": { 

509 "schema": { 

510 "$ref": "#/components/schemas/TeamPublic" 

511 } 

512 } 

513 }, 

514 }, 

515 "422": { 

516 "description": "Validation Error", 

517 "content": { 

518 "application/json": { 

519 "schema": { 

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

521 } 

522 } 

523 }, 

524 }, 

525 }, 

526 }, 

527 }, 

528 }, 

529 "components": { 

530 "schemas": { 

531 "HTTPValidationError": { 

532 "title": "HTTPValidationError", 

533 "type": "object", 

534 "properties": { 

535 "detail": { 

536 "title": "Detail", 

537 "type": "array", 

538 "items": { 

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

540 }, 

541 } 

542 }, 

543 }, 

544 "HeroCreate": { 

545 "title": "HeroCreate", 

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

547 "type": "object", 

548 "properties": { 

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

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

551 "age": { 

552 "title": "Age", 

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

554 }, 

555 "team_id": { 

556 "title": "Team Id", 

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

558 }, 

559 }, 

560 }, 

561 "HeroPublic": { 

562 "title": "HeroPublic", 

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

564 "type": "object", 

565 "properties": { 

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

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

568 "age": { 

569 "title": "Age", 

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

571 }, 

572 "team_id": { 

573 "title": "Team Id", 

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

575 }, 

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

577 }, 

578 }, 

579 "HeroPublicWithTeam": { 

580 "title": "HeroPublicWithTeam", 

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

582 "type": "object", 

583 "properties": { 

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

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

586 "age": { 

587 "title": "Age", 

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

589 }, 

590 "team_id": { 

591 "title": "Team Id", 

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

593 }, 

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

595 "team": { 

596 "anyOf": [ 

597 {"$ref": "#/components/schemas/TeamPublic"}, 

598 {"type": "null"}, 

599 ] 

600 }, 

601 }, 

602 }, 

603 "HeroUpdate": { 

604 "title": "HeroUpdate", 

605 "type": "object", 

606 "properties": { 

607 "name": { 

608 "title": "Name", 

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

610 }, 

611 "secret_name": { 

612 "title": "Secret Name", 

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

614 }, 

615 "age": { 

616 "title": "Age", 

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

618 }, 

619 "team_id": { 

620 "title": "Team Id", 

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

622 }, 

623 }, 

624 }, 

625 "TeamCreate": { 

626 "title": "TeamCreate", 

627 "required": ["name", "headquarters"], 

628 "type": "object", 

629 "properties": { 

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

631 "headquarters": {"title": "Headquarters", "type": "string"}, 

632 }, 

633 }, 

634 "TeamPublic": { 

635 "title": "TeamPublic", 

636 "required": ["name", "headquarters", "id"], 

637 "type": "object", 

638 "properties": { 

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

640 "headquarters": {"title": "Headquarters", "type": "string"}, 

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

642 }, 

643 }, 

644 "TeamPublicWithHeroes": { 

645 "title": "TeamPublicWithHeroes", 

646 "required": ["name", "headquarters", "id"], 

647 "type": "object", 

648 "properties": { 

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

650 "headquarters": {"title": "Headquarters", "type": "string"}, 

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

652 "heroes": { 

653 "title": "Heroes", 

654 "type": "array", 

655 "items": {"$ref": "#/components/schemas/HeroPublic"}, 

656 "default": [], 

657 }, 

658 }, 

659 }, 

660 "TeamUpdate": { 

661 "title": "TeamUpdate", 

662 "type": "object", 

663 "properties": { 

664 "id": { 

665 "title": "Id", 

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

667 }, 

668 "name": { 

669 "title": "Name", 

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

671 }, 

672 "headquarters": { 

673 "title": "Headquarters", 

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

675 }, 

676 }, 

677 }, 

678 "ValidationError": { 

679 "title": "ValidationError", 

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

681 "type": "object", 

682 "properties": { 

683 "loc": { 

684 "title": "Location", 

685 "type": "array", 

686 "items": { 

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

688 }, 

689 }, 

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

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

692 }, 

693 }, 

694 } 

695 }, 

696 }