Browse Source
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>pull/14420/head
committed by
GitHub
4 changed files with 195 additions and 20 deletions
@ -0,0 +1,46 @@ |
|||||
|
from typing import Dict |
||||
|
|
||||
|
import pytest |
||||
|
from fastapi import Depends, FastAPI, Security |
||||
|
from fastapi.testclient import TestClient |
||||
|
from typing_extensions import Annotated |
||||
|
|
||||
|
|
||||
|
@pytest.fixture(name="call_counter") |
||||
|
def call_counter_fixture(): |
||||
|
return {"count": 0} |
||||
|
|
||||
|
|
||||
|
@pytest.fixture(name="app") |
||||
|
def app_fixture(call_counter: Dict[str, int]): |
||||
|
def get_db(): |
||||
|
call_counter["count"] += 1 |
||||
|
return f"db_{call_counter['count']}" |
||||
|
|
||||
|
def get_user(db: Annotated[str, Depends(get_db)]): |
||||
|
return "user" |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/") |
||||
|
def endpoint( |
||||
|
db: Annotated[str, Depends(get_db)], |
||||
|
user: Annotated[str, Security(get_user, scopes=["read"])], |
||||
|
): |
||||
|
return {"db": db} |
||||
|
|
||||
|
return app |
||||
|
|
||||
|
|
||||
|
@pytest.fixture(name="client") |
||||
|
def client_fixture(app: FastAPI): |
||||
|
return TestClient(app) |
||||
|
|
||||
|
|
||||
|
def test_security_scopes_dependency_called_once( |
||||
|
client: TestClient, call_counter: Dict[str, int] |
||||
|
): |
||||
|
response = client.get("/") |
||||
|
|
||||
|
assert response.status_code == 200 |
||||
|
assert call_counter["count"] == 1 |
||||
@ -0,0 +1,107 @@ |
|||||
|
# Ref: https://github.com/fastapi/fastapi/discussions/6024#discussioncomment-8541913 |
||||
|
|
||||
|
from typing import Dict |
||||
|
|
||||
|
import pytest |
||||
|
from fastapi import Depends, FastAPI, Security |
||||
|
from fastapi.security import SecurityScopes |
||||
|
from fastapi.testclient import TestClient |
||||
|
from typing_extensions import Annotated |
||||
|
|
||||
|
|
||||
|
@pytest.fixture(name="call_counts") |
||||
|
def call_counts_fixture(): |
||||
|
return { |
||||
|
"get_db_session": 0, |
||||
|
"get_current_user": 0, |
||||
|
"get_user_me": 0, |
||||
|
"get_user_items": 0, |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@pytest.fixture(name="app") |
||||
|
def app_fixture(call_counts: Dict[str, int]): |
||||
|
def get_db_session(): |
||||
|
call_counts["get_db_session"] += 1 |
||||
|
return f"db_session_{call_counts['get_db_session']}" |
||||
|
|
||||
|
def get_current_user( |
||||
|
security_scopes: SecurityScopes, |
||||
|
db_session: Annotated[str, Depends(get_db_session)], |
||||
|
): |
||||
|
call_counts["get_current_user"] += 1 |
||||
|
return { |
||||
|
"user": f"user_{call_counts['get_current_user']}", |
||||
|
"scopes": security_scopes.scopes, |
||||
|
"db_session": db_session, |
||||
|
} |
||||
|
|
||||
|
def get_user_me( |
||||
|
current_user: Annotated[dict, Security(get_current_user, scopes=["me"])], |
||||
|
): |
||||
|
call_counts["get_user_me"] += 1 |
||||
|
return { |
||||
|
"user_me": f"user_me_{call_counts['get_user_me']}", |
||||
|
"current_user": current_user, |
||||
|
} |
||||
|
|
||||
|
def get_user_items( |
||||
|
user_me: Annotated[dict, Depends(get_user_me)], |
||||
|
): |
||||
|
call_counts["get_user_items"] += 1 |
||||
|
return { |
||||
|
"user_items": f"user_items_{call_counts['get_user_items']}", |
||||
|
"user_me": user_me, |
||||
|
} |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/") |
||||
|
def path_operation( |
||||
|
user_me: Annotated[dict, Depends(get_user_me)], |
||||
|
user_items: Annotated[dict, Security(get_user_items, scopes=["items"])], |
||||
|
): |
||||
|
return { |
||||
|
"user_me": user_me, |
||||
|
"user_items": user_items, |
||||
|
} |
||||
|
|
||||
|
return app |
||||
|
|
||||
|
|
||||
|
@pytest.fixture(name="client") |
||||
|
def client_fixture(app: FastAPI): |
||||
|
return TestClient(app) |
||||
|
|
||||
|
|
||||
|
def test_security_scopes_sub_dependency_caching( |
||||
|
client: TestClient, call_counts: Dict[str, int] |
||||
|
): |
||||
|
response = client.get("/") |
||||
|
|
||||
|
assert response.status_code == 200 |
||||
|
assert call_counts["get_db_session"] == 1 |
||||
|
assert call_counts["get_current_user"] == 2 |
||||
|
assert call_counts["get_user_me"] == 2 |
||||
|
assert call_counts["get_user_items"] == 1 |
||||
|
assert response.json() == { |
||||
|
"user_me": { |
||||
|
"user_me": "user_me_1", |
||||
|
"current_user": { |
||||
|
"user": "user_1", |
||||
|
"scopes": ["me"], |
||||
|
"db_session": "db_session_1", |
||||
|
}, |
||||
|
}, |
||||
|
"user_items": { |
||||
|
"user_items": "user_items_1", |
||||
|
"user_me": { |
||||
|
"user_me": "user_me_2", |
||||
|
"current_user": { |
||||
|
"user": "user_2", |
||||
|
"scopes": ["items", "me"], |
||||
|
"db_session": "db_session_1", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
Loading…
Reference in new issue