Files
autocad-mcp-pro/tests/test_tool_profiles.py
T
Umutcan EdizsalanandCursor 3cbe30df54 feat(server): tool profiles, paper-space layouts + viewports, ISO 286 fits, opt-in COM 3D solids
- TOOL_PROFILE=lean|core|full applied in the lifespan via server-level enable/disable; system_about reports the active profile; opt-in solid_* tools are hidden while ENABLE_3D=false
- layouts: layout_list/create/set_current + viewport_create (scaled model viewports) on both backends; drawing_export_pdf(layout=...); ezdxf uses TILEMODE + active-layout binding, COM switches ActiveLayout and restores it
- ISO 286: engineering/fits.py authored IT4-11 + fundamental-deviation tables (1-500 mm; shafts d..p/h/js, holes D..H/JS) with clear out-of-scope errors; dimension_linear/radius/diameter gained fit= resolved from the measured nominal
- tolerances: DIMTM now signed in deviation/limit modes so double-positive fits (p6 +0.035/+0.022) render correctly; legacy positive-magnitude contract preserved
- solids: solid_box/cylinder/extrude/revolve/boolean native on COM (AddBox/AddCylinder/AddRegion+AddExtrudedSolid/AddRevolvedSolid/Boolean); ezdxf reports the honest solid_3d capability boundary
- capability maps: paper_space native, new viewport_render feature, ENABLE_3D-gated solid_3d
- 60 new tests (profiles, layouts, viewports, layout PDF, fits, gating); version pins in tests now read version.__version__

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 15:15:45 +03:00

79 lines
2.9 KiB
Python

"""Tool-profile (TOOL_PROFILE=lean/core/full) behavior."""
from __future__ import annotations
import pytest
import pytest_asyncio
from fastmcp import Client
import config
import server
pytestmark = pytest.mark.asyncio
@pytest_asyncio.fixture(autouse=True)
async def _restore_full_profile():
"""Profiles mutate global server enablement; always restore full."""
yield
await server._apply_tool_profile("full")
async def _registered_names() -> set[str]:
return {tool.name for tool in await server._registered_tools() if getattr(tool, "name", None)}
async def test_lean_names_all_exist_in_registry():
registered = await _registered_names()
missing = server.LEAN_TOOL_NAMES - registered
assert not missing, f"LEAN_TOOL_NAMES references unknown tools: {sorted(missing)}"
async def test_core_exclusions_all_exist_in_registry():
registered = await _registered_names()
missing = server.CORE_EXCLUDED_TOOL_NAMES - registered
assert not missing, f"CORE_EXCLUDED_TOOL_NAMES references unknown tools: {sorted(missing)}"
async def test_full_profile_hides_only_gated_solids():
"""Full hides nothing except the opt-in 3D tools while ENABLE_3D=false."""
info = await server._apply_tool_profile("full")
assert info["profile"] == "full"
assert set(info["disabled_tools"]) == set(server.SOLID_TOOL_NAMES)
assert info["enabled_count"] == info["registered_count"] - len(server.SOLID_TOOL_NAMES)
async def test_invalid_profile_falls_back_to_full():
info = await server._apply_tool_profile("does-not-exist")
assert info["profile"] == "full"
assert set(info["disabled_tools"]) == set(server.SOLID_TOOL_NAMES)
async def test_lean_profile_filters_client_view(monkeypatch):
monkeypatch.setattr(config.settings, "backend", "ezdxf")
monkeypatch.setattr(config.settings, "tool_profile", "lean")
async with Client(server.mcp) as client:
visible = {tool.name for tool in await client.list_tools()}
assert visible == set(server.LEAN_TOOL_NAMES)
async def test_core_profile_hides_escape_hatches_keeps_engineering(monkeypatch):
monkeypatch.setattr(config.settings, "backend", "ezdxf")
monkeypatch.setattr(config.settings, "tool_profile", "core")
async with Client(server.mcp) as client:
visible = {tool.name for tool in await client.list_tools()}
assert "system_run_command" not in visible
assert "system_run_lisp" not in visible
assert "gear_draw_spur_front_view" in visible
assert "drawing_refine" in visible
registered = await _registered_names()
assert visible == registered - server.CORE_EXCLUDED_TOOL_NAMES - server.SOLID_TOOL_NAMES
async def test_profile_switch_is_idempotent():
await server._apply_tool_profile("lean")
info = await server._apply_tool_profile("full")
assert set(info["disabled_tools"]) == set(server.SOLID_TOOL_NAMES)
lean_again = await server._apply_tool_profile("lean")
assert lean_again["enabled_count"] == len(server.LEAN_TOOL_NAMES)