BareGit
"""Validation and dispatch tests for MCP browser tools."""

from __future__ import annotations

from types import SimpleNamespace
import unittest

from src.browser_session import neverCancelled
from src.tool_handlers import InvalidArgumentsError, ToolHandlers


class FakeBrowser:
    """Record JavaScript dispatch without a browser connection."""

    def __init__(self) -> None:
        self.config = SimpleNamespace(request_timeout_ms=30000)
        self.calls: list[tuple[object, ...]] = []

    async def runJavaScript(self, script, timeout_ms, cancelled):
        """Return a deterministic JavaScript result."""
        self.calls.append((script, timeout_ms, cancelled))
        return {"result": 4, "result_type": "number"}


class ToolHandlersTest(unittest.IsolatedAsyncioTestCase):
    """Verify run_javascript arguments before browser dispatch."""

    async def test_dispatches_javascript_with_default_timeout(self) -> None:
        browser = FakeBrowser()
        handlers = ToolHandlers(browser)
        result = await handlers.call(
            "run_javascript",
            {"script": "2 + 2"},
            neverCancelled,
        )
        self.assertEqual(
            result["structuredContent"],
            {"result": 4, "result_type": "number"},
        )
        self.assertEqual(
            browser.calls,
            [("2 + 2", 30000, neverCancelled)],
        )

    async def test_rejects_invalid_javascript_arguments(self) -> None:
        handlers = ToolHandlers(FakeBrowser())
        cases = (
            {},
            {"script": ""},
            {"script": "1", "timeout_ms": 0},
            {"script": "1", "extra": True},
        )
        for arguments in cases:
            with self.subTest(arguments=arguments):
                with self.assertRaises(InvalidArgumentsError):
                    await handlers.call(
                        "run_javascript",
                        arguments,
                        neverCancelled,
                    )


if __name__ == "__main__":
    unittest.main()