WIP
This commit is contained in:
162
tests/web/test_admin_auth.py
Normal file
162
tests/web/test_admin_auth.py
Normal file
@@ -0,0 +1,162 @@
|
||||
"""
|
||||
Tests for Admin Authentication.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from datetime import datetime, timedelta
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from fastapi import HTTPException
|
||||
|
||||
from src.data.admin_db import AdminDB
|
||||
from src.data.admin_models import AdminToken
|
||||
from src.web.core.auth import (
|
||||
get_admin_db,
|
||||
reset_admin_db,
|
||||
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
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_db():
|
||||
"""Reset admin DB after each test."""
|
||||
yield
|
||||
reset_admin_db()
|
||||
|
||||
|
||||
class TestValidateAdminToken:
|
||||
"""Tests for validate_admin_token dependency."""
|
||||
|
||||
def test_missing_token_raises_401(self, mock_admin_db):
|
||||
"""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)
|
||||
)
|
||||
|
||||
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):
|
||||
"""Test that invalid token raises 401."""
|
||||
import asyncio
|
||||
|
||||
mock_admin_db.is_valid_admin_token.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)
|
||||
)
|
||||
|
||||
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):
|
||||
"""Test that valid token is returned."""
|
||||
import asyncio
|
||||
|
||||
token = "valid-test-token"
|
||||
mock_admin_db.is_valid_admin_token.return_value = True
|
||||
|
||||
result = asyncio.get_event_loop().run_until_complete(
|
||||
validate_admin_token(token, mock_admin_db)
|
||||
)
|
||||
|
||||
assert result == token
|
||||
mock_admin_db.update_admin_token_usage.assert_called_once_with(token)
|
||||
|
||||
|
||||
class TestAdminDB:
|
||||
"""Tests for AdminDB operations."""
|
||||
|
||||
def test_is_valid_admin_token_active(self):
|
||||
"""Test valid active token."""
|
||||
with patch("src.data.admin_db.get_session_context") as mock_ctx:
|
||||
mock_session = MagicMock()
|
||||
mock_ctx.return_value.__enter__.return_value = mock_session
|
||||
|
||||
mock_token = AdminToken(
|
||||
token="test-token",
|
||||
name="Test",
|
||||
is_active=True,
|
||||
expires_at=None,
|
||||
)
|
||||
mock_session.get.return_value = mock_token
|
||||
|
||||
db = AdminDB()
|
||||
assert db.is_valid_admin_token("test-token") is True
|
||||
|
||||
def test_is_valid_admin_token_inactive(self):
|
||||
"""Test inactive token."""
|
||||
with patch("src.data.admin_db.get_session_context") as mock_ctx:
|
||||
mock_session = MagicMock()
|
||||
mock_ctx.return_value.__enter__.return_value = mock_session
|
||||
|
||||
mock_token = AdminToken(
|
||||
token="test-token",
|
||||
name="Test",
|
||||
is_active=False,
|
||||
expires_at=None,
|
||||
)
|
||||
mock_session.get.return_value = mock_token
|
||||
|
||||
db = AdminDB()
|
||||
assert db.is_valid_admin_token("test-token") is False
|
||||
|
||||
def test_is_valid_admin_token_expired(self):
|
||||
"""Test expired token."""
|
||||
with patch("src.data.admin_db.get_session_context") as mock_ctx:
|
||||
mock_session = MagicMock()
|
||||
mock_ctx.return_value.__enter__.return_value = mock_session
|
||||
|
||||
mock_token = AdminToken(
|
||||
token="test-token",
|
||||
name="Test",
|
||||
is_active=True,
|
||||
expires_at=datetime.utcnow() - timedelta(days=1),
|
||||
)
|
||||
mock_session.get.return_value = mock_token
|
||||
|
||||
db = AdminDB()
|
||||
assert db.is_valid_admin_token("test-token") is False
|
||||
|
||||
def test_is_valid_admin_token_not_found(self):
|
||||
"""Test token not found."""
|
||||
with patch("src.data.admin_db.get_session_context") 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
|
||||
|
||||
|
||||
class TestGetAdminDb:
|
||||
"""Tests for get_admin_db function."""
|
||||
|
||||
def test_returns_singleton(self):
|
||||
"""Test that get_admin_db returns singleton."""
|
||||
reset_admin_db()
|
||||
|
||||
db1 = get_admin_db()
|
||||
db2 = get_admin_db()
|
||||
|
||||
assert db1 is db2
|
||||
|
||||
def test_reset_clears_singleton(self):
|
||||
"""Test that reset clears singleton."""
|
||||
db1 = get_admin_db()
|
||||
reset_admin_db()
|
||||
db2 = get_admin_db()
|
||||
|
||||
assert db1 is not db2
|
||||
Reference in New Issue
Block a user