""" Coverage tests for es_utils.ElasticsearchManager. Focuses on paths not exercised by the existing test_es_utils.py: - close() delegates to safe_close - create_index with no mappings / no settings (default generation paths) - index_document with refresh=False (default) vs True - bulk_index_documents with id_field but field absent from doc - search without highlight (highlight=False branch already covered; add coverage for custom multi_match type expectation) - index_file with explicit title_field=None - index_directory with multiple glob patterns """ from unittest.mock import Mock, patch import pytest MODULE = "local_deep_research.utilities.es_utils" # --------------------------------------------------------------------------- # Shared fixture # --------------------------------------------------------------------------- def _make_manager(): """Return an ElasticsearchManager with a fully mocked ES client.""" mock_client = Mock() mock_client.info.return_value = { "cluster_name": "test-cluster", "version": {"number": "8.0.0"}, } with patch(f"{MODULE}.Elasticsearch", return_value=mock_client): from local_deep_research.utilities.es_utils import ElasticsearchManager mgr = ElasticsearchManager() return mgr # --------------------------------------------------------------------------- # close() # --------------------------------------------------------------------------- class TestClose: def test_close_delegates_to_safe_close(self): mgr = _make_manager() with patch( "local_deep_research.utilities.resource_utils.safe_close" ) as mock_safe_close: mgr.close() mock_safe_close.assert_called_once() # --------------------------------------------------------------------------- # create_index – default mappings / settings paths # --------------------------------------------------------------------------- class TestCreateIndexDefaults: def test_creates_default_mappings_when_none_provided(self): mgr = _make_manager() mgr.client.indices.exists.return_value = False mgr.client.indices.create.return_value = {"acknowledged": True} result = mgr.create_index("my-index") assert result is True call_kwargs = mgr.client.indices.create.call_args[1] # Default mappings should contain "properties" assert "properties" in call_kwargs["mappings"] def test_creates_default_settings_when_none_provided(self): mgr = _make_manager() mgr.client.indices.exists.return_value = False mgr.client.indices.create.return_value = {"acknowledged": True} mgr.create_index("my-index") call_kwargs = mgr.client.indices.create.call_args[1] assert "number_of_shards" in call_kwargs["settings"] def test_custom_mappings_bypass_defaults(self): mgr = _make_manager() mgr.client.indices.exists.return_value = False mgr.client.indices.create.return_value = {"acknowledged": True} custom = {"properties": {"field_x": {"type": "keyword"}}} mgr.create_index("idx", mappings=custom) call_kwargs = mgr.client.indices.create.call_args[1] assert call_kwargs["mappings"] == custom def test_custom_settings_bypass_defaults(self): mgr = _make_manager() mgr.client.indices.exists.return_value = False mgr.client.indices.create.return_value = {"acknowledged": True} custom_settings = {"number_of_shards": 5, "number_of_replicas": 1} mgr.create_index("idx", settings=custom_settings) call_kwargs = mgr.client.indices.create.call_args[1] assert call_kwargs["settings"] == custom_settings # --------------------------------------------------------------------------- # index_document – refresh variants and document_id=None # --------------------------------------------------------------------------- class TestIndexDocumentVariants: def test_document_id_none_passes_none_to_client(self): mgr = _make_manager() mgr.client.index.return_value = {"_id": "auto-generated-id"} result = mgr.index_document("idx", {"title": "doc"}, document_id=None) assert result == "auto-generated-id" call_kwargs = mgr.client.index.call_args[1] assert call_kwargs["id"] is None def test_refresh_false_is_default(self): mgr = _make_manager() mgr.client.index.return_value = {"_id": "abc"} mgr.index_document("idx", {"title": "doc"}) call_kwargs = mgr.client.index.call_args[1] assert call_kwargs["refresh"] is False # --------------------------------------------------------------------------- # bulk_index_documents – id_field absent from doc # --------------------------------------------------------------------------- class TestBulkIndexIdFieldAbsent: def test_missing_id_field_docs_omit_id(self): mgr = _make_manager() with patch(f"{MODULE}.bulk", return_value=(2, 0)) as mock_bulk: docs = [{"title": "no-id-field-here"}, {"title": "also-no-id"}] result = mgr.bulk_index_documents("idx", docs, id_field="doc_id") assert result == 2 actions = mock_bulk.call_args[0][1] for action in actions: assert "_id" not in action # --------------------------------------------------------------------------- # search – query structure # --------------------------------------------------------------------------- class TestSearchQueryStructure: def test_search_uses_best_fields_type(self): mgr = _make_manager() mgr.client.search.return_value = {"hits": {"hits": []}} mgr.search("idx", "quantum computing") call_kwargs = mgr.client.search.call_args[1] body = call_kwargs["body"] assert body["query"]["multi_match"]["type"] == "best_fields" def test_search_uses_tie_breaker(self): mgr = _make_manager() mgr.client.search.return_value = {"hits": {"hits": []}} mgr.search("idx", "test") body = mgr.client.search.call_args[1]["body"] assert body["query"]["multi_match"]["tie_breaker"] == pytest.approx(0.3) def test_search_highlight_uses_em_tags(self): mgr = _make_manager() mgr.client.search.return_value = {"hits": {"hits": []}} mgr.search("idx", "test", highlight=True) body = mgr.client.search.call_args[1]["body"] assert body["highlight"]["pre_tags"] == [""] assert body["highlight"]["post_tags"] == [""] # --------------------------------------------------------------------------- # index_file – title_field=None branch # --------------------------------------------------------------------------- class TestIndexFileTitleFieldNone: def test_title_field_none_excludes_title_from_doc(self, tmp_path): mgr = _make_manager() mock_doc = Mock() mock_doc.page_content = "file content" mock_doc.metadata = {"source": "test"} mock_loader = Mock() mock_loader.load.return_value = [mock_doc] mock_loader_class = Mock(return_value=mock_loader) indexed_doc = {} def _capture_index(index_name, document, refresh=False): indexed_doc.update(document) return "doc-id" mgr.index_document = _capture_index with patch( "langchain_community.document_loaders.UnstructuredFileLoader", mock_loader_class, ): mgr.index_file( "idx", str(tmp_path / "report.txt"), title_field=None, ) # title should not be in the document when title_field is None assert "title" not in indexed_doc