quick adding (not working)
This commit is contained in:
309
tests/conftest.py
Normal file
309
tests/conftest.py
Normal file
@@ -0,0 +1,309 @@
|
||||
"""Pytest configuration and fixtures for the test suite."""
|
||||
|
||||
import asyncio
|
||||
from datetime import datetime, timezone
|
||||
from typing import AsyncGenerator, Generator
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from sqlalchemy import event
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||
from sqlalchemy.pool import StaticPool
|
||||
|
||||
from daemon_boyfriend.config import Settings
|
||||
from daemon_boyfriend.models.base import Base
|
||||
|
||||
# --- Event Loop Fixture ---
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def event_loop() -> Generator[asyncio.AbstractEventLoop, None, None]:
|
||||
"""Create an event loop for the test session."""
|
||||
loop = asyncio.new_event_loop()
|
||||
yield loop
|
||||
loop.close()
|
||||
|
||||
|
||||
# --- Database Fixtures ---
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def async_engine():
|
||||
"""Create an async SQLite engine for testing."""
|
||||
engine = create_async_engine(
|
||||
"sqlite+aiosqlite:///:memory:",
|
||||
connect_args={"check_same_thread": False},
|
||||
poolclass=StaticPool,
|
||||
echo=False,
|
||||
)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
|
||||
yield engine
|
||||
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.drop_all)
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def db_session(async_engine) -> AsyncGenerator[AsyncSession, None]:
|
||||
"""Create a database session for testing."""
|
||||
async_session_maker = async_sessionmaker(
|
||||
async_engine,
|
||||
class_=AsyncSession,
|
||||
expire_on_commit=False,
|
||||
)
|
||||
|
||||
async with async_session_maker() as session:
|
||||
yield session
|
||||
await session.rollback()
|
||||
|
||||
|
||||
# --- Mock Settings Fixture ---
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_settings() -> Settings:
|
||||
"""Create mock settings for testing."""
|
||||
with patch.dict(
|
||||
"os.environ",
|
||||
{
|
||||
"DISCORD_TOKEN": "test_token",
|
||||
"AI_PROVIDER": "openai",
|
||||
"AI_MODEL": "gpt-4o-mini",
|
||||
"OPENAI_API_KEY": "test_openai_key",
|
||||
"ANTHROPIC_API_KEY": "test_anthropic_key",
|
||||
"GEMINI_API_KEY": "test_gemini_key",
|
||||
"OPENROUTER_API_KEY": "test_openrouter_key",
|
||||
"BOT_NAME": "TestBot",
|
||||
"BOT_PERSONALITY": "helpful and friendly",
|
||||
"DATABASE_URL": "",
|
||||
"LIVING_AI_ENABLED": "true",
|
||||
"MOOD_ENABLED": "true",
|
||||
"RELATIONSHIP_ENABLED": "true",
|
||||
},
|
||||
):
|
||||
return Settings()
|
||||
|
||||
|
||||
# --- Mock Discord Fixtures ---
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_discord_user() -> MagicMock:
|
||||
"""Create a mock Discord user."""
|
||||
user = MagicMock()
|
||||
user.id = 123456789
|
||||
user.name = "TestUser"
|
||||
user.display_name = "Test User"
|
||||
user.mention = "<@123456789>"
|
||||
user.bot = False
|
||||
return user
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_discord_message(mock_discord_user) -> MagicMock:
|
||||
"""Create a mock Discord message."""
|
||||
message = MagicMock()
|
||||
message.author = mock_discord_user
|
||||
message.content = "Hello, bot!"
|
||||
message.channel = MagicMock()
|
||||
message.channel.id = 987654321
|
||||
message.channel.send = AsyncMock()
|
||||
message.channel.typing = MagicMock(return_value=AsyncMock())
|
||||
message.guild = MagicMock()
|
||||
message.guild.id = 111222333
|
||||
message.guild.name = "Test Guild"
|
||||
message.id = 555666777
|
||||
message.mentions = []
|
||||
return message
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_discord_bot() -> MagicMock:
|
||||
"""Create a mock Discord bot."""
|
||||
bot = MagicMock()
|
||||
bot.user = MagicMock()
|
||||
bot.user.id = 999888777
|
||||
bot.user.name = "TestBot"
|
||||
bot.user.mentioned_in = MagicMock(return_value=True)
|
||||
return bot
|
||||
|
||||
|
||||
# --- Mock AI Provider Fixtures ---
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_ai_response() -> MagicMock:
|
||||
"""Create a mock AI response."""
|
||||
from daemon_boyfriend.services.providers.base import AIResponse
|
||||
|
||||
return AIResponse(
|
||||
content="This is a test response from the AI.",
|
||||
model="test-model",
|
||||
usage={"prompt_tokens": 10, "completion_tokens": 20, "total_tokens": 30},
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_openai_client() -> MagicMock:
|
||||
"""Create a mock OpenAI client."""
|
||||
client = MagicMock()
|
||||
|
||||
response = MagicMock()
|
||||
response.choices = [MagicMock()]
|
||||
response.choices[0].message.content = "Test OpenAI response"
|
||||
response.model = "gpt-4o-mini"
|
||||
response.usage = MagicMock()
|
||||
response.usage.prompt_tokens = 10
|
||||
response.usage.completion_tokens = 20
|
||||
response.usage.total_tokens = 30
|
||||
|
||||
client.chat.completions.create = AsyncMock(return_value=response)
|
||||
return client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_anthropic_client() -> MagicMock:
|
||||
"""Create a mock Anthropic client."""
|
||||
client = MagicMock()
|
||||
|
||||
response = MagicMock()
|
||||
response.content = [MagicMock()]
|
||||
response.content[0].type = "text"
|
||||
response.content[0].text = "Test Anthropic response"
|
||||
response.model = "claude-sonnet-4-20250514"
|
||||
response.usage = MagicMock()
|
||||
response.usage.input_tokens = 10
|
||||
response.usage.output_tokens = 20
|
||||
|
||||
client.messages.create = AsyncMock(return_value=response)
|
||||
return client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_gemini_client() -> MagicMock:
|
||||
"""Create a mock Gemini client."""
|
||||
client = MagicMock()
|
||||
|
||||
response = MagicMock()
|
||||
response.text = "Test Gemini response"
|
||||
response.usage_metadata = MagicMock()
|
||||
response.usage_metadata.prompt_token_count = 10
|
||||
response.usage_metadata.candidates_token_count = 20
|
||||
response.usage_metadata.total_token_count = 30
|
||||
|
||||
client.aio.models.generate_content = AsyncMock(return_value=response)
|
||||
return client
|
||||
|
||||
|
||||
# --- Model Fixtures ---
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_user(db_session: AsyncSession):
|
||||
"""Create a sample user in the database."""
|
||||
from daemon_boyfriend.models import User
|
||||
|
||||
user = User(
|
||||
discord_id=123456789,
|
||||
discord_username="testuser",
|
||||
discord_display_name="Test User",
|
||||
)
|
||||
db_session.add(user)
|
||||
await db_session.commit()
|
||||
await db_session.refresh(user)
|
||||
return user
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_user_with_facts(db_session: AsyncSession, sample_user):
|
||||
"""Create a sample user with facts."""
|
||||
from daemon_boyfriend.models import UserFact
|
||||
|
||||
facts = [
|
||||
UserFact(
|
||||
user_id=sample_user.id,
|
||||
fact_type="hobby",
|
||||
fact_content="likes programming",
|
||||
confidence=1.0,
|
||||
source="explicit",
|
||||
),
|
||||
UserFact(
|
||||
user_id=sample_user.id,
|
||||
fact_type="preference",
|
||||
fact_content="prefers dark mode",
|
||||
confidence=0.8,
|
||||
source="conversation",
|
||||
),
|
||||
]
|
||||
|
||||
for fact in facts:
|
||||
db_session.add(fact)
|
||||
|
||||
await db_session.commit()
|
||||
return sample_user
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_conversation(db_session: AsyncSession, sample_user):
|
||||
"""Create a sample conversation."""
|
||||
from daemon_boyfriend.models import Conversation
|
||||
|
||||
conversation = Conversation(
|
||||
user_id=sample_user.id,
|
||||
guild_id=111222333,
|
||||
channel_id=987654321,
|
||||
)
|
||||
db_session.add(conversation)
|
||||
await db_session.commit()
|
||||
await db_session.refresh(conversation)
|
||||
return conversation
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_bot_state(db_session: AsyncSession):
|
||||
"""Create a sample bot state."""
|
||||
from daemon_boyfriend.models import BotState
|
||||
|
||||
bot_state = BotState(
|
||||
guild_id=111222333,
|
||||
mood_valence=0.5,
|
||||
mood_arousal=0.3,
|
||||
)
|
||||
db_session.add(bot_state)
|
||||
await db_session.commit()
|
||||
await db_session.refresh(bot_state)
|
||||
return bot_state
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def sample_user_relationship(db_session: AsyncSession, sample_user):
|
||||
"""Create a sample user relationship."""
|
||||
from daemon_boyfriend.models import UserRelationship
|
||||
|
||||
relationship = UserRelationship(
|
||||
user_id=sample_user.id,
|
||||
guild_id=111222333,
|
||||
relationship_score=50.0,
|
||||
total_interactions=10,
|
||||
positive_interactions=8,
|
||||
negative_interactions=1,
|
||||
)
|
||||
db_session.add(relationship)
|
||||
await db_session.commit()
|
||||
await db_session.refresh(relationship)
|
||||
return relationship
|
||||
|
||||
|
||||
# --- Utility Fixtures ---
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def utc_now() -> datetime:
|
||||
"""Get current UTC time."""
|
||||
return datetime.now(timezone.utc)
|
||||
Reference in New Issue
Block a user