Coverage for tests/test_tutorial/test_request_form_models/test_tutorial002_pv1.py: 100%
44 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 fastapi.testclient import TestClient 1abcdef
6from ...utils import needs_py39, needs_pydanticv1 1abcdef
9@pytest.fixture( 1abcdef
10 name="client",
11 params=[
12 "tutorial002_pv1",
13 "tutorial002_pv1_an",
14 pytest.param("tutorial002_pv1_an_py39", marks=needs_py39),
15 ],
16)
17def get_client(request: pytest.FixtureRequest): 1abcdef
18 mod = importlib.import_module(f"docs_src.request_form_models.{request.param}") 1abcdef
20 client = TestClient(mod.app) 1abcdef
21 return client 1abcdef
24# TODO: remove when deprecating Pydantic v1
25@needs_pydanticv1 1abcdef
26def test_post_body_form(client: TestClient): 1abcdef
27 response = client.post("/login/", data={"username": "Foo", "password": "secret"}) 1ghijkl
28 assert response.status_code == 200 1ghijkl
29 assert response.json() == {"username": "Foo", "password": "secret"} 1ghijkl
32# TODO: remove when deprecating Pydantic v1
33@needs_pydanticv1 1abcdef
34def test_post_body_extra_form(client: TestClient): 1abcdef
35 response = client.post( 1mnopqr
36 "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"}
37 )
38 assert response.status_code == 422 1mnopqr
39 assert response.json() == { 1mnopqr
40 "detail": [
41 {
42 "type": "value_error.extra",
43 "loc": ["body", "extra"],
44 "msg": "extra fields not permitted",
45 }
46 ]
47 }
50# TODO: remove when deprecating Pydantic v1
51@needs_pydanticv1 1abcdef
52def test_post_body_form_no_password(client: TestClient): 1abcdef
53 response = client.post("/login/", data={"username": "Foo"}) 1stuvwx
54 assert response.status_code == 422 1stuvwx
55 assert response.json() == { 1stuvwx
56 "detail": [
57 {
58 "type": "value_error.missing",
59 "loc": ["body", "password"],
60 "msg": "field required",
61 }
62 ]
63 }
66# TODO: remove when deprecating Pydantic v1
67@needs_pydanticv1 1abcdef
68def test_post_body_form_no_username(client: TestClient): 1abcdef
69 response = client.post("/login/", data={"password": "secret"}) 1yzABCD
70 assert response.status_code == 422 1yzABCD
71 assert response.json() == { 1yzABCD
72 "detail": [
73 {
74 "type": "value_error.missing",
75 "loc": ["body", "username"],
76 "msg": "field required",
77 }
78 ]
79 }
82# TODO: remove when deprecating Pydantic v1
83@needs_pydanticv1 1abcdef
84def test_post_body_form_no_data(client: TestClient): 1abcdef
85 response = client.post("/login/") 1EFGHIJ
86 assert response.status_code == 422 1EFGHIJ
87 assert response.json() == { 1EFGHIJ
88 "detail": [
89 {
90 "type": "value_error.missing",
91 "loc": ["body", "username"],
92 "msg": "field required",
93 },
94 {
95 "type": "value_error.missing",
96 "loc": ["body", "password"],
97 "msg": "field required",
98 },
99 ]
100 }
103# TODO: remove when deprecating Pydantic v1
104@needs_pydanticv1 1abcdef
105def test_post_body_json(client: TestClient): 1abcdef
106 response = client.post("/login/", json={"username": "Foo", "password": "secret"}) 1KLMNOP
107 assert response.status_code == 422, response.text 1KLMNOP
108 assert response.json() == { 1KLMNOP
109 "detail": [
110 {
111 "type": "value_error.missing",
112 "loc": ["body", "username"],
113 "msg": "field required",
114 },
115 {
116 "type": "value_error.missing",
117 "loc": ["body", "password"],
118 "msg": "field required",
119 },
120 ]
121 }
124# TODO: remove when deprecating Pydantic v1
125@needs_pydanticv1 1abcdef
126def test_openapi_schema(client: TestClient): 1abcdef
127 response = client.get("/openapi.json") 1QRSTUV
128 assert response.status_code == 200, response.text 1QRSTUV
129 assert response.json() == { 1QRSTUV
130 "openapi": "3.1.0",
131 "info": {"title": "FastAPI", "version": "0.1.0"},
132 "paths": {
133 "/login/": {
134 "post": {
135 "responses": {
136 "200": {
137 "description": "Successful Response",
138 "content": {"application/json": {"schema": {}}},
139 },
140 "422": {
141 "description": "Validation Error",
142 "content": {
143 "application/json": {
144 "schema": {
145 "$ref": "#/components/schemas/HTTPValidationError"
146 }
147 }
148 },
149 },
150 },
151 "summary": "Login",
152 "operationId": "login_login__post",
153 "requestBody": {
154 "content": {
155 "application/x-www-form-urlencoded": {
156 "schema": {"$ref": "#/components/schemas/FormData"}
157 }
158 },
159 "required": True,
160 },
161 }
162 }
163 },
164 "components": {
165 "schemas": {
166 "FormData": {
167 "properties": {
168 "username": {"type": "string", "title": "Username"},
169 "password": {"type": "string", "title": "Password"},
170 },
171 "additionalProperties": False,
172 "type": "object",
173 "required": ["username", "password"],
174 "title": "FormData",
175 },
176 "ValidationError": {
177 "title": "ValidationError",
178 "required": ["loc", "msg", "type"],
179 "type": "object",
180 "properties": {
181 "loc": {
182 "title": "Location",
183 "type": "array",
184 "items": {
185 "anyOf": [{"type": "string"}, {"type": "integer"}]
186 },
187 },
188 "msg": {"title": "Message", "type": "string"},
189 "type": {"title": "Error Type", "type": "string"},
190 },
191 },
192 "HTTPValidationError": {
193 "title": "HTTPValidationError",
194 "type": "object",
195 "properties": {
196 "detail": {
197 "title": "Detail",
198 "type": "array",
199 "items": {"$ref": "#/components/schemas/ValidationError"},
200 }
201 },
202 },
203 }
204 },
205 }