+import importlib
+
+import pytest
from fastapi.testclient import TestClient
-from docs_src.security.tutorial001 import app
+from ...utils import needs_py39
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ "tutorial001",
+ "tutorial001_an",
+ pytest.param("tutorial001_an_py39", marks=needs_py39),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.security.{request.param}")
-client = TestClient(app)
+ client = TestClient(mod.app)
+ return client
-def test_no_token():
+def test_no_token(client: TestClient):
response = client.get("/items")
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
assert response.headers["WWW-Authenticate"] == "Bearer"
-def test_token():
+def test_token(client: TestClient):
response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"token": "testtoken"}
-def test_incorrect_token():
+def test_incorrect_token(client: TestClient):
response = client.get("/items", headers={"Authorization": "Notexistent testtoken"})
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
assert response.headers["WWW-Authenticate"] == "Bearer"
-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
+++ /dev/null
-from fastapi.testclient import TestClient
-
-from docs_src.security.tutorial001_an import app
-
-client = TestClient(app)
-
-
-def test_no_token():
- response = client.get("/items")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-def test_token():
- response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
- assert response.status_code == 200, response.text
- assert response.json() == {"token": "testtoken"}
-
-
-def test_incorrect_token():
- response = client.get("/items", headers={"Authorization": "Notexistent testtoken"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-def test_openapi_schema():
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Items",
- "operationId": "read_items_items__get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- }
- },
- "components": {
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {"password": {"scopes": {}, "tokenUrl": "token"}},
- }
- }
- },
- }
+++ /dev/null
-import pytest
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="client")
-def get_client():
- from docs_src.security.tutorial001_an_py39 import app
-
- client = TestClient(app)
- return client
-
-
-@needs_py39
-def test_no_token(client: TestClient):
- response = client.get("/items")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_token(client: TestClient):
- response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
- assert response.status_code == 200, response.text
- assert response.json() == {"token": "testtoken"}
-
-
-@needs_py39
-def test_incorrect_token(client: TestClient):
- response = client.get("/items", headers={"Authorization": "Notexistent testtoken"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Items",
- "operationId": "read_items_items__get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- }
- },
- "components": {
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {"password": {"scopes": {}, "tokenUrl": "token"}},
- }
- }
- },
- }
+import importlib
+
+import pytest
from dirty_equals import IsDict
from fastapi.testclient import TestClient
-from docs_src.security.tutorial003 import app
+from ...utils import needs_py39, needs_py310
+
+
+@pytest.fixture(
+ name="client",
+ params=[
+ "tutorial003",
+ pytest.param("tutorial003_py310", marks=needs_py310),
+ "tutorial003_an",
+ pytest.param("tutorial003_an_py39", marks=needs_py39),
+ pytest.param("tutorial003_an_py310", marks=needs_py310),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.security.{request.param}")
-client = TestClient(app)
+ client = TestClient(mod.app)
+ return client
-def test_login():
+def test_login(client: TestClient):
response = client.post("/token", data={"username": "johndoe", "password": "secret"})
assert response.status_code == 200, response.text
assert response.json() == {"access_token": "johndoe", "token_type": "bearer"}
-def test_login_incorrect_password():
+def test_login_incorrect_password(client: TestClient):
response = client.post(
"/token", data={"username": "johndoe", "password": "incorrect"}
)
assert response.json() == {"detail": "Incorrect username or password"}
-def test_login_incorrect_username():
+def test_login_incorrect_username(client: TestClient):
response = client.post("/token", data={"username": "foo", "password": "secret"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "Incorrect username or password"}
-def test_no_token():
+def test_no_token(client: TestClient):
response = client.get("/users/me")
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
assert response.headers["WWW-Authenticate"] == "Bearer"
-def test_token():
+def test_token(client: TestClient):
response = client.get("/users/me", headers={"Authorization": "Bearer johndoe"})
assert response.status_code == 200, response.text
assert response.json() == {
}
-def test_incorrect_token():
+def test_incorrect_token(client: TestClient):
response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}
assert response.headers["WWW-Authenticate"] == "Bearer"
-def test_incorrect_token_type():
+def test_incorrect_token_type(client: TestClient):
response = client.get(
"/users/me", headers={"Authorization": "Notexistent testtoken"}
)
assert response.headers["WWW-Authenticate"] == "Bearer"
-def test_inactive_user():
+def test_inactive_user(client: TestClient):
response = client.get("/users/me", headers={"Authorization": "Bearer alice"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "Inactive user"}
-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
+++ /dev/null
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from docs_src.security.tutorial003_an import app
-
-client = TestClient(app)
-
-
-def test_login():
- response = client.post("/token", data={"username": "johndoe", "password": "secret"})
- assert response.status_code == 200, response.text
- assert response.json() == {"access_token": "johndoe", "token_type": "bearer"}
-
-
-def test_login_incorrect_password():
- response = client.post(
- "/token", data={"username": "johndoe", "password": "incorrect"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-def test_login_incorrect_username():
- response = client.post("/token", data={"username": "foo", "password": "secret"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-def test_no_token():
- response = client.get("/users/me")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-def test_token():
- response = client.get("/users/me", headers={"Authorization": "Bearer johndoe"})
- assert response.status_code == 200, response.text
- assert response.json() == {
- "username": "johndoe",
- "full_name": "John Doe",
- "email": "johndoe@example.com",
- "hashed_password": "fakehashedsecret",
- "disabled": False,
- }
-
-
-def test_incorrect_token():
- response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Invalid authentication credentials"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-def test_incorrect_token_type():
- response = client.get(
- "/users/me", headers={"Authorization": "Notexistent testtoken"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-def test_inactive_user():
- response = client.get("/users/me", headers={"Authorization": "Bearer alice"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Inactive user"}
-
-
-def test_openapi_schema():
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/token": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Login",
- "operationId": "login_token_post",
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "$ref": "#/components/schemas/Body_login_token_post"
- }
- }
- },
- "required": True,
- },
- }
- },
- "/users/me": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Users Me",
- "operationId": "read_users_me_users_me_get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- },
- },
- "components": {
- "schemas": {
- "Body_login_token_post": {
- "title": "Body_login_token_post",
- "required": ["username", "password"],
- "type": "object",
- "properties": {
- "grant_type": IsDict(
- {
- "title": "Grant Type",
- "anyOf": [
- {"pattern": "password", "type": "string"},
- {"type": "null"},
- ],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Grant Type",
- "pattern": "password",
- "type": "string",
- }
- ),
- "username": {"title": "Username", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- "scope": {"title": "Scope", "type": "string", "default": ""},
- "client_id": IsDict(
- {
- "title": "Client Id",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Id", "type": "string"}
- ),
- "client_secret": IsDict(
- {
- "title": "Client Secret",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Secret", "type": "string"}
- ),
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- },
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {"password": {"scopes": {}, "tokenUrl": "token"}},
- }
- },
- },
- }
+++ /dev/null
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-@pytest.fixture(name="client")
-def get_client():
- from docs_src.security.tutorial003_an_py310 import app
-
- client = TestClient(app)
- return client
-
-
-@needs_py310
-def test_login(client: TestClient):
- response = client.post("/token", data={"username": "johndoe", "password": "secret"})
- assert response.status_code == 200, response.text
- assert response.json() == {"access_token": "johndoe", "token_type": "bearer"}
-
-
-@needs_py310
-def test_login_incorrect_password(client: TestClient):
- response = client.post(
- "/token", data={"username": "johndoe", "password": "incorrect"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py310
-def test_login_incorrect_username(client: TestClient):
- response = client.post("/token", data={"username": "foo", "password": "secret"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py310
-def test_no_token(client: TestClient):
- response = client.get("/users/me")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer johndoe"})
- assert response.status_code == 200, response.text
- assert response.json() == {
- "username": "johndoe",
- "full_name": "John Doe",
- "email": "johndoe@example.com",
- "hashed_password": "fakehashedsecret",
- "disabled": False,
- }
-
-
-@needs_py310
-def test_incorrect_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Invalid authentication credentials"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_incorrect_token_type(client: TestClient):
- response = client.get(
- "/users/me", headers={"Authorization": "Notexistent testtoken"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_inactive_user(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer alice"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Inactive user"}
-
-
-@needs_py310
-def test_openapi_schema(client: TestClient):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/token": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Login",
- "operationId": "login_token_post",
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "$ref": "#/components/schemas/Body_login_token_post"
- }
- }
- },
- "required": True,
- },
- }
- },
- "/users/me": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Users Me",
- "operationId": "read_users_me_users_me_get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- },
- },
- "components": {
- "schemas": {
- "Body_login_token_post": {
- "title": "Body_login_token_post",
- "required": ["username", "password"],
- "type": "object",
- "properties": {
- "grant_type": IsDict(
- {
- "title": "Grant Type",
- "anyOf": [
- {"pattern": "password", "type": "string"},
- {"type": "null"},
- ],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Grant Type",
- "pattern": "password",
- "type": "string",
- }
- ),
- "username": {"title": "Username", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- "scope": {"title": "Scope", "type": "string", "default": ""},
- "client_id": IsDict(
- {
- "title": "Client Id",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Id", "type": "string"}
- ),
- "client_secret": IsDict(
- {
- "title": "Client Secret",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Secret", "type": "string"}
- ),
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- },
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {"password": {"scopes": {}, "tokenUrl": "token"}},
- }
- },
- },
- }
+++ /dev/null
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="client")
-def get_client():
- from docs_src.security.tutorial003_an_py39 import app
-
- client = TestClient(app)
- return client
-
-
-@needs_py39
-def test_login(client: TestClient):
- response = client.post("/token", data={"username": "johndoe", "password": "secret"})
- assert response.status_code == 200, response.text
- assert response.json() == {"access_token": "johndoe", "token_type": "bearer"}
-
-
-@needs_py39
-def test_login_incorrect_password(client: TestClient):
- response = client.post(
- "/token", data={"username": "johndoe", "password": "incorrect"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py39
-def test_login_incorrect_username(client: TestClient):
- response = client.post("/token", data={"username": "foo", "password": "secret"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py39
-def test_no_token(client: TestClient):
- response = client.get("/users/me")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer johndoe"})
- assert response.status_code == 200, response.text
- assert response.json() == {
- "username": "johndoe",
- "full_name": "John Doe",
- "email": "johndoe@example.com",
- "hashed_password": "fakehashedsecret",
- "disabled": False,
- }
-
-
-@needs_py39
-def test_incorrect_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Invalid authentication credentials"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_incorrect_token_type(client: TestClient):
- response = client.get(
- "/users/me", headers={"Authorization": "Notexistent testtoken"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_inactive_user(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer alice"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Inactive user"}
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/token": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Login",
- "operationId": "login_token_post",
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "$ref": "#/components/schemas/Body_login_token_post"
- }
- }
- },
- "required": True,
- },
- }
- },
- "/users/me": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Users Me",
- "operationId": "read_users_me_users_me_get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- },
- },
- "components": {
- "schemas": {
- "Body_login_token_post": {
- "title": "Body_login_token_post",
- "required": ["username", "password"],
- "type": "object",
- "properties": {
- "grant_type": IsDict(
- {
- "title": "Grant Type",
- "anyOf": [
- {"pattern": "password", "type": "string"},
- {"type": "null"},
- ],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Grant Type",
- "pattern": "password",
- "type": "string",
- }
- ),
- "username": {"title": "Username", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- "scope": {"title": "Scope", "type": "string", "default": ""},
- "client_id": IsDict(
- {
- "title": "Client Id",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Id", "type": "string"}
- ),
- "client_secret": IsDict(
- {
- "title": "Client Secret",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Secret", "type": "string"}
- ),
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- },
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {"password": {"scopes": {}, "tokenUrl": "token"}},
- }
- },
- },
- }
+++ /dev/null
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-@pytest.fixture(name="client")
-def get_client():
- from docs_src.security.tutorial003_py310 import app
-
- client = TestClient(app)
- return client
-
-
-@needs_py310
-def test_login(client: TestClient):
- response = client.post("/token", data={"username": "johndoe", "password": "secret"})
- assert response.status_code == 200, response.text
- assert response.json() == {"access_token": "johndoe", "token_type": "bearer"}
-
-
-@needs_py310
-def test_login_incorrect_password(client: TestClient):
- response = client.post(
- "/token", data={"username": "johndoe", "password": "incorrect"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py310
-def test_login_incorrect_username(client: TestClient):
- response = client.post("/token", data={"username": "foo", "password": "secret"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py310
-def test_no_token(client: TestClient):
- response = client.get("/users/me")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer johndoe"})
- assert response.status_code == 200, response.text
- assert response.json() == {
- "username": "johndoe",
- "full_name": "John Doe",
- "email": "johndoe@example.com",
- "hashed_password": "fakehashedsecret",
- "disabled": False,
- }
-
-
-@needs_py310
-def test_incorrect_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Invalid authentication credentials"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_incorrect_token_type(client: TestClient):
- response = client.get(
- "/users/me", headers={"Authorization": "Notexistent testtoken"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_inactive_user(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer alice"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Inactive user"}
-
-
-@needs_py310
-def test_openapi_schema(client: TestClient):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/token": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Login",
- "operationId": "login_token_post",
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "$ref": "#/components/schemas/Body_login_token_post"
- }
- }
- },
- "required": True,
- },
- }
- },
- "/users/me": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Users Me",
- "operationId": "read_users_me_users_me_get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- },
- },
- "components": {
- "schemas": {
- "Body_login_token_post": {
- "title": "Body_login_token_post",
- "required": ["username", "password"],
- "type": "object",
- "properties": {
- "grant_type": IsDict(
- {
- "title": "Grant Type",
- "anyOf": [
- {"pattern": "password", "type": "string"},
- {"type": "null"},
- ],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Grant Type",
- "pattern": "password",
- "type": "string",
- }
- ),
- "username": {"title": "Username", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- "scope": {"title": "Scope", "type": "string", "default": ""},
- "client_id": IsDict(
- {
- "title": "Client Id",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Id", "type": "string"}
- ),
- "client_secret": IsDict(
- {
- "title": "Client Secret",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Secret", "type": "string"}
- ),
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- },
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {"password": {"scopes": {}, "tokenUrl": "token"}},
- }
- },
- },
- }
+import importlib
+from types import ModuleType
+
+import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
-from docs_src.security.tutorial005 import (
- app,
- create_access_token,
- fake_users_db,
- get_password_hash,
- verify_password,
+from ...utils import needs_py39, needs_py310
+
+
+@pytest.fixture(
+ name="mod",
+ params=[
+ "tutorial005",
+ pytest.param("tutorial005_py310", marks=needs_py310),
+ "tutorial005_an",
+ pytest.param("tutorial005_py39", marks=needs_py39),
+ pytest.param("tutorial005_an_py39", marks=needs_py39),
+ pytest.param("tutorial005_an_py310", marks=needs_py310),
+ ],
)
+def get_mod(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.security.{request.param}")
-client = TestClient(app)
+ return mod
-def get_access_token(username="johndoe", password="secret", scope=None):
+def get_access_token(
+ *, username="johndoe", password="secret", scope=None, client: TestClient
+):
data = {"username": username, "password": password}
if scope:
data["scope"] = scope
return access_token
-def test_login():
+def test_login(mod: ModuleType):
+ client = TestClient(mod.app)
response = client.post("/token", data={"username": "johndoe", "password": "secret"})
assert response.status_code == 200, response.text
content = response.json()
assert content["token_type"] == "bearer"
-def test_login_incorrect_password():
+def test_login_incorrect_password(mod: ModuleType):
+ client = TestClient(mod.app)
response = client.post(
"/token", data={"username": "johndoe", "password": "incorrect"}
)
assert response.json() == {"detail": "Incorrect username or password"}
-def test_login_incorrect_username():
+def test_login_incorrect_username(mod: ModuleType):
+ client = TestClient(mod.app)
response = client.post("/token", data={"username": "foo", "password": "secret"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "Incorrect username or password"}
-def test_no_token():
+def test_no_token(mod: ModuleType):
+ client = TestClient(mod.app)
response = client.get("/users/me")
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
assert response.headers["WWW-Authenticate"] == "Bearer"
-def test_token():
- access_token = get_access_token(scope="me")
+def test_token(mod: ModuleType):
+ client = TestClient(mod.app)
+ access_token = get_access_token(scope="me", client=client)
response = client.get(
"/users/me", headers={"Authorization": f"Bearer {access_token}"}
)
}
-def test_incorrect_token():
+def test_incorrect_token(mod: ModuleType):
+ client = TestClient(mod.app)
response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Could not validate credentials"}
assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-def test_incorrect_token_type():
+def test_incorrect_token_type(mod: ModuleType):
+ client = TestClient(mod.app)
response = client.get(
"/users/me", headers={"Authorization": "Notexistent testtoken"}
)
assert response.headers["WWW-Authenticate"] == "Bearer"
-def test_verify_password():
- assert verify_password("secret", fake_users_db["johndoe"]["hashed_password"])
+def test_verify_password(mod: ModuleType):
+ assert mod.verify_password(
+ "secret", mod.fake_users_db["johndoe"]["hashed_password"]
+ )
-def test_get_password_hash():
- assert get_password_hash("secretalice")
+def test_get_password_hash(mod: ModuleType):
+ assert mod.get_password_hash("secretalice")
-def test_create_access_token():
- access_token = create_access_token(data={"data": "foo"})
+def test_create_access_token(mod: ModuleType):
+ access_token = mod.create_access_token(data={"data": "foo"})
assert access_token
-def test_token_no_sub():
+def test_token_no_sub(mod: ModuleType):
+ client = TestClient(mod.app)
+
response = client.get(
"/users/me",
headers={
assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-def test_token_no_username():
+def test_token_no_username(mod: ModuleType):
+ client = TestClient(mod.app)
+
response = client.get(
"/users/me",
headers={
assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-def test_token_no_scope():
- access_token = get_access_token()
+def test_token_no_scope(mod: ModuleType):
+ client = TestClient(mod.app)
+
+ access_token = get_access_token(client=client)
response = client.get(
"/users/me", headers={"Authorization": f"Bearer {access_token}"}
)
assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-def test_token_nonexistent_user():
+def test_token_nonexistent_user(mod: ModuleType):
+ client = TestClient(mod.app)
+
response = client.get(
"/users/me",
headers={
assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-def test_token_inactive_user():
+def test_token_inactive_user(mod: ModuleType):
+ client = TestClient(mod.app)
+
access_token = get_access_token(
- username="alice", password="secretalice", scope="me"
+ username="alice", password="secretalice", scope="me", client=client
)
response = client.get(
"/users/me", headers={"Authorization": f"Bearer {access_token}"}
assert response.json() == {"detail": "Inactive user"}
-def test_read_items():
- access_token = get_access_token(scope="me items")
+def test_read_items(mod: ModuleType):
+ client = TestClient(mod.app)
+ access_token = get_access_token(scope="me items", client=client)
response = client.get(
"/users/me/items/", headers={"Authorization": f"Bearer {access_token}"}
)
assert response.json() == [{"item_id": "Foo", "owner": "johndoe"}]
-def test_read_system_status():
- access_token = get_access_token()
+def test_read_system_status(mod: ModuleType):
+ client = TestClient(mod.app)
+ access_token = get_access_token(client=client)
response = client.get(
"/status/", headers={"Authorization": f"Bearer {access_token}"}
)
assert response.json() == {"status": "ok"}
-def test_read_system_status_no_token():
+def test_read_system_status_no_token(mod: ModuleType):
+ client = TestClient(mod.app)
response = client.get("/status/")
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
assert response.headers["WWW-Authenticate"] == "Bearer"
-def test_openapi_schema():
+def test_openapi_schema(mod: ModuleType):
+ client = TestClient(mod.app)
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
+++ /dev/null
-from dirty_equals import IsDict, IsOneOf
-from fastapi.testclient import TestClient
-
-from docs_src.security.tutorial005_an import (
- app,
- create_access_token,
- fake_users_db,
- get_password_hash,
- verify_password,
-)
-
-client = TestClient(app)
-
-
-def get_access_token(username="johndoe", password="secret", scope=None):
- data = {"username": username, "password": password}
- if scope:
- data["scope"] = scope
- response = client.post("/token", data=data)
- content = response.json()
- access_token = content.get("access_token")
- return access_token
-
-
-def test_login():
- response = client.post("/token", data={"username": "johndoe", "password": "secret"})
- assert response.status_code == 200, response.text
- content = response.json()
- assert "access_token" in content
- assert content["token_type"] == "bearer"
-
-
-def test_login_incorrect_password():
- response = client.post(
- "/token", data={"username": "johndoe", "password": "incorrect"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-def test_login_incorrect_username():
- response = client.post("/token", data={"username": "foo", "password": "secret"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-def test_no_token():
- response = client.get("/users/me")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-def test_token():
- access_token = get_access_token(scope="me")
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {
- "username": "johndoe",
- "full_name": "John Doe",
- "email": "johndoe@example.com",
- "disabled": False,
- }
-
-
-def test_incorrect_token():
- response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-def test_incorrect_token_type():
- response = client.get(
- "/users/me", headers={"Authorization": "Notexistent testtoken"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-def test_verify_password():
- assert verify_password("secret", fake_users_db["johndoe"]["hashed_password"])
-
-
-def test_get_password_hash():
- assert get_password_hash("secretalice")
-
-
-def test_create_access_token():
- access_token = create_access_token(data={"data": "foo"})
- assert access_token
-
-
-def test_token_no_sub():
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiZm9vIn0.9ynBhuYb4e6aW3oJr_K_TBgwcMTDpRToQIE25L57rOE"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-def test_token_no_username():
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmb28ifQ.NnExK_dlNAYyzACrXtXDrcWOgGY2JuPbI4eDaHdfK5Y"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-def test_token_no_scope():
- access_token = get_access_token()
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not enough permissions"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-def test_token_nonexistent_user():
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VybmFtZTpib2IifQ.HcfCW67Uda-0gz54ZWTqmtgJnZeNem0Q757eTa9EZuw"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-def test_token_inactive_user():
- access_token = get_access_token(
- username="alice", password="secretalice", scope="me"
- )
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Inactive user"}
-
-
-def test_read_items():
- access_token = get_access_token(scope="me items")
- response = client.get(
- "/users/me/items/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == [{"item_id": "Foo", "owner": "johndoe"}]
-
-
-def test_read_system_status():
- access_token = get_access_token()
- response = client.get(
- "/status/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {"status": "ok"}
-
-
-def test_read_system_status_no_token():
- response = client.get("/status/")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-def test_openapi_schema():
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/token": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Token"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Login For Access Token",
- "operationId": "login_for_access_token_token_post",
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "$ref": "#/components/schemas/Body_login_for_access_token_token_post"
- }
- }
- },
- "required": True,
- },
- }
- },
- "/users/me/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- }
- },
- "summary": "Read Users Me",
- "operationId": "read_users_me_users_me__get",
- "security": [{"OAuth2PasswordBearer": ["me"]}],
- }
- },
- "/users/me/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Own Items",
- "operationId": "read_own_items_users_me_items__get",
- "security": [{"OAuth2PasswordBearer": ["items", "me"]}],
- }
- },
- "/status/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read System Status",
- "operationId": "read_system_status_status__get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- },
- },
- "components": {
- "schemas": {
- "User": {
- "title": "User",
- "required": IsOneOf(
- ["username", "email", "full_name", "disabled"],
- # TODO: remove when deprecating Pydantic v1
- ["username"],
- ),
- "type": "object",
- "properties": {
- "username": {"title": "Username", "type": "string"},
- "email": IsDict(
- {
- "title": "Email",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Email", "type": "string"}
- ),
- "full_name": IsDict(
- {
- "title": "Full Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Full Name", "type": "string"}
- ),
- "disabled": IsDict(
- {
- "title": "Disabled",
- "anyOf": [{"type": "boolean"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Disabled", "type": "boolean"}
- ),
- },
- },
- "Token": {
- "title": "Token",
- "required": ["access_token", "token_type"],
- "type": "object",
- "properties": {
- "access_token": {"title": "Access Token", "type": "string"},
- "token_type": {"title": "Token Type", "type": "string"},
- },
- },
- "Body_login_for_access_token_token_post": {
- "title": "Body_login_for_access_token_token_post",
- "required": ["username", "password"],
- "type": "object",
- "properties": {
- "grant_type": IsDict(
- {
- "title": "Grant Type",
- "anyOf": [
- {"pattern": "password", "type": "string"},
- {"type": "null"},
- ],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Grant Type",
- "pattern": "password",
- "type": "string",
- }
- ),
- "username": {"title": "Username", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- "scope": {"title": "Scope", "type": "string", "default": ""},
- "client_id": IsDict(
- {
- "title": "Client Id",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Id", "type": "string"}
- ),
- "client_secret": IsDict(
- {
- "title": "Client Secret",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Secret", "type": "string"}
- ),
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- },
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {
- "password": {
- "scopes": {
- "me": "Read information about the current user.",
- "items": "Read items.",
- },
- "tokenUrl": "token",
- }
- },
- }
- },
- },
- }
+++ /dev/null
-import pytest
-from dirty_equals import IsDict, IsOneOf
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-@pytest.fixture(name="client")
-def get_client():
- from docs_src.security.tutorial005_an_py310 import app
-
- client = TestClient(app)
- return client
-
-
-def get_access_token(
- *, username="johndoe", password="secret", scope=None, client: TestClient
-):
- data = {"username": username, "password": password}
- if scope:
- data["scope"] = scope
- response = client.post("/token", data=data)
- content = response.json()
- access_token = content.get("access_token")
- return access_token
-
-
-@needs_py310
-def test_login(client: TestClient):
- response = client.post("/token", data={"username": "johndoe", "password": "secret"})
- assert response.status_code == 200, response.text
- content = response.json()
- assert "access_token" in content
- assert content["token_type"] == "bearer"
-
-
-@needs_py310
-def test_login_incorrect_password(client: TestClient):
- response = client.post(
- "/token", data={"username": "johndoe", "password": "incorrect"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py310
-def test_login_incorrect_username(client: TestClient):
- response = client.post("/token", data={"username": "foo", "password": "secret"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py310
-def test_no_token(client: TestClient):
- response = client.get("/users/me")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_token(client: TestClient):
- access_token = get_access_token(scope="me", client=client)
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {
- "username": "johndoe",
- "full_name": "John Doe",
- "email": "johndoe@example.com",
- "disabled": False,
- }
-
-
-@needs_py310
-def test_incorrect_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_incorrect_token_type(client: TestClient):
- response = client.get(
- "/users/me", headers={"Authorization": "Notexistent testtoken"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_verify_password():
- from docs_src.security.tutorial005_an_py310 import fake_users_db, verify_password
-
- assert verify_password("secret", fake_users_db["johndoe"]["hashed_password"])
-
-
-@needs_py310
-def test_get_password_hash():
- from docs_src.security.tutorial005_an_py310 import get_password_hash
-
- assert get_password_hash("secretalice")
-
-
-@needs_py310
-def test_create_access_token():
- from docs_src.security.tutorial005_an_py310 import create_access_token
-
- access_token = create_access_token(data={"data": "foo"})
- assert access_token
-
-
-@needs_py310
-def test_token_no_sub(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiZm9vIn0.9ynBhuYb4e6aW3oJr_K_TBgwcMTDpRToQIE25L57rOE"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_token_no_username(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmb28ifQ.NnExK_dlNAYyzACrXtXDrcWOgGY2JuPbI4eDaHdfK5Y"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_token_no_scope(client: TestClient):
- access_token = get_access_token(client=client)
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not enough permissions"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_token_nonexistent_user(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VybmFtZTpib2IifQ.HcfCW67Uda-0gz54ZWTqmtgJnZeNem0Q757eTa9EZuw"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_token_inactive_user(client: TestClient):
- access_token = get_access_token(
- username="alice", password="secretalice", scope="me", client=client
- )
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Inactive user"}
-
-
-@needs_py310
-def test_read_items(client: TestClient):
- access_token = get_access_token(scope="me items", client=client)
- response = client.get(
- "/users/me/items/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == [{"item_id": "Foo", "owner": "johndoe"}]
-
-
-@needs_py310
-def test_read_system_status(client: TestClient):
- access_token = get_access_token(client=client)
- response = client.get(
- "/status/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {"status": "ok"}
-
-
-@needs_py310
-def test_read_system_status_no_token(client: TestClient):
- response = client.get("/status/")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_openapi_schema(client: TestClient):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/token": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Token"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Login For Access Token",
- "operationId": "login_for_access_token_token_post",
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "$ref": "#/components/schemas/Body_login_for_access_token_token_post"
- }
- }
- },
- "required": True,
- },
- }
- },
- "/users/me/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- }
- },
- "summary": "Read Users Me",
- "operationId": "read_users_me_users_me__get",
- "security": [{"OAuth2PasswordBearer": ["me"]}],
- }
- },
- "/users/me/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Own Items",
- "operationId": "read_own_items_users_me_items__get",
- "security": [{"OAuth2PasswordBearer": ["items", "me"]}],
- }
- },
- "/status/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read System Status",
- "operationId": "read_system_status_status__get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- },
- },
- "components": {
- "schemas": {
- "User": {
- "title": "User",
- "required": IsOneOf(
- ["username", "email", "full_name", "disabled"],
- # TODO: remove when deprecating Pydantic v1
- ["username"],
- ),
- "type": "object",
- "properties": {
- "username": {"title": "Username", "type": "string"},
- "email": IsDict(
- {
- "title": "Email",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Email", "type": "string"}
- ),
- "full_name": IsDict(
- {
- "title": "Full Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Full Name", "type": "string"}
- ),
- "disabled": IsDict(
- {
- "title": "Disabled",
- "anyOf": [{"type": "boolean"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Disabled", "type": "boolean"}
- ),
- },
- },
- "Token": {
- "title": "Token",
- "required": ["access_token", "token_type"],
- "type": "object",
- "properties": {
- "access_token": {"title": "Access Token", "type": "string"},
- "token_type": {"title": "Token Type", "type": "string"},
- },
- },
- "Body_login_for_access_token_token_post": {
- "title": "Body_login_for_access_token_token_post",
- "required": ["username", "password"],
- "type": "object",
- "properties": {
- "grant_type": IsDict(
- {
- "title": "Grant Type",
- "anyOf": [
- {"pattern": "password", "type": "string"},
- {"type": "null"},
- ],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Grant Type",
- "pattern": "password",
- "type": "string",
- }
- ),
- "username": {"title": "Username", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- "scope": {"title": "Scope", "type": "string", "default": ""},
- "client_id": IsDict(
- {
- "title": "Client Id",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Id", "type": "string"}
- ),
- "client_secret": IsDict(
- {
- "title": "Client Secret",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Secret", "type": "string"}
- ),
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- },
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {
- "password": {
- "scopes": {
- "me": "Read information about the current user.",
- "items": "Read items.",
- },
- "tokenUrl": "token",
- }
- },
- }
- },
- },
- }
+++ /dev/null
-import pytest
-from dirty_equals import IsDict, IsOneOf
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="client")
-def get_client():
- from docs_src.security.tutorial005_an_py39 import app
-
- client = TestClient(app)
- return client
-
-
-def get_access_token(
- *, username="johndoe", password="secret", scope=None, client: TestClient
-):
- data = {"username": username, "password": password}
- if scope:
- data["scope"] = scope
- response = client.post("/token", data=data)
- content = response.json()
- access_token = content.get("access_token")
- return access_token
-
-
-@needs_py39
-def test_login(client: TestClient):
- response = client.post("/token", data={"username": "johndoe", "password": "secret"})
- assert response.status_code == 200, response.text
- content = response.json()
- assert "access_token" in content
- assert content["token_type"] == "bearer"
-
-
-@needs_py39
-def test_login_incorrect_password(client: TestClient):
- response = client.post(
- "/token", data={"username": "johndoe", "password": "incorrect"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py39
-def test_login_incorrect_username(client: TestClient):
- response = client.post("/token", data={"username": "foo", "password": "secret"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py39
-def test_no_token(client: TestClient):
- response = client.get("/users/me")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_token(client: TestClient):
- access_token = get_access_token(scope="me", client=client)
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {
- "username": "johndoe",
- "full_name": "John Doe",
- "email": "johndoe@example.com",
- "disabled": False,
- }
-
-
-@needs_py39
-def test_incorrect_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_incorrect_token_type(client: TestClient):
- response = client.get(
- "/users/me", headers={"Authorization": "Notexistent testtoken"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_verify_password():
- from docs_src.security.tutorial005_an_py39 import fake_users_db, verify_password
-
- assert verify_password("secret", fake_users_db["johndoe"]["hashed_password"])
-
-
-@needs_py39
-def test_get_password_hash():
- from docs_src.security.tutorial005_an_py39 import get_password_hash
-
- assert get_password_hash("secretalice")
-
-
-@needs_py39
-def test_create_access_token():
- from docs_src.security.tutorial005_an_py39 import create_access_token
-
- access_token = create_access_token(data={"data": "foo"})
- assert access_token
-
-
-@needs_py39
-def test_token_no_sub(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiZm9vIn0.9ynBhuYb4e6aW3oJr_K_TBgwcMTDpRToQIE25L57rOE"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_token_no_username(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmb28ifQ.NnExK_dlNAYyzACrXtXDrcWOgGY2JuPbI4eDaHdfK5Y"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_token_no_scope(client: TestClient):
- access_token = get_access_token(client=client)
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not enough permissions"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_token_nonexistent_user(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VybmFtZTpib2IifQ.HcfCW67Uda-0gz54ZWTqmtgJnZeNem0Q757eTa9EZuw"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_token_inactive_user(client: TestClient):
- access_token = get_access_token(
- username="alice", password="secretalice", scope="me", client=client
- )
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Inactive user"}
-
-
-@needs_py39
-def test_read_items(client: TestClient):
- access_token = get_access_token(scope="me items", client=client)
- response = client.get(
- "/users/me/items/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == [{"item_id": "Foo", "owner": "johndoe"}]
-
-
-@needs_py39
-def test_read_system_status(client: TestClient):
- access_token = get_access_token(client=client)
- response = client.get(
- "/status/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {"status": "ok"}
-
-
-@needs_py39
-def test_read_system_status_no_token(client: TestClient):
- response = client.get("/status/")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/token": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Token"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Login For Access Token",
- "operationId": "login_for_access_token_token_post",
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "$ref": "#/components/schemas/Body_login_for_access_token_token_post"
- }
- }
- },
- "required": True,
- },
- }
- },
- "/users/me/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- }
- },
- "summary": "Read Users Me",
- "operationId": "read_users_me_users_me__get",
- "security": [{"OAuth2PasswordBearer": ["me"]}],
- }
- },
- "/users/me/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Own Items",
- "operationId": "read_own_items_users_me_items__get",
- "security": [{"OAuth2PasswordBearer": ["items", "me"]}],
- }
- },
- "/status/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read System Status",
- "operationId": "read_system_status_status__get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- },
- },
- "components": {
- "schemas": {
- "User": {
- "title": "User",
- "required": IsOneOf(
- ["username", "email", "full_name", "disabled"],
- # TODO: remove when deprecating Pydantic v1
- ["username"],
- ),
- "type": "object",
- "properties": {
- "username": {"title": "Username", "type": "string"},
- "email": IsDict(
- {
- "title": "Email",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Email", "type": "string"}
- ),
- "full_name": IsDict(
- {
- "title": "Full Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Full Name", "type": "string"}
- ),
- "disabled": IsDict(
- {
- "title": "Disabled",
- "anyOf": [{"type": "boolean"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Disabled", "type": "boolean"}
- ),
- },
- },
- "Token": {
- "title": "Token",
- "required": ["access_token", "token_type"],
- "type": "object",
- "properties": {
- "access_token": {"title": "Access Token", "type": "string"},
- "token_type": {"title": "Token Type", "type": "string"},
- },
- },
- "Body_login_for_access_token_token_post": {
- "title": "Body_login_for_access_token_token_post",
- "required": ["username", "password"],
- "type": "object",
- "properties": {
- "grant_type": IsDict(
- {
- "title": "Grant Type",
- "anyOf": [
- {"pattern": "password", "type": "string"},
- {"type": "null"},
- ],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Grant Type",
- "pattern": "password",
- "type": "string",
- }
- ),
- "username": {"title": "Username", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- "scope": {"title": "Scope", "type": "string", "default": ""},
- "client_id": IsDict(
- {
- "title": "Client Id",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Id", "type": "string"}
- ),
- "client_secret": IsDict(
- {
- "title": "Client Secret",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Secret", "type": "string"}
- ),
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- },
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {
- "password": {
- "scopes": {
- "me": "Read information about the current user.",
- "items": "Read items.",
- },
- "tokenUrl": "token",
- }
- },
- }
- },
- },
- }
+++ /dev/null
-import pytest
-from dirty_equals import IsDict, IsOneOf
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-@pytest.fixture(name="client")
-def get_client():
- from docs_src.security.tutorial005_py310 import app
-
- client = TestClient(app)
- return client
-
-
-def get_access_token(
- *, username="johndoe", password="secret", scope=None, client: TestClient
-):
- data = {"username": username, "password": password}
- if scope:
- data["scope"] = scope
- response = client.post("/token", data=data)
- content = response.json()
- access_token = content.get("access_token")
- return access_token
-
-
-@needs_py310
-def test_login(client: TestClient):
- response = client.post("/token", data={"username": "johndoe", "password": "secret"})
- assert response.status_code == 200, response.text
- content = response.json()
- assert "access_token" in content
- assert content["token_type"] == "bearer"
-
-
-@needs_py310
-def test_login_incorrect_password(client: TestClient):
- response = client.post(
- "/token", data={"username": "johndoe", "password": "incorrect"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py310
-def test_login_incorrect_username(client: TestClient):
- response = client.post("/token", data={"username": "foo", "password": "secret"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py310
-def test_no_token(client: TestClient):
- response = client.get("/users/me")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_token(client: TestClient):
- access_token = get_access_token(scope="me", client=client)
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {
- "username": "johndoe",
- "full_name": "John Doe",
- "email": "johndoe@example.com",
- "disabled": False,
- }
-
-
-@needs_py310
-def test_incorrect_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_incorrect_token_type(client: TestClient):
- response = client.get(
- "/users/me", headers={"Authorization": "Notexistent testtoken"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_verify_password():
- from docs_src.security.tutorial005_py310 import fake_users_db, verify_password
-
- assert verify_password("secret", fake_users_db["johndoe"]["hashed_password"])
-
-
-@needs_py310
-def test_get_password_hash():
- from docs_src.security.tutorial005_py310 import get_password_hash
-
- assert get_password_hash("secretalice")
-
-
-@needs_py310
-def test_create_access_token():
- from docs_src.security.tutorial005_py310 import create_access_token
-
- access_token = create_access_token(data={"data": "foo"})
- assert access_token
-
-
-@needs_py310
-def test_token_no_sub(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiZm9vIn0.9ynBhuYb4e6aW3oJr_K_TBgwcMTDpRToQIE25L57rOE"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_token_no_username(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmb28ifQ.NnExK_dlNAYyzACrXtXDrcWOgGY2JuPbI4eDaHdfK5Y"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_token_no_scope(client: TestClient):
- access_token = get_access_token(client=client)
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not enough permissions"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_token_nonexistent_user(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VybmFtZTpib2IifQ.HcfCW67Uda-0gz54ZWTqmtgJnZeNem0Q757eTa9EZuw"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py310
-def test_token_inactive_user(client: TestClient):
- access_token = get_access_token(
- username="alice", password="secretalice", scope="me", client=client
- )
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Inactive user"}
-
-
-@needs_py310
-def test_read_items(client: TestClient):
- access_token = get_access_token(scope="me items", client=client)
- response = client.get(
- "/users/me/items/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == [{"item_id": "Foo", "owner": "johndoe"}]
-
-
-@needs_py310
-def test_read_system_status(client: TestClient):
- access_token = get_access_token(client=client)
- response = client.get(
- "/status/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {"status": "ok"}
-
-
-@needs_py310
-def test_read_system_status_no_token(client: TestClient):
- response = client.get("/status/")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py310
-def test_openapi_schema(client: TestClient):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/token": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Token"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Login For Access Token",
- "operationId": "login_for_access_token_token_post",
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "$ref": "#/components/schemas/Body_login_for_access_token_token_post"
- }
- }
- },
- "required": True,
- },
- }
- },
- "/users/me/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- }
- },
- "summary": "Read Users Me",
- "operationId": "read_users_me_users_me__get",
- "security": [{"OAuth2PasswordBearer": ["me"]}],
- }
- },
- "/users/me/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Own Items",
- "operationId": "read_own_items_users_me_items__get",
- "security": [{"OAuth2PasswordBearer": ["items", "me"]}],
- }
- },
- "/status/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read System Status",
- "operationId": "read_system_status_status__get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- },
- },
- "components": {
- "schemas": {
- "User": {
- "title": "User",
- "required": IsOneOf(
- ["username", "email", "full_name", "disabled"],
- # TODO: remove when deprecating Pydantic v1
- ["username"],
- ),
- "type": "object",
- "properties": {
- "username": {"title": "Username", "type": "string"},
- "email": IsDict(
- {
- "title": "Email",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Email", "type": "string"}
- ),
- "full_name": IsDict(
- {
- "title": "Full Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Full Name", "type": "string"}
- ),
- "disabled": IsDict(
- {
- "title": "Disabled",
- "anyOf": [{"type": "boolean"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Disabled", "type": "boolean"}
- ),
- },
- },
- "Token": {
- "title": "Token",
- "required": ["access_token", "token_type"],
- "type": "object",
- "properties": {
- "access_token": {"title": "Access Token", "type": "string"},
- "token_type": {"title": "Token Type", "type": "string"},
- },
- },
- "Body_login_for_access_token_token_post": {
- "title": "Body_login_for_access_token_token_post",
- "required": ["username", "password"],
- "type": "object",
- "properties": {
- "grant_type": IsDict(
- {
- "title": "Grant Type",
- "anyOf": [
- {"pattern": "password", "type": "string"},
- {"type": "null"},
- ],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Grant Type",
- "pattern": "password",
- "type": "string",
- }
- ),
- "username": {"title": "Username", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- "scope": {"title": "Scope", "type": "string", "default": ""},
- "client_id": IsDict(
- {
- "title": "Client Id",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Id", "type": "string"}
- ),
- "client_secret": IsDict(
- {
- "title": "Client Secret",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Secret", "type": "string"}
- ),
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- },
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {
- "password": {
- "scopes": {
- "me": "Read information about the current user.",
- "items": "Read items.",
- },
- "tokenUrl": "token",
- }
- },
- }
- },
- },
- }
+++ /dev/null
-import pytest
-from dirty_equals import IsDict, IsOneOf
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="client")
-def get_client():
- from docs_src.security.tutorial005_py39 import app
-
- client = TestClient(app)
- return client
-
-
-def get_access_token(
- *, username="johndoe", password="secret", scope=None, client: TestClient
-):
- data = {"username": username, "password": password}
- if scope:
- data["scope"] = scope
- response = client.post("/token", data=data)
- content = response.json()
- access_token = content.get("access_token")
- return access_token
-
-
-@needs_py39
-def test_login(client: TestClient):
- response = client.post("/token", data={"username": "johndoe", "password": "secret"})
- assert response.status_code == 200, response.text
- content = response.json()
- assert "access_token" in content
- assert content["token_type"] == "bearer"
-
-
-@needs_py39
-def test_login_incorrect_password(client: TestClient):
- response = client.post(
- "/token", data={"username": "johndoe", "password": "incorrect"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py39
-def test_login_incorrect_username(client: TestClient):
- response = client.post("/token", data={"username": "foo", "password": "secret"})
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Incorrect username or password"}
-
-
-@needs_py39
-def test_no_token(client: TestClient):
- response = client.get("/users/me")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_token(client: TestClient):
- access_token = get_access_token(scope="me", client=client)
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {
- "username": "johndoe",
- "full_name": "John Doe",
- "email": "johndoe@example.com",
- "disabled": False,
- }
-
-
-@needs_py39
-def test_incorrect_token(client: TestClient):
- response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"})
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_incorrect_token_type(client: TestClient):
- response = client.get(
- "/users/me", headers={"Authorization": "Notexistent testtoken"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_verify_password():
- from docs_src.security.tutorial005_py39 import fake_users_db, verify_password
-
- assert verify_password("secret", fake_users_db["johndoe"]["hashed_password"])
-
-
-@needs_py39
-def test_get_password_hash():
- from docs_src.security.tutorial005_py39 import get_password_hash
-
- assert get_password_hash("secretalice")
-
-
-@needs_py39
-def test_create_access_token():
- from docs_src.security.tutorial005_py39 import create_access_token
-
- access_token = create_access_token(data={"data": "foo"})
- assert access_token
-
-
-@needs_py39
-def test_token_no_sub(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiZm9vIn0.9ynBhuYb4e6aW3oJr_K_TBgwcMTDpRToQIE25L57rOE"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_token_no_username(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmb28ifQ.NnExK_dlNAYyzACrXtXDrcWOgGY2JuPbI4eDaHdfK5Y"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_token_no_scope(client: TestClient):
- access_token = get_access_token(client=client)
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not enough permissions"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_token_nonexistent_user(client: TestClient):
- response = client.get(
- "/users/me",
- headers={
- "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VybmFtZTpib2IifQ.HcfCW67Uda-0gz54ZWTqmtgJnZeNem0Q757eTa9EZuw"
- },
- )
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Could not validate credentials"}
- assert response.headers["WWW-Authenticate"] == 'Bearer scope="me"'
-
-
-@needs_py39
-def test_token_inactive_user(client: TestClient):
- access_token = get_access_token(
- username="alice", password="secretalice", scope="me", client=client
- )
- response = client.get(
- "/users/me", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 400, response.text
- assert response.json() == {"detail": "Inactive user"}
-
-
-@needs_py39
-def test_read_items(client: TestClient):
- access_token = get_access_token(scope="me items", client=client)
- response = client.get(
- "/users/me/items/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == [{"item_id": "Foo", "owner": "johndoe"}]
-
-
-@needs_py39
-def test_read_system_status(client: TestClient):
- access_token = get_access_token(client=client)
- response = client.get(
- "/status/", headers={"Authorization": f"Bearer {access_token}"}
- )
- assert response.status_code == 200, response.text
- assert response.json() == {"status": "ok"}
-
-
-@needs_py39
-def test_read_system_status_no_token(client: TestClient):
- response = client.get("/status/")
- assert response.status_code == 401, response.text
- assert response.json() == {"detail": "Not authenticated"}
- assert response.headers["WWW-Authenticate"] == "Bearer"
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/token": {
- "post": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/Token"}
- }
- },
- },
- "422": {
- "description": "Validation Error",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/HTTPValidationError"
- }
- }
- },
- },
- },
- "summary": "Login For Access Token",
- "operationId": "login_for_access_token_token_post",
- "requestBody": {
- "content": {
- "application/x-www-form-urlencoded": {
- "schema": {
- "$ref": "#/components/schemas/Body_login_for_access_token_token_post"
- }
- }
- },
- "required": True,
- },
- }
- },
- "/users/me/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {"$ref": "#/components/schemas/User"}
- }
- },
- }
- },
- "summary": "Read Users Me",
- "operationId": "read_users_me_users_me__get",
- "security": [{"OAuth2PasswordBearer": ["me"]}],
- }
- },
- "/users/me/items/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Own Items",
- "operationId": "read_own_items_users_me_items__get",
- "security": [{"OAuth2PasswordBearer": ["items", "me"]}],
- }
- },
- "/status/": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read System Status",
- "operationId": "read_system_status_status__get",
- "security": [{"OAuth2PasswordBearer": []}],
- }
- },
- },
- "components": {
- "schemas": {
- "User": {
- "title": "User",
- "required": IsOneOf(
- ["username", "email", "full_name", "disabled"],
- # TODO: remove when deprecating Pydantic v1
- ["username"],
- ),
- "type": "object",
- "properties": {
- "username": {"title": "Username", "type": "string"},
- "email": IsDict(
- {
- "title": "Email",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Email", "type": "string"}
- ),
- "full_name": IsDict(
- {
- "title": "Full Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Full Name", "type": "string"}
- ),
- "disabled": IsDict(
- {
- "title": "Disabled",
- "anyOf": [{"type": "boolean"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Disabled", "type": "boolean"}
- ),
- },
- },
- "Token": {
- "title": "Token",
- "required": ["access_token", "token_type"],
- "type": "object",
- "properties": {
- "access_token": {"title": "Access Token", "type": "string"},
- "token_type": {"title": "Token Type", "type": "string"},
- },
- },
- "Body_login_for_access_token_token_post": {
- "title": "Body_login_for_access_token_token_post",
- "required": ["username", "password"],
- "type": "object",
- "properties": {
- "grant_type": IsDict(
- {
- "title": "Grant Type",
- "anyOf": [
- {"pattern": "password", "type": "string"},
- {"type": "null"},
- ],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Grant Type",
- "pattern": "password",
- "type": "string",
- }
- ),
- "username": {"title": "Username", "type": "string"},
- "password": {"title": "Password", "type": "string"},
- "scope": {"title": "Scope", "type": "string", "default": ""},
- "client_id": IsDict(
- {
- "title": "Client Id",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Id", "type": "string"}
- ),
- "client_secret": IsDict(
- {
- "title": "Client Secret",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Client Secret", "type": "string"}
- ),
- },
- },
- "ValidationError": {
- "title": "ValidationError",
- "required": ["loc", "msg", "type"],
- "type": "object",
- "properties": {
- "loc": {
- "title": "Location",
- "type": "array",
- "items": {
- "anyOf": [{"type": "string"}, {"type": "integer"}]
- },
- },
- "msg": {"title": "Message", "type": "string"},
- "type": {"title": "Error Type", "type": "string"},
- },
- },
- "HTTPValidationError": {
- "title": "HTTPValidationError",
- "type": "object",
- "properties": {
- "detail": {
- "title": "Detail",
- "type": "array",
- "items": {"$ref": "#/components/schemas/ValidationError"},
- }
- },
- },
- },
- "securitySchemes": {
- "OAuth2PasswordBearer": {
- "type": "oauth2",
- "flows": {
- "password": {
- "scopes": {
- "me": "Read information about the current user.",
- "items": "Read items.",
- },
- "tokenUrl": "token",
- }
- },
- }
- },
- },
- }
+import importlib
from base64 import b64encode
+import pytest
from fastapi.testclient import TestClient
-from docs_src.security.tutorial006 import app
+from ...utils import needs_py39
-client = TestClient(app)
+@pytest.fixture(
+ name="client",
+ params=[
+ "tutorial006",
+ "tutorial006_an",
+ pytest.param("tutorial006_an_py39", marks=needs_py39),
+ ],
+)
+def get_client(request: pytest.FixtureRequest):
+ mod = importlib.import_module(f"docs_src.security.{request.param}")
-def test_security_http_basic():
+ client = TestClient(mod.app)
+ return client
+
+
+def test_security_http_basic(client: TestClient):
response = client.get("/users/me", auth=("john", "secret"))
assert response.status_code == 200, response.text
assert response.json() == {"username": "john", "password": "secret"}
-def test_security_http_basic_no_credentials():
+def test_security_http_basic_no_credentials(client: TestClient):
response = client.get("/users/me")
assert response.json() == {"detail": "Not authenticated"}
assert response.status_code == 401, response.text
assert response.headers["WWW-Authenticate"] == "Basic"
-def test_security_http_basic_invalid_credentials():
+def test_security_http_basic_invalid_credentials(client: TestClient):
response = client.get(
"/users/me", headers={"Authorization": "Basic notabase64token"}
)
assert response.json() == {"detail": "Invalid authentication credentials"}
-def test_security_http_basic_non_basic_credentials():
+def test_security_http_basic_non_basic_credentials(client: TestClient):
payload = b64encode(b"johnsecret").decode("ascii")
auth_header = f"Basic {payload}"
response = client.get("/users/me", headers={"Authorization": auth_header})
assert response.json() == {"detail": "Invalid authentication credentials"}
-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
+++ /dev/null
-from base64 import b64encode
-
-from fastapi.testclient import TestClient
-
-from docs_src.security.tutorial006_an import app
-
-client = TestClient(app)
-
-
-def test_security_http_basic():
- response = client.get("/users/me", auth=("john", "secret"))
- assert response.status_code == 200, response.text
- assert response.json() == {"username": "john", "password": "secret"}
-
-
-def test_security_http_basic_no_credentials():
- response = client.get("/users/me")
- assert response.json() == {"detail": "Not authenticated"}
- assert response.status_code == 401, response.text
- assert response.headers["WWW-Authenticate"] == "Basic"
-
-
-def test_security_http_basic_invalid_credentials():
- response = client.get(
- "/users/me", headers={"Authorization": "Basic notabase64token"}
- )
- assert response.status_code == 401, response.text
- assert response.headers["WWW-Authenticate"] == "Basic"
- assert response.json() == {"detail": "Invalid authentication credentials"}
-
-
-def test_security_http_basic_non_basic_credentials():
- payload = b64encode(b"johnsecret").decode("ascii")
- auth_header = f"Basic {payload}"
- response = client.get("/users/me", headers={"Authorization": auth_header})
- assert response.status_code == 401, response.text
- assert response.headers["WWW-Authenticate"] == "Basic"
- assert response.json() == {"detail": "Invalid authentication credentials"}
-
-
-def test_openapi_schema():
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/users/me": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Current User",
- "operationId": "read_current_user_users_me_get",
- "security": [{"HTTPBasic": []}],
- }
- }
- },
- "components": {
- "securitySchemes": {"HTTPBasic": {"type": "http", "scheme": "basic"}}
- },
- }
+++ /dev/null
-from base64 import b64encode
-
-import pytest
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-@pytest.fixture(name="client")
-def get_client():
- from docs_src.security.tutorial006_an import app
-
- client = TestClient(app)
- return client
-
-
-@needs_py39
-def test_security_http_basic(client: TestClient):
- response = client.get("/users/me", auth=("john", "secret"))
- assert response.status_code == 200, response.text
- assert response.json() == {"username": "john", "password": "secret"}
-
-
-@needs_py39
-def test_security_http_basic_no_credentials(client: TestClient):
- response = client.get("/users/me")
- assert response.json() == {"detail": "Not authenticated"}
- assert response.status_code == 401, response.text
- assert response.headers["WWW-Authenticate"] == "Basic"
-
-
-@needs_py39
-def test_security_http_basic_invalid_credentials(client: TestClient):
- response = client.get(
- "/users/me", headers={"Authorization": "Basic notabase64token"}
- )
- assert response.status_code == 401, response.text
- assert response.headers["WWW-Authenticate"] == "Basic"
- assert response.json() == {"detail": "Invalid authentication credentials"}
-
-
-@needs_py39
-def test_security_http_basic_non_basic_credentials(client: TestClient):
- payload = b64encode(b"johnsecret").decode("ascii")
- auth_header = f"Basic {payload}"
- response = client.get("/users/me", headers={"Authorization": auth_header})
- assert response.status_code == 401, response.text
- assert response.headers["WWW-Authenticate"] == "Basic"
- assert response.json() == {"detail": "Invalid authentication credentials"}
-
-
-@needs_py39
-def test_openapi_schema(client: TestClient):
- response = client.get("/openapi.json")
- assert response.status_code == 200, response.text
- assert response.json() == {
- "openapi": "3.1.0",
- "info": {"title": "FastAPI", "version": "0.1.0"},
- "paths": {
- "/users/me": {
- "get": {
- "responses": {
- "200": {
- "description": "Successful Response",
- "content": {"application/json": {"schema": {}}},
- }
- },
- "summary": "Read Current User",
- "operationId": "read_current_user_users_me_get",
- "security": [{"HTTPBasic": []}],
- }
- }
- },
- "components": {
- "securitySchemes": {"HTTPBasic": {"type": "http", "scheme": "basic"}}
- },
- }