forked from innovacion/searchbox
This commit renames the package from vector-search-mcp to searchbox. The package imports and executable name are updated accordingly.
164 lines
4.2 KiB
Python
164 lines
4.2 KiB
Python
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import pytest
|
|
from qdrant_client import models
|
|
|
|
from searchbox.engine import get_engine
|
|
from searchbox.models import Match, MatchAny, MatchExclude, SearchRow
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def clear_engine_cache():
|
|
"""Clear the engine cache before each test for proper isolation"""
|
|
get_engine.cache_clear()
|
|
yield
|
|
get_engine.cache_clear()
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_qdrant_client():
|
|
"""Create a mock Qdrant client for testing"""
|
|
client = AsyncMock()
|
|
|
|
# Default search response
|
|
client.search.return_value = [
|
|
models.ScoredPoint(
|
|
id=1,
|
|
score=0.95,
|
|
payload={"text": "Test document 1", "category": "test"},
|
|
version=1,
|
|
),
|
|
models.ScoredPoint(
|
|
id=2,
|
|
score=0.85,
|
|
payload={"text": "Test document 2", "category": "test"},
|
|
version=1,
|
|
),
|
|
]
|
|
|
|
return client
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_settings():
|
|
"""Create mock settings for testing"""
|
|
settings = MagicMock()
|
|
settings.url = "http://localhost:6333"
|
|
settings.api_key = "test_api_key"
|
|
return settings
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_embedding():
|
|
"""Provide a sample embedding vector for testing"""
|
|
return [0.1, 0.2, 0.3, 0.4, 0.5]
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_conditions():
|
|
"""Provide sample conditions for testing"""
|
|
return [
|
|
Match(key="category", value="document"),
|
|
MatchAny(key="tags", any=["python", "rust"]),
|
|
MatchExclude(key="status", exclude=["deleted"]),
|
|
]
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_scored_points():
|
|
"""Provide sample ScoredPoint objects for testing"""
|
|
return [
|
|
models.ScoredPoint(
|
|
id=1,
|
|
score=0.95,
|
|
payload={"text": "First document", "category": "tech"},
|
|
version=1,
|
|
),
|
|
models.ScoredPoint(
|
|
id=2,
|
|
score=0.87,
|
|
payload={"text": "Second document", "category": "science"},
|
|
version=1,
|
|
),
|
|
models.ScoredPoint(
|
|
id=3,
|
|
score=0.75,
|
|
payload=None, # This should be filtered out
|
|
version=1,
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_search_rows():
|
|
"""Provide sample SearchRow objects for testing"""
|
|
return [
|
|
SearchRow(
|
|
chunk_id="1",
|
|
score=0.95,
|
|
payload={"text": "First document", "category": "tech"},
|
|
),
|
|
SearchRow(
|
|
chunk_id="2",
|
|
score=0.87,
|
|
payload={"text": "Second document", "category": "science"},
|
|
),
|
|
]
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_qdrant_engine_dependencies():
|
|
"""Mock all external dependencies for QdrantEngine"""
|
|
with (
|
|
patch("vector_search_mcp.engine.qdrant_engine.Settings") as mock_settings_class,
|
|
patch(
|
|
"vector_search_mcp.engine.qdrant_engine.AsyncQdrantClient"
|
|
) as mock_client_class,
|
|
):
|
|
# Setup mock settings
|
|
mock_settings = MagicMock()
|
|
mock_settings.url = "http://localhost:6333"
|
|
mock_settings.api_key = "test_api_key"
|
|
mock_settings_class.return_value = mock_settings
|
|
|
|
# Setup mock client
|
|
mock_client = AsyncMock()
|
|
mock_client_class.return_value = mock_client
|
|
|
|
yield {
|
|
"settings_class": mock_settings_class,
|
|
"client_class": mock_client_class,
|
|
"settings": mock_settings,
|
|
"client": mock_client,
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def qdrant_filter_single():
|
|
"""Create a single-condition Qdrant filter for testing"""
|
|
return models.Filter(
|
|
must=[
|
|
models.FieldCondition(
|
|
key="category", match=models.MatchValue(value="document")
|
|
)
|
|
]
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def qdrant_filter_multiple():
|
|
"""Create a multi-condition Qdrant filter for testing"""
|
|
return models.Filter(
|
|
must=[
|
|
models.FieldCondition(
|
|
key="category", match=models.MatchValue(value="document")
|
|
),
|
|
models.FieldCondition(
|
|
key="tags", match=models.MatchAny(any=["python", "rust"])
|
|
),
|
|
models.FieldCondition(
|
|
key="status", match=models.MatchExcept(**{"except": ["deleted"]})
|
|
),
|
|
]
|
|
)
|