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