Files
Octop/tests/unit/mobile/test_mobile_setup.py
0ce9cf46d3 feat(dashboard): layout refactor, email invites, KB text editor, remote desktop (#380)
* feat: minimal layout, user email, KB text docs, and remote desktop hub

Add classic/minimal chrome with a unified chat records host, optional user
email (invite/login), in-app markdown/txt knowledge editing, and a combined
remote desktop/phone control surface—plus host path and mobile setup hardening.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(host_dirs): don't jail host-root browse to home drive on Windows

The restrict_to_home=False case allows any absolute host path (no home
jail). On POSIX everything sits under '/'; on Windows the denylist is
empty and windows_neutralize_host_root rewrites root_dir '/' at runtime,
so a drive-relative '/' must stay allowed. The new _path_within_base
containment incorrectly rejected root_dir '/' on Windows when the checkout
drive differed from the home drive, breaking from-expert/local_shell agent
creation.

Also mark test_install_published_expert_accepts_create_options posix_only:
it relies on local_shell workspace file writes unsupported on Windows.

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-22 22:04:09 +08:00

69 lines
2.5 KiB
Python

"""tests/unit/mobile/test_mobile_setup.py"""
from __future__ import annotations
from unittest.mock import patch
from octop.config import CapabilitiesConfig, MobileCapabilities, OctopConfig
from octop.infra.mobile.setup import mobile_status
def _cfg(**mobile: object) -> OctopConfig:
return OctopConfig(
capabilities=CapabilitiesConfig(
mobile=MobileCapabilities(**mobile) # type: ignore[arg-type]
)
)
def test_mobile_status_disabled() -> None:
status = mobile_status(_cfg(enabled=False, backend="none"))
assert status.mobile_supported is False
assert status.setup_state == "unsupported"
def test_mobile_status_physical_ready() -> None:
with (
patch("octop.infra.mobile.setup.find_adb", return_value="/adb"),
patch("octop.infra.mobile.setup.list_devices", return_value=["emulator-5554"]),
):
status = mobile_status(_cfg(enabled=True, backend="physical"))
assert status.setup_state == "ready"
assert status.selected_device == "emulator-5554"
def test_mobile_status_physical_needs_device() -> None:
with (
patch("octop.infra.mobile.setup.find_adb", return_value="/adb"),
patch("octop.infra.mobile.setup.list_devices", return_value=[]),
):
status = mobile_status(_cfg(enabled=True, backend="physical"))
assert status.setup_state == "needs_device"
def test_mobile_status_container_reconnects_adb() -> None:
with (
patch("octop.infra.mobile.setup.find_adb", return_value="/adb"),
patch("octop.infra.mobile.setup._container_running", return_value=True),
patch(
"octop.infra.mobile.setup.list_devices",
side_effect=[[], ["127.0.0.1:5555"]],
),
patch("octop.infra.mobile.setup.adb_connect", return_value=True) as connect,
):
status = mobile_status(_cfg(enabled=True, backend="redroid"))
connect.assert_called_once_with("127.0.0.1:5555", adb="/adb")
assert status.setup_state == "ready"
assert status.selected_device == "127.0.0.1:5555"
def test_mobile_status_container_missing_adb_binary() -> None:
with (
patch("octop.infra.mobile.setup.find_adb", return_value=None),
patch("octop.infra.mobile.setup._container_running", return_value=True),
patch("octop.infra.mobile.setup.list_devices", return_value=[]),
):
status = mobile_status(_cfg(enabled=True, backend="redroid"), locale="en")
assert status.setup_state == "needs_device"
assert "adb was not found" in status.reason