Coverage for tests/test_tutorial/test_bigger_applications/test_main_an_py39.py: 100%

134 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-08 03:53 +0000

1import pytest 1eabcd

2from dirty_equals import IsDict 1eabcd

3from fastapi.testclient import TestClient 1eabcd

4 

5from ...utils import needs_py39 1eabcd

6 

7 

8@pytest.fixture(name="client") 1eabcd

9def get_client(): 1eabcd

10 from docs_src.bigger_applications.app_an_py39.main import app 1abcd

11 

12 client = TestClient(app) 1abcd

13 return client 1abcd

14 

15 

16@needs_py39 1eabcd

17def test_users_token_jessica(client: TestClient): 1eabcd

18 response = client.get("/users?token=jessica") 1abcd

19 assert response.status_code == 200 1abcd

20 assert response.json() == [{"username": "Rick"}, {"username": "Morty"}] 1abcd

21 

22 

23@needs_py39 1eabcd

24def test_users_with_no_token(client: TestClient): 1eabcd

25 response = client.get("/users") 1abcd

26 assert response.status_code == 422 1abcd

27 assert response.json() == IsDict( 1abcd

28 { 

29 "detail": [ 

30 { 

31 "type": "missing", 

32 "loc": ["query", "token"], 

33 "msg": "Field required", 

34 "input": None, 

35 } 

36 ] 

37 } 

38 ) | IsDict( 

39 # TODO: remove when deprecating Pydantic v1 

40 { 

41 "detail": [ 

42 { 

43 "loc": ["query", "token"], 

44 "msg": "field required", 

45 "type": "value_error.missing", 

46 }, 

47 ] 

48 } 

49 ) 

50 

51 

52@needs_py39 1eabcd

53def test_users_foo_token_jessica(client: TestClient): 1eabcd

54 response = client.get("/users/foo?token=jessica") 1abcd

55 assert response.status_code == 200 1abcd

56 assert response.json() == {"username": "foo"} 1abcd

57 

58 

59@needs_py39 1eabcd

60def test_users_foo_with_no_token(client: TestClient): 1eabcd

61 response = client.get("/users/foo") 1abcd

62 assert response.status_code == 422 1abcd

63 assert response.json() == IsDict( 1abcd

64 { 

65 "detail": [ 

66 { 

67 "type": "missing", 

68 "loc": ["query", "token"], 

69 "msg": "Field required", 

70 "input": None, 

71 } 

72 ] 

73 } 

74 ) | IsDict( 

75 # TODO: remove when deprecating Pydantic v1 

76 { 

77 "detail": [ 

78 { 

79 "loc": ["query", "token"], 

80 "msg": "field required", 

81 "type": "value_error.missing", 

82 }, 

83 ] 

84 } 

85 ) 

86 

87 

88@needs_py39 1eabcd

89def test_users_me_token_jessica(client: TestClient): 1eabcd

90 response = client.get("/users/me?token=jessica") 1abcd

91 assert response.status_code == 200 1abcd

92 assert response.json() == {"username": "fakecurrentuser"} 1abcd

93 

94 

95@needs_py39 1eabcd

96def test_users_me_with_no_token(client: TestClient): 1eabcd

97 response = client.get("/users/me") 1abcd

98 assert response.status_code == 422 1abcd

99 assert response.json() == IsDict( 1abcd

100 { 

101 "detail": [ 

102 { 

103 "type": "missing", 

104 "loc": ["query", "token"], 

105 "msg": "Field required", 

106 "input": None, 

107 } 

108 ] 

109 } 

110 ) | IsDict( 

111 # TODO: remove when deprecating Pydantic v1 

112 { 

113 "detail": [ 

114 { 

115 "loc": ["query", "token"], 

116 "msg": "field required", 

117 "type": "value_error.missing", 

118 }, 

119 ] 

120 } 

121 ) 

122 

123 

124@needs_py39 1eabcd

125def test_users_token_monica_with_no_jessica(client: TestClient): 1eabcd

126 response = client.get("/users?token=monica") 1abcd

127 assert response.status_code == 400 1abcd

128 assert response.json() == {"detail": "No Jessica token provided"} 1abcd

129 

130 

131@needs_py39 1eabcd

132def test_items_token_jessica(client: TestClient): 1eabcd

133 response = client.get( 1abcd

134 "/items?token=jessica", headers={"X-Token": "fake-super-secret-token"} 

135 ) 

136 assert response.status_code == 200 1abcd

137 assert response.json() == { 1abcd

138 "plumbus": {"name": "Plumbus"}, 

139 "gun": {"name": "Portal Gun"}, 

140 } 

141 

142 

143@needs_py39 1eabcd

144def test_items_with_no_token_jessica(client: TestClient): 1eabcd

145 response = client.get("/items", headers={"X-Token": "fake-super-secret-token"}) 1abcd

146 assert response.status_code == 422 1abcd

147 assert response.json() == IsDict( 1abcd

148 { 

149 "detail": [ 

150 { 

151 "type": "missing", 

152 "loc": ["query", "token"], 

153 "msg": "Field required", 

154 "input": None, 

155 } 

156 ] 

157 } 

158 ) | IsDict( 

159 # TODO: remove when deprecating Pydantic v1 

160 { 

161 "detail": [ 

162 { 

163 "loc": ["query", "token"], 

164 "msg": "field required", 

165 "type": "value_error.missing", 

166 }, 

167 ] 

168 } 

169 ) 

170 

171 

172@needs_py39 1eabcd

173def test_items_plumbus_token_jessica(client: TestClient): 1eabcd

174 response = client.get( 1abcd

175 "/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"} 

176 ) 

177 assert response.status_code == 200 1abcd

178 assert response.json() == {"name": "Plumbus", "item_id": "plumbus"} 1abcd

179 

180 

181@needs_py39 1eabcd

182def test_items_bar_token_jessica(client: TestClient): 1eabcd

183 response = client.get( 1abcd

184 "/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"} 

185 ) 

186 assert response.status_code == 404 1abcd

187 assert response.json() == {"detail": "Item not found"} 1abcd

188 

189 

190@needs_py39 1eabcd

191def test_items_plumbus_with_no_token(client: TestClient): 1eabcd

192 response = client.get( 1abcd

193 "/items/plumbus", headers={"X-Token": "fake-super-secret-token"} 

194 ) 

195 assert response.status_code == 422 1abcd

196 assert response.json() == IsDict( 1abcd

197 { 

198 "detail": [ 

199 { 

200 "type": "missing", 

201 "loc": ["query", "token"], 

202 "msg": "Field required", 

203 "input": None, 

204 } 

205 ] 

206 } 

207 ) | IsDict( 

208 # TODO: remove when deprecating Pydantic v1 

209 { 

210 "detail": [ 

211 { 

212 "loc": ["query", "token"], 

213 "msg": "field required", 

214 "type": "value_error.missing", 

215 }, 

216 ] 

217 } 

218 ) 

219 

220 

221@needs_py39 1eabcd

222def test_items_with_invalid_token(client: TestClient): 1eabcd

223 response = client.get("/items?token=jessica", headers={"X-Token": "invalid"}) 1abcd

224 assert response.status_code == 400 1abcd

225 assert response.json() == {"detail": "X-Token header invalid"} 1abcd

226 

227 

228@needs_py39 1eabcd

229def test_items_bar_with_invalid_token(client: TestClient): 1eabcd

230 response = client.get("/items/bar?token=jessica", headers={"X-Token": "invalid"}) 1abcd

231 assert response.status_code == 400 1abcd

232 assert response.json() == {"detail": "X-Token header invalid"} 1abcd

233 

234 

235@needs_py39 1eabcd

236def test_items_with_missing_x_token_header(client: TestClient): 1eabcd

237 response = client.get("/items?token=jessica") 1abcd

238 assert response.status_code == 422 1abcd

239 assert response.json() == IsDict( 1abcd

240 { 

241 "detail": [ 

242 { 

243 "type": "missing", 

244 "loc": ["header", "x-token"], 

245 "msg": "Field required", 

246 "input": None, 

247 } 

248 ] 

249 } 

250 ) | IsDict( 

251 # TODO: remove when deprecating Pydantic v1 

252 { 

253 "detail": [ 

254 { 

255 "loc": ["header", "x-token"], 

256 "msg": "field required", 

257 "type": "value_error.missing", 

258 } 

259 ] 

260 } 

261 ) 

262 

263 

264@needs_py39 1eabcd

265def test_items_plumbus_with_missing_x_token_header(client: TestClient): 1eabcd

266 response = client.get("/items/plumbus?token=jessica") 1abcd

267 assert response.status_code == 422 1abcd

268 assert response.json() == IsDict( 1abcd

269 { 

270 "detail": [ 

271 { 

272 "type": "missing", 

273 "loc": ["header", "x-token"], 

274 "msg": "Field required", 

275 "input": None, 

276 } 

277 ] 

278 } 

279 ) | IsDict( 

280 # TODO: remove when deprecating Pydantic v1 

281 { 

282 "detail": [ 

283 { 

284 "loc": ["header", "x-token"], 

285 "msg": "field required", 

286 "type": "value_error.missing", 

287 } 

288 ] 

289 } 

290 ) 

291 

292 

293@needs_py39 1eabcd

294def test_root_token_jessica(client: TestClient): 1eabcd

295 response = client.get("/?token=jessica") 1abcd

296 assert response.status_code == 200 1abcd

297 assert response.json() == {"message": "Hello Bigger Applications!"} 1abcd

298 

299 

300@needs_py39 1eabcd

301def test_root_with_no_token(client: TestClient): 1eabcd

302 response = client.get("/") 1abcd

303 assert response.status_code == 422 1abcd

304 assert response.json() == IsDict( 1abcd

305 { 

306 "detail": [ 

307 { 

308 "type": "missing", 

309 "loc": ["query", "token"], 

310 "msg": "Field required", 

311 "input": None, 

312 } 

313 ] 

314 } 

315 ) | IsDict( 

316 # TODO: remove when deprecating Pydantic v1 

317 { 

318 "detail": [ 

319 { 

320 "loc": ["query", "token"], 

321 "msg": "field required", 

322 "type": "value_error.missing", 

323 }, 

324 ] 

325 } 

326 ) 

327 

328 

329@needs_py39 1eabcd

330def test_put_no_header(client: TestClient): 1eabcd

331 response = client.put("/items/foo") 1abcd

332 assert response.status_code == 422, response.text 1abcd

333 assert response.json() == IsDict( 1abcd

334 { 

335 "detail": [ 

336 { 

337 "type": "missing", 

338 "loc": ["query", "token"], 

339 "msg": "Field required", 

340 "input": None, 

341 }, 

342 { 

343 "type": "missing", 

344 "loc": ["header", "x-token"], 

345 "msg": "Field required", 

346 "input": None, 

347 }, 

348 ] 

349 } 

350 ) | IsDict( 

351 # TODO: remove when deprecating Pydantic v1 

352 { 

353 "detail": [ 

354 { 

355 "loc": ["query", "token"], 

356 "msg": "field required", 

357 "type": "value_error.missing", 

358 }, 

359 { 

360 "loc": ["header", "x-token"], 

361 "msg": "field required", 

362 "type": "value_error.missing", 

363 }, 

364 ] 

365 } 

366 ) 

367 

368 

369@needs_py39 1eabcd

370def test_put_invalid_header(client: TestClient): 1eabcd

371 response = client.put("/items/foo", headers={"X-Token": "invalid"}) 1abcd

372 assert response.status_code == 400, response.text 1abcd

373 assert response.json() == {"detail": "X-Token header invalid"} 1abcd

374 

375 

376@needs_py39 1eabcd

377def test_put(client: TestClient): 1eabcd

378 response = client.put( 1abcd

379 "/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"} 

380 ) 

381 assert response.status_code == 200, response.text 1abcd

382 assert response.json() == {"item_id": "plumbus", "name": "The great Plumbus"} 1abcd

383 

384 

385@needs_py39 1eabcd

386def test_put_forbidden(client: TestClient): 1eabcd

387 response = client.put( 1abcd

388 "/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"} 

389 ) 

390 assert response.status_code == 403, response.text 1abcd

391 assert response.json() == {"detail": "You can only update the item: plumbus"} 1abcd

392 

393 

394@needs_py39 1eabcd

395def test_admin(client: TestClient): 1eabcd

396 response = client.post( 1abcd

397 "/admin/?token=jessica", headers={"X-Token": "fake-super-secret-token"} 

398 ) 

399 assert response.status_code == 200, response.text 1abcd

400 assert response.json() == {"message": "Admin getting schwifty"} 1abcd

401 

402 

403@needs_py39 1eabcd

404def test_admin_invalid_header(client: TestClient): 1eabcd

405 response = client.post("/admin/", headers={"X-Token": "invalid"}) 1abcd

406 assert response.status_code == 400, response.text 1abcd

407 assert response.json() == {"detail": "X-Token header invalid"} 1abcd

408 

409 

410@needs_py39 1eabcd

411def test_openapi_schema(client: TestClient): 1eabcd

412 response = client.get("/openapi.json") 1abcd

413 assert response.status_code == 200, response.text 1abcd

414 assert response.json() == { 1abcd

415 "openapi": "3.1.0", 

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

417 "paths": { 

418 "/users/": { 

419 "get": { 

420 "tags": ["users"], 

421 "summary": "Read Users", 

422 "operationId": "read_users_users__get", 

423 "parameters": [ 

424 { 

425 "required": True, 

426 "schema": {"title": "Token", "type": "string"}, 

427 "name": "token", 

428 "in": "query", 

429 } 

430 ], 

431 "responses": { 

432 "200": { 

433 "description": "Successful Response", 

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

435 }, 

436 "422": { 

437 "description": "Validation Error", 

438 "content": { 

439 "application/json": { 

440 "schema": { 

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

442 } 

443 } 

444 }, 

445 }, 

446 }, 

447 } 

448 }, 

449 "/users/me": { 

450 "get": { 

451 "tags": ["users"], 

452 "summary": "Read User Me", 

453 "operationId": "read_user_me_users_me_get", 

454 "parameters": [ 

455 { 

456 "required": True, 

457 "schema": {"title": "Token", "type": "string"}, 

458 "name": "token", 

459 "in": "query", 

460 } 

461 ], 

462 "responses": { 

463 "200": { 

464 "description": "Successful Response", 

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

466 }, 

467 "422": { 

468 "description": "Validation Error", 

469 "content": { 

470 "application/json": { 

471 "schema": { 

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

473 } 

474 } 

475 }, 

476 }, 

477 }, 

478 } 

479 }, 

480 "/users/{username}": { 

481 "get": { 

482 "tags": ["users"], 

483 "summary": "Read User", 

484 "operationId": "read_user_users__username__get", 

485 "parameters": [ 

486 { 

487 "required": True, 

488 "schema": {"title": "Username", "type": "string"}, 

489 "name": "username", 

490 "in": "path", 

491 }, 

492 { 

493 "required": True, 

494 "schema": {"title": "Token", "type": "string"}, 

495 "name": "token", 

496 "in": "query", 

497 }, 

498 ], 

499 "responses": { 

500 "200": { 

501 "description": "Successful Response", 

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

503 }, 

504 "422": { 

505 "description": "Validation Error", 

506 "content": { 

507 "application/json": { 

508 "schema": { 

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

510 } 

511 } 

512 }, 

513 }, 

514 }, 

515 } 

516 }, 

517 "/items/": { 

518 "get": { 

519 "tags": ["items"], 

520 "summary": "Read Items", 

521 "operationId": "read_items_items__get", 

522 "parameters": [ 

523 { 

524 "required": True, 

525 "schema": {"title": "Token", "type": "string"}, 

526 "name": "token", 

527 "in": "query", 

528 }, 

529 { 

530 "required": True, 

531 "schema": {"title": "X-Token", "type": "string"}, 

532 "name": "x-token", 

533 "in": "header", 

534 }, 

535 ], 

536 "responses": { 

537 "200": { 

538 "description": "Successful Response", 

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

540 }, 

541 "404": {"description": "Not found"}, 

542 "422": { 

543 "description": "Validation Error", 

544 "content": { 

545 "application/json": { 

546 "schema": { 

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

548 } 

549 } 

550 }, 

551 }, 

552 }, 

553 } 

554 }, 

555 "/items/{item_id}": { 

556 "get": { 

557 "tags": ["items"], 

558 "summary": "Read Item", 

559 "operationId": "read_item_items__item_id__get", 

560 "parameters": [ 

561 { 

562 "required": True, 

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

564 "name": "item_id", 

565 "in": "path", 

566 }, 

567 { 

568 "required": True, 

569 "schema": {"title": "Token", "type": "string"}, 

570 "name": "token", 

571 "in": "query", 

572 }, 

573 { 

574 "required": True, 

575 "schema": {"title": "X-Token", "type": "string"}, 

576 "name": "x-token", 

577 "in": "header", 

578 }, 

579 ], 

580 "responses": { 

581 "200": { 

582 "description": "Successful Response", 

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

584 }, 

585 "404": {"description": "Not found"}, 

586 "422": { 

587 "description": "Validation Error", 

588 "content": { 

589 "application/json": { 

590 "schema": { 

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

592 } 

593 } 

594 }, 

595 }, 

596 }, 

597 }, 

598 "put": { 

599 "tags": ["items", "custom"], 

600 "summary": "Update Item", 

601 "operationId": "update_item_items__item_id__put", 

602 "parameters": [ 

603 { 

604 "required": True, 

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

606 "name": "item_id", 

607 "in": "path", 

608 }, 

609 { 

610 "required": True, 

611 "schema": {"title": "Token", "type": "string"}, 

612 "name": "token", 

613 "in": "query", 

614 }, 

615 { 

616 "required": True, 

617 "schema": {"title": "X-Token", "type": "string"}, 

618 "name": "x-token", 

619 "in": "header", 

620 }, 

621 ], 

622 "responses": { 

623 "200": { 

624 "description": "Successful Response", 

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

626 }, 

627 "404": {"description": "Not found"}, 

628 "403": {"description": "Operation forbidden"}, 

629 "422": { 

630 "description": "Validation Error", 

631 "content": { 

632 "application/json": { 

633 "schema": { 

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

635 } 

636 } 

637 }, 

638 }, 

639 }, 

640 }, 

641 }, 

642 "/admin/": { 

643 "post": { 

644 "tags": ["admin"], 

645 "summary": "Update Admin", 

646 "operationId": "update_admin_admin__post", 

647 "parameters": [ 

648 { 

649 "required": True, 

650 "schema": {"title": "Token", "type": "string"}, 

651 "name": "token", 

652 "in": "query", 

653 }, 

654 { 

655 "required": True, 

656 "schema": {"title": "X-Token", "type": "string"}, 

657 "name": "x-token", 

658 "in": "header", 

659 }, 

660 ], 

661 "responses": { 

662 "200": { 

663 "description": "Successful Response", 

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

665 }, 

666 "418": {"description": "I'm a teapot"}, 

667 "422": { 

668 "description": "Validation Error", 

669 "content": { 

670 "application/json": { 

671 "schema": { 

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

673 } 

674 } 

675 }, 

676 }, 

677 }, 

678 } 

679 }, 

680 "/": { 

681 "get": { 

682 "summary": "Root", 

683 "operationId": "root__get", 

684 "parameters": [ 

685 { 

686 "required": True, 

687 "schema": {"title": "Token", "type": "string"}, 

688 "name": "token", 

689 "in": "query", 

690 } 

691 ], 

692 "responses": { 

693 "200": { 

694 "description": "Successful Response", 

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

696 }, 

697 "422": { 

698 "description": "Validation Error", 

699 "content": { 

700 "application/json": { 

701 "schema": { 

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

703 } 

704 } 

705 }, 

706 }, 

707 }, 

708 } 

709 }, 

710 }, 

711 "components": { 

712 "schemas": { 

713 "HTTPValidationError": { 

714 "title": "HTTPValidationError", 

715 "type": "object", 

716 "properties": { 

717 "detail": { 

718 "title": "Detail", 

719 "type": "array", 

720 "items": {"$ref": "#/components/schemas/ValidationError"}, 

721 } 

722 }, 

723 }, 

724 "ValidationError": { 

725 "title": "ValidationError", 

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

727 "type": "object", 

728 "properties": { 

729 "loc": { 

730 "title": "Location", 

731 "type": "array", 

732 "items": { 

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

734 }, 

735 }, 

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

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

738 }, 

739 }, 

740 } 

741 }, 

742 }