Skip to main content
Glama

Wikipedia MCP Server

test_server_tools.py20.2 kB
""" Comprehensive tests for Wikipedia MCP server tools. """ import pytest from unittest.mock import Mock, patch, MagicMock from wikipedia_mcp.server import create_server from wikipedia_mcp.wikipedia_client import WikipediaClient class TestWikipediaClient: """Test the WikipediaClient class.""" def setup_method(self): """Set up test fixtures.""" self.client = WikipediaClient() @patch('wikipedia_mcp.wikipedia_client.requests.get') def test_search_success(self, mock_get): """Test successful search operation.""" # Mock API response mock_response = Mock() mock_response.raise_for_status.return_value = None mock_response.json.return_value = { 'query': { 'search': [ { 'title': 'Python (programming language)', 'snippet': 'Python is a programming language', 'pageid': 12345, 'wordcount': 1000, 'timestamp': '2023-01-01T00:00:00Z' } ] } } mock_get.return_value = mock_response # Test search results = self.client.search('Python', limit=1) # Assertions assert len(results) == 1 assert results[0]['title'] == 'Python (programming language)' assert results[0]['snippet'] == 'Python is a programming language' assert results[0]['pageid'] == 12345 mock_get.assert_called_once() @patch('wikipedia_mcp.wikipedia_client.requests.get') def test_search_failure(self, mock_get): """Test search operation with API failure.""" mock_get.side_effect = Exception("API Error") results = self.client.search('Python') assert results == [] @patch('wikipedia_mcp.wikipedia_client.WikipediaClient._extract_sections') def test_get_article_success(self, mock_extract_sections): """Test successful article retrieval.""" # Mock Wikipedia page mock_page = Mock() mock_page.exists.return_value = True mock_page.title = 'Python (programming language)' mock_page.pageid = 12345 mock_page.summary = 'Python is a programming language' mock_page.text = 'Full article text here' mock_page.fullurl = 'https://en.wikipedia.org/wiki/Python_(programming_language)' mock_page.categories = {'Category:Programming languages': None} mock_page.links = {'Link1': None, 'Link2': None} mock_page.sections = [] mock_extract_sections.return_value = [{'title': 'History', 'level': 0, 'text': 'History text', 'sections': []}] with patch.object(self.client.wiki, 'page', return_value=mock_page): article = self.client.get_article('Python (programming language)') assert article['exists'] is True assert article['title'] == 'Python (programming language)' assert article['pageid'] == 12345 assert article['summary'] == 'Python is a programming language' assert article['text'] == 'Full article text here' assert len(article['categories']) == 1 assert len(article['links']) == 2 def test_get_article_not_found(self): """Test article retrieval for non-existent page.""" mock_page = Mock() mock_page.exists.return_value = False with patch.object(self.client.wiki, 'page', return_value=mock_page): article = self.client.get_article('NonExistentPage') assert article['exists'] is False assert article['error'] == 'Page does not exist' def test_get_summary_success(self): """Test successful summary retrieval.""" mock_page = Mock() mock_page.exists.return_value = True mock_page.summary = 'This is a test summary' with patch.object(self.client.wiki, 'page', return_value=mock_page): summary = self.client.get_summary('Test Page') assert summary == 'This is a test summary' def test_get_summary_not_found(self): """Test summary retrieval for non-existent page.""" mock_page = Mock() mock_page.exists.return_value = False with patch.object(self.client.wiki, 'page', return_value=mock_page): summary = self.client.get_summary('NonExistentPage') assert "No Wikipedia article found for 'NonExistentPage'" in summary @patch('wikipedia_mcp.wikipedia_client.WikipediaClient._extract_sections') def test_get_sections_success(self, mock_extract_sections): """Test successful sections retrieval.""" mock_page = Mock() mock_page.exists.return_value = True mock_page.sections = [] mock_extract_sections.return_value = [ {'title': 'History', 'level': 0, 'text': 'History text', 'sections': []}, {'title': 'Features', 'level': 0, 'text': 'Features text', 'sections': []} ] with patch.object(self.client.wiki, 'page', return_value=mock_page): sections = self.client.get_sections('Test Page') assert len(sections) == 2 assert sections[0]['title'] == 'History' assert sections[1]['title'] == 'Features' def test_get_sections_not_found(self): """Test sections retrieval for non-existent page.""" mock_page = Mock() mock_page.exists.return_value = False with patch.object(self.client.wiki, 'page', return_value=mock_page): sections = self.client.get_sections('NonExistentPage') assert sections == [] def test_get_links_success(self): """Test successful links retrieval.""" mock_page = Mock() mock_page.exists.return_value = True mock_page.links = {'Link1': None, 'Link2': None, 'Link3': None} with patch.object(self.client.wiki, 'page', return_value=mock_page): links = self.client.get_links('Test Page') assert len(links) == 3 assert 'Link1' in links assert 'Link2' in links assert 'Link3' in links def test_get_links_not_found(self): """Test links retrieval for non-existent page.""" mock_page = Mock() mock_page.exists.return_value = False with patch.object(self.client.wiki, 'page', return_value=mock_page): links = self.client.get_links('NonExistentPage') assert links == [] def test_get_related_topics_success(self): """Test successful related topics retrieval.""" mock_page = Mock() mock_page.exists.return_value = True mock_page.links = {'Related Link 1': None, 'Related Link 2': None} mock_page.categories = {'Category:Test Category': None} # Mock related page mock_related_page = Mock() mock_related_page.exists.return_value = True mock_related_page.summary = 'Summary of related page' mock_related_page.fullurl = 'https://en.wikipedia.org/wiki/Related_Link_1' with patch.object(self.client.wiki, 'page') as mock_wiki_page: mock_wiki_page.side_effect = lambda title: mock_related_page if title in ['Related Link 1', 'Related Link 2'] else mock_page related = self.client.get_related_topics('Test Page', limit=3) assert len(related) >= 1 assert any(topic['type'] == 'link' for topic in related) def test_get_related_topics_not_found(self): """Test related topics retrieval for non-existent page.""" mock_page = Mock() mock_page.exists.return_value = False with patch.object(self.client.wiki, 'page', return_value=mock_page): related = self.client.get_related_topics('NonExistentPage') assert related == [] def test_extract_sections(self): """Test section extraction helper method.""" # Mock section structure mock_subsection = Mock() mock_subsection.title = 'Subsection' mock_subsection.text = 'Subsection text' mock_subsection.sections = [] mock_section = Mock() mock_section.title = 'Main Section' mock_section.text = 'Main section text' mock_section.sections = [mock_subsection] sections = self.client._extract_sections([mock_section]) assert len(sections) == 1 assert sections[0]['title'] == 'Main Section' assert sections[0]['level'] == 0 assert sections[0]['text'] == 'Main section text' assert len(sections[0]['sections']) == 1 assert sections[0]['sections'][0]['title'] == 'Subsection' assert sections[0]['sections'][0]['level'] == 1 def test_summarize_for_query_success(self): """Test successful query-focused summary retrieval.""" mock_page = Mock() mock_page.exists.return_value = True mock_page.title = 'Test Page' mock_page.text = 'This is a long text about a specific keyword. We want to find this keyword and summarize around it.' mock_page.summary = 'This is a general summary.' with patch.object(self.client.wiki, 'page', return_value=mock_page): summary = self.client.summarize_for_query('Test Page', 'keyword', max_length=50) assert 'keyword' in summary assert len(summary) <= 50 + 3 # for "..." def test_summarize_for_query_not_found(self): """Test query-focused summary when query is not in text.""" mock_page = Mock() mock_page.exists.return_value = True mock_page.title = 'Test Page' mock_page.text = 'This is some other text.' mock_page.summary = 'A general summary content.' with patch.object(self.client.wiki, 'page', return_value=mock_page): summary = self.client.summarize_for_query('Test Page', 'missing_keyword', max_length=30) assert 'A general summary content.'[:30] in summary # Should return start of summary def test_summarize_for_query_page_not_exists(self): """Test query-focused summary when page does not exist.""" mock_page = Mock() mock_page.exists.return_value = False with patch.object(self.client.wiki, 'page', return_value=mock_page): summary = self.client.summarize_for_query('NonExistent Page', 'keyword') assert "No Wikipedia article found for 'NonExistent Page'" in summary def test_summarize_section_success(self): """Test successful section summary retrieval.""" mock_section_target = Mock() mock_section_target.title = 'Target Section' mock_section_target.text = 'This is the text of the target section. It is fairly long.' mock_section_target.sections = [] mock_page = Mock() mock_page.exists.return_value = True mock_page.title = 'Test Page' mock_page.sections = [mock_section_target] with patch.object(self.client.wiki, 'page', return_value=mock_page): summary = self.client.summarize_section('Test Page', 'Target Section', max_length=20) assert summary == 'This is the text of ...' assert len(summary) <= 20 + 3 def test_summarize_section_not_found(self): """Test section summary when section does not exist.""" mock_other_section = Mock() mock_other_section.title = 'Other Section' mock_other_section.text = 'Some text.' mock_other_section.sections = [] mock_page = Mock() mock_page.exists.return_value = True mock_page.title = 'Test Page' mock_page.sections = [mock_other_section] with patch.object(self.client.wiki, 'page', return_value=mock_page): summary = self.client.summarize_section('Test Page', 'Missing Section') assert "Section 'Missing Section' not found or is empty" in summary def test_summarize_section_page_not_exists(self): """Test section summary when page does not exist.""" mock_page = Mock() mock_page.exists.return_value = False with patch.object(self.client.wiki, 'page', return_value=mock_page): summary = self.client.summarize_section('NonExistent Page', 'Any Section') assert "No Wikipedia article found for 'NonExistent Page'" in summary def test_extract_facts_success_from_summary(self): """Test successful fact extraction from page summary.""" mock_page = Mock() mock_page.exists.return_value = True mock_page.title = 'Test Page' mock_page.summary = 'Fact one. Fact two. Fact three. Fact four. Fact five. Fact six.' mock_page.sections = [] with patch.object(self.client.wiki, 'page', return_value=mock_page): facts = self.client.extract_facts('Test Page', count=3) assert len(facts) == 3 assert facts[0] == 'Fact one.' assert facts[1] == 'Fact two.' assert facts[2] == 'Fact three.' def test_extract_facts_success_from_section(self): """Test successful fact extraction from a specific section.""" mock_target_section = Mock() mock_target_section.title = 'Key Info' mock_target_section.text = 'Important fact A. Important fact B. Important fact C.' mock_target_section.sections = [] mock_page = Mock() mock_page.exists.return_value = True mock_page.title = 'Test Page' mock_page.summary = 'General summary.' mock_page.sections = [mock_target_section] with patch.object(self.client.wiki, 'page', return_value=mock_page): facts = self.client.extract_facts('Test Page', topic_within_article='Key Info', count=2) assert len(facts) == 2 assert facts[0] == 'Important fact A.' assert facts[1] == 'Important fact B.' def test_extract_facts_section_not_found_fallback_to_summary(self): """Test fact extraction falls back to summary if section not found.""" mock_page = Mock() mock_page.exists.return_value = True mock_page.title = 'Test Page' mock_page.summary = 'Summary fact 1. Summary fact 2.' mock_page.sections = [] # No sections defined with patch.object(self.client.wiki, 'page', return_value=mock_page): facts = self.client.extract_facts('Test Page', topic_within_article='Missing Section', count=1) assert len(facts) == 1 assert facts[0] == 'Summary fact 1.' def test_extract_facts_page_not_exists(self): """Test fact extraction when page does not exist.""" mock_page = Mock() mock_page.exists.return_value = False with patch.object(self.client.wiki, 'page', return_value=mock_page): facts = self.client.extract_facts('NonExistent Page') assert len(facts) == 1 assert "No Wikipedia article found for 'NonExistent Page'" in facts[0] def test_extract_facts_no_content(self): """Test fact extraction when there is no summary or section text.""" mock_page = Mock() mock_page.exists.return_value = True mock_page.title = 'Empty Page' mock_page.summary = '' # Empty summary mock_page.sections = [] with patch.object(self.client.wiki, 'page', return_value=mock_page): facts = self.client.extract_facts('Empty Page') assert len(facts) == 1 assert "No content found to extract facts from." in facts[0] class TestMCPServerTools: """Test the MCP server tools.""" def setup_method(self): """Set up test fixtures.""" self.server = create_server() @patch('wikipedia_mcp.server.WikipediaClient') def test_create_server_with_language(self, MockWikipediaClient): """Test that create_server initializes WikipediaClient with the specified language.""" create_server(language="ja") MockWikipediaClient.assert_called_once_with(language="ja", country=None, enable_cache=False, access_token=None) @patch('wikipedia_mcp.server.WikipediaClient') def test_create_server_default_language(self, MockWikipediaClient): """Test that create_server uses 'en' if no language is specified.""" create_server() MockWikipediaClient.assert_called_once_with(language="en", country=None, enable_cache=False, access_token=None) @patch('wikipedia_mcp.server.WikipediaClient') def test_create_server_with_cache_enabled(self, MockWikipediaClient): """Test that create_server initializes WikipediaClient with caching enabled.""" create_server(language="en", enable_cache=True) MockWikipediaClient.assert_called_once_with(language="en", country=None, enable_cache=True, access_token=None) @patch('wikipedia_mcp.server.WikipediaClient') def test_create_server_with_cache_disabled(self, MockWikipediaClient): """Test that create_server initializes WikipediaClient with caching disabled by default.""" create_server(language="en", enable_cache=False) MockWikipediaClient.assert_called_once_with(language="en", country=None, enable_cache=False, access_token=None) def test_search_wikipedia_tool(self): """Test search_wikipedia tool registration.""" # Test that server can be created without errors server = create_server() assert server is not None assert server.name == "Wikipedia" def test_get_article_tool(self): """Test get_article tool registration.""" server = create_server() assert server is not None assert server.name == "Wikipedia" def test_get_summary_tool(self): """Test get_summary tool registration.""" server = create_server() assert server is not None assert server.name == "Wikipedia" def test_get_sections_tool(self): """Test get_sections tool registration.""" server = create_server() assert server is not None assert server.name == "Wikipedia" def test_get_links_tool(self): """Test get_links tool registration.""" server = create_server() assert server is not None assert server.name == "Wikipedia" def test_get_related_topics_tool(self): """Test get_related_topics tool registration.""" server = create_server() assert server is not None assert server.name == "Wikipedia" class TestIntegration: """Integration tests for the complete system.""" def test_server_creation(self): """Test that server can be created without errors.""" server = create_server() assert server is not None assert server.name == "Wikipedia" def test_client_initialization(self): """Test that client can be initialized with different languages.""" client_en = WikipediaClient("en") assert client_en.original_language == "en" assert client_en.base_language == "en" assert client_en.language_variant is None client_es = WikipediaClient("es") assert client_es.original_language == "es" assert client_es.base_language == "es" assert client_es.language_variant is None @pytest.mark.integration def test_real_wikipedia_search(self): """Integration test with real Wikipedia API (marked as integration).""" client = WikipediaClient() results = client.search("Python programming", limit=1) # This test requires internet connection if results: # Only assert if we got results (network dependent) assert len(results) >= 1 assert 'title' in results[0] assert 'snippet' in results[0] @pytest.mark.integration def test_real_wikipedia_summary(self): """Integration test for real summary retrieval.""" client = WikipediaClient() summary = client.get_summary("Python (programming language)") # This test requires internet connection if "Error" not in summary and "No Wikipedia article found" not in summary: assert len(summary) > 0 assert isinstance(summary, str) if __name__ == "__main__": pytest.main([__file__, "-v"])

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/Rudra-ravi/wikipedia-mcp'

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