Initial commit: Penpot MCP Server - Complete AI-powered design workflow automation with MCP protocol, Penpot API integration, Claude AI support, CLI tools, and comprehensive documentation
This commit is contained in:
1
tests/__init__.py
Normal file
1
tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Package tests."""
|
||||
52
tests/conftest.py
Normal file
52
tests/conftest.py
Normal file
@@ -0,0 +1,52 @@
|
||||
"""Test configuration for Penpot MCP tests."""
|
||||
|
||||
import os
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from penpot_mcp.api.penpot_api import PenpotAPI
|
||||
from penpot_mcp.server.mcp_server import PenpotMCPServer
|
||||
|
||||
# Add the project root directory to the Python path
|
||||
os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_penpot_api(monkeypatch):
|
||||
"""Create a mock PenpotAPI object."""
|
||||
mock_api = MagicMock(spec=PenpotAPI)
|
||||
# Add default behavior to the mock
|
||||
mock_api.list_projects.return_value = [
|
||||
{"id": "project1", "name": "Test Project 1"},
|
||||
{"id": "project2", "name": "Test Project 2"}
|
||||
]
|
||||
mock_api.get_project_files.return_value = [
|
||||
{"id": "file1", "name": "Test File 1"},
|
||||
{"id": "file2", "name": "Test File 2"}
|
||||
]
|
||||
mock_api.get_file.return_value = {
|
||||
"id": "file1",
|
||||
"name": "Test File",
|
||||
"data": {
|
||||
"pages": [
|
||||
{
|
||||
"id": "page1",
|
||||
"name": "Page 1",
|
||||
"objects": {
|
||||
"obj1": {"id": "obj1", "name": "Object 1", "type": "frame"},
|
||||
"obj2": {"id": "obj2", "name": "Object 2", "type": "text"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
return mock_api
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_server(mock_penpot_api):
|
||||
"""Create a mock PenpotMCPServer with a mock API."""
|
||||
server = PenpotMCPServer(name="Test Server")
|
||||
server.api = mock_penpot_api
|
||||
return server
|
||||
86
tests/test_cache.py
Normal file
86
tests/test_cache.py
Normal file
@@ -0,0 +1,86 @@
|
||||
"""
|
||||
Tests for the memory caching functionality.
|
||||
"""
|
||||
|
||||
import time
|
||||
import pytest
|
||||
from penpot_mcp.utils.cache import MemoryCache
|
||||
|
||||
@pytest.fixture
|
||||
def memory_cache():
|
||||
"""Create a MemoryCache instance with a short TTL for testing."""
|
||||
return MemoryCache(ttl_seconds=2)
|
||||
|
||||
def test_cache_set_get(memory_cache):
|
||||
"""Test setting and getting a file from cache."""
|
||||
test_data = {"test": "data"}
|
||||
file_id = "test123"
|
||||
|
||||
# Set data in cache
|
||||
memory_cache.set(file_id, test_data)
|
||||
|
||||
# Get data from cache
|
||||
cached_data = memory_cache.get(file_id)
|
||||
assert cached_data == test_data
|
||||
|
||||
def test_cache_expiration(memory_cache):
|
||||
"""Test that cached files expire after TTL."""
|
||||
test_data = {"test": "data"}
|
||||
file_id = "test123"
|
||||
|
||||
# Set data in cache
|
||||
memory_cache.set(file_id, test_data)
|
||||
|
||||
# Data should be available immediately
|
||||
assert memory_cache.get(file_id) == test_data
|
||||
|
||||
# Wait for cache to expire
|
||||
time.sleep(3)
|
||||
|
||||
# Data should be expired
|
||||
assert memory_cache.get(file_id) is None
|
||||
|
||||
def test_cache_clear(memory_cache):
|
||||
"""Test clearing the cache."""
|
||||
test_data = {"test": "data"}
|
||||
file_id = "test123"
|
||||
|
||||
# Set data in cache
|
||||
memory_cache.set(file_id, test_data)
|
||||
|
||||
# Verify data is cached
|
||||
assert memory_cache.get(file_id) == test_data
|
||||
|
||||
# Clear cache
|
||||
memory_cache.clear()
|
||||
|
||||
# Verify data is gone
|
||||
assert memory_cache.get(file_id) is None
|
||||
|
||||
def test_get_all_cached_files(memory_cache):
|
||||
"""Test getting all cached files."""
|
||||
test_data1 = {"test": "data1"}
|
||||
test_data2 = {"test": "data2"}
|
||||
|
||||
# Set multiple files in cache
|
||||
memory_cache.set("file1", test_data1)
|
||||
memory_cache.set("file2", test_data2)
|
||||
|
||||
# Get all cached files
|
||||
all_files = memory_cache.get_all_cached_files()
|
||||
|
||||
# Verify all files are present
|
||||
assert len(all_files) == 2
|
||||
assert all_files["file1"] == test_data1
|
||||
assert all_files["file2"] == test_data2
|
||||
|
||||
# Wait for cache to expire
|
||||
time.sleep(3)
|
||||
|
||||
# Verify expired files are removed
|
||||
all_files = memory_cache.get_all_cached_files()
|
||||
assert len(all_files) == 0
|
||||
|
||||
def test_cache_nonexistent_file(memory_cache):
|
||||
"""Test getting a nonexistent file from cache."""
|
||||
assert memory_cache.get("nonexistent") is None
|
||||
38
tests/test_config.py
Normal file
38
tests/test_config.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""Tests for config module."""
|
||||
|
||||
from penpot_mcp.utils import config
|
||||
|
||||
|
||||
def test_config_values():
|
||||
"""Test that config has the expected values and types."""
|
||||
assert isinstance(config.PORT, int)
|
||||
assert isinstance(config.DEBUG, bool)
|
||||
assert isinstance(config.PENPOT_API_URL, str)
|
||||
assert config.RESOURCES_PATH is not None
|
||||
|
||||
|
||||
def test_environment_variable_override(monkeypatch):
|
||||
"""Test that environment variables override default config values."""
|
||||
# Save original values
|
||||
original_port = config.PORT
|
||||
original_debug = config.DEBUG
|
||||
original_api_url = config.PENPOT_API_URL
|
||||
|
||||
# Override with environment variables
|
||||
monkeypatch.setenv("PORT", "8080")
|
||||
monkeypatch.setenv("DEBUG", "false")
|
||||
monkeypatch.setenv("PENPOT_API_URL", "https://test.example.com/api")
|
||||
|
||||
# Reload the config module to apply the environment variables
|
||||
import importlib
|
||||
importlib.reload(config)
|
||||
|
||||
# Check the new values
|
||||
assert config.PORT == 8080
|
||||
assert config.DEBUG is False
|
||||
assert config.PENPOT_API_URL == "https://test.example.com/api"
|
||||
|
||||
# Restore original values
|
||||
monkeypatch.setattr(config, "PORT", original_port)
|
||||
monkeypatch.setattr(config, "DEBUG", original_debug)
|
||||
monkeypatch.setattr(config, "PENPOT_API_URL", original_api_url)
|
||||
1074
tests/test_mcp_server.py
Normal file
1074
tests/test_mcp_server.py
Normal file
File diff suppressed because it is too large
Load Diff
1090
tests/test_penpot_tree.py
Normal file
1090
tests/test_penpot_tree.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user