mcp-adb/tests/test_connectivity.py
Ryan Malloy fb297f7937 Add pytest suite (216 tests) and fix UI/notification parser bugs
Test infrastructure with conftest fixtures mocking run_shell_args/run_adb
for device-free testing across all 8 mixins.

Fixed: UI parser regex couldn't match hyphenated XML attributes
(content-desc, resource-id). Notification parser captured trailing
parenthesis in package names.
2026-02-11 03:38:37 -07:00

123 lines
4.9 KiB
Python

"""Tests for connectivity mixin (connect, disconnect, tcpip, pair, properties)."""
import pytest
from tests.conftest import fail, ok
class TestAdbConnect:
async def test_success(self, server):
server.run_adb.return_value = ok(stdout="connected to 10.0.0.1:5555")
result = await server.adb_connect("10.0.0.1")
assert result["success"] is True
assert result["address"] == "10.0.0.1:5555"
server.run_adb.assert_called_once_with(["connect", "10.0.0.1:5555"])
async def test_custom_port(self, server):
server.run_adb.return_value = ok(stdout="connected to 10.0.0.1:5556")
result = await server.adb_connect("10.0.0.1", port=5556)
assert result["address"] == "10.0.0.1:5556"
async def test_already_connected(self, server):
server.run_adb.return_value = ok(stdout="already connected to 10.0.0.1:5555")
result = await server.adb_connect("10.0.0.1")
assert result["success"] is True
assert result["already_connected"] is True
async def test_failure(self, server):
server.run_adb.return_value = ok(stdout="failed to connect")
result = await server.adb_connect("10.0.0.1")
assert result["success"] is False
class TestAdbDisconnect:
async def test_success(self, server):
server.run_adb.return_value = ok(stdout="disconnected 10.0.0.1:5555")
result = await server.adb_disconnect("10.0.0.1")
assert result["success"] is True
assert result["address"] == "10.0.0.1:5555"
async def test_failure(self, server):
server.run_adb.return_value = ok(stdout="error: no such device")
result = await server.adb_disconnect("10.0.0.1")
assert result["success"] is False
class TestAdbTcpip:
@pytest.mark.usefixtures("_dev_mode")
async def test_success(self, server, ctx):
server.run_shell_args.return_value = ok(
stdout="10: wlan0 inet 192.168.1.100/24"
)
server.run_adb.return_value = ok(stdout="restarting in TCP mode port: 5555")
result = await server.adb_tcpip(ctx)
assert result["success"] is True
assert result["device_ip"] == "192.168.1.100"
assert result["connect_address"] == "192.168.1.100:5555"
@pytest.mark.usefixtures("_dev_mode")
async def test_rejects_network_device(self, server, ctx):
server.set_current_device("10.20.0.25:5555")
result = await server.adb_tcpip(ctx)
assert result["success"] is False
assert "already a network device" in result["error"]
@pytest.mark.usefixtures("_dev_mode")
async def test_no_wifi_ip(self, server, ctx):
server.run_shell_args.return_value = ok(stdout="wlan0: no ip")
result = await server.adb_tcpip(ctx)
assert result["success"] is False
assert "WiFi" in result["error"]
@pytest.mark.usefixtures("_dev_mode")
async def test_custom_port(self, server, ctx):
server.run_shell_args.return_value = ok(
stdout="10: wlan0 inet 192.168.1.50/24"
)
server.run_adb.return_value = ok()
result = await server.adb_tcpip(ctx, port=5556)
assert result["port"] == 5556
assert result["connect_address"] == "192.168.1.50:5556"
@pytest.mark.usefixtures("_no_dev_mode")
async def test_requires_dev_mode(self, server, ctx):
result = await server.adb_tcpip(ctx)
assert result["success"] is False
assert "developer mode" in result["error"].lower()
class TestAdbPair:
async def test_success(self, server):
server.run_adb.return_value = ok(stdout="Successfully paired to 10.0.0.1:37000")
result = await server.adb_pair("10.0.0.1", 37000, "123456")
assert result["success"] is True
server.run_adb.assert_called_once_with(["pair", "10.0.0.1:37000", "123456"])
async def test_failure(self, server):
server.run_adb.return_value = fail("Failed: wrong code")
result = await server.adb_pair("10.0.0.1", 37000, "000000")
assert result["success"] is False
class TestDeviceProperties:
async def test_returns_properties(self, server):
props = {
"ro.product.model": "Pixel 6",
"ro.product.manufacturer": "Google",
"ro.build.version.release": "14",
"ro.build.version.sdk": "34",
"ro.board.platform": "gs101",
}
server.get_device_property.side_effect = lambda p, d=None: props.get(p)
result = await server.device_properties()
assert result["success"] is True
assert result["identity"]["model"] == "Pixel 6"
assert result["software"]["android_version"] == "14"
assert result["hardware"]["chipset"] == "gs101"
async def test_no_properties(self, server):
server.get_device_property.return_value = None
result = await server.device_properties()
assert result["success"] is False
assert "No properties" in result["error"]