Coverage for tests/test_tutorial/test_security/test_tutorial003_an_py310.py: 100%
57 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-08 03:53 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-08 03:53 +0000
1import pytest 1deabc
2from dirty_equals import IsDict 1deabc
3from fastapi.testclient import TestClient 1deabc
5from ...utils import needs_py310 1deabc
8@pytest.fixture(name="client") 1deabc
9def get_client(): 1deabc
10 from docs_src.security.tutorial003_an_py310 import app 1abc
12 client = TestClient(app) 1abc
13 return client 1abc
16@needs_py310 1deabc
17def test_login(client: TestClient): 1deabc
18 response = client.post("/token", data={"username": "johndoe", "password": "secret"}) 1abc
19 assert response.status_code == 200, response.text 1abc
20 assert response.json() == {"access_token": "johndoe", "token_type": "bearer"} 1abc
23@needs_py310 1deabc
24def test_login_incorrect_password(client: TestClient): 1deabc
25 response = client.post( 1abc
26 "/token", data={"username": "johndoe", "password": "incorrect"}
27 )
28 assert response.status_code == 400, response.text 1abc
29 assert response.json() == {"detail": "Incorrect username or password"} 1abc
32@needs_py310 1deabc
33def test_login_incorrect_username(client: TestClient): 1deabc
34 response = client.post("/token", data={"username": "foo", "password": "secret"}) 1abc
35 assert response.status_code == 400, response.text 1abc
36 assert response.json() == {"detail": "Incorrect username or password"} 1abc
39@needs_py310 1deabc
40def test_no_token(client: TestClient): 1deabc
41 response = client.get("/users/me") 1abc
42 assert response.status_code == 401, response.text 1abc
43 assert response.json() == {"detail": "Not authenticated"} 1abc
44 assert response.headers["WWW-Authenticate"] == "Bearer" 1abc
47@needs_py310 1deabc
48def test_token(client: TestClient): 1deabc
49 response = client.get("/users/me", headers={"Authorization": "Bearer johndoe"}) 1abc
50 assert response.status_code == 200, response.text 1abc
51 assert response.json() == { 1abc
52 "username": "johndoe",
53 "full_name": "John Doe",
54 "email": "johndoe@example.com",
55 "hashed_password": "fakehashedsecret",
56 "disabled": False,
57 }
60@needs_py310 1deabc
61def test_incorrect_token(client: TestClient): 1deabc
62 response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"}) 1abc
63 assert response.status_code == 401, response.text 1abc
64 assert response.json() == {"detail": "Invalid authentication credentials"} 1abc
65 assert response.headers["WWW-Authenticate"] == "Bearer" 1abc
68@needs_py310 1deabc
69def test_incorrect_token_type(client: TestClient): 1deabc
70 response = client.get( 1abc
71 "/users/me", headers={"Authorization": "Notexistent testtoken"}
72 )
73 assert response.status_code == 401, response.text 1abc
74 assert response.json() == {"detail": "Not authenticated"} 1abc
75 assert response.headers["WWW-Authenticate"] == "Bearer" 1abc
78@needs_py310 1deabc
79def test_inactive_user(client: TestClient): 1deabc
80 response = client.get("/users/me", headers={"Authorization": "Bearer alice"}) 1abc
81 assert response.status_code == 400, response.text 1abc
82 assert response.json() == {"detail": "Inactive user"} 1abc
85@needs_py310 1deabc
86def test_openapi_schema(client: TestClient): 1deabc
87 response = client.get("/openapi.json") 1abc
88 assert response.status_code == 200, response.text 1abc
89 assert response.json() == { 1abc
90 "openapi": "3.1.0",
91 "info": {"title": "FastAPI", "version": "0.1.0"},
92 "paths": {
93 "/token": {
94 "post": {
95 "responses": {
96 "200": {
97 "description": "Successful Response",
98 "content": {"application/json": {"schema": {}}},
99 },
100 "422": {
101 "description": "Validation Error",
102 "content": {
103 "application/json": {
104 "schema": {
105 "$ref": "#/components/schemas/HTTPValidationError"
106 }
107 }
108 },
109 },
110 },
111 "summary": "Login",
112 "operationId": "login_token_post",
113 "requestBody": {
114 "content": {
115 "application/x-www-form-urlencoded": {
116 "schema": {
117 "$ref": "#/components/schemas/Body_login_token_post"
118 }
119 }
120 },
121 "required": True,
122 },
123 }
124 },
125 "/users/me": {
126 "get": {
127 "responses": {
128 "200": {
129 "description": "Successful Response",
130 "content": {"application/json": {"schema": {}}},
131 }
132 },
133 "summary": "Read Users Me",
134 "operationId": "read_users_me_users_me_get",
135 "security": [{"OAuth2PasswordBearer": []}],
136 }
137 },
138 },
139 "components": {
140 "schemas": {
141 "Body_login_token_post": {
142 "title": "Body_login_token_post",
143 "required": ["username", "password"],
144 "type": "object",
145 "properties": {
146 "grant_type": IsDict(
147 {
148 "title": "Grant Type",
149 "anyOf": [
150 {"pattern": "password", "type": "string"},
151 {"type": "null"},
152 ],
153 }
154 )
155 | IsDict(
156 # TODO: remove when deprecating Pydantic v1
157 {
158 "title": "Grant Type",
159 "pattern": "password",
160 "type": "string",
161 }
162 ),
163 "username": {"title": "Username", "type": "string"},
164 "password": {"title": "Password", "type": "string"},
165 "scope": {"title": "Scope", "type": "string", "default": ""},
166 "client_id": IsDict(
167 {
168 "title": "Client Id",
169 "anyOf": [{"type": "string"}, {"type": "null"}],
170 }
171 )
172 | IsDict(
173 # TODO: remove when deprecating Pydantic v1
174 {"title": "Client Id", "type": "string"}
175 ),
176 "client_secret": IsDict(
177 {
178 "title": "Client Secret",
179 "anyOf": [{"type": "string"}, {"type": "null"}],
180 }
181 )
182 | IsDict(
183 # TODO: remove when deprecating Pydantic v1
184 {"title": "Client Secret", "type": "string"}
185 ),
186 },
187 },
188 "ValidationError": {
189 "title": "ValidationError",
190 "required": ["loc", "msg", "type"],
191 "type": "object",
192 "properties": {
193 "loc": {
194 "title": "Location",
195 "type": "array",
196 "items": {
197 "anyOf": [{"type": "string"}, {"type": "integer"}]
198 },
199 },
200 "msg": {"title": "Message", "type": "string"},
201 "type": {"title": "Error Type", "type": "string"},
202 },
203 },
204 "HTTPValidationError": {
205 "title": "HTTPValidationError",
206 "type": "object",
207 "properties": {
208 "detail": {
209 "title": "Detail",
210 "type": "array",
211 "items": {"$ref": "#/components/schemas/ValidationError"},
212 }
213 },
214 },
215 },
216 "securitySchemes": {
217 "OAuth2PasswordBearer": {
218 "type": "oauth2",
219 "flows": {"password": {"scopes": {}, "tokenUrl": "token"}},
220 }
221 },
222 },
223 }