Skip to main content
Glama
brianirish

Laravel 12 Docs MCP Server

by brianirish
conftest.py9.92 kB
"""Pytest configuration and fixtures for Laravel MCP Companion tests.""" import tempfile import json import pytest from pathlib import Path from unittest.mock import MagicMock, patch from typing import Dict, Any, Generator # Import the modules we'll be testing import laravel_mcp_companion import docs_updater from shutdown_handler import GracefulShutdown # Register custom markers to avoid warnings def pytest_configure(config): config.addinivalue_line("markers", "slow: marks tests as slow (deselect with '-m \"not slow\"')") config.addinivalue_line("markers", "integration: marks tests as integration tests") config.addinivalue_line("markers", "unit: marks tests as unit tests") config.addinivalue_line("markers", "network: marks tests that require network access") config.addinivalue_line("markers", "external: marks tests that interact with external services") @pytest.fixture def temp_dir() -> Generator[Path, None, None]: """Create a temporary directory for test files.""" with tempfile.TemporaryDirectory() as tmp_dir: yield Path(tmp_dir) @pytest.fixture def test_docs_dir(temp_dir: Path) -> Path: """Create a test documentation directory structure.""" docs_dir = temp_dir / "docs" docs_dir.mkdir() # Create version directories for version in ["11.x", "12.x"]: version_dir = docs_dir / version version_dir.mkdir() # Create sample markdown files (version_dir / "installation.md").write_text(f"# Installation\n\nLaravel {version} installation guide.") (version_dir / "routing.md").write_text(f"# Routing\n\nLaravel {version} routing documentation.") (version_dir / "eloquent.md").write_text(f"# Eloquent ORM\n\nEloquent documentation for {version}.") # Create metadata directory and file metadata_dir = version_dir / ".metadata" metadata_dir.mkdir() metadata = { "version": version, "commit_sha": f"abc123{version[-1]}", "commit_date": "2024-01-01T12:00:00Z", "commit_message": f"Update {version} documentation", "commit_url": f"https://github.com/laravel/docs/commit/abc123{version[-1]}", "sync_time": "2024-01-01T12:00:00Z" } (metadata_dir / "sync_info.json").write_text(json.dumps(metadata, indent=2)) return docs_dir @pytest.fixture def test_external_docs_dir(temp_dir: Path) -> Path: """Create a test external documentation directory structure.""" external_dir = temp_dir / "docs" / "external" external_dir.mkdir(parents=True) # Create service directories with sample files services = ["forge", "vapor", "envoyer", "nova"] for service in services: service_dir = external_dir / service service_dir.mkdir() # Create sample documentation files (service_dir / "introduction.md").write_text(f"# {service.title()}\n\nIntroduction to Laravel {service.title()}.") (service_dir / "getting-started.md").write_text(f"# Getting Started\n\nHow to get started with {service.title()}.") # Create cache metadata metadata = { "service": service, "fetched_sections": ["introduction", "getting-started"], "total_sections": 2, "success_rate": 1.0, "discovery_method": "manual configuration", "cached_at": 1704110400.0 # 2024-01-01 12:00:00 } (service_dir / ".cache_metadata.json").write_text(json.dumps(metadata, indent=2)) return external_dir @pytest.fixture def sample_package_catalog() -> Dict[str, Any]: """Sample package catalog for testing.""" return { "laravel/cashier": { "name": "Laravel Cashier", "description": "Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.", "categories": ["payment", "billing", "subscription"], "use_cases": [ "Implementing subscription billing", "Processing one-time payments" ], "installation": "composer require laravel/cashier", "documentation_link": "laravel://packages/cashier.md" }, "laravel/sanctum": { "name": "Laravel Sanctum", "description": "Laravel Sanctum provides a featherweight authentication system for SPAs.", "categories": ["authentication", "api", "security"], "use_cases": [ "Authenticating SPAs", "API token authentication" ], "installation": "composer require laravel/sanctum", "documentation_link": "laravel://authentication/sanctum.md" } } @pytest.fixture def mock_github_api() -> Generator[MagicMock, None, None]: """Mock GitHub API responses.""" with patch('docs_updater.urllib.request.urlopen') as mock_urlopen: # Mock successful API response mock_response = MagicMock() mock_response.read.return_value = json.dumps({ "commit": { "sha": "abc123def456", "commit": { "committer": {"date": "2024-01-01T12:00:00Z"}, "message": "Update documentation" }, "html_url": "https://github.com/laravel/docs/commit/abc123def456" } }).encode() mock_response.__enter__ = lambda self: self mock_response.__exit__ = lambda self, *args: None mock_urlopen.return_value = mock_response yield mock_urlopen @pytest.fixture def mock_file_download() -> Generator[MagicMock, None, None]: """Mock file downloads for testing.""" with patch('docs_updater.urllib.request.urlopen') as mock_urlopen: # Mock successful download mock_response = MagicMock() mock_response.read.return_value = b"Mock file content" mock_response.__enter__ = lambda self: self mock_response.__exit__ = lambda self, *args: None mock_urlopen.return_value = mock_response yield mock_urlopen @pytest.fixture def mock_fastmcp(): """Mock FastMCP for testing tool registration.""" with patch('laravel_mcp_companion.FastMCP') as mock_mcp: mock_instance = MagicMock() mock_mcp.return_value = mock_instance yield mock_instance @pytest.fixture def docs_updater_instance(test_docs_dir: Path) -> docs_updater.DocsUpdater: """Create a DocsUpdater instance for testing.""" return docs_updater.DocsUpdater(test_docs_dir, "12.x") @pytest.fixture def external_docs_fetcher(test_docs_dir: Path) -> docs_updater.ExternalDocsFetcher: """Create an ExternalDocsFetcher instance for testing.""" return docs_updater.ExternalDocsFetcher(test_docs_dir) @pytest.fixture def multi_source_updater(test_docs_dir: Path) -> docs_updater.MultiSourceDocsUpdater: """Create a MultiSourceDocsUpdater instance for testing.""" return docs_updater.MultiSourceDocsUpdater(test_docs_dir, "12.x") @pytest.fixture def shutdown_handler() -> GracefulShutdown: """Create a GracefulShutdown instance for testing.""" return GracefulShutdown() @pytest.fixture def mock_logger(): """Mock logger for testing.""" return MagicMock() @pytest.fixture(autouse=True) def clear_caches(): """Clear all caches before each test.""" # Import mcp_tools for cache clearing import mcp_tools # Clear mcp_tools caches mcp_tools.clear_caches() # Clear main module caches if they exist if hasattr(laravel_mcp_companion, '_file_content_cache'): laravel_mcp_companion._file_content_cache.clear() if hasattr(laravel_mcp_companion, '_search_result_cache'): laravel_mcp_companion._search_result_cache.clear() # Clear function cache if it exists if hasattr(laravel_mcp_companion, 'get_file_content_cached') and hasattr(laravel_mcp_companion.get_file_content_cached, 'cache_clear'): laravel_mcp_companion.get_file_content_cached.cache_clear() yield # Clear caches after test mcp_tools.clear_caches() if hasattr(laravel_mcp_companion, '_file_content_cache'): laravel_mcp_companion._file_content_cache.clear() if hasattr(laravel_mcp_companion, '_search_result_cache'): laravel_mcp_companion._search_result_cache.clear() if hasattr(laravel_mcp_companion, 'get_file_content_cached') and hasattr(laravel_mcp_companion.get_file_content_cached, 'cache_clear'): laravel_mcp_companion.get_file_content_cached.cache_clear() @pytest.fixture def sample_html_content() -> str: """Sample HTML content for testing HTML processing.""" return """ <!DOCTYPE html> <html> <head><title>Laravel Documentation</title></head> <body> <main> <h1>Laravel Installation</h1> <p>Welcome to Laravel! This guide will help you install Laravel.</p> <h2>Requirements</h2> <ul> <li>PHP >= 8.1</li> <li>Composer</li> </ul> <h2>Installation Steps</h2> <ol> <li>Run <code>composer create-project laravel/laravel myapp</code></li> <li>Navigate to your project: <code>cd myapp</code></li> <li>Start the development server: <code>php artisan serve</code></li> </ol> </main> </body> </html> """ # Mock environment variables for consistent testing @pytest.fixture(autouse=True) def setup_test_environment(monkeypatch): """Set up test environment variables.""" monkeypatch.setenv("PYTEST_RUNNING", "1") # Ensure we don't accidentally hit real APIs during tests monkeypatch.setenv("GITHUB_API_URL", "http://mock-api.test")

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/brianirish/laravel-docs-mcp'

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