import pytest
from app.core.services.tool import ToolService
@pytest.mark.asyncio
async def test_mesh_file_explorer_none_path_and_session():
"""Test that UI tools don't crash when passing None for paths or unauthenticated session IDs."""
from app.core.tools.definitions.mesh_file_explorer import MeshFileExplorerTool
import app.core.services.tool as ts
from unittest.mock import MagicMock
# Mock services
services_mock = MagicMock()
# Mock orchestrator and mirror
mirror_mock = MagicMock()
mirror_mock.get_workspace_path.return_value = "/tmp/fake_workspace/__fs_explorer__"
orchestrator_mock = MagicMock()
orchestrator_mock.mirror = mirror_mock
services_mock.orchestrator = orchestrator_mock
# Init tool service wrapper purely to mimic the router context
tool = MeshFileExplorerTool()
# 1. Provide an empty context (simulating no active session attached to the UI call)
context = {
"services": services_mock,
"session_id": "__fs_explorer__",
"node_id": "hub" # Execute on hub to hit the _hub_fs branch
}
# Arguments where path is None
args = {
"action": "list",
"path": None
}
task_fn, task_args = tool.prepare_task(args, context)
assert task_fn is not None
# Execute the synchronous task returned by the plugin
result = task_fn(**task_args)
# It shouldn't crash with TypeError. It might error with "Path not found" which is handled.
assert "error" in result or "files" in result
@pytest.mark.asyncio
async def test_tool_service_node_id_validation():
"""Test that ToolService rejects unauthorized/hallucinated node IDs."""
from unittest.mock import MagicMock
service = ToolService()
# Mock DB session and Session object
db_mock = MagicMock()
session_obj = MagicMock()
session_obj.attached_node_ids = ["test-node-1"]
db_mock.query().filter().first.return_value = session_obj
# We don't even need the dummy_skill, call_tool will block it early!
# The AI guessed "node1"
args = {"node_id": "node1"}
res = await service.call_tool(
tool_name="dummy_skill",
arguments=args,
db=db_mock,
session_db_id=1
)
assert res.get("success") is False
assert "NOT attached or doesn't exist" in res.get("error")