"""Tests for the controlBrowser tool's action surface.

These are deterministic schema/summary checks — they do not drive a real
browser. The actual cursor movement is exercised live on the browser host
(xdotool + CDP), which these tests cannot reach.
"""

import pytest

from jarvis.tools.builtin.control_browser import ControlBrowserTool


@pytest.fixture
def tool():
    return ControlBrowserTool()


def test_movemouse_is_an_exposed_action(tool):
    # A weak model confabulated "moved the mouse" because no move/hover action
    # existed to call. The cursor-move capability must be a real action so the
    # request "move the mouse to the search box" maps to a tool call.
    enum = tool.inputSchema["properties"]["action"]["enum"]
    assert "moveMouse" in enum


def test_movemouse_summary_reports_the_target(tool):
    summary = tool._summarise("moveMouse", {"site": "naver"}, {"ok": True, "target": "naver"})
    assert "마우스" in summary and "naver" in summary


def test_description_distinguishes_cursor_paths(tool):
    # The model must know navigate is address-bar only (no mouse) while
    # search/type/moveMouse move the real cursor — that distinction is the
    # whole point of the fix.
    desc = tool.description
    assert "moveMouse" in desc
    assert "address bar" in desc  # navigate is described as address-bar typing


def test_search_summary_flags_cursorless_fallback(tool):
    # When the real xdotool cursor path didn't run, the summary must say so
    # rather than implying a human-like search happened.
    human = tool._summarise("search", {"query": "날씨"}, {"ok": True, "site": "naver", "query": "날씨", "input": "human"})
    assert "참고: 실제 마우스" not in human

    fell_back = tool._summarise("search", {"query": "날씨"}, {"ok": True, "site": "naver", "query": "날씨", "input": "api-fallback"})
    assert "실제 마우스 커서 이동 없이" in fell_back


def test_movemouse_summary_only_runs_on_success(tool):
    # _summarise is only called on ok:true; an ok:false (target not found / no
    # xdotool) is handled by run() as a failure reply, so a failed move can no
    # longer be reported as "moved". Sanity-check the success summary names a
    # target rather than a placeholder when one is present.
    summary = tool._summarise("moveMouse", {"selector": "#query"}, {"ok": True, "target": "#query"})
    assert "#query" in summary
