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