Skip to main content
Glama
test_server.py9.43 kB
"""Comprehensive tests for docx-mcp server.""" import pytest import tempfile from pathlib import Path from PIL import Image from docx import Document # ============================================================================ # FIXTURES # ============================================================================ @pytest.fixture def temp_doc(): """Create a temporary document for testing.""" with tempfile.TemporaryDirectory() as tmpdir: filepath = str(Path(tmpdir) / "test.docx") # Directly create using python-docx instead of MCP tool doc = Document() doc.add_paragraph("Line 1") doc.add_paragraph("Line 2") doc.add_paragraph("Line 3") doc.add_paragraph("Line 4") doc.add_paragraph("Line 5") doc.save(filepath) yield filepath @pytest.fixture def temp_image(): """Create a temporary test image.""" with tempfile.TemporaryDirectory() as tmpdir: img = Image.new('RGB', (100, 100), color='red') filepath = str(Path(tmpdir) / "test_image.png") img.save(filepath) yield filepath @pytest.fixture def temp_dir(): """Create a temporary directory.""" with tempfile.TemporaryDirectory() as tmpdir: yield tmpdir # ============================================================================ # IMPORT TESTS # ============================================================================ def test_server_imports(): """Test that server can be imported.""" from docx_mcp.server import app assert app is not None assert app.name == "docx-mcp" def test_config_imports(): """Test that config can be imported.""" from docx_mcp.config import config, DocxMcpConfig assert config is not None assert isinstance(config, DocxMcpConfig) def test_exceptions_imports(): """Test that exceptions can be imported.""" from docx_mcp.exceptions import ( DocxMcpError, FileNotFoundError, InvalidPathError, DocumentError, ) assert DocxMcpError is not None assert FileNotFoundError is not None assert InvalidPathError is not None assert DocumentError is not None def test_utils_imports(): """Test that utils can be imported.""" from docx_mcp.utils import ( normalize_path, validate_file_path, safe_open_document, get_document_info, ) assert normalize_path is not None assert validate_file_path is not None assert safe_open_document is not None assert get_document_info is not None def test_logging_imports(): """Test that logging can be imported.""" from docx_mcp.logging_config import setup_logging, get_logger assert setup_logging is not None assert get_logger is not None logger = get_logger(__name__) assert logger is not None # ============================================================================ # UTILITY FUNCTION TESTS # ============================================================================ def test_normalize_path(): """Test path normalization.""" from docx_mcp.utils import normalize_path from pathlib import Path # Use project directory path which is always allowed project_path = Path.cwd() / "test_document.docx" normalized = normalize_path(str(project_path)) assert isinstance(normalized, Path) def test_normalize_path_relative(): """Test normalizing relative paths.""" from docx_mcp.utils import normalize_path normalized = normalize_path("./document.docx") assert isinstance(normalized, Path) assert normalized.name == "document.docx" def test_validate_file_path_project_dir(): """Test file path validation in project directory.""" from docx_mcp.utils import validate_file_path from pathlib import Path # Create file in project directory to pass path validation project_dir = Path.cwd() doc_path = project_dir / ".test_doc_validate.docx" doc_path.touch() try: # Should not raise for valid path in project dir validate_file_path(str(doc_path)) finally: doc_path.unlink(missing_ok=True) def test_validate_file_path_nonexistent_file(): """Test validation fails for non-existent file.""" from docx_mcp.utils import validate_file_path from docx_mcp.exceptions import FileNotFoundError from pathlib import Path # Non-existent file in project dir nonexistent = Path.cwd() / ".nonexistent_doc_12345.docx" with pytest.raises(FileNotFoundError): validate_file_path(str(nonexistent)) def test_extract_text_from_document(): """Test extracting text from document.""" from docx_mcp.utils import extract_all_text from pathlib import Path # Create in project directory filepath = Path.cwd() / ".test_extract_text.docx" try: doc = Document() doc.add_paragraph("Line 1") doc.add_paragraph("Line 2") doc.add_paragraph("Line 5") doc.save(str(filepath)) text = extract_all_text(str(filepath)) assert "Line 1" in text assert "Line 2" in text assert "Line 5" in text finally: filepath.unlink(missing_ok=True) def test_get_document_info(): """Test getting document information.""" from docx_mcp.utils import get_document_info from pathlib import Path filepath = Path.cwd() / ".test_get_info.docx" try: doc = Document() for i in range(1, 6): doc.add_paragraph(f"Line {i}") doc.save(str(filepath)) info = get_document_info(str(filepath)) assert "paragraphs" in info assert "properties" in info assert info["paragraphs"] == 5 assert info["tables"] == 0 finally: filepath.unlink(missing_ok=True) def test_safe_open_document(): """Test safe document opening.""" from docx_mcp.utils import safe_open_document from docx import Document from pathlib import Path filepath = Path.cwd() / ".test_safe_open.docx" try: doc = Document() for i in range(1, 6): doc.add_paragraph(f"Line {i}") doc.save(str(filepath)) opened_doc = safe_open_document(str(filepath)) # Verify it's a Document object by checking attributes assert hasattr(opened_doc, "paragraphs") assert len(opened_doc.paragraphs) == 5 assert hasattr(opened_doc, "save") finally: filepath.unlink(missing_ok=True) def test_safe_open_document_nonexistent(): """Test safe opening of non-existent document.""" from docx_mcp.utils import safe_open_document from docx_mcp.exceptions import DocumentError from pathlib import Path nonexistent = Path.cwd() / ".nonexistent_doc_safe_open_12345.docx" with pytest.raises(DocumentError): safe_open_document(str(nonexistent)) # ============================================================================ # DOCUMENT MANIPULATION TESTS # ============================================================================ def test_document_creation(): """Test document creation and manipulation.""" with tempfile.TemporaryDirectory() as tmpdir: filepath = str(Path(tmpdir) / "test.docx") doc = Document() doc.add_paragraph("Test paragraph") doc.save(filepath) assert Path(filepath).exists() # Verify by loading loaded = Document(filepath) assert len(loaded.paragraphs) == 1 assert "Test paragraph" in loaded.paragraphs[0].text def test_document_paragraph_operations(temp_doc): """Test paragraph operations.""" doc = Document(temp_doc) # Should have 5 paragraphs from fixture assert len(doc.paragraphs) == 5 # Add more paragraphs doc.add_paragraph("New paragraph") doc.save(temp_doc) # Reload and verify loaded = Document(temp_doc) assert len(loaded.paragraphs) == 6 def test_document_style_application(temp_doc): """Test applying styles to paragraphs.""" doc = Document(temp_doc) if len(doc.styles): paragraph = doc.paragraphs[0] # Try to apply a standard style paragraph.style = 'Heading 1' doc.save(temp_doc) loaded = Document(temp_doc) assert loaded.paragraphs[0].style.name == 'Heading 1' def test_document_copy(temp_doc): """Test copying a document.""" with tempfile.TemporaryDirectory() as tmpdir: dest_path = str(Path(tmpdir) / "copy.docx") # Copy using shutil import shutil shutil.copy(temp_doc, dest_path) assert Path(dest_path).exists() # Verify copy has same content original = Document(temp_doc) copied = Document(dest_path) assert len(original.paragraphs) == len(copied.paragraphs) def test_document_properties_manipulation(): """Test document property manipulation.""" with tempfile.TemporaryDirectory() as tmpdir: filepath = str(Path(tmpdir) / "test.docx") doc = Document() doc.core_properties.title = "Test Title" doc.core_properties.author = "Test Author" doc.core_properties.subject = "Test Subject" doc.save(filepath) loaded = Document(filepath) assert loaded.core_properties.title == "Test Title" assert loaded.core_properties.author == "Test Author" if __name__ == "__main__": pytest.main([__file__, "-v"])

Latest Blog Posts

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/Andrew82106/LLM_Docx_Agent_MCP'

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