Coverage for tests/test_tutorial/test_cookie_param_models/test_tutorial002.py: 100%
40 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-05 00:03 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-05 00:03 +0000
1import importlib 1abcdef
3import pytest 1abcdef
4from dirty_equals import IsDict 1abcdef
5from fastapi.testclient import TestClient 1abcdef
6from inline_snapshot import snapshot 1abcdef
8from tests.utils import ( 1abcdef
9 needs_py39,
10 needs_py310,
11 needs_pydanticv1,
12 needs_pydanticv2,
13 pydantic_snapshot,
14)
17@pytest.fixture( 1abcdef
18 name="client",
19 params=[
20 pytest.param("tutorial002", marks=needs_pydanticv2),
21 pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
22 pytest.param("tutorial002_an", marks=needs_pydanticv2),
23 pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]),
24 pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
25 pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]),
26 pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
27 pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]),
28 pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]),
29 pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
30 ],
31)
32def get_client(request: pytest.FixtureRequest): 1abcdef
33 mod = importlib.import_module(f"docs_src.cookie_param_models.{request.param}") 1abcdef
35 client = TestClient(mod.app) 1abcdef
36 return client 1abcdef
39def test_cookie_param_model(client: TestClient): 1abcdef
40 with client as c: 1ghijkl
41 c.cookies.set("session_id", "123") 1ghijkl
42 c.cookies.set("fatebook_tracker", "456") 1ghijkl
43 c.cookies.set("googall_tracker", "789") 1ghijkl
44 response = c.get("/items/") 1ghijkl
45 assert response.status_code == 200 1ghijkl
46 assert response.json() == { 1ghijkl
47 "session_id": "123",
48 "fatebook_tracker": "456",
49 "googall_tracker": "789",
50 }
53def test_cookie_param_model_defaults(client: TestClient): 1abcdef
54 with client as c: 1stuvwx
55 c.cookies.set("session_id", "123") 1stuvwx
56 response = c.get("/items/") 1stuvwx
57 assert response.status_code == 200 1stuvwx
58 assert response.json() == { 1stuvwx
59 "session_id": "123",
60 "fatebook_tracker": None,
61 "googall_tracker": None,
62 }
65def test_cookie_param_model_invalid(client: TestClient): 1abcdef
66 response = client.get("/items/") 1yzABCD
67 assert response.status_code == 422 1yzABCD
68 assert response.json() == pydantic_snapshot( 1yzABCD
69 v2=snapshot(
70 {
71 "detail": [
72 {
73 "type": "missing",
74 "loc": ["cookie", "session_id"],
75 "msg": "Field required",
76 "input": {},
77 }
78 ]
79 }
80 ),
81 v1=snapshot(
82 {
83 "detail": [
84 {
85 "type": "value_error.missing",
86 "loc": ["cookie", "session_id"],
87 "msg": "field required",
88 }
89 ]
90 }
91 ),
92 )
95def test_cookie_param_model_extra(client: TestClient): 1abcdef
96 with client as c: 1mnopqr
97 c.cookies.set("session_id", "123") 1mnopqr
98 c.cookies.set("extra", "track-me-here-too") 1mnopqr
99 response = c.get("/items/") 1mnopqr
100 assert response.status_code == 422 1mnopqr
101 assert response.json() == snapshot( 1mnopqr
102 IsDict(
103 {
104 "detail": [
105 {
106 "type": "extra_forbidden",
107 "loc": ["cookie", "extra"],
108 "msg": "Extra inputs are not permitted",
109 "input": "track-me-here-too",
110 }
111 ]
112 }
113 )
114 | IsDict(
115 # TODO: remove when deprecating Pydantic v1
116 {
117 "detail": [
118 {
119 "type": "value_error.extra",
120 "loc": ["cookie", "extra"],
121 "msg": "extra fields not permitted",
122 }
123 ]
124 }
125 )
126 )
129def test_openapi_schema(client: TestClient): 1abcdef
130 response = client.get("/openapi.json") 1EFGHIJ
131 assert response.status_code == 200, response.text 1EFGHIJ
132 assert response.json() == snapshot( 1EFGHIJ
133 {
134 "openapi": "3.1.0",
135 "info": {"title": "FastAPI", "version": "0.1.0"},
136 "paths": {
137 "/items/": {
138 "get": {
139 "summary": "Read Items",
140 "operationId": "read_items_items__get",
141 "parameters": [
142 {
143 "name": "session_id",
144 "in": "cookie",
145 "required": True,
146 "schema": {"type": "string", "title": "Session Id"},
147 },
148 {
149 "name": "fatebook_tracker",
150 "in": "cookie",
151 "required": False,
152 "schema": pydantic_snapshot(
153 v2=snapshot(
154 {
155 "anyOf": [
156 {"type": "string"},
157 {"type": "null"},
158 ],
159 "title": "Fatebook Tracker",
160 }
161 ),
162 v1=snapshot(
163 # TODO: remove when deprecating Pydantic v1
164 {
165 "type": "string",
166 "title": "Fatebook Tracker",
167 }
168 ),
169 ),
170 },
171 {
172 "name": "googall_tracker",
173 "in": "cookie",
174 "required": False,
175 "schema": IsDict(
176 {
177 "anyOf": [{"type": "string"}, {"type": "null"}],
178 "title": "Googall Tracker",
179 }
180 )
181 | IsDict(
182 # TODO: remove when deprecating Pydantic v1
183 {
184 "type": "string",
185 "title": "Googall Tracker",
186 }
187 ),
188 },
189 ],
190 "responses": {
191 "200": {
192 "description": "Successful Response",
193 "content": {"application/json": {"schema": {}}},
194 },
195 "422": {
196 "description": "Validation Error",
197 "content": {
198 "application/json": {
199 "schema": {
200 "$ref": "#/components/schemas/HTTPValidationError"
201 }
202 }
203 },
204 },
205 },
206 }
207 }
208 },
209 "components": {
210 "schemas": {
211 "HTTPValidationError": {
212 "properties": {
213 "detail": {
214 "items": {
215 "$ref": "#/components/schemas/ValidationError"
216 },
217 "type": "array",
218 "title": "Detail",
219 }
220 },
221 "type": "object",
222 "title": "HTTPValidationError",
223 },
224 "ValidationError": {
225 "properties": {
226 "loc": {
227 "items": {
228 "anyOf": [{"type": "string"}, {"type": "integer"}]
229 },
230 "type": "array",
231 "title": "Location",
232 },
233 "msg": {"type": "string", "title": "Message"},
234 "type": {"type": "string", "title": "Error Type"},
235 },
236 "type": "object",
237 "required": ["loc", "msg", "type"],
238 "title": "ValidationError",
239 },
240 }
241 },
242 }
243 )