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-06-10 09:40 +0000

1import importlib 1ijklmnop

2from types import ModuleType 1ijklmnop

3 

4import pytest 1ijklmnop

5from dirty_equals import IsOneOf 1ijklmnop

6from fastapi.testclient import TestClient 1ijklmnop

7from sqlmodel import create_engine 1ijklmnop

8from sqlmodel.pool import StaticPool 1ijklmnop

9 

10 

11@pytest.fixture( 1ijklmnop

12 name="module", 

13 params=[ 

14 pytest.param("tutorial001_py310"), 

15 ], 

16) 

17def get_module(request: pytest.FixtureRequest) -> ModuleType: 1ijklmnop

18 mod = importlib.import_module( 1ijklmnop

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

20 ) 

21 mod.sqlite_url = "sqlite://" 1ijklmnop

22 mod.engine = create_engine( 1ijklmnop

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

24 ) 

25 return mod 1ijklmnop

26 

27 

28def test_tutorial(module: ModuleType): 1ijklmnop

29 with TestClient(module.app) as client: 1abcdefgh

30 team_preventers = {"name": "Preventers", "headquarters": "Sharp Tower"} 1abcdefgh

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

32 response = client.post("/teams/", json=team_preventers) 1abcdefgh

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

34 team_preventers_data = response.json() 1abcdefgh

35 team_preventers_id = team_preventers_data["id"] 1abcdefgh

36 response = client.post("/teams/", json=team_z_force) 1abcdefgh

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

38 team_z_force_data = response.json() 1abcdefgh

39 team_z_force_id = team_z_force_data["id"] 1abcdefgh

40 response = client.get("/teams/") 1abcdefgh

41 data = response.json() 1abcdefgh

42 assert len(data) == 2 1abcdefgh

43 response = client.get("/teams/9000") 1abcdefgh

44 assert response.status_code == 404, response.text 1abcdefgh

45 response = client.patch( 1abcdefgh

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

47 ) 

48 data = response.json() 1abcdefgh

49 assert response.status_code == 200, response.text 1abcdefgh

50 assert data["name"] == team_preventers["name"] 1abcdefgh

51 assert data["headquarters"] == "Preventers Tower" 1abcdefgh

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

53 assert response.status_code == 404, response.text 1abcdefgh

54 

55 hero1_data = { 1abcdefgh

56 "name": "Deadpond", 

57 "secret_name": "Dive Wilson", 

58 "team_id": team_z_force_id, 

59 } 

60 hero2_data = { 1abcdefgh

61 "name": "Spider-Boy", 

62 "secret_name": "Pedro Parqueador", 

63 "id": 9000, 

64 } 

65 hero3_data = { 1abcdefgh

66 "name": "Rusty-Man", 

67 "secret_name": "Tommy Sharp", 

68 "age": 48, 

69 "team_id": team_preventers_id, 

70 } 

71 response = client.post("/heroes/", json=hero1_data) 1abcdefgh

72 assert response.status_code == 200, response.text 1abcdefgh

73 hero1 = response.json() 1abcdefgh

74 hero1_id = hero1["id"] 1abcdefgh

75 response = client.post("/heroes/", json=hero2_data) 1abcdefgh

76 assert response.status_code == 200, response.text 1abcdefgh

77 hero2 = response.json() 1abcdefgh

78 hero2_id = hero2["id"] 1abcdefgh

79 response = client.post("/heroes/", json=hero3_data) 1abcdefgh

80 assert response.status_code == 200, response.text 1abcdefgh

81 response = client.get("/heroes/9000") 1abcdefgh

82 assert response.status_code == 404, response.text 1abcdefgh

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

84 assert response.status_code == 200, response.text 1abcdefgh

85 data = response.json() 1abcdefgh

86 assert len(data) == 3 1abcdefgh

87 response = client.get(f"/heroes/{hero1_id}") 1abcdefgh

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

89 data = response.json() 1abcdefgh

90 assert data["name"] == hero1_data["name"] 1abcdefgh

91 assert data["team"]["name"] == team_z_force["name"] 1abcdefgh

92 response = client.patch( 1abcdefgh

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

94 ) 

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

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

97 assert response.status_code == 404, response.text 1abcdefgh

98 response = client.delete(f"/heroes/{hero2_id}") 1abcdefgh

99 assert response.status_code == 200, response.text 1abcdefgh

100 response = client.get("/heroes/") 1abcdefgh

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

102 data = response.json() 1abcdefgh

103 assert len(data) == 2 1abcdefgh

104 response = client.delete("/heroes/9000") 1abcdefgh

105 assert response.status_code == 404, response.text 1abcdefgh

106 

107 response = client.get(f"/teams/{team_preventers_id}") 1abcdefgh

108 data = response.json() 1abcdefgh

109 assert response.status_code == 200, response.text 1abcdefgh

110 assert data["name"] == team_preventers_data["name"] 1abcdefgh

111 assert data["heroes"][0]["name"] == hero3_data["name"] 1abcdefgh

112 

113 response = client.delete(f"/teams/{team_preventers_id}") 1abcdefgh

114 assert response.status_code == 200, response.text 1abcdefgh

115 response = client.delete("/teams/9000") 1abcdefgh

116 assert response.status_code == 404, response.text 1abcdefgh

117 response = client.get("/teams/") 1abcdefgh

118 assert response.status_code == 200, response.text 1abcdefgh

119 data = response.json() 1abcdefgh

120 assert len(data) == 1 1abcdefgh

121 

122 response = client.get("/openapi.json") 1abcdefgh

123 assert response.status_code == 200, response.text 1abcdefgh

124 assert response.json() == { 1abcdefgh

125 "openapi": "3.1.0", 

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

127 "paths": { 

128 "/heroes/": { 

129 "get": { 

130 "summary": "Read Heroes", 

131 "operationId": "read_heroes_heroes__get", 

132 "parameters": [ 

133 { 

134 "required": False, 

135 "schema": { 

136 "title": "Offset", 

137 "type": "integer", 

138 "default": 0, 

139 }, 

140 "name": "offset", 

141 "in": "query", 

142 }, 

143 { 

144 "required": False, 

145 "schema": { 

146 "title": "Limit", 

147 "maximum": 100.0, 

148 "type": "integer", 

149 "default": 100, 

150 }, 

151 "name": "limit", 

152 "in": "query", 

153 }, 

154 ], 

155 "responses": { 

156 "200": { 

157 "description": "Successful Response", 

158 "content": { 

159 "application/json": { 

160 "schema": { 

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

162 "type": "array", 

163 "items": { 

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

165 }, 

166 } 

167 } 

168 }, 

169 }, 

170 "422": { 

171 "description": "Validation Error", 

172 "content": { 

173 "application/json": { 

174 "schema": { 

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

176 } 

177 } 

178 }, 

179 }, 

180 }, 

181 }, 

182 "post": { 

183 "summary": "Create Hero", 

184 "operationId": "create_hero_heroes__post", 

185 "requestBody": { 

186 "content": { 

187 "application/json": { 

188 "schema": { 

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

190 } 

191 } 

192 }, 

193 "required": True, 

194 }, 

195 "responses": { 

196 "200": { 

197 "description": "Successful Response", 

198 "content": { 

199 "application/json": { 

200 "schema": { 

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

202 } 

203 } 

204 }, 

205 }, 

206 "422": { 

207 "description": "Validation Error", 

208 "content": { 

209 "application/json": { 

210 "schema": { 

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

212 } 

213 } 

214 }, 

215 }, 

216 }, 

217 }, 

218 }, 

219 "/heroes/{hero_id}": { 

220 "get": { 

221 "summary": "Read Hero", 

222 "operationId": "read_hero_heroes__hero_id__get", 

223 "parameters": [ 

224 { 

225 "required": True, 

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

227 "name": "hero_id", 

228 "in": "path", 

229 } 

230 ], 

231 "responses": { 

232 "200": { 

233 "description": "Successful Response", 

234 "content": { 

235 "application/json": { 

236 "schema": { 

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

238 } 

239 } 

240 }, 

241 }, 

242 "422": { 

243 "description": "Validation Error", 

244 "content": { 

245 "application/json": { 

246 "schema": { 

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

248 } 

249 } 

250 }, 

251 }, 

252 }, 

253 }, 

254 "delete": { 

255 "summary": "Delete Hero", 

256 "operationId": "delete_hero_heroes__hero_id__delete", 

257 "parameters": [ 

258 { 

259 "required": True, 

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

261 "name": "hero_id", 

262 "in": "path", 

263 } 

264 ], 

265 "responses": { 

266 "200": { 

267 "description": "Successful Response", 

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

269 }, 

270 "422": { 

271 "description": "Validation Error", 

272 "content": { 

273 "application/json": { 

274 "schema": { 

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

276 } 

277 } 

278 }, 

279 }, 

280 }, 

281 }, 

282 "patch": { 

283 "summary": "Update Hero", 

284 "operationId": "update_hero_heroes__hero_id__patch", 

285 "parameters": [ 

286 { 

287 "required": True, 

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

289 "name": "hero_id", 

290 "in": "path", 

291 } 

292 ], 

293 "requestBody": { 

294 "content": { 

295 "application/json": { 

296 "schema": { 

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

298 } 

299 } 

300 }, 

301 "required": True, 

302 }, 

303 "responses": { 

304 "200": { 

305 "description": "Successful Response", 

306 "content": { 

307 "application/json": { 

308 "schema": { 

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

310 } 

311 } 

312 }, 

313 }, 

314 "422": { 

315 "description": "Validation Error", 

316 "content": { 

317 "application/json": { 

318 "schema": { 

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

320 } 

321 } 

322 }, 

323 }, 

324 }, 

325 }, 

326 }, 

327 "/teams/": { 

328 "get": { 

329 "summary": "Read Teams", 

330 "operationId": "read_teams_teams__get", 

331 "parameters": [ 

332 { 

333 "required": False, 

334 "schema": { 

335 "title": "Offset", 

336 "type": "integer", 

337 "default": 0, 

338 }, 

339 "name": "offset", 

340 "in": "query", 

341 }, 

342 { 

343 "required": False, 

344 "schema": { 

345 "title": "Limit", 

346 "maximum": 100.0, 

347 "type": "integer", 

348 "default": 100, 

349 }, 

350 "name": "limit", 

351 "in": "query", 

352 }, 

353 ], 

354 "responses": { 

355 "200": { 

356 "description": "Successful Response", 

357 "content": { 

358 "application/json": { 

359 "schema": { 

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

361 "type": "array", 

362 "items": { 

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

364 }, 

365 } 

366 } 

367 }, 

368 }, 

369 "422": { 

370 "description": "Validation Error", 

371 "content": { 

372 "application/json": { 

373 "schema": { 

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

375 } 

376 } 

377 }, 

378 }, 

379 }, 

380 }, 

381 "post": { 

382 "summary": "Create Team", 

383 "operationId": "create_team_teams__post", 

384 "requestBody": { 

385 "content": { 

386 "application/json": { 

387 "schema": { 

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

389 } 

390 } 

391 }, 

392 "required": True, 

393 }, 

394 "responses": { 

395 "200": { 

396 "description": "Successful Response", 

397 "content": { 

398 "application/json": { 

399 "schema": { 

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

401 } 

402 } 

403 }, 

404 }, 

405 "422": { 

406 "description": "Validation Error", 

407 "content": { 

408 "application/json": { 

409 "schema": { 

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

411 } 

412 } 

413 }, 

414 }, 

415 }, 

416 }, 

417 }, 

418 "/teams/{team_id}": { 

419 "get": { 

420 "summary": "Read Team", 

421 "operationId": "read_team_teams__team_id__get", 

422 "parameters": [ 

423 { 

424 "required": True, 

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

426 "name": "team_id", 

427 "in": "path", 

428 } 

429 ], 

430 "responses": { 

431 "200": { 

432 "description": "Successful Response", 

433 "content": { 

434 "application/json": { 

435 "schema": { 

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

437 } 

438 } 

439 }, 

440 }, 

441 "422": { 

442 "description": "Validation Error", 

443 "content": { 

444 "application/json": { 

445 "schema": { 

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

447 } 

448 } 

449 }, 

450 }, 

451 }, 

452 }, 

453 "delete": { 

454 "summary": "Delete Team", 

455 "operationId": "delete_team_teams__team_id__delete", 

456 "parameters": [ 

457 { 

458 "required": True, 

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

460 "name": "team_id", 

461 "in": "path", 

462 } 

463 ], 

464 "responses": { 

465 "200": { 

466 "description": "Successful Response", 

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

468 }, 

469 "422": { 

470 "description": "Validation Error", 

471 "content": { 

472 "application/json": { 

473 "schema": { 

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

475 } 

476 } 

477 }, 

478 }, 

479 }, 

480 }, 

481 "patch": { 

482 "summary": "Update Team", 

483 "operationId": "update_team_teams__team_id__patch", 

484 "parameters": [ 

485 { 

486 "required": True, 

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

488 "name": "team_id", 

489 "in": "path", 

490 } 

491 ], 

492 "requestBody": { 

493 "content": { 

494 "application/json": { 

495 "schema": { 

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

497 } 

498 } 

499 }, 

500 "required": True, 

501 }, 

502 "responses": { 

503 "200": { 

504 "description": "Successful Response", 

505 "content": { 

506 "application/json": { 

507 "schema": { 

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

509 } 

510 } 

511 }, 

512 }, 

513 "422": { 

514 "description": "Validation Error", 

515 "content": { 

516 "application/json": { 

517 "schema": { 

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

519 } 

520 } 

521 }, 

522 }, 

523 }, 

524 }, 

525 }, 

526 }, 

527 "components": { 

528 "schemas": { 

529 "HTTPValidationError": { 

530 "title": "HTTPValidationError", 

531 "type": "object", 

532 "properties": { 

533 "detail": { 

534 "title": "Detail", 

535 "type": "array", 

536 "items": { 

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

538 }, 

539 } 

540 }, 

541 }, 

542 "HeroCreate": { 

543 "title": "HeroCreate", 

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

545 "type": "object", 

546 "properties": { 

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

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

549 "age": { 

550 "title": "Age", 

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

552 }, 

553 "team_id": { 

554 "title": "Team Id", 

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

556 }, 

557 }, 

558 }, 

559 "HeroPublic": { 

560 "title": "HeroPublic", 

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

562 "type": "object", 

563 "properties": { 

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

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

566 "age": { 

567 "title": "Age", 

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

569 }, 

570 "team_id": { 

571 "title": "Team Id", 

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

573 }, 

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

575 }, 

576 }, 

577 "HeroPublicWithTeam": { 

578 "title": "HeroPublicWithTeam", 

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

580 "type": "object", 

581 "properties": { 

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

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

584 "age": { 

585 "title": "Age", 

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

587 }, 

588 "team_id": { 

589 "title": "Team Id", 

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

591 }, 

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

593 "team": { 

594 "anyOf": [ 

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

596 {"type": "null"}, 

597 ] 

598 }, 

599 }, 

600 }, 

601 "HeroUpdate": { 

602 "title": "HeroUpdate", 

603 "type": "object", 

604 "properties": { 

605 "name": { 

606 "title": "Name", 

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

608 }, 

609 "secret_name": { 

610 "title": "Secret Name", 

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

612 }, 

613 "age": { 

614 "title": "Age", 

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

616 }, 

617 "team_id": { 

618 "title": "Team Id", 

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

620 }, 

621 }, 

622 }, 

623 "TeamCreate": { 

624 "title": "TeamCreate", 

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

626 "type": "object", 

627 "properties": { 

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

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

630 }, 

631 }, 

632 "TeamPublic": { 

633 "title": "TeamPublic", 

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

635 "type": "object", 

636 "properties": { 

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

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

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

640 }, 

641 }, 

642 "TeamPublicWithHeroes": { 

643 "title": "TeamPublicWithHeroes", 

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

645 "type": "object", 

646 "properties": { 

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

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

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

650 "heroes": { 

651 "title": "Heroes", 

652 "type": "array", 

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

654 "default": [], 

655 }, 

656 }, 

657 }, 

658 "TeamUpdate": { 

659 "title": "TeamUpdate", 

660 "type": "object", 

661 "properties": { 

662 "id": { 

663 "title": "Id", 

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

665 }, 

666 "name": { 

667 "title": "Name", 

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

669 }, 

670 "headquarters": { 

671 "title": "Headquarters", 

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

673 }, 

674 }, 

675 }, 

676 "ValidationError": { 

677 "title": "ValidationError", 

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

679 "type": "object", 

680 "properties": IsOneOf( 

681 { 

682 "loc": { 

683 "title": "Location", 

684 "type": "array", 

685 "items": { 

686 "anyOf": [ 

687 {"type": "string"}, 

688 {"type": "integer"}, 

689 ] 

690 }, 

691 }, 

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

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

694 }, 

695 { 

696 "loc": { 

697 "title": "Location", 

698 "type": "array", 

699 "items": { 

700 "anyOf": [ 

701 {"type": "string"}, 

702 {"type": "integer"}, 

703 ] 

704 }, 

705 }, 

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

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

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

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

710 }, 

711 ), 

712 }, 

713 } 

714 }, 

715 }