Coverage for tests/test_tutorial/test_request_form_models/test_tutorial002.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_pydanticv2 1abcdef
9@pytest.fixture( 1abcdef
10 name="client",
11 params=[
12 "tutorial002",
13 "tutorial002_an",
14 pytest.param("tutorial002_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@needs_pydanticv2 1abcdef
25def test_post_body_form(client: TestClient): 1abcdef
26 response = client.post("/login/", data={"username": "Foo", "password": "secret"}) 1ghijkl
27 assert response.status_code == 200 1ghijkl
28 assert response.json() == {"username": "Foo", "password": "secret"} 1ghijkl
31@needs_pydanticv2 1abcdef
32def test_post_body_extra_form(client: TestClient): 1abcdef
33 response = client.post( 1mnopqr
34 "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"}
35 )
36 assert response.status_code == 422 1mnopqr
37 assert response.json() == { 1mnopqr
38 "detail": [
39 {
40 "type": "extra_forbidden",
41 "loc": ["body", "extra"],
42 "msg": "Extra inputs are not permitted",
43 "input": "extra",
44 }
45 ]
46 }
49@needs_pydanticv2 1abcdef
50def test_post_body_form_no_password(client: TestClient): 1abcdef
51 response = client.post("/login/", data={"username": "Foo"}) 1stuvwx
52 assert response.status_code == 422 1stuvwx
53 assert response.json() == { 1stuvwx
54 "detail": [
55 {
56 "type": "missing",
57 "loc": ["body", "password"],
58 "msg": "Field required",
59 "input": {"username": "Foo"},
60 }
61 ]
62 }
65@needs_pydanticv2 1abcdef
66def test_post_body_form_no_username(client: TestClient): 1abcdef
67 response = client.post("/login/", data={"password": "secret"}) 1yzABCD
68 assert response.status_code == 422 1yzABCD
69 assert response.json() == { 1yzABCD
70 "detail": [
71 {
72 "type": "missing",
73 "loc": ["body", "username"],
74 "msg": "Field required",
75 "input": {"password": "secret"},
76 }
77 ]
78 }
81@needs_pydanticv2 1abcdef
82def test_post_body_form_no_data(client: TestClient): 1abcdef
83 response = client.post("/login/") 1EFGHIJ
84 assert response.status_code == 422 1EFGHIJ
85 assert response.json() == { 1EFGHIJ
86 "detail": [
87 {
88 "type": "missing",
89 "loc": ["body", "username"],
90 "msg": "Field required",
91 "input": {},
92 },
93 {
94 "type": "missing",
95 "loc": ["body", "password"],
96 "msg": "Field required",
97 "input": {},
98 },
99 ]
100 }
103@needs_pydanticv2 1abcdef
104def test_post_body_json(client: TestClient): 1abcdef
105 response = client.post("/login/", json={"username": "Foo", "password": "secret"}) 1KLMNOP
106 assert response.status_code == 422, response.text 1KLMNOP
107 assert response.json() == { 1KLMNOP
108 "detail": [
109 {
110 "type": "missing",
111 "loc": ["body", "username"],
112 "msg": "Field required",
113 "input": {},
114 },
115 {
116 "type": "missing",
117 "loc": ["body", "password"],
118 "msg": "Field required",
119 "input": {},
120 },
121 ]
122 }
125@needs_pydanticv2 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 }