"""Define patches used for androidtv tests.""" from unittest.mock import mock_open, patch class AdbDeviceTcpFake: """A fake of the `adb_shell.adb_device.AdbDeviceTcp` class.""" def __init__(self, *args, **kwargs): """Initialize a fake `adb_shell.adb_device.AdbDeviceTcp` instance.""" self.available = False def close(self): """Close the socket connection.""" self.available = False def connect(self, *args, **kwargs): """Try to connect to a device.""" raise NotImplementedError def shell(self, cmd): """Send an ADB shell command.""" return None class ClientFakeSuccess: """A fake of the `ppadb.client.Client` class when the connection and shell commands succeed.""" def __init__(self, host="127.0.0.1", port=5037): """Initialize a `ClientFakeSuccess` instance.""" self._devices = [] def devices(self): """Get a list of the connected devices.""" return self._devices def device(self, serial): """Mock the `Client.device` method when the device is connected via ADB.""" device = DeviceFake(serial) self._devices.append(device) return device class ClientFakeFail: """A fake of the `ppadb.client.Client` class when the connection and shell commands fail.""" def __init__(self, host="127.0.0.1", port=5037): """Initialize a `ClientFakeFail` instance.""" self._devices = [] def devices(self): """Get a list of the connected devices.""" return self._devices def device(self, serial): """Mock the `Client.device` method when the device is not connected via ADB.""" self._devices = [] class DeviceFake: """A fake of the `ppadb.device.Device` class.""" def __init__(self, host): """Initialize a `DeviceFake` instance.""" self.host = host def get_serial_no(self): """Get the serial number for the device (IP:PORT).""" return self.host def shell(self, cmd): """Send an ADB shell command.""" raise NotImplementedError def patch_connect(success): """Mock the `adb_shell.adb_device.AdbDeviceTcp` and `ppadb.client.Client` classes.""" def connect_success_python(self, *args, **kwargs): """Mock the `AdbDeviceTcpFake.connect` method when it succeeds.""" self.available = True def connect_fail_python(self, *args, **kwargs): """Mock the `AdbDeviceTcpFake.connect` method when it fails.""" raise OSError if success: return { "python": patch( f"{__name__}.AdbDeviceTcpFake.connect", connect_success_python ), "server": patch("androidtv.adb_manager.Client", ClientFakeSuccess), } return { "python": patch(f"{__name__}.AdbDeviceTcpFake.connect", connect_fail_python), "server": patch("androidtv.adb_manager.Client", ClientFakeFail), } def patch_shell(response=None, error=False): """Mock the `AdbDeviceTcpFake.shell` and `DeviceFake.shell` methods.""" def shell_success(self, cmd): """Mock the `AdbDeviceTcpFake.shell` and `DeviceFake.shell` methods when they are successful.""" self.shell_cmd = cmd return response def shell_fail_python(self, cmd): """Mock the `AdbDeviceTcpFake.shell` method when it fails.""" self.shell_cmd = cmd raise AttributeError def shell_fail_server(self, cmd): """Mock the `DeviceFake.shell` method when it fails.""" self.shell_cmd = cmd raise ConnectionResetError if not error: return { "python": patch(f"{__name__}.AdbDeviceTcpFake.shell", shell_success), "server": patch(f"{__name__}.DeviceFake.shell", shell_success), } return { "python": patch(f"{__name__}.AdbDeviceTcpFake.shell", shell_fail_python), "server": patch(f"{__name__}.DeviceFake.shell", shell_fail_server), } PATCH_ADB_DEVICE_TCP = patch("androidtv.adb_manager.AdbDeviceTcp", AdbDeviceTcpFake) PATCH_ANDROIDTV_OPEN = patch("androidtv.adb_manager.open", mock_open()) PATCH_KEYGEN = patch("homeassistant.components.androidtv.media_player.keygen") PATCH_SIGNER = patch("androidtv.adb_manager.PythonRSASigner") def isfile(filepath): """Mock `os.path.isfile`.""" return filepath.endswith("adbkey") PATCH_ISFILE = patch("os.path.isfile", isfile) PATCH_ACCESS = patch("os.access", return_value=True) def patch_firetv_update(state, current_app, running_apps): """Patch the `FireTV.update()` method.""" return patch( "androidtv.firetv.FireTV.update", return_value=(state, current_app, running_apps), ) def patch_androidtv_update( state, current_app, running_apps, device, is_volume_muted, volume_level ): """Patch the `AndroidTV.update()` method.""" return patch( "androidtv.androidtv.AndroidTV.update", return_value=( state, current_app, running_apps, device, is_volume_muted, volume_level, ), ) PATCH_LAUNCH_APP = patch("androidtv.basetv.BaseTV.launch_app") PATCH_STOP_APP = patch("androidtv.basetv.BaseTV.stop_app")