Files

188 lines
6.7 KiB
Python

"""Tests for ADB command execution module."""
import pytest
import unittest.mock as mock
import subprocess
from unittest.mock import patch, MagicMock
from src.core.adb_command import ADBCommandRunner
class TestADBCommandRunner:
"""Test ADB command runner functionality."""
def test_init(self):
"""Test ADBCommandRunner initialization."""
runner = ADBCommandRunner()
assert runner.current_process is None
@patch("src.core.adb_command.get_adb_binary_path")
@patch("subprocess.run")
def test_run_adb_command_success(self, mock_subprocess, mock_get_path):
"""Test successful ADB command execution."""
mock_get_path.return_value = "/path/to/adb"
mock_result = MagicMock()
mock_result.returncode = 0
mock_result.stdout = "device_list"
mock_result.stderr = ""
mock_subprocess.return_value = mock_result
runner = ADBCommandRunner()
stdout, stderr, returncode = runner.run_adb_command(["devices"])
assert returncode == 0
assert stdout == "device_list"
assert stderr == ""
mock_subprocess.assert_called_once_with(
["/path/to/adb", "devices"], capture_output=True, text=True, timeout=15
)
@patch("src.core.adb_command.get_adb_binary_path")
@patch("subprocess.run")
def test_run_adb_command_failure(self, mock_subprocess, mock_get_path):
"""Test ADB command execution failure."""
mock_get_path.return_value = "/path/to/adb"
mock_result = MagicMock()
mock_result.returncode = 1
mock_result.stdout = ""
mock_result.stderr = "error message"
mock_subprocess.return_value = mock_result
runner = ADBCommandRunner()
stdout, stderr, returncode = runner.run_adb_command(["invalid"])
assert returncode == 1
assert stdout == ""
assert stderr == "error message"
@patch("src.core.adb_command.get_adb_binary_path")
@patch("subprocess.run")
def test_run_adb_command_exception(self, mock_subprocess, mock_get_path):
"""Test ADB command execution with exception."""
mock_get_path.return_value = "/path/to/adb"
mock_subprocess.side_effect = FileNotFoundError("ADB not found")
runner = ADBCommandRunner()
stdout, stderr, returncode = runner.run_adb_command(["devices"])
assert returncode == -1
assert stdout is None
assert "ADB not found" in stderr
@patch("src.core.adb_command.get_adb_binary_path")
@patch("subprocess.Popen")
def test_run_adb_command_no_capture(self, mock_popen, mock_get_path):
"""Test ADB command execution without output capture."""
mock_get_path.return_value = "/path/to/adb"
mock_process = MagicMock()
mock_popen.return_value = mock_process
runner = ADBCommandRunner()
result = runner.run_adb_command(["devices"], capture_output=False)
assert result == mock_process
mock_popen.assert_called_once_with(
["/path/to/adb", "devices"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)
def test_check_device_no_process(self):
"""Test device check with no current process."""
runner = ADBCommandRunner()
result = runner.check_device()
assert result is None
@patch("src.core.adb_command.get_adb_binary_path")
@patch("subprocess.run")
def test_check_device_with_devices(self, mock_subprocess, mock_get_path):
"""Test device check with connected devices."""
mock_get_path.return_value = "/path/to/adb"
mock_result = MagicMock()
mock_result.returncode = 0
mock_result.stdout = (
"List of devices attached\ndevice1\tdevice\ndevice2\tdevice"
)
mock_subprocess.return_value = mock_result
runner = ADBCommandRunner()
result = runner.check_device()
assert result == "device1"
@patch("src.core.adb_command.get_adb_binary_path")
@patch("subprocess.run")
def test_check_device_no_devices(self, mock_subprocess, mock_get_path):
"""Test device check with no connected devices."""
mock_get_path.return_value = "/path/to/adb"
mock_result = MagicMock()
mock_result.returncode = 0
mock_result.stdout = "List of devices attached\n"
mock_subprocess.return_value = mock_result
runner = ADBCommandRunner()
result = runner.check_device()
assert result is None
def test_parse_progress_valid_percentage(self):
"""Test parsing valid progress percentage."""
runner = ADBCommandRunner()
result = runner.parse_progress("Transferring: 45%")
assert result == 45
def test_parse_progress_valid_fraction(self):
"""Test parsing valid progress fraction."""
runner = ADBCommandRunner()
result = runner.parse_progress("1024/2048 KB transferred")
assert result == 50
def test_parse_progress_valid_bytes(self):
"""Test parsing valid progress bytes."""
runner = ADBCommandRunner()
result = runner.parse_progress("2048 KB/s (1048576 bytes in 2.5s)")
assert result == 100
def test_parse_progress_invalid(self):
"""Test parsing invalid progress string."""
runner = ADBCommandRunner()
result = runner.parse_progress("No progress info here")
assert result is None
def test_parse_progress_empty(self):
"""Test parsing empty progress string."""
runner = ADBCommandRunner()
result = runner.parse_progress("")
assert result is None
def test_cancel_current_operation_no_process(self):
"""Test canceling operation with no current process."""
runner = ADBCommandRunner()
result = runner.cancel_current_operation()
assert result is False
def test_cancel_current_operation_with_process(self):
"""Test canceling operation with active process."""
runner = ADBCommandRunner()
mock_process = MagicMock()
mock_process.poll.return_value = None # Process is running
runner.current_process = mock_process
result = runner.cancel_current_operation()
assert result is True
mock_process.terminate.assert_called_once()
def test_cancel_current_operation_finished_process(self):
"""Test canceling operation with finished process."""
runner = ADBCommandRunner()
mock_process = MagicMock()
mock_process.poll.return_value = 0 # Process finished
runner.current_process = mock_process
result = runner.cancel_current_operation()
assert result is False
mock_process.terminate.assert_not_called()