"""Tests for the trash MCP tools — patch the trash service.""" from unittest.mock import AsyncMock, patch import pytest from scribe.mcp._context import _user_id_ctx @pytest.fixture(autouse=True) def _bind_user(): token = _user_id_ctx.set(7) yield _user_id_ctx.reset(token) @pytest.mark.asyncio async def test_list_trash_wraps_batches(): with patch("scribe.mcp.tools.trash.trash_svc.list_trash", AsyncMock(return_value=[{"batch_id": "b1", "count": 2}])): from scribe.mcp.tools.trash import list_trash out = await list_trash() assert out["batches"][0]["batch_id"] == "b1" @pytest.mark.asyncio async def test_restore_delegates(): with patch("scribe.mcp.tools.trash.trash_svc.restore", AsyncMock(return_value=3)) as mock: from scribe.mcp.tools.trash import restore out = await restore("b1") assert out == {"restored": 3, "batch_id": "b1"} assert mock.call_args.args == (7, "b1") @pytest.mark.asyncio async def test_purge_trash_requires_confirmed(): with patch("scribe.mcp.tools.trash.trash_svc.purge", AsyncMock()) as mock: from scribe.mcp.tools.trash import purge_trash out = await purge_trash("b1", confirmed=False) assert out.get("confirmed_required") is True assert not mock.called @pytest.mark.asyncio async def test_purge_trash_when_confirmed(): with patch("scribe.mcp.tools.trash.trash_svc.purge", AsyncMock(return_value=5)) as mock: from scribe.mcp.tools.trash import purge_trash out = await purge_trash("b1", confirmed=True) assert out == {"purged": 5, "batch_id": "b1"} assert mock.called def test_register_attaches_three_tools(): from scribe.mcp.tools.trash import register names: list[str] = [] class FakeMCP: def tool(self, name=None): def deco(fn): names.append(name) return fn return deco register(FakeMCP()) assert set(names) == {"list_trash", "restore", "purge_trash"}