mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 13:47:19 +08:00
225 lines
7.0 KiB
Python
225 lines
7.0 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
from uuid import UUID
|
|
|
|
import pytest
|
|
from server.auth.token_manager import KeycloakUserInfo
|
|
from server.constants import ORG_SETTINGS_VERSION
|
|
from server.verified_models.verified_model_service import (
|
|
StoredVerifiedModel, # noqa: F401
|
|
)
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.ext.asyncio import (
|
|
AsyncSession,
|
|
async_sessionmaker,
|
|
create_async_engine,
|
|
)
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
# Anything not loaded here may not have a table created for it.
|
|
from storage.api_key import ApiKey # noqa: F401
|
|
from storage.base import Base
|
|
from storage.billing_session import BillingSession
|
|
from storage.conversation_work import ConversationWork
|
|
from storage.device_code import DeviceCode # noqa: F401
|
|
from storage.feedback import Feedback
|
|
from storage.github_app_installation import GithubAppInstallation
|
|
from storage.org import Org
|
|
from storage.org_invitation import OrgInvitation # noqa: F401
|
|
from storage.org_member import OrgMember
|
|
from storage.role import Role
|
|
from storage.slack_conversation import SlackConversation # noqa: F401
|
|
from storage.stored_conversation_metadata import StoredConversationMetadata
|
|
from storage.stored_conversation_metadata_saas import (
|
|
StoredConversationMetadataSaas,
|
|
)
|
|
from storage.stored_offline_token import StoredOfflineToken
|
|
from storage.stripe_customer import StripeCustomer
|
|
from storage.user import User
|
|
|
|
|
|
@pytest.fixture
|
|
def create_keycloak_user_info():
|
|
"""Fixture that returns a factory function to create KeycloakUserInfo models.
|
|
|
|
Usage:
|
|
def test_example(create_keycloak_user_info):
|
|
user_info = create_keycloak_user_info(sub='user123', email='test@example.com')
|
|
"""
|
|
|
|
def _create(**kwargs) -> KeycloakUserInfo:
|
|
defaults = {
|
|
'sub': 'test_user_id',
|
|
'preferred_username': 'test_user',
|
|
}
|
|
defaults.update(kwargs)
|
|
return KeycloakUserInfo(**defaults)
|
|
|
|
return _create
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
def db_path(tmp_path):
|
|
"""Create a unique temp file path for each test."""
|
|
return str(tmp_path / 'test.db')
|
|
|
|
|
|
@pytest.fixture
|
|
def engine(db_path):
|
|
"""Create a sync engine with tables using file-based DB."""
|
|
engine = create_engine(
|
|
f'sqlite:///{db_path}', connect_args={'check_same_thread': False}
|
|
)
|
|
Base.metadata.create_all(engine)
|
|
return engine
|
|
|
|
|
|
@pytest.fixture
|
|
def session_maker(engine):
|
|
return sessionmaker(bind=engine)
|
|
|
|
|
|
@pytest.fixture
|
|
def async_engine(db_path):
|
|
"""Create an async engine using the SAME file-based database."""
|
|
async_engine = create_async_engine(
|
|
f'sqlite+aiosqlite:///{db_path}',
|
|
connect_args={'check_same_thread': False},
|
|
)
|
|
|
|
async def create_tables():
|
|
async with async_engine.begin() as conn:
|
|
await conn.run_sync(Base.metadata.create_all)
|
|
|
|
# Run the async function synchronously
|
|
import asyncio
|
|
|
|
asyncio.run(create_tables())
|
|
return async_engine
|
|
|
|
|
|
@pytest.fixture
|
|
async def async_session_maker(async_engine):
|
|
"""Create an async session maker bound to the async engine."""
|
|
async_session_maker = async_sessionmaker(
|
|
bind=async_engine,
|
|
class_=AsyncSession,
|
|
expire_on_commit=False,
|
|
)
|
|
return async_session_maker
|
|
|
|
|
|
def add_minimal_fixtures(session_maker):
|
|
with session_maker() as session:
|
|
session.add(
|
|
BillingSession(
|
|
id='mock-billing-session-id',
|
|
user_id='mock-user-id',
|
|
status='completed',
|
|
price=20,
|
|
price_code='NA',
|
|
created_at=datetime.fromisoformat('2025-03-03'),
|
|
updated_at=datetime.fromisoformat('2025-03-04'),
|
|
)
|
|
)
|
|
session.add(
|
|
Feedback(
|
|
id='mock-feedback-id',
|
|
version='1.0',
|
|
email='user@all-hands.dev',
|
|
polarity='positive',
|
|
permissions='public',
|
|
trajectory=[],
|
|
)
|
|
)
|
|
session.add(
|
|
GithubAppInstallation(
|
|
installation_id='mock-installation-id',
|
|
encrypted_token='',
|
|
created_at=datetime.fromisoformat('2025-03-05'),
|
|
updated_at=datetime.fromisoformat('2025-03-06'),
|
|
)
|
|
)
|
|
session.add(
|
|
StoredConversationMetadata(
|
|
conversation_id='mock-conversation-id',
|
|
created_at=datetime.fromisoformat('2025-03-07'),
|
|
last_updated_at=datetime.fromisoformat('2025-03-08'),
|
|
accumulated_cost=5.25,
|
|
prompt_tokens=500,
|
|
completion_tokens=250,
|
|
total_tokens=750,
|
|
)
|
|
)
|
|
session.add(
|
|
StoredConversationMetadataSaas(
|
|
conversation_id='mock-conversation-id',
|
|
user_id=UUID('5594c7b6-f959-4b81-92e9-b09c206f5081'),
|
|
org_id=UUID('5594c7b6-f959-4b81-92e9-b09c206f5081'),
|
|
)
|
|
)
|
|
session.add(
|
|
StoredOfflineToken(
|
|
user_id='mock-user-id',
|
|
offline_token='mock-offline-token',
|
|
created_at=datetime.fromisoformat('2025-03-07'),
|
|
updated_at=datetime.fromisoformat('2025-03-08'),
|
|
)
|
|
)
|
|
session.add(
|
|
Org(
|
|
id=uuid.UUID('5594c7b6-f959-4b81-92e9-b09c206f5081'),
|
|
name='mock-org',
|
|
org_version=ORG_SETTINGS_VERSION,
|
|
enable_default_condenser=True,
|
|
enable_proactive_conversation_starters=True,
|
|
)
|
|
)
|
|
session.add(
|
|
Role(
|
|
id=1,
|
|
name='admin',
|
|
rank=1,
|
|
)
|
|
)
|
|
session.add(
|
|
User(
|
|
id=uuid.UUID('5594c7b6-f959-4b81-92e9-b09c206f5081'),
|
|
current_org_id=uuid.UUID('5594c7b6-f959-4b81-92e9-b09c206f5081'),
|
|
user_consents_to_analytics=True,
|
|
)
|
|
)
|
|
session.add(
|
|
OrgMember(
|
|
org_id=uuid.UUID('5594c7b6-f959-4b81-92e9-b09c206f5081'),
|
|
user_id=uuid.UUID('5594c7b6-f959-4b81-92e9-b09c206f5081'),
|
|
role_id=1,
|
|
llm_api_key='mock-api-key',
|
|
status='active',
|
|
)
|
|
)
|
|
session.add(
|
|
StripeCustomer(
|
|
keycloak_user_id='mock-user-id',
|
|
stripe_customer_id='mock-stripe-customer-id',
|
|
created_at=datetime.fromisoformat('2025-03-09'),
|
|
updated_at=datetime.fromisoformat('2025-03-10'),
|
|
)
|
|
)
|
|
session.add(
|
|
ConversationWork(
|
|
conversation_id='mock-conversation-id',
|
|
user_id='mock-user-id',
|
|
created_at=datetime.fromisoformat('2025-03-07'),
|
|
updated_at=datetime.fromisoformat('2025-03-08'),
|
|
)
|
|
)
|
|
session.commit()
|
|
|
|
|
|
@pytest.fixture
|
|
def session_maker_with_minimal_fixtures(engine):
|
|
session_maker = sessionmaker(bind=engine)
|
|
add_minimal_fixtures(session_maker)
|
|
return session_maker
|