MCP Toolbox
by ai-zerolab
- tests
- figma
import json
from pathlib import Path
from unittest.mock import patch
import pytest
from mcp_toolbox.figma.tools import (
CacheManager,
FigmaApiClient,
figma_delete_comment,
figma_get_comments,
figma_get_component,
figma_get_file,
figma_get_file_components,
figma_get_file_nodes,
figma_get_file_styles,
figma_get_image,
figma_get_image_fills,
figma_get_project_files,
figma_get_style,
figma_get_team_component_sets,
figma_get_team_components,
figma_get_team_projects,
figma_get_team_styles,
figma_post_comment,
)
# Helper function to load mock data
def load_mock_data(filename):
mock_dir = Path(__file__).parent.parent / "mock" / "figma"
file_path = mock_dir / filename
if not file_path.exists():
# Create empty mock data if it doesn't exist
mock_data = {"mock": "data"}
with open(file_path, "w") as f:
json.dump(mock_data, f)
with open(file_path) as f:
return json.load(f)
# Patch the FigmaApiClient.make_request method
@pytest.fixture
def mock_make_request():
with patch.object(FigmaApiClient, "make_request") as mock:
def side_effect(path, method="GET", data=None):
# Extract the tool name from the path
parts = path.strip("/").split("/")
if len(parts) >= 2 and parts[0] == "files" and parts[1]:
file_key = parts[1]
if len(parts) == 2:
# get_file
return load_mock_data("get_file.json")
elif len(parts) == 3:
if parts[2] == "nodes":
# get_file_nodes
return load_mock_data("get_file_nodes.json")
elif parts[2] == "images":
# get_image_fills
return load_mock_data("get_image_fills.json")
elif parts[2] == "components":
# get_file_components
return load_mock_data("get_file_components.json")
elif parts[2] == "styles":
# get_file_styles
return load_mock_data("get_file_styles.json")
elif parts[2] == "comments":
if method == "GET":
# get_comments
return load_mock_data("get_comments.json")
elif method == "POST":
# post_comment
return load_mock_data("post_comment.json")
elif len(parts) == 4 and parts[2] == "comments":
# delete_comment
return load_mock_data("delete_comment.json")
elif parts[0] == "images" and len(parts) >= 2:
# get_image
return load_mock_data("get_image.json")
elif parts[0] == "teams" and len(parts) >= 3:
team_id = parts[1]
if parts[2] == "projects":
# get_team_projects
return load_mock_data("get_team_projects.json")
elif parts[2] == "components":
# get_team_components
return load_mock_data("get_team_components.json")
elif parts[2] == "component_sets":
# get_team_component_sets
return load_mock_data("get_team_component_sets.json")
elif parts[2] == "styles":
# get_team_styles
return load_mock_data("get_team_styles.json")
elif parts[0] == "projects" and len(parts) >= 3:
# get_project_files
return load_mock_data("get_project_files.json")
elif parts[0] == "components" and len(parts) >= 2:
# get_component
return load_mock_data("get_component.json")
elif parts[0] == "styles" and len(parts) >= 2:
# get_style
return load_mock_data("get_style.json")
# Default mock data
return {"mock": "data"}
mock.side_effect = side_effect
yield mock
# Patch the CacheManager.save_to_cache method
@pytest.fixture
def mock_save_to_cache():
with patch.object(CacheManager, "save_to_cache") as mock:
mock.return_value = "/mock/path/to/cache/file.json"
yield mock
# Test get_file function
@pytest.mark.asyncio
async def test_get_file(mock_make_request, mock_save_to_cache):
# Test with minimal parameters
result = await figma_get_file("test_file_key")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key")
# Verify save_to_cache was called
mock_save_to_cache.assert_called_once()
# Verify the result contains expected fields
assert "file_path" in result
assert "message" in result
assert result["file_path"] == "/mock/path/to/cache/file.json"
# Reset mocks for next test
mock_make_request.reset_mock()
mock_save_to_cache.reset_mock()
# Test with all parameters
result = await figma_get_file("test_file_key", version="123", depth=2, branch_data=True)
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key?version=123&depth=2&branch_data=True")
# Test get_file_nodes function
@pytest.mark.asyncio
async def test_get_file_nodes(mock_make_request, mock_save_to_cache):
# Test with minimal parameters
result = await figma_get_file_nodes("test_file_key", ["node1", "node2"])
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key/nodes?ids=node1,node2")
# Verify save_to_cache was called
mock_save_to_cache.assert_called_once()
# Verify the result contains expected fields
assert "file_path" in result
assert "message" in result
assert result["file_path"] == "/mock/path/to/cache/file.json"
# Reset mocks for next test
mock_make_request.reset_mock()
mock_save_to_cache.reset_mock()
# Test with all parameters
result = await figma_get_file_nodes("test_file_key", ["node1", "node2"], depth=2, version="123")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key/nodes?ids=node1,node2&depth=2&version=123")
# Test get_image function
@pytest.mark.asyncio
async def test_get_image(mock_make_request):
# Test with minimal parameters
result = await figma_get_image("test_file_key", ["node1", "node2"])
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/images/test_file_key?ids=node1,node2")
# Reset mock for next test
mock_make_request.reset_mock()
# Test with all parameters
result = await figma_get_image(
"test_file_key",
["node1", "node2"],
scale=2.0,
format_type="png",
svg_include_id=True,
svg_simplify_stroke=True,
use_absolute_bounds=True,
)
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with(
"/images/test_file_key?ids=node1,node2&scale=2.0&format=png&svg_include_id=True&svg_simplify_stroke=True&use_absolute_bounds=True"
)
# Test get_image_fills function
@pytest.mark.asyncio
async def test_get_image_fills(mock_make_request):
result = await figma_get_image_fills("test_file_key")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key/images")
# Test get_comments function
@pytest.mark.asyncio
async def test_get_comments(mock_make_request):
result = await figma_get_comments("test_file_key")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key/comments")
# Test post_comment function
@pytest.mark.asyncio
async def test_post_comment(mock_make_request):
# Test with minimal parameters
result = await figma_post_comment("test_file_key", "Test comment")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key/comments", "POST", {"message": "Test comment"})
# Reset mock for next test
mock_make_request.reset_mock()
# Test with all parameters
client_meta = {"x": 100, "y": 200, "node_id": "node1", "node_offset": {"x": 10, "y": 20}}
result = await figma_post_comment("test_file_key", "Test comment", client_meta=client_meta, comment_id="comment1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with(
"/files/test_file_key/comments",
"POST",
{"message": "Test comment", "client_meta": client_meta, "comment_id": "comment1"},
)
# Test delete_comment function
@pytest.mark.asyncio
async def test_delete_comment(mock_make_request):
result = await figma_delete_comment("test_file_key", "comment1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key/comments/comment1", "DELETE")
# Test get_team_projects function
@pytest.mark.asyncio
async def test_get_team_projects(mock_make_request):
# Test with minimal parameters
result = await figma_get_team_projects("team1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/teams/team1/projects")
# Reset mock for next test
mock_make_request.reset_mock()
# Test with all parameters
result = await figma_get_team_projects("team1", page_size=10, cursor="cursor1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/teams/team1/projects?page_size=10&cursor=cursor1")
# Test get_project_files function
@pytest.mark.asyncio
async def test_get_project_files(mock_make_request):
# Test with minimal parameters
result = await figma_get_project_files("project1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/projects/project1/files")
# Reset mock for next test
mock_make_request.reset_mock()
# Test with all parameters
result = await figma_get_project_files("project1", page_size=10, cursor="cursor1", branch_data=True)
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/projects/project1/files?page_size=10&cursor=cursor1&branch_data=True")
# Test get_team_components function
@pytest.mark.asyncio
async def test_get_team_components(mock_make_request):
# Test with minimal parameters
result = await figma_get_team_components("team1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/teams/team1/components")
# Reset mock for next test
mock_make_request.reset_mock()
# Test with all parameters
result = await figma_get_team_components("team1", page_size=10, cursor="cursor1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/teams/team1/components?page_size=10&cursor=cursor1")
# Test get_file_components function
@pytest.mark.asyncio
async def test_get_file_components(mock_make_request):
result = await figma_get_file_components("test_file_key")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key/components")
# Test get_component function
@pytest.mark.asyncio
async def test_get_component(mock_make_request):
result = await figma_get_component("component1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/components/component1")
# Test get_team_component_sets function
@pytest.mark.asyncio
async def test_get_team_component_sets(mock_make_request):
# Test with minimal parameters
result = await figma_get_team_component_sets("team1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/teams/team1/component_sets")
# Reset mock for next test
mock_make_request.reset_mock()
# Test with all parameters
result = await figma_get_team_component_sets("team1", page_size=10, cursor="cursor1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/teams/team1/component_sets?page_size=10&cursor=cursor1")
# Test get_team_styles function
@pytest.mark.asyncio
async def test_get_team_styles(mock_make_request):
# Test with minimal parameters
result = await figma_get_team_styles("team1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/teams/team1/styles")
# Reset mock for next test
mock_make_request.reset_mock()
# Test with all parameters
result = await figma_get_team_styles("team1", page_size=10, cursor="cursor1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/teams/team1/styles?page_size=10&cursor=cursor1")
# Test get_file_styles function
@pytest.mark.asyncio
async def test_get_file_styles(mock_make_request):
result = await figma_get_file_styles("test_file_key")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/files/test_file_key/styles")
# Test get_style function
@pytest.mark.asyncio
async def test_get_style(mock_make_request):
result = await figma_get_style("style1")
# Verify make_request was called with correct parameters
mock_make_request.assert_called_once_with("/styles/style1")