mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-05-10 18:58:21 +00:00
- Move all unit tests from tests/ to tests/unittest/ - Add tests/e2e/ directory for end-to-end tests - Update conftest.py for new test structure - Add new tests for auth dependencies, policies, route injection - Add new tests for run callbacks, create store, execution artifacts - Remove obsolete tests for deleted persistence layer Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
158 lines
5.3 KiB
Python
158 lines
5.3 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import UTC, datetime
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
from fastapi import HTTPException
|
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
|
|
|
from app.plugins.auth.domain.config import AuthConfig
|
|
from app.plugins.auth.security.dependencies import (
|
|
get_current_user_from_request,
|
|
get_current_user_id,
|
|
get_optional_user_from_request,
|
|
)
|
|
from app.plugins.auth.domain.jwt import create_access_token
|
|
from app.plugins.auth.runtime.config_state import set_auth_config
|
|
from app.plugins.auth.storage import DbUserRepository, UserCreate
|
|
from store.persistence import MappedBase
|
|
from app.plugins.auth.storage.models import User as UserModel # noqa: F401
|
|
|
|
_TEST_SECRET = "test-secret-auth-dependencies-min-32"
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _setup_auth_config():
|
|
set_auth_config(AuthConfig(jwt_secret=_TEST_SECRET))
|
|
yield
|
|
set_auth_config(AuthConfig(jwt_secret=_TEST_SECRET))
|
|
|
|
|
|
async def _make_request(tmp_path, *, cookie: str | None = None, users: list[UserCreate] | None = None):
|
|
engine = create_async_engine(
|
|
f"sqlite+aiosqlite:///{tmp_path / 'auth-deps.db'}",
|
|
future=True,
|
|
)
|
|
async with engine.begin() as conn:
|
|
await conn.run_sync(MappedBase.metadata.create_all)
|
|
session_factory = async_sessionmaker(
|
|
bind=engine,
|
|
class_=AsyncSession,
|
|
expire_on_commit=False,
|
|
autoflush=False,
|
|
)
|
|
session = session_factory()
|
|
if users:
|
|
repo = DbUserRepository(session)
|
|
for user in users:
|
|
await repo.create_user(user)
|
|
await session.commit()
|
|
request = SimpleNamespace(
|
|
cookies={"access_token": cookie} if cookie is not None else {},
|
|
state=SimpleNamespace(_auth_session=session),
|
|
)
|
|
return request, session, engine
|
|
|
|
|
|
class TestAuthDependencies:
|
|
@pytest.mark.anyio
|
|
async def test_no_cookie_returns_401(self, tmp_path):
|
|
request, session, engine = await _make_request(tmp_path)
|
|
try:
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
await get_current_user_from_request(request)
|
|
finally:
|
|
await session.close()
|
|
await engine.dispose()
|
|
|
|
assert exc_info.value.status_code == 401
|
|
assert exc_info.value.detail["code"] == "not_authenticated"
|
|
|
|
@pytest.mark.anyio
|
|
async def test_invalid_token_returns_401(self, tmp_path):
|
|
request, session, engine = await _make_request(tmp_path, cookie="garbage")
|
|
try:
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
await get_current_user_from_request(request)
|
|
finally:
|
|
await session.close()
|
|
await engine.dispose()
|
|
|
|
assert exc_info.value.status_code == 401
|
|
assert exc_info.value.detail["code"] == "token_invalid"
|
|
|
|
@pytest.mark.anyio
|
|
async def test_missing_user_returns_401(self, tmp_path):
|
|
token = create_access_token("missing-user", token_version=0)
|
|
request, session, engine = await _make_request(tmp_path, cookie=token)
|
|
try:
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
await get_current_user_from_request(request)
|
|
finally:
|
|
await session.close()
|
|
await engine.dispose()
|
|
|
|
assert exc_info.value.status_code == 401
|
|
assert exc_info.value.detail["code"] == "user_not_found"
|
|
|
|
@pytest.mark.anyio
|
|
async def test_token_version_mismatch_returns_401(self, tmp_path):
|
|
token = create_access_token("user-1", token_version=0)
|
|
request, session, engine = await _make_request(
|
|
tmp_path,
|
|
cookie=token,
|
|
users=[
|
|
UserCreate(
|
|
id="user-1",
|
|
email="user1@example.com",
|
|
token_version=2,
|
|
)
|
|
],
|
|
)
|
|
try:
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
await get_current_user_from_request(request)
|
|
finally:
|
|
await session.close()
|
|
await engine.dispose()
|
|
|
|
assert exc_info.value.status_code == 401
|
|
assert exc_info.value.detail["code"] == "token_invalid"
|
|
|
|
@pytest.mark.anyio
|
|
async def test_valid_token_returns_user(self, tmp_path):
|
|
token = create_access_token("user-2", token_version=3)
|
|
request, session, engine = await _make_request(
|
|
tmp_path,
|
|
cookie=token,
|
|
users=[
|
|
UserCreate(
|
|
id="user-2",
|
|
email="user2@example.com",
|
|
token_version=3,
|
|
)
|
|
],
|
|
)
|
|
try:
|
|
user = await get_current_user_from_request(request)
|
|
user_id = await get_current_user_id(request)
|
|
finally:
|
|
await session.close()
|
|
await engine.dispose()
|
|
|
|
assert user.id == "user-2"
|
|
assert user.email == "user2@example.com"
|
|
assert user_id == "user-2"
|
|
|
|
@pytest.mark.anyio
|
|
async def test_optional_user_returns_none_on_failure(self, tmp_path):
|
|
request, session, engine = await _make_request(tmp_path, cookie="bad-token")
|
|
try:
|
|
user = await get_optional_user_from_request(request)
|
|
finally:
|
|
await session.close()
|
|
await engine.dispose()
|
|
|
|
assert user is None
|