Skip to main content
Glama

MCP Outline Server

by Vortiago
test_document_search.py11.3 kB
""" Tests for document search tools. """ from unittest.mock import MagicMock, patch import pytest from mcp_outline.features.documents.common import OutlineClientError from mcp_outline.features.documents.document_search import ( _format_collection_documents, _format_collections, _format_documents_list, _format_search_results, ) # Mock FastMCP for registering tools class MockMCP: def __init__(self): self.tools = {} def tool(self): def decorator(func): self.tools[func.__name__] = func return func return decorator # Sample test data SAMPLE_SEARCH_RESULTS = [ { "document": { "id": "doc1", "title": "Test Document 1" }, "context": "This is a test document." }, { "document": { "id": "doc2", "title": "Test Document 2" }, "context": "Another test document." } ] SAMPLE_DOCUMENTS = [ { "id": "doc1", "title": "Test Document 1", "updatedAt": "2023-01-01T12:00:00Z" }, { "id": "doc2", "title": "Test Document 2", "updatedAt": "2023-01-02T12:00:00Z" } ] SAMPLE_COLLECTIONS = [ { "id": "coll1", "name": "Test Collection 1", "description": "Collection description" }, { "id": "coll2", "name": "Test Collection 2", "description": "" } ] SAMPLE_COLLECTION_DOCUMENTS = [ { "id": "doc1", "title": "Root Document", "children": [ { "id": "doc2", "title": "Child Document", "children": [] } ] } ] class TestDocumentSearchFormatters: """Tests for document search formatting functions.""" def test_format_search_results_with_data(self): """Test formatting search results with valid data.""" result = _format_search_results(SAMPLE_SEARCH_RESULTS) # Verify the result contains the expected information assert "# Search Results" in result assert "Test Document 1" in result assert "doc1" in result assert "This is a test document." in result assert "Test Document 2" in result def test_format_search_results_empty(self): """Test formatting empty search results.""" result = _format_search_results([]) assert "No documents found" in result def test_format_documents_list_with_data(self): """Test formatting document list with valid data.""" result = _format_documents_list(SAMPLE_DOCUMENTS, "Document List") # Verify the result contains the expected information assert "# Document List" in result assert "Test Document 1" in result assert "doc1" in result assert "2023-01-01" in result assert "Test Document 2" in result def test_format_collections_with_data(self): """Test formatting collections with valid data.""" result = _format_collections(SAMPLE_COLLECTIONS) # Verify the result contains the expected information assert "# Collections" in result assert "Test Collection 1" in result assert "coll1" in result assert "Collection description" in result assert "Test Collection 2" in result def test_format_collections_empty(self): """Test formatting empty collections list.""" result = _format_collections([]) assert "No collections found" in result def test_format_collection_documents_with_data(self): """Test formatting collection document structure with valid data.""" result = _format_collection_documents(SAMPLE_COLLECTION_DOCUMENTS) # Verify the result contains the expected information assert "# Collection Structure" in result assert "Root Document" in result assert "doc1" in result assert "Child Document" in result assert "doc2" in result def test_format_collection_documents_empty(self): """Test formatting empty collection document structure.""" result = _format_collection_documents([]) assert "No documents found in this collection" in result @pytest.fixture def mcp(): """Fixture to provide mock MCP instance.""" return MockMCP() @pytest.fixture def register_search_tools(mcp): """Fixture to register document search tools.""" from mcp_outline.features.documents.document_search import register_tools register_tools(mcp) return mcp class TestDocumentSearchTools: """Tests for document search tools.""" @patch("mcp_outline.features.documents.document_search.get_outline_client") def test_search_documents_success( self, mock_get_client, register_search_tools ): """Test search_documents tool success case.""" # Set up mock client mock_client = MagicMock() mock_client.search_documents.return_value = SAMPLE_SEARCH_RESULTS mock_get_client.return_value = mock_client # Call the tool result = register_search_tools.tools["search_documents"]("test query") # Verify client was called correctly mock_client.search_documents.assert_called_once_with( "test query", None ) # Verify result contains expected information assert "Test Document 1" in result assert "doc1" in result @patch("mcp_outline.features.documents.document_search.get_outline_client") def test_search_documents_with_collection( self, mock_get_client, register_search_tools ): """Test search_documents tool with collection filter.""" # Set up mock client mock_client = MagicMock() mock_client.search_documents.return_value = SAMPLE_SEARCH_RESULTS mock_get_client.return_value = mock_client # Call the tool _ = register_search_tools.tools["search_documents"]( "test query", "coll1" ) # Verify client was called correctly mock_client.search_documents.assert_called_once_with( "test query", "coll1") @patch("mcp_outline.features.documents.document_search.get_outline_client") def test_search_documents_client_error( self, mock_get_client, register_search_tools ): """Test search_documents tool with client error.""" # Set up mock client to raise an error mock_client = MagicMock() mock_client.search_documents.side_effect = OutlineClientError( "API error") mock_get_client.return_value = mock_client # Call the tool result = register_search_tools.tools["search_documents"]("test query") # Verify error is handled and returned assert "Error searching documents" in result assert "API error" in result @patch("mcp_outline.features.documents.document_search.get_outline_client") def test_list_collections_success( self, mock_get_client, register_search_tools ): """Test list_collections tool success case.""" # Set up mock client mock_client = MagicMock() mock_client.list_collections.return_value = SAMPLE_COLLECTIONS mock_get_client.return_value = mock_client # Call the tool result = register_search_tools.tools["list_collections"]() # Verify client was called correctly mock_client.list_collections.assert_called_once() # Verify result contains expected information assert "Test Collection 1" in result assert "coll1" in result @patch("mcp_outline.features.documents.document_search.get_outline_client") def test_get_collection_structure_success( self, mock_get_client, register_search_tools ): """Test get_collection_structure tool success case.""" # Set up mock client mock_client = MagicMock() mock_client.get_collection_documents.return_value = ( SAMPLE_COLLECTION_DOCUMENTS) mock_get_client.return_value = mock_client # Call the tool result = register_search_tools.tools[ "get_collection_structure"]("coll1") # Verify client was called correctly mock_client.get_collection_documents.assert_called_once_with("coll1") # Verify result contains expected information assert "Root Document" in result assert "Child Document" in result @patch("mcp_outline.features.documents.document_search.get_outline_client") def test_get_document_id_from_title_exact_match( self, mock_get_client, register_search_tools ): """Test get_document_id_from_title tool with exact match.""" # Search results with exact title match exact_match_results = [ { "document": { "id": "doc1", "title": "Exact Match" } } ] # Set up mock client mock_client = MagicMock() mock_client.search_documents.return_value = exact_match_results mock_get_client.return_value = mock_client # Call the tool result = register_search_tools.tools["get_document_id_from_title"]( "Exact Match" ) # Verify client was called correctly mock_client.search_documents.assert_called_once_with( "Exact Match", None) # Verify result contains expected information assert "Document ID: doc1" in result assert "Exact Match" in result @patch("mcp_outline.features.documents.document_search.get_outline_client") def test_get_document_id_from_title_best_match( self, mock_get_client, register_search_tools ): """Test get_document_id_from_title tool with best match (non-exact).""" # Set up mock client mock_client = MagicMock() mock_client.search_documents.return_value = SAMPLE_SEARCH_RESULTS mock_get_client.return_value = mock_client # Call the tool with title that doesn't exactly match result = register_search_tools.tools[ "get_document_id_from_title"]("Test Doc") # Verify result contains expected information assert "Best match" in result assert "doc1" in result @patch("mcp_outline.features.documents.document_search.get_outline_client") def test_get_document_id_from_title_no_results( self, mock_get_client, register_search_tools ): """Test get_document_id_from_title tool with no results.""" # Set up mock client mock_client = MagicMock() mock_client.search_documents.return_value = [] mock_get_client.return_value = mock_client # Call the tool result = register_search_tools.tools[ "get_document_id_from_title"]("Nonexistent") # Verify result contains expected information assert "No documents found" in result assert "Nonexistent" in result

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Vortiago/mcp-outline'

If you have feedback or need assistance with the MCP directory API, please join our Discord server