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

109 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-12 18:15 +0000

1import importlib 1abdc

2 

3import pytest 1abdc

4from fastapi.testclient import TestClient 1abdc

5from inline_snapshot import snapshot 1abdc

6 

7 

8@pytest.fixture( 1abdc

9 name="client", 

10 params=[ 

11 "app_an_py310.main", 

12 ], 

13) 

14def get_client(request: pytest.FixtureRequest): 1abdc

15 mod = importlib.import_module(f"docs_src.bigger_applications.{request.param}") 1abc

16 

17 client = TestClient(mod.app) 1abc

18 return client 1abc

19 

20 

21def test_users_token_jessica(client: TestClient): 1abdc

22 response = client.get("/users?token=jessica") 1efg

23 assert response.status_code == 200 1efg

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

25 

26 

27def test_users_with_no_token(client: TestClient): 1abdc

28 response = client.get("/users") 1hij

29 assert response.status_code == 422 1hij

30 assert response.json() == { 1hij

31 "detail": [ 

32 { 

33 "type": "missing", 

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

35 "msg": "Field required", 

36 "input": None, 

37 } 

38 ] 

39 } 

40 

41 

42def test_users_foo_token_jessica(client: TestClient): 1abdc

43 response = client.get("/users/foo?token=jessica") 1klm

44 assert response.status_code == 200 1klm

45 assert response.json() == {"username": "foo"} 1klm

46 

47 

48def test_users_foo_with_no_token(client: TestClient): 1abdc

49 response = client.get("/users/foo") 1nop

50 assert response.status_code == 422 1nop

51 assert response.json() == { 1nop

52 "detail": [ 

53 { 

54 "type": "missing", 

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

56 "msg": "Field required", 

57 "input": None, 

58 } 

59 ] 

60 } 

61 

62 

63def test_users_me_token_jessica(client: TestClient): 1abdc

64 response = client.get("/users/me?token=jessica") 1qrs

65 assert response.status_code == 200 1qrs

66 assert response.json() == {"username": "fakecurrentuser"} 1qrs

67 

68 

69def test_users_me_with_no_token(client: TestClient): 1abdc

70 response = client.get("/users/me") 1tuv

71 assert response.status_code == 422 1tuv

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

73 "detail": [ 

74 { 

75 "type": "missing", 

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

77 "msg": "Field required", 

78 "input": None, 

79 } 

80 ] 

81 } 

82 

83 

84def test_users_token_monica_with_no_jessica(client: TestClient): 1abdc

85 response = client.get("/users?token=monica") 1wxy

86 assert response.status_code == 400 1wxy

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

88 

89 

90def test_items_token_jessica(client: TestClient): 1abdc

91 response = client.get( 1zAB

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

93 ) 

94 assert response.status_code == 200 1zAB

95 assert response.json() == { 1zAB

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

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

98 } 

99 

100 

101def test_items_with_no_token_jessica(client: TestClient): 1abdc

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

103 assert response.status_code == 422 1CDE

104 assert response.json() == { 1CDE

105 "detail": [ 

106 { 

107 "type": "missing", 

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

109 "msg": "Field required", 

110 "input": None, 

111 } 

112 ] 

113 } 

114 

115 

116def test_items_plumbus_token_jessica(client: TestClient): 1abdc

117 response = client.get( 1FGH

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

119 ) 

120 assert response.status_code == 200 1FGH

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

122 

123 

124def test_items_bar_token_jessica(client: TestClient): 1abdc

125 response = client.get( 1IJK

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

127 ) 

128 assert response.status_code == 404 1IJK

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

130 

131 

132def test_items_plumbus_with_no_token(client: TestClient): 1abdc

133 response = client.get( 1LMN

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

135 ) 

136 assert response.status_code == 422 1LMN

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

138 "detail": [ 

139 { 

140 "type": "missing", 

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

142 "msg": "Field required", 

143 "input": None, 

144 } 

145 ] 

146 } 

147 

148 

149def test_items_with_invalid_token(client: TestClient): 1abdc

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

151 assert response.status_code == 400 1OPQ

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

153 

154 

155def test_items_bar_with_invalid_token(client: TestClient): 1abdc

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

157 assert response.status_code == 400 1RST

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

159 

160 

161def test_items_with_missing_x_token_header(client: TestClient): 1abdc

162 response = client.get("/items?token=jessica") 1UVW

163 assert response.status_code == 422 1UVW

164 assert response.json() == { 1UVW

165 "detail": [ 

166 { 

167 "type": "missing", 

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

169 "msg": "Field required", 

170 "input": None, 

171 } 

172 ] 

173 } 

174 

175 

176def test_items_plumbus_with_missing_x_token_header(client: TestClient): 1abdc

177 response = client.get("/items/plumbus?token=jessica") 1XYZ

178 assert response.status_code == 422 1XYZ

179 assert response.json() == { 1XYZ

180 "detail": [ 

181 { 

182 "type": "missing", 

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

184 "msg": "Field required", 

185 "input": None, 

186 } 

187 ] 

188 } 

189 

190 

191def test_root_token_jessica(client: TestClient): 1abdc

192 response = client.get("/?token=jessica") 1012

193 assert response.status_code == 200 1012

194 assert response.json() == {"message": "Hello Bigger Applications!"} 1012

195 

196 

197def test_root_with_no_token(client: TestClient): 1abdc

198 response = client.get("/") 1345

199 assert response.status_code == 422 1345

200 assert response.json() == { 1345

201 "detail": [ 

202 { 

203 "type": "missing", 

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

205 "msg": "Field required", 

206 "input": None, 

207 } 

208 ] 

209 } 

210 

211 

212def test_put_no_header(client: TestClient): 1abdc

213 response = client.put("/items/foo") 1678

214 assert response.status_code == 422, response.text 1678

215 assert response.json() == { 1678

216 "detail": [ 

217 { 

218 "type": "missing", 

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

220 "msg": "Field required", 

221 "input": None, 

222 }, 

223 { 

224 "type": "missing", 

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

226 "msg": "Field required", 

227 "input": None, 

228 }, 

229 ] 

230 } 

231 

232 

233def test_put_invalid_header(client: TestClient): 1abdc

234 response = client.put("/items/foo", headers={"X-Token": "invalid"}) 19!#

235 assert response.status_code == 400, response.text 19!#

236 assert response.json() == {"detail": "X-Token header invalid"} 19!#

237 

238 

239def test_put(client: TestClient): 1abdc

240 response = client.put( 1$%'

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

242 ) 

243 assert response.status_code == 200, response.text 1$%'

244 assert response.json() == {"item_id": "plumbus", "name": "The great Plumbus"} 1$%'

245 

246 

247def test_put_forbidden(client: TestClient): 1abdc

248 response = client.put( 1()*

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

250 ) 

251 assert response.status_code == 403, response.text 1()*

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

253 

254 

255def test_admin(client: TestClient): 1abdc

256 response = client.post( 1+,-

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

258 ) 

259 assert response.status_code == 200, response.text 1+,-

260 assert response.json() == {"message": "Admin getting schwifty"} 1+,-

261 

262 

263def test_admin_invalid_header(client: TestClient): 1abdc

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

265 assert response.status_code == 400, response.text 1./:

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

267 

268 

269def test_openapi_schema(client: TestClient): 1abdc

270 response = client.get("/openapi.json") 1;=?

271 assert response.status_code == 200, response.text 1;=?

272 assert response.json() == snapshot( 1;=?

273 { 

274 "openapi": "3.1.0", 

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

276 "paths": { 

277 "/users/": { 

278 "get": { 

279 "tags": ["users"], 

280 "summary": "Read Users", 

281 "operationId": "read_users_users__get", 

282 "parameters": [ 

283 { 

284 "required": True, 

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

286 "name": "token", 

287 "in": "query", 

288 } 

289 ], 

290 "responses": { 

291 "200": { 

292 "description": "Successful Response", 

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

294 }, 

295 "422": { 

296 "description": "Validation Error", 

297 "content": { 

298 "application/json": { 

299 "schema": { 

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

301 } 

302 } 

303 }, 

304 }, 

305 }, 

306 } 

307 }, 

308 "/users/me": { 

309 "get": { 

310 "tags": ["users"], 

311 "summary": "Read User Me", 

312 "operationId": "read_user_me_users_me_get", 

313 "parameters": [ 

314 { 

315 "required": True, 

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

317 "name": "token", 

318 "in": "query", 

319 } 

320 ], 

321 "responses": { 

322 "200": { 

323 "description": "Successful Response", 

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

325 }, 

326 "422": { 

327 "description": "Validation Error", 

328 "content": { 

329 "application/json": { 

330 "schema": { 

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

332 } 

333 } 

334 }, 

335 }, 

336 }, 

337 } 

338 }, 

339 "/users/{username}": { 

340 "get": { 

341 "tags": ["users"], 

342 "summary": "Read User", 

343 "operationId": "read_user_users__username__get", 

344 "parameters": [ 

345 { 

346 "required": True, 

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

348 "name": "username", 

349 "in": "path", 

350 }, 

351 { 

352 "required": True, 

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

354 "name": "token", 

355 "in": "query", 

356 }, 

357 ], 

358 "responses": { 

359 "200": { 

360 "description": "Successful Response", 

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

362 }, 

363 "422": { 

364 "description": "Validation Error", 

365 "content": { 

366 "application/json": { 

367 "schema": { 

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

369 } 

370 } 

371 }, 

372 }, 

373 }, 

374 } 

375 }, 

376 "/items/": { 

377 "get": { 

378 "tags": ["items"], 

379 "summary": "Read Items", 

380 "operationId": "read_items_items__get", 

381 "parameters": [ 

382 { 

383 "required": True, 

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

385 "name": "token", 

386 "in": "query", 

387 }, 

388 { 

389 "required": True, 

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

391 "name": "x-token", 

392 "in": "header", 

393 }, 

394 ], 

395 "responses": { 

396 "200": { 

397 "description": "Successful Response", 

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

399 }, 

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

401 "422": { 

402 "description": "Validation Error", 

403 "content": { 

404 "application/json": { 

405 "schema": { 

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

407 } 

408 } 

409 }, 

410 }, 

411 }, 

412 } 

413 }, 

414 "/items/{item_id}": { 

415 "get": { 

416 "tags": ["items"], 

417 "summary": "Read Item", 

418 "operationId": "read_item_items__item_id__get", 

419 "parameters": [ 

420 { 

421 "required": True, 

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

423 "name": "item_id", 

424 "in": "path", 

425 }, 

426 { 

427 "required": True, 

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

429 "name": "token", 

430 "in": "query", 

431 }, 

432 { 

433 "required": True, 

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

435 "name": "x-token", 

436 "in": "header", 

437 }, 

438 ], 

439 "responses": { 

440 "200": { 

441 "description": "Successful Response", 

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

443 }, 

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

445 "422": { 

446 "description": "Validation Error", 

447 "content": { 

448 "application/json": { 

449 "schema": { 

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

451 } 

452 } 

453 }, 

454 }, 

455 }, 

456 }, 

457 "put": { 

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

459 "summary": "Update Item", 

460 "operationId": "update_item_items__item_id__put", 

461 "parameters": [ 

462 { 

463 "required": True, 

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

465 "name": "item_id", 

466 "in": "path", 

467 }, 

468 { 

469 "required": True, 

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

471 "name": "token", 

472 "in": "query", 

473 }, 

474 { 

475 "required": True, 

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

477 "name": "x-token", 

478 "in": "header", 

479 }, 

480 ], 

481 "responses": { 

482 "200": { 

483 "description": "Successful Response", 

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

485 }, 

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

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

488 "422": { 

489 "description": "Validation Error", 

490 "content": { 

491 "application/json": { 

492 "schema": { 

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

494 } 

495 } 

496 }, 

497 }, 

498 }, 

499 }, 

500 }, 

501 "/admin/": { 

502 "post": { 

503 "tags": ["admin"], 

504 "summary": "Update Admin", 

505 "operationId": "update_admin_admin__post", 

506 "parameters": [ 

507 { 

508 "required": True, 

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

510 "name": "token", 

511 "in": "query", 

512 }, 

513 { 

514 "required": True, 

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

516 "name": "x-token", 

517 "in": "header", 

518 }, 

519 ], 

520 "responses": { 

521 "200": { 

522 "description": "Successful Response", 

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

524 }, 

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

526 "422": { 

527 "description": "Validation Error", 

528 "content": { 

529 "application/json": { 

530 "schema": { 

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

532 } 

533 } 

534 }, 

535 }, 

536 }, 

537 } 

538 }, 

539 "/": { 

540 "get": { 

541 "summary": "Root", 

542 "operationId": "root__get", 

543 "parameters": [ 

544 { 

545 "required": True, 

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

547 "name": "token", 

548 "in": "query", 

549 } 

550 ], 

551 "responses": { 

552 "200": { 

553 "description": "Successful Response", 

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

555 }, 

556 "422": { 

557 "description": "Validation Error", 

558 "content": { 

559 "application/json": { 

560 "schema": { 

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

562 } 

563 } 

564 }, 

565 }, 

566 }, 

567 } 

568 }, 

569 }, 

570 "components": { 

571 "schemas": { 

572 "HTTPValidationError": { 

573 "title": "HTTPValidationError", 

574 "type": "object", 

575 "properties": { 

576 "detail": { 

577 "title": "Detail", 

578 "type": "array", 

579 "items": { 

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

581 }, 

582 } 

583 }, 

584 }, 

585 "ValidationError": { 

586 "title": "ValidationError", 

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

588 "type": "object", 

589 "properties": { 

590 "loc": { 

591 "title": "Location", 

592 "type": "array", 

593 "items": { 

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

595 }, 

596 }, 

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

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

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

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

601 }, 

602 }, 

603 } 

604 }, 

605 } 

606 )