Coverage for tests/test_tutorial/test_bigger_applications/test_main.py: 100%
110 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-13 13:38 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-13 13:38 +0000
1import importlib 1abcde
3import pytest 1abcde
4from dirty_equals import IsDict 1abcde
5from fastapi.testclient import TestClient 1abcde
7from ...utils import needs_py39 1abcde
10@pytest.fixture( 1abcde
11 name="client",
12 params=[
13 "app_an.main",
14 pytest.param("app_an_py39.main", marks=needs_py39),
15 "app.main",
16 ],
17)
18def get_client(request: pytest.FixtureRequest): 1abcde
19 mod = importlib.import_module(f"docs_src.bigger_applications.{request.param}") 1abcde
21 client = TestClient(mod.app) 1abcde
22 return client 1abcde
25def test_users_token_jessica(client: TestClient): 1abcde
26 response = client.get("/users?token=jessica") 1fghij
27 assert response.status_code == 200 1fghij
28 assert response.json() == [{"username": "Rick"}, {"username": "Morty"}] 1fghij
31def test_users_with_no_token(client: TestClient): 1abcde
32 response = client.get("/users") 1klmno
33 assert response.status_code == 422 1klmno
34 assert response.json() == IsDict( 1klmno
35 {
36 "detail": [
37 {
38 "type": "missing",
39 "loc": ["query", "token"],
40 "msg": "Field required",
41 "input": None,
42 }
43 ]
44 }
45 ) | IsDict(
46 # TODO: remove when deprecating Pydantic v1
47 {
48 "detail": [
49 {
50 "loc": ["query", "token"],
51 "msg": "field required",
52 "type": "value_error.missing",
53 },
54 ]
55 }
56 )
59def test_users_foo_token_jessica(client: TestClient): 1abcde
60 response = client.get("/users/foo?token=jessica") 1pqrst
61 assert response.status_code == 200 1pqrst
62 assert response.json() == {"username": "foo"} 1pqrst
65def test_users_foo_with_no_token(client: TestClient): 1abcde
66 response = client.get("/users/foo") 1uvwxy
67 assert response.status_code == 422 1uvwxy
68 assert response.json() == IsDict( 1uvwxy
69 {
70 "detail": [
71 {
72 "type": "missing",
73 "loc": ["query", "token"],
74 "msg": "Field required",
75 "input": None,
76 }
77 ]
78 }
79 ) | IsDict(
80 # TODO: remove when deprecating Pydantic v1
81 {
82 "detail": [
83 {
84 "loc": ["query", "token"],
85 "msg": "field required",
86 "type": "value_error.missing",
87 },
88 ]
89 }
90 )
93def test_users_me_token_jessica(client: TestClient): 1abcde
94 response = client.get("/users/me?token=jessica") 1zABCD
95 assert response.status_code == 200 1zABCD
96 assert response.json() == {"username": "fakecurrentuser"} 1zABCD
99def test_users_me_with_no_token(client: TestClient): 1abcde
100 response = client.get("/users/me") 1EFGHI
101 assert response.status_code == 422 1EFGHI
102 assert response.json() == IsDict( 1EFGHI
103 {
104 "detail": [
105 {
106 "type": "missing",
107 "loc": ["query", "token"],
108 "msg": "Field required",
109 "input": None,
110 }
111 ]
112 }
113 ) | IsDict(
114 # TODO: remove when deprecating Pydantic v1
115 {
116 "detail": [
117 {
118 "loc": ["query", "token"],
119 "msg": "field required",
120 "type": "value_error.missing",
121 },
122 ]
123 }
124 )
127def test_users_token_monica_with_no_jessica(client: TestClient): 1abcde
128 response = client.get("/users?token=monica") 1JKLMN
129 assert response.status_code == 400 1JKLMN
130 assert response.json() == {"detail": "No Jessica token provided"} 1JKLMN
133def test_items_token_jessica(client: TestClient): 1abcde
134 response = client.get( 1OPQRS
135 "/items?token=jessica", headers={"X-Token": "fake-super-secret-token"}
136 )
137 assert response.status_code == 200 1OPQRS
138 assert response.json() == { 1OPQRS
139 "plumbus": {"name": "Plumbus"},
140 "gun": {"name": "Portal Gun"},
141 }
144def test_items_with_no_token_jessica(client: TestClient): 1abcde
145 response = client.get("/items", headers={"X-Token": "fake-super-secret-token"}) 1TUVWX
146 assert response.status_code == 422 1TUVWX
147 assert response.json() == IsDict( 1TUVWX
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 )
172def test_items_plumbus_token_jessica(client: TestClient): 1abcde
173 response = client.get( 1YZ012
174 "/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"}
175 )
176 assert response.status_code == 200 1YZ012
177 assert response.json() == {"name": "Plumbus", "item_id": "plumbus"} 1YZ012
180def test_items_bar_token_jessica(client: TestClient): 1abcde
181 response = client.get( 134567
182 "/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"}
183 )
184 assert response.status_code == 404 134567
185 assert response.json() == {"detail": "Item not found"} 134567
188def test_items_plumbus_with_no_token(client: TestClient): 1abcde
189 response = client.get( 189!#$
190 "/items/plumbus", headers={"X-Token": "fake-super-secret-token"}
191 )
192 assert response.status_code == 422 189!#$
193 assert response.json() == IsDict( 189!#$
194 {
195 "detail": [
196 {
197 "type": "missing",
198 "loc": ["query", "token"],
199 "msg": "Field required",
200 "input": None,
201 }
202 ]
203 }
204 ) | IsDict(
205 # TODO: remove when deprecating Pydantic v1
206 {
207 "detail": [
208 {
209 "loc": ["query", "token"],
210 "msg": "field required",
211 "type": "value_error.missing",
212 },
213 ]
214 }
215 )
218def test_items_with_invalid_token(client: TestClient): 1abcde
219 response = client.get("/items?token=jessica", headers={"X-Token": "invalid"}) 1%'()*
220 assert response.status_code == 400 1%'()*
221 assert response.json() == {"detail": "X-Token header invalid"} 1%'()*
224def test_items_bar_with_invalid_token(client: TestClient): 1abcde
225 response = client.get("/items/bar?token=jessica", headers={"X-Token": "invalid"}) 1+,-./
226 assert response.status_code == 400 1+,-./
227 assert response.json() == {"detail": "X-Token header invalid"} 1+,-./
230def test_items_with_missing_x_token_header(client: TestClient): 1abcde
231 response = client.get("/items?token=jessica") 1:;=?@
232 assert response.status_code == 422 1:;=?@
233 assert response.json() == IsDict( 1:;=?@
234 {
235 "detail": [
236 {
237 "type": "missing",
238 "loc": ["header", "x-token"],
239 "msg": "Field required",
240 "input": None,
241 }
242 ]
243 }
244 ) | IsDict(
245 # TODO: remove when deprecating Pydantic v1
246 {
247 "detail": [
248 {
249 "loc": ["header", "x-token"],
250 "msg": "field required",
251 "type": "value_error.missing",
252 }
253 ]
254 }
255 )
258def test_items_plumbus_with_missing_x_token_header(client: TestClient): 1abcde
259 response = client.get("/items/plumbus?token=jessica") 1[]^_`
260 assert response.status_code == 422 1[]^_`
261 assert response.json() == IsDict( 1[]^_`
262 {
263 "detail": [
264 {
265 "type": "missing",
266 "loc": ["header", "x-token"],
267 "msg": "Field required",
268 "input": None,
269 }
270 ]
271 }
272 ) | IsDict(
273 # TODO: remove when deprecating Pydantic v1
274 {
275 "detail": [
276 {
277 "loc": ["header", "x-token"],
278 "msg": "field required",
279 "type": "value_error.missing",
280 }
281 ]
282 }
283 )
286def test_root_token_jessica(client: TestClient): 1abcde
287 response = client.get("/?token=jessica") 2{ | } ~ ab
288 assert response.status_code == 200 2{ | } ~ ab
289 assert response.json() == {"message": "Hello Bigger Applications!"} 2{ | } ~ ab
292def test_root_with_no_token(client: TestClient): 1abcde
293 response = client.get("/") 2bbcbdbebfb
294 assert response.status_code == 422 2bbcbdbebfb
295 assert response.json() == IsDict( 2bbcbdbebfb
296 {
297 "detail": [
298 {
299 "type": "missing",
300 "loc": ["query", "token"],
301 "msg": "Field required",
302 "input": None,
303 }
304 ]
305 }
306 ) | IsDict(
307 # TODO: remove when deprecating Pydantic v1
308 {
309 "detail": [
310 {
311 "loc": ["query", "token"],
312 "msg": "field required",
313 "type": "value_error.missing",
314 },
315 ]
316 }
317 )
320def test_put_no_header(client: TestClient): 1abcde
321 response = client.put("/items/foo") 2gbhbibjbkb
322 assert response.status_code == 422, response.text 2gbhbibjbkb
323 assert response.json() == IsDict( 2gbhbibjbkb
324 {
325 "detail": [
326 {
327 "type": "missing",
328 "loc": ["query", "token"],
329 "msg": "Field required",
330 "input": None,
331 },
332 {
333 "type": "missing",
334 "loc": ["header", "x-token"],
335 "msg": "Field required",
336 "input": None,
337 },
338 ]
339 }
340 ) | IsDict(
341 # TODO: remove when deprecating Pydantic v1
342 {
343 "detail": [
344 {
345 "loc": ["query", "token"],
346 "msg": "field required",
347 "type": "value_error.missing",
348 },
349 {
350 "loc": ["header", "x-token"],
351 "msg": "field required",
352 "type": "value_error.missing",
353 },
354 ]
355 }
356 )
359def test_put_invalid_header(client: TestClient): 1abcde
360 response = client.put("/items/foo", headers={"X-Token": "invalid"}) 2lbmbnbobpb
361 assert response.status_code == 400, response.text 2lbmbnbobpb
362 assert response.json() == {"detail": "X-Token header invalid"} 2lbmbnbobpb
365def test_put(client: TestClient): 1abcde
366 response = client.put( 2qbrbsbtbub
367 "/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"}
368 )
369 assert response.status_code == 200, response.text 2qbrbsbtbub
370 assert response.json() == {"item_id": "plumbus", "name": "The great Plumbus"} 2qbrbsbtbub
373def test_put_forbidden(client: TestClient): 1abcde
374 response = client.put( 2vbwbxbybzb
375 "/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"}
376 )
377 assert response.status_code == 403, response.text 2vbwbxbybzb
378 assert response.json() == {"detail": "You can only update the item: plumbus"} 2vbwbxbybzb
381def test_admin(client: TestClient): 1abcde
382 response = client.post( 2AbBbCbDbEb
383 "/admin/?token=jessica", headers={"X-Token": "fake-super-secret-token"}
384 )
385 assert response.status_code == 200, response.text 2AbBbCbDbEb
386 assert response.json() == {"message": "Admin getting schwifty"} 2AbBbCbDbEb
389def test_admin_invalid_header(client: TestClient): 1abcde
390 response = client.post("/admin/", headers={"X-Token": "invalid"}) 2FbGbHbIbJb
391 assert response.status_code == 400, response.text 2FbGbHbIbJb
392 assert response.json() == {"detail": "X-Token header invalid"} 2FbGbHbIbJb
395def test_openapi_schema(client: TestClient): 1abcde
396 response = client.get("/openapi.json") 2KbLbMbNbOb
397 assert response.status_code == 200, response.text 2KbLbMbNbOb
398 assert response.json() == { 2KbLbMbNbOb
399 "openapi": "3.1.0",
400 "info": {"title": "FastAPI", "version": "0.1.0"},
401 "paths": {
402 "/users/": {
403 "get": {
404 "tags": ["users"],
405 "summary": "Read Users",
406 "operationId": "read_users_users__get",
407 "parameters": [
408 {
409 "required": True,
410 "schema": {"title": "Token", "type": "string"},
411 "name": "token",
412 "in": "query",
413 }
414 ],
415 "responses": {
416 "200": {
417 "description": "Successful Response",
418 "content": {"application/json": {"schema": {}}},
419 },
420 "422": {
421 "description": "Validation Error",
422 "content": {
423 "application/json": {
424 "schema": {
425 "$ref": "#/components/schemas/HTTPValidationError"
426 }
427 }
428 },
429 },
430 },
431 }
432 },
433 "/users/me": {
434 "get": {
435 "tags": ["users"],
436 "summary": "Read User Me",
437 "operationId": "read_user_me_users_me_get",
438 "parameters": [
439 {
440 "required": True,
441 "schema": {"title": "Token", "type": "string"},
442 "name": "token",
443 "in": "query",
444 }
445 ],
446 "responses": {
447 "200": {
448 "description": "Successful Response",
449 "content": {"application/json": {"schema": {}}},
450 },
451 "422": {
452 "description": "Validation Error",
453 "content": {
454 "application/json": {
455 "schema": {
456 "$ref": "#/components/schemas/HTTPValidationError"
457 }
458 }
459 },
460 },
461 },
462 }
463 },
464 "/users/{username}": {
465 "get": {
466 "tags": ["users"],
467 "summary": "Read User",
468 "operationId": "read_user_users__username__get",
469 "parameters": [
470 {
471 "required": True,
472 "schema": {"title": "Username", "type": "string"},
473 "name": "username",
474 "in": "path",
475 },
476 {
477 "required": True,
478 "schema": {"title": "Token", "type": "string"},
479 "name": "token",
480 "in": "query",
481 },
482 ],
483 "responses": {
484 "200": {
485 "description": "Successful Response",
486 "content": {"application/json": {"schema": {}}},
487 },
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 "/items/": {
502 "get": {
503 "tags": ["items"],
504 "summary": "Read Items",
505 "operationId": "read_items_items__get",
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 "404": {"description": "Not found"},
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 "/items/{item_id}": {
540 "get": {
541 "tags": ["items"],
542 "summary": "Read Item",
543 "operationId": "read_item_items__item_id__get",
544 "parameters": [
545 {
546 "required": True,
547 "schema": {"title": "Item Id", "type": "string"},
548 "name": "item_id",
549 "in": "path",
550 },
551 {
552 "required": True,
553 "schema": {"title": "Token", "type": "string"},
554 "name": "token",
555 "in": "query",
556 },
557 {
558 "required": True,
559 "schema": {"title": "X-Token", "type": "string"},
560 "name": "x-token",
561 "in": "header",
562 },
563 ],
564 "responses": {
565 "200": {
566 "description": "Successful Response",
567 "content": {"application/json": {"schema": {}}},
568 },
569 "404": {"description": "Not found"},
570 "422": {
571 "description": "Validation Error",
572 "content": {
573 "application/json": {
574 "schema": {
575 "$ref": "#/components/schemas/HTTPValidationError"
576 }
577 }
578 },
579 },
580 },
581 },
582 "put": {
583 "tags": ["items", "custom"],
584 "summary": "Update Item",
585 "operationId": "update_item_items__item_id__put",
586 "parameters": [
587 {
588 "required": True,
589 "schema": {"title": "Item Id", "type": "string"},
590 "name": "item_id",
591 "in": "path",
592 },
593 {
594 "required": True,
595 "schema": {"title": "Token", "type": "string"},
596 "name": "token",
597 "in": "query",
598 },
599 {
600 "required": True,
601 "schema": {"title": "X-Token", "type": "string"},
602 "name": "x-token",
603 "in": "header",
604 },
605 ],
606 "responses": {
607 "200": {
608 "description": "Successful Response",
609 "content": {"application/json": {"schema": {}}},
610 },
611 "404": {"description": "Not found"},
612 "403": {"description": "Operation forbidden"},
613 "422": {
614 "description": "Validation Error",
615 "content": {
616 "application/json": {
617 "schema": {
618 "$ref": "#/components/schemas/HTTPValidationError"
619 }
620 }
621 },
622 },
623 },
624 },
625 },
626 "/admin/": {
627 "post": {
628 "tags": ["admin"],
629 "summary": "Update Admin",
630 "operationId": "update_admin_admin__post",
631 "parameters": [
632 {
633 "required": True,
634 "schema": {"title": "Token", "type": "string"},
635 "name": "token",
636 "in": "query",
637 },
638 {
639 "required": True,
640 "schema": {"title": "X-Token", "type": "string"},
641 "name": "x-token",
642 "in": "header",
643 },
644 ],
645 "responses": {
646 "200": {
647 "description": "Successful Response",
648 "content": {"application/json": {"schema": {}}},
649 },
650 "418": {"description": "I'm a teapot"},
651 "422": {
652 "description": "Validation Error",
653 "content": {
654 "application/json": {
655 "schema": {
656 "$ref": "#/components/schemas/HTTPValidationError"
657 }
658 }
659 },
660 },
661 },
662 }
663 },
664 "/": {
665 "get": {
666 "summary": "Root",
667 "operationId": "root__get",
668 "parameters": [
669 {
670 "required": True,
671 "schema": {"title": "Token", "type": "string"},
672 "name": "token",
673 "in": "query",
674 }
675 ],
676 "responses": {
677 "200": {
678 "description": "Successful Response",
679 "content": {"application/json": {"schema": {}}},
680 },
681 "422": {
682 "description": "Validation Error",
683 "content": {
684 "application/json": {
685 "schema": {
686 "$ref": "#/components/schemas/HTTPValidationError"
687 }
688 }
689 },
690 },
691 },
692 }
693 },
694 },
695 "components": {
696 "schemas": {
697 "HTTPValidationError": {
698 "title": "HTTPValidationError",
699 "type": "object",
700 "properties": {
701 "detail": {
702 "title": "Detail",
703 "type": "array",
704 "items": {"$ref": "#/components/schemas/ValidationError"},
705 }
706 },
707 },
708 "ValidationError": {
709 "title": "ValidationError",
710 "required": ["loc", "msg", "type"],
711 "type": "object",
712 "properties": {
713 "loc": {
714 "title": "Location",
715 "type": "array",
716 "items": {
717 "anyOf": [{"type": "string"}, {"type": "integer"}]
718 },
719 },
720 "msg": {"title": "Message", "type": "string"},
721 "type": {"title": "Error Type", "type": "string"},
722 },
723 },
724 }
725 },
726 }