This commit is contained in:
Yaojia Wang
2026-02-01 18:51:54 +01:00
parent 4126196dea
commit a564ac9d70
82 changed files with 13123 additions and 3282 deletions

View File

@@ -8,80 +8,80 @@ from unittest.mock import MagicMock, patch
from fastapi import HTTPException
from inference.data.admin_db import AdminDB
from inference.data.repositories import TokenRepository
from inference.data.admin_models import AdminToken
from inference.web.core.auth import (
get_admin_db,
reset_admin_db,
get_token_repository,
reset_token_repository,
validate_admin_token,
)
@pytest.fixture
def mock_admin_db():
"""Create a mock AdminDB."""
db = MagicMock(spec=AdminDB)
db.is_valid_admin_token.return_value = True
return db
def mock_token_repo():
"""Create a mock TokenRepository."""
repo = MagicMock(spec=TokenRepository)
repo.is_valid.return_value = True
return repo
@pytest.fixture(autouse=True)
def reset_db():
"""Reset admin DB after each test."""
def reset_repo():
"""Reset token repository after each test."""
yield
reset_admin_db()
reset_token_repository()
class TestValidateAdminToken:
"""Tests for validate_admin_token dependency."""
def test_missing_token_raises_401(self, mock_admin_db):
def test_missing_token_raises_401(self, mock_token_repo):
"""Test that missing token raises 401."""
import asyncio
with pytest.raises(HTTPException) as exc_info:
asyncio.get_event_loop().run_until_complete(
validate_admin_token(None, mock_admin_db)
validate_admin_token(None, mock_token_repo)
)
assert exc_info.value.status_code == 401
assert "Admin token required" in exc_info.value.detail
def test_invalid_token_raises_401(self, mock_admin_db):
def test_invalid_token_raises_401(self, mock_token_repo):
"""Test that invalid token raises 401."""
import asyncio
mock_admin_db.is_valid_admin_token.return_value = False
mock_token_repo.is_valid.return_value = False
with pytest.raises(HTTPException) as exc_info:
asyncio.get_event_loop().run_until_complete(
validate_admin_token("invalid-token", mock_admin_db)
validate_admin_token("invalid-token", mock_token_repo)
)
assert exc_info.value.status_code == 401
assert "Invalid or expired" in exc_info.value.detail
def test_valid_token_returns_token(self, mock_admin_db):
def test_valid_token_returns_token(self, mock_token_repo):
"""Test that valid token is returned."""
import asyncio
token = "valid-test-token"
mock_admin_db.is_valid_admin_token.return_value = True
mock_token_repo.is_valid.return_value = True
result = asyncio.get_event_loop().run_until_complete(
validate_admin_token(token, mock_admin_db)
validate_admin_token(token, mock_token_repo)
)
assert result == token
mock_admin_db.update_admin_token_usage.assert_called_once_with(token)
mock_token_repo.update_usage.assert_called_once_with(token)
class TestAdminDB:
"""Tests for AdminDB operations."""
class TestTokenRepository:
"""Tests for TokenRepository operations."""
def test_is_valid_admin_token_active(self):
def test_is_valid_active_token(self):
"""Test valid active token."""
with patch("inference.data.admin_db.get_session_context") as mock_ctx:
with patch("inference.data.repositories.token_repository.BaseRepository._session") as mock_ctx:
mock_session = MagicMock()
mock_ctx.return_value.__enter__.return_value = mock_session
@@ -93,12 +93,12 @@ class TestAdminDB:
)
mock_session.get.return_value = mock_token
db = AdminDB()
assert db.is_valid_admin_token("test-token") is True
repo = TokenRepository()
assert repo.is_valid("test-token") is True
def test_is_valid_admin_token_inactive(self):
def test_is_valid_inactive_token(self):
"""Test inactive token."""
with patch("inference.data.admin_db.get_session_context") as mock_ctx:
with patch("inference.data.repositories.token_repository.BaseRepository._session") as mock_ctx:
mock_session = MagicMock()
mock_ctx.return_value.__enter__.return_value = mock_session
@@ -110,12 +110,12 @@ class TestAdminDB:
)
mock_session.get.return_value = mock_token
db = AdminDB()
assert db.is_valid_admin_token("test-token") is False
repo = TokenRepository()
assert repo.is_valid("test-token") is False
def test_is_valid_admin_token_expired(self):
def test_is_valid_expired_token(self):
"""Test expired token."""
with patch("inference.data.admin_db.get_session_context") as mock_ctx:
with patch("inference.data.repositories.token_repository.BaseRepository._session") as mock_ctx:
mock_session = MagicMock()
mock_ctx.return_value.__enter__.return_value = mock_session
@@ -127,36 +127,38 @@ class TestAdminDB:
)
mock_session.get.return_value = mock_token
db = AdminDB()
assert db.is_valid_admin_token("test-token") is False
repo = TokenRepository()
# Need to also mock _now() to ensure proper comparison
with patch.object(repo, "_now", return_value=datetime.utcnow()):
assert repo.is_valid("test-token") is False
def test_is_valid_admin_token_not_found(self):
def test_is_valid_token_not_found(self):
"""Test token not found."""
with patch("inference.data.admin_db.get_session_context") as mock_ctx:
with patch("inference.data.repositories.token_repository.BaseRepository._session") as mock_ctx:
mock_session = MagicMock()
mock_ctx.return_value.__enter__.return_value = mock_session
mock_session.get.return_value = None
db = AdminDB()
assert db.is_valid_admin_token("nonexistent") is False
repo = TokenRepository()
assert repo.is_valid("nonexistent") is False
class TestGetAdminDb:
"""Tests for get_admin_db function."""
class TestGetTokenRepository:
"""Tests for get_token_repository function."""
def test_returns_singleton(self):
"""Test that get_admin_db returns singleton."""
reset_admin_db()
"""Test that get_token_repository returns singleton."""
reset_token_repository()
db1 = get_admin_db()
db2 = get_admin_db()
repo1 = get_token_repository()
repo2 = get_token_repository()
assert db1 is db2
assert repo1 is repo2
def test_reset_clears_singleton(self):
"""Test that reset clears singleton."""
db1 = get_admin_db()
reset_admin_db()
db2 = get_admin_db()
repo1 = get_token_repository()
reset_token_repository()
repo2 = get_token_repository()
assert db1 is not db2
assert repo1 is not repo2