quick adding (not working)

This commit is contained in:
2026-01-12 20:41:04 +01:00
parent 743bed67f3
commit d371fb77cf
6 changed files with 1710 additions and 1 deletions

309
tests/conftest.py Normal file
View 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)