129 lines
3.9 KiB
Python
129 lines
3.9 KiB
Python
"""
|
|
Tests for Qdrant Multitenant Client.
|
|
|
|
Tests the Qdrant vector database client with tenant isolation.
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, patch, MagicMock
|
|
|
|
from src.clients.qdrant_client import (
|
|
QdrantMultitenant,
|
|
SearchResult,
|
|
get_qdrant_client
|
|
)
|
|
|
|
|
|
class TestQdrantMultitenant:
|
|
"""Tests for QdrantMultitenant class."""
|
|
|
|
@pytest.fixture
|
|
def client(self):
|
|
"""Create a Qdrant client for testing."""
|
|
return QdrantMultitenant(embedding_dim=384)
|
|
|
|
def test_init_defaults(self, client):
|
|
"""Test default initialization."""
|
|
assert client._embedding_dim == 384
|
|
assert client._on_disk is True
|
|
assert client._client is None
|
|
|
|
def test_init_custom_collection(self):
|
|
"""Test custom collection name."""
|
|
client = QdrantMultitenant(collection_name="custom_collection")
|
|
assert client._collection == "custom_collection"
|
|
|
|
@patch('src.clients.qdrant_client.QdrantClient')
|
|
def test_connect_success(self, mock_qdrant_class, client):
|
|
"""Test successful connection."""
|
|
mock_qdrant = MagicMock()
|
|
mock_qdrant.get_collections.return_value = Mock(collections=[])
|
|
mock_qdrant_class.return_value = mock_qdrant
|
|
|
|
result = client.connect()
|
|
|
|
assert result is True
|
|
assert client._client is not None
|
|
|
|
@patch('src.clients.qdrant_client.QdrantClient')
|
|
def test_connect_failure(self, mock_qdrant_class, client):
|
|
"""Test connection failure."""
|
|
mock_qdrant_class.side_effect = Exception("Connection refused")
|
|
|
|
result = client.connect()
|
|
|
|
assert result is False
|
|
assert client._client is None
|
|
|
|
def test_upsert_without_tenant_fails(self, client):
|
|
"""Test upsert fails without tenant_id."""
|
|
client._client = MagicMock()
|
|
|
|
result = client.upsert_document(
|
|
doc_id="doc1",
|
|
content="Test content",
|
|
embedding=[0.1] * 384,
|
|
tenant_id="" # Empty tenant_id
|
|
)
|
|
|
|
assert result is False
|
|
|
|
def test_search_without_tenant_fails(self, client):
|
|
"""Test search fails without tenant_id."""
|
|
client._client = MagicMock()
|
|
|
|
results = client.search(
|
|
query_embedding=[0.1] * 384,
|
|
tenant_id="" # Empty tenant_id - MUST fail
|
|
)
|
|
|
|
assert results == []
|
|
|
|
@patch('src.clients.qdrant_client.QdrantClient')
|
|
def test_upsert_success(self, mock_qdrant_class, client):
|
|
"""Test successful document upsert."""
|
|
mock_qdrant = MagicMock()
|
|
mock_qdrant.get_collections.return_value = Mock(collections=[])
|
|
mock_qdrant_class.return_value = mock_qdrant
|
|
client.connect()
|
|
|
|
result = client.upsert_document(
|
|
doc_id="doc1",
|
|
content="Test document content",
|
|
embedding=[0.1] * 384,
|
|
tenant_id="tenant-001",
|
|
metadata={"technology": "linux"}
|
|
)
|
|
|
|
assert result is True
|
|
mock_qdrant.upsert.assert_called_once()
|
|
|
|
def test_search_result_dataclass(self):
|
|
"""Test SearchResult dataclass."""
|
|
result = SearchResult(
|
|
id="doc1",
|
|
score=0.95,
|
|
content="This is the document content",
|
|
metadata={"technology": "linux"},
|
|
tenant_id="tenant-001"
|
|
)
|
|
|
|
assert result.score == 0.95
|
|
assert result.tenant_id == "tenant-001"
|
|
assert "linux" in result.metadata.get("technology", "")
|
|
|
|
|
|
class TestQdrantSingleton:
|
|
"""Tests for singleton instance."""
|
|
|
|
def test_get_qdrant_client_singleton(self):
|
|
"""Test singleton returns same instance."""
|
|
# Reset singleton
|
|
import src.clients.qdrant_client as module
|
|
module._qdrant_client = None
|
|
|
|
client1 = get_qdrant_client()
|
|
client2 = get_qdrant_client()
|
|
|
|
assert client1 is client2
|