"""Tests for DocumentationResourceManager."""
import pytest
from pathlib import Path
from mkdocs_mcp.resources import DocumentationResourceManager
from mcp.types import TextContent
class TestDocumentationResourceManager:
"""Test cases for DocumentationResourceManager."""
@pytest.fixture
def resource_manager(self, temp_docs_dir: Path) -> DocumentationResourceManager:
"""Create a resource manager instance for testing."""
return DocumentationResourceManager(temp_docs_dir)
@pytest.fixture
def empty_resource_manager(self, empty_docs_dir: Path) -> DocumentationResourceManager:
"""Create a resource manager for an empty directory."""
return DocumentationResourceManager(empty_docs_dir)
async def test_list_resources(self, resource_manager: DocumentationResourceManager):
"""Test listing all documentation resources."""
resources = await resource_manager.list_resources()
# Should find all .md files
assert len(resources) == 4 # index.md, installation.md, configuration.md, reference.md
# Check that URIs are properly formatted
uris = [r.uri for r in resources]
assert "docs://index.md" in uris
assert "docs://getting-started/installation.md" in uris
assert "docs://getting-started/configuration.md" in uris
assert "docs://api/reference.md" in uris
# Check that resources have proper metadata
for resource in resources:
assert resource.name
assert resource.description
assert resource.mimeType == "text/markdown"
async def test_list_resources_empty_dir(self, empty_resource_manager: DocumentationResourceManager):
"""Test listing resources from an empty directory."""
resources = await empty_resource_manager.list_resources()
assert len(resources) == 0
async def test_read_resource(self, resource_manager: DocumentationResourceManager):
"""Test reading a documentation resource."""
content = await resource_manager.read_resource("docs://index.md")
assert isinstance(content, TextContent)
assert content.type == "text"
assert "# Home Page" in content.text
assert "Welcome to our documentation" in content.text
# Check that frontmatter is included
assert "title: Home Page" in content.text
async def test_read_resource_with_subdirectory(self, resource_manager: DocumentationResourceManager):
"""Test reading a resource from a subdirectory."""
content = await resource_manager.read_resource("docs://getting-started/installation.md")
assert isinstance(content, TextContent)
assert "# Installation" in content.text
assert "python --version" in content.text
async def test_read_nonexistent_resource(self, resource_manager: DocumentationResourceManager):
"""Test reading a resource that doesn't exist."""
with pytest.raises(FileNotFoundError):
await resource_manager.read_resource("docs://nonexistent.md")
async def test_read_invalid_uri(self, resource_manager: DocumentationResourceManager):
"""Test reading with an invalid URI format."""
with pytest.raises(ValueError, match="Invalid URI scheme"):
await resource_manager.read_resource("http://example.com/file.md")
def test_uri_to_path(self, resource_manager: DocumentationResourceManager):
"""Test converting URI to file path."""
# Test basic URI
path = resource_manager._uri_to_path("docs://index.md")
assert path.name == "index.md"
# Test URI with subdirectory
path = resource_manager._uri_to_path("docs://getting-started/installation.md")
assert path.name == "installation.md"
assert path.parent.name == "getting-started"
# Test invalid scheme
with pytest.raises(ValueError, match="Invalid URI scheme"):
resource_manager._uri_to_path("http://example.com/file.md")
def test_path_to_uri(self, resource_manager: DocumentationResourceManager):
"""Test converting file path to URI."""
# Test basic file
file_path = resource_manager.docs_path / "index.md"
uri = resource_manager._path_to_uri(file_path)
assert uri == "docs://index.md"
# Test file in subdirectory
file_path = resource_manager.docs_path / "getting-started" / "installation.md"
uri = resource_manager._path_to_uri(file_path)
assert uri == "docs://getting-started/installation.md"
async def test_create_resource_with_frontmatter(self, temp_docs_dir: Path):
"""Test creating resource from file with frontmatter."""
resource_manager = DocumentationResourceManager(temp_docs_dir)
# Test with index.md which has frontmatter
index_path = temp_docs_dir / "index.md"
resource = await resource_manager._create_resource(index_path)
assert resource.name == "Home Page" # From frontmatter title
assert resource.description == "Welcome to our documentation" # From frontmatter description
assert resource.uri == "docs://index.md"
async def test_create_resource_without_frontmatter(self, temp_docs_dir: Path):
"""Test creating resource from file without frontmatter."""
resource_manager = DocumentationResourceManager(temp_docs_dir)
# Test with configuration.md which has no frontmatter
config_path = temp_docs_dir / "getting-started" / "configuration.md"
resource = await resource_manager._create_resource(config_path)
assert resource.name == "Configuration" # Extracted from # Configuration
assert resource.uri == "docs://getting-started/configuration.md"
async def test_resource_caching(self, resource_manager: DocumentationResourceManager):
"""Test that resources are properly cached."""
# First call should populate cache
resources1 = await resource_manager.list_resources()
# Check cache is populated
assert len(resource_manager._resource_cache) == 4
# Second call should return same results
resources2 = await resource_manager.list_resources()
assert len(resources1) == len(resources2)
# Resources should be the same (by URI)
uris1 = {r.uri for r in resources1}
uris2 = {r.uri for r in resources2}
assert uris1 == uris2