import pytest from unittest.mock import MagicMock, patch from src.services.i2c_service import I2CService, smbus2 from src.models.device import DeviceStatus from src.models.cell import CellLimits, MeasureValues @pytest.fixture def mock_smbus(): with patch('smbus2.SMBus') as mock: yield mock @pytest.fixture def i2c_service(mock_smbus: smbus2.SMBus): config = { 'i2c': { 'bus': 1, 'debug': False } } return I2CService(config) def test_request_status_list(i2c_service: I2CService, mock_smbus: smbus2.SMBus): # Arrange mock_instance = mock_smbus.return_value mock_instance.read_i2c_block_data.return_value = [0, 1, 2] # Mix of different states i2c_address = 0x48 num_slots = 3 # Act result = i2c_service.request_status_list(i2c_address, num_slots) # Assert assert len(result) == 3 assert result[0] == DeviceStatus.EMPTY assert result[1] == DeviceStatus.INSERTED assert result[2] == DeviceStatus.MEASURING mock_instance.read_i2c_block_data.assert_called_once_with(i2c_address, i2c_service.status_register, num_slots) def test_request_measure_values(i2c_service: I2CService, mock_smbus: smbus2.SMBus): # Arrange mock_instance = mock_smbus.return_value mock_instance.read_i2c_block_data.return_value = [42, 36, 15] # voltage values * 10 i2c_address = 0x48 slot_id = 1 # Act result = i2c_service.request_measure_values(i2c_address, slot_id) # Assert assert isinstance(result, MeasureValues) mock_instance.read_i2c_block_data.assert_called_once_with(i2c_address, i2c_service.cell_data_register, 3, slot_id) def test_send_cell_limits(i2c_service: I2CService, mock_smbus: smbus2.SMBus): # Arrange mock_instance = mock_smbus.return_value i2c_address = 0x48 slot_id = 1 limits = CellLimits(min_volt=3.2, max_volt=4.2, max_curr=2.0) # Act result = i2c_service.send_cell_limits(i2c_address, slot_id, limits) # Assert assert result is True mock_instance.write_block_data.assert_called_once_with( i2c_address, i2c_service.status_register, [slot_id, limits.min_volt, limits.max_volt, limits.max_curr] ) def test_debug_mode(): # Arrange config = { 'i2c': { 'debug': True } } service = I2CService(config) # Act status_list = service.request_status_list(0x48, 2) measure_values = service.request_measure_values(0x48, 1) limits_result = service.send_cell_limits(0x48, 1, CellLimits(3.2, 4.2, 2.0)) # Assert assert len(status_list) == 2 assert all(status == DeviceStatus.EMPTY for status in status_list) assert isinstance(measure_values, MeasureValues) assert limits_result is True