"""Tests for VectorStore port — verify the protocol contract is implementable.""" from __future__ import annotations import pytest from domain.ports import VectorStore from domain.vector_schema import IndexedChunk, SearchResult class FakeVectorStore: """Minimal concrete implementation to verify the protocol is implementable.""" async def ensure_index(self, index_name: str, mapping: dict) -> None: pass async def index_chunks(self, index_name: str, chunks: list[IndexedChunk]) -> int: return len(chunks) async def search_similar( self, index_name: str, embedding: list[float], *, k: int = 10, doc_id: str | None = None, ) -> list[SearchResult]: return [] async def get_chunks( self, index_name: str, doc_id: str, *, limit: int = 1000, ) -> list[SearchResult]: return [] async def delete_document(self, index_name: str, doc_id: str) -> int: return 0 class TestVectorStorePort: def test_fake_satisfies_protocol(self): """A class implementing all methods is accepted as a VectorStore.""" store: VectorStore = FakeVectorStore() assert store is not None @pytest.mark.asyncio async def test_ensure_index(self): store = FakeVectorStore() await store.ensure_index("test-index", {"mappings": {}}) @pytest.mark.asyncio async def test_index_chunks(self): store = FakeVectorStore() chunk = IndexedChunk( doc_id="d1", filename="test.pdf", content="Hello", embedding=[0.1] * 384, chunk_index=0, chunk_type="text", page_number=1, ) count = await store.index_chunks("test-index", [chunk]) assert count == 1 @pytest.mark.asyncio async def test_search_similar(self): store = FakeVectorStore() results = await store.search_similar("test-index", [0.1] * 384, k=5) assert results == [] @pytest.mark.asyncio async def test_search_similar_with_doc_filter(self): store = FakeVectorStore() results = await store.search_similar("test-index", [0.1] * 384, k=5, doc_id="d1") assert results == [] @pytest.mark.asyncio async def test_get_chunks(self): store = FakeVectorStore() results = await store.get_chunks("test-index", "d1") assert results == [] @pytest.mark.asyncio async def test_get_chunks_with_limit(self): store = FakeVectorStore() results = await store.get_chunks("test-index", "d1", limit=50) assert results == [] @pytest.mark.asyncio async def test_delete_document(self): store = FakeVectorStore() count = await store.delete_document("test-index", "d1") assert count == 0 def test_protocol_methods_list(self): """Verify the protocol exposes the expected methods.""" expected = { "ensure_index", "index_chunks", "search_similar", "get_chunks", "delete_document", } protocol_methods = { name for name in dir(VectorStore) if not name.startswith("_") and callable(getattr(VectorStore, name, None)) } assert expected.issubset(protocol_methods)