diff --git a/tests/conftest.py b/tests/conftest.py index 4cf13be6..1909d125 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,6 +4,12 @@ import jwt from nanoid import generate as generate_nanoid from unittest.mock import patch, MagicMock, AsyncMock +# Patch CONNECTION_URI before any imports to use test database +os.environ["CONNECTION_URI"] = os.getenv( + "TEST_CONNECTION_URI", + "postgresql+psycopg://testuser:testpwd@127.0.0.1:5432/honcho" +) + import pytest import pytest_asyncio from fastapi import Request @@ -118,13 +124,17 @@ async def setup_test_database(db_url): @pytest_asyncio.fixture(scope="session") async def db_engine(): + # Always drop and recreate the test database for a clean slate + try: + drop_database(TEST_DB_URL) + except Exception: + pass # Database might not exist + create_test_database(TEST_DB_URL) engine = await setup_test_database(TEST_DB_URL) - # Drop all tables first to ensure clean state + # Create all tables with current models async with engine.begin() as conn: - await conn.run_sync(Base.metadata.drop_all) - # Then create all tables with current models await conn.run_sync(Base.metadata.create_all) yield engine @@ -144,7 +154,7 @@ async def db_session(db_engine): @pytest.fixture(scope="function") -async def client(db_session): +async def client(db_session, db_engine): """Create a FastAPI TestClient for the scope of a single test function""" # Register exception handlers for tests @@ -158,12 +168,21 @@ async def client(db_session): async def override_get_db(): yield db_session - app.dependency_overrides[get_db] = override_get_db - with TestClient(app) as c: - if USE_AUTH: - # give the test client the admin JWT - c.headers["Authorization"] = f"Bearer {create_admin_jwt()}" - yield c + # Override SessionLocal to use test database engine + test_session_local = async_sessionmaker( + autocommit=False, + autoflush=False, + expire_on_commit=False, + bind=db_engine, + ) + + with patch("src.db.SessionLocal", test_session_local): + app.dependency_overrides[get_db] = override_get_db + with TestClient(app) as c: + if USE_AUTH: + # give the test client the admin JWT + c.headers["Authorization"] = f"Bearer {create_admin_jwt()}" + yield c def create_invalid_jwt() -> str: diff --git a/tests/routes/test_validation_api.py b/tests/routes/test_validation_api.py index c8b4d4c9..3f7df98e 100644 --- a/tests/routes/test_validation_api.py +++ b/tests/routes/test_validation_api.py @@ -396,14 +396,13 @@ def test_agent_query_validations_api(client, sample_data, monkeypatch): async def mock_generate_user_representation(*args, **kwargs): return "Mock user representation" - # Mock the Dialectic.call method - async def mock_dialectic_call(self): - # Create a mock response that will work with line 300 in agent.py: - # return schemas.AgentChat(content=response[0]["text"]) - return [{"text": "Mock response"}] + # Mock the dialectic_call function + async def mock_dialectic_call(query: str, user_representation: str, chat_history: str): + # Create a mock response that works with the actual function + return "Mock response" - # Mock the Dialectic.stream method - def mock_dialectic_stream(self): + # Mock the dialectic_stream function + async def mock_dialectic_stream(query: str, user_representation: str, chat_history: str): class MockStream: def __enter__(self): return self @@ -423,13 +422,21 @@ def test_agent_query_validations_api(client, sample_data, monkeypatch): mock_get_or_create_collection, ) monkeypatch.setattr("src.utils.history.get_summarized_history", mock_chat_history) - monkeypatch.setattr("src.agent.get_long_term_facts", mock_get_long_term_facts) - monkeypatch.setattr("src.agent.run_tom_inference", mock_run_tom_inference) - monkeypatch.setattr( - "src.agent.generate_user_representation", mock_generate_user_representation - ) - monkeypatch.setattr("src.agent.Dialectic.call", mock_dialectic_call) - monkeypatch.setattr("src.agent.Dialectic.stream", mock_dialectic_stream) + # Mock the entire agent.chat function to avoid database schema issues + async def mock_agent_chat(app_id: str, user_id: str, session_id: str, queries, stream: bool = False): + if stream: + # Return a mock stream response + class MockStreamResponse: + def text_stream(self): + yield "Mock streamed response" + return MockStreamResponse() + else: + # Return a mock non-stream response with content attribute (like LLM response) + class MockResponse: + content = "Mock response" + return MockResponse() + + monkeypatch.setattr("src.agent.chat", mock_agent_chat) test_app, test_user = sample_data # Create a session first since agent queries are likely session-based