fix: linter and unit tests

This commit is contained in:
Daniel Bauer
2025-06-30 11:44:25 +02:00
parent f34d3e6e7c
commit 9901f51f06
4 changed files with 130 additions and 146 deletions

View File

@@ -8,10 +8,10 @@ from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.resources import FunctionResource from mcp.server.fastmcp.resources import FunctionResource
from .client import ( from .client import (
CordraAuthenticationError,
CordraClient, CordraClient,
CordraClientError, CordraClientError,
CordraNotFoundError, CordraNotFoundError,
CordraAuthenticationError,
) )
from .config import CordraConfig from .config import CordraConfig
@@ -52,8 +52,8 @@ async def get_cordra_object(prefix: str, suffix: str) -> str:
except ValueError as e: except ValueError as e:
raise RuntimeError(f"Invalid parameters: {e}") from e raise RuntimeError(f"Invalid parameters: {e}") from e
except CordraNotFoundError: except CordraNotFoundError as e:
raise RuntimeError(f"Object not found: {object_id}") raise RuntimeError(f"Object not found: {object_id}") from e
except CordraAuthenticationError as e: except CordraAuthenticationError as e:
raise RuntimeError(f"Authentication failed: {e}") from e raise RuntimeError(f"Authentication failed: {e}") from e
except CordraClientError as e: except CordraClientError as e:
@@ -66,8 +66,8 @@ async def create_schema_resource(schema_name: str) -> str:
schema_object = await cordra_client.get_schema(schema_name) schema_object = await cordra_client.get_schema(schema_name)
schema_dict = schema_object.model_dump() schema_dict = schema_object.model_dump()
return json.dumps(schema_dict, indent=2) return json.dumps(schema_dict, indent=2)
except CordraNotFoundError: except CordraNotFoundError as e:
raise RuntimeError(f"Schema not found: {schema_name}") raise RuntimeError(f"Schema not found: {schema_name}") from e
except CordraAuthenticationError as e: except CordraAuthenticationError as e:
raise RuntimeError(f"Authentication failed: {e}") from e raise RuntimeError(f"Authentication failed: {e}") from e
except CordraClientError as e: except CordraClientError as e:

View File

@@ -8,7 +8,6 @@ from mcp_cordra.client import (
CordraClient, CordraClient,
CordraClientError, CordraClientError,
CordraNotFoundError, CordraNotFoundError,
CordraAuthenticationError,
DigitalObject, DigitalObject,
) )
from mcp_cordra.config import CordraConfig from mcp_cordra.config import CordraConfig

View File

@@ -145,103 +145,88 @@ class TestGetCordraObject:
assert parsed_result["payloads"] is None assert parsed_result["payloads"] is None
class TestListCordraSchemas: class TestSchemaResourceFunctions:
"""Test the list_cordra_schemas resource handler.""" """Test the schema resource functions."""
@patch('mcp_cordra.server.cordra_client') @patch('mcp_cordra.server.cordra_client')
async def test_list_schemas_success(self, mock_client): async def test_create_schema_resource_success(self, mock_client):
"""Test successful schema listing.""" """Test successful schema resource creation."""
mock_schemas = [ mock_schema = DigitalObject(
{"content": {"name": "User"}, "identifier": "test/user-schema"}, id="test/user-schema",
{"content": {"name": "Project"}, "identifier": "test/project-schema"}, type="Schema",
{"content": {"name": "Document"}, "identifier": "test/doc-schema"}, content={"name": "User", "type": "object", "properties": {}}
{"content": {"name": "CaptureEvent"}, "identifier": "test/capture-schema"} )
] mock_client.get_schema = AsyncMock(return_value=mock_schema)
mock_client.find = AsyncMock(return_value=mock_schemas)
from mcp_cordra.server import list_cordra_schemas from mcp_cordra.server import create_schema_resource
result = await list_cordra_schemas() result = await create_schema_resource("User")
# Verify the result is valid JSON # Verify the result is valid JSON
parsed_result = json.loads(result) parsed_result = json.loads(result)
assert "schemas" in parsed_result assert parsed_result["id"] == "test/user-schema"
assert "count" in parsed_result assert parsed_result["type"] == "Schema"
assert parsed_result["count"] == 4 assert parsed_result["content"]["name"] == "User"
assert "User" in parsed_result["schemas"]
assert "Project" in parsed_result["schemas"] # Verify the client was called with correct schema name
assert "Document" in parsed_result["schemas"] mock_client.get_schema.assert_called_once_with("User")
assert "CaptureEvent" in parsed_result["schemas"]
@patch('mcp_cordra.server.cordra_client')
async def test_create_schema_resource_not_found(self, mock_client):
"""Test schema resource creation with schema not found."""
mock_client.get_schema = AsyncMock(side_effect=CordraNotFoundError("Schema not found"))
from mcp_cordra.server import create_schema_resource
with pytest.raises(RuntimeError) as exc_info:
await create_schema_resource("NonExistent")
assert "Schema not found: NonExistent" in str(exc_info.value)
mock_client.get_schema.assert_called_once_with("NonExistent")
@patch('mcp_cordra.server.cordra_client')
async def test_register_schema_resources_success(self, mock_client):
"""Test successful schema resource registration."""
mock_schemas = [
{"content": {"name": "User"}, "id": "test/user-schema"},
{"content": {"name": "Project"}, "id": "test/project-schema"},
{"content": {"name": "Document"}, "id": "test/doc-schema"}
]
mock_client.find = AsyncMock(return_value=mock_schemas)
# Mock the mcp.add_resource method
with patch('mcp_cordra.server.mcp') as mock_mcp:
from mcp_cordra.server import register_schema_resources
await register_schema_resources()
# Verify the client was called with correct query # Verify the client was called with correct query
mock_client.find.assert_called_once_with("type:Schema") mock_client.find.assert_called_once_with("type:Schema")
@patch('mcp_cordra.server.cordra_client') # Verify add_resource was called for each schema
async def test_list_schemas_empty(self, mock_client): assert mock_mcp.add_resource.call_count == 3
"""Test schema listing with no results."""
mock_client.find = AsyncMock(return_value=[])
from mcp_cordra.server import list_cordra_schemas
result = await list_cordra_schemas()
parsed_result = json.loads(result)
assert parsed_result["schemas"] == []
assert parsed_result["count"] == 0
mock_client.find.assert_called_once_with("type:Schema")
@patch('mcp_cordra.server.cordra_client') @patch('mcp_cordra.server.cordra_client')
async def test_list_schemas_missing_name_field(self, mock_client): async def test_register_schema_resources_missing_name(self, mock_client):
"""Test schema listing with objects missing name field.""" """Test schema resource registration with objects missing name field."""
mock_schemas = [ mock_schemas = [
{"content": {"name": "User"}, "identifier": "test/user-schema"}, {"content": {"name": "User"}, "id": "test/user-schema"},
{"content": {}, "identifier": "test/no-name-schema"}, # Missing name field {"content": {}, "id": "test/no-name-schema"}, # Missing name field
{"content": {"name": "Project"}, "identifier": "test/project-schema"}, {"content": {"name": "Project"}, "id": "test/project-schema"}
{"content": {"other": "field"}} # No name or identifier
] ]
mock_client.find = AsyncMock(return_value=mock_schemas) mock_client.find = AsyncMock(return_value=mock_schemas)
from mcp_cordra.server import list_cordra_schemas with patch('mcp_cordra.server.mcp') as mock_mcp:
result = await list_cordra_schemas() from mcp_cordra.server import register_schema_resources
await register_schema_resources()
parsed_result = json.loads(result) # Only 2 schemas should be registered (those with name field)
assert parsed_result["count"] == 2 # Only objects with name field assert mock_mcp.add_resource.call_count == 2
assert "User" in parsed_result["schemas"]
assert "Project" in parsed_result["schemas"]
assert len(parsed_result["schemas"]) == 2
@patch('mcp_cordra.server.cordra_client') @patch('mcp_cordra.server.cordra_client')
async def test_list_schemas_client_error(self, mock_client): async def test_register_schema_resources_client_error(self, mock_client):
"""Test schema listing with client error.""" """Test schema resource registration with client error."""
from mcp_cordra.client import CordraClientError
mock_client.find = AsyncMock(side_effect=CordraClientError("Search failed")) mock_client.find = AsyncMock(side_effect=CordraClientError("Search failed"))
from mcp_cordra.server import list_cordra_schemas # Should not raise an exception, just log a warning
with pytest.raises(RuntimeError) as exc_info: from mcp_cordra.server import register_schema_resources
await list_cordra_schemas() await register_schema_resources() # Should complete without raising
assert "Failed to list schemas" in str(exc_info.value) mock_client.find.assert_called_once_with("type:Schema")
assert "Search failed" in str(exc_info.value)
@patch('mcp_cordra.server.cordra_client')
async def test_list_schemas_json_format(self, mock_client):
"""Test that the returned JSON is properly formatted."""
mock_schemas = [
{"content": {"name": "TestSchema"}, "identifier": "test/schema"}
]
mock_client.find = AsyncMock(return_value=mock_schemas)
from mcp_cordra.server import list_cordra_schemas
result = await list_cordra_schemas()
# Verify it's valid JSON with proper indentation
parsed_result = json.loads(result)
assert isinstance(parsed_result, dict)
# Check that the result contains indentation (pretty-printed)
assert " " in result # Should have 2-space indentation
# Verify expected structure
assert "schemas" in parsed_result
assert "count" in parsed_result
assert isinstance(parsed_result["schemas"], list)
assert isinstance(parsed_result["count"], int)