"""Tests for the IronOS number platform.""" from collections.abc import AsyncGenerator from unittest.mock import AsyncMock, patch from pynecil import CharSetting, CommunicationError import pytest from syrupy.assertion import SnapshotAssertion from homeassistant.components.number import ( ATTR_VALUE, DOMAIN as NUMBER_DOMAIN, SERVICE_SET_VALUE, ) from homeassistant.config_entries import ConfigEntryState from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import entity_registry as er from tests.common import MockConfigEntry, snapshot_platform @pytest.fixture(autouse=True) async def sensor_only() -> AsyncGenerator[None, None]: """Enable only the number platform.""" with patch( "homeassistant.components.iron_os.PLATFORMS", [Platform.NUMBER], ): yield @pytest.mark.usefixtures( "entity_registry_enabled_by_default", "mock_pynecil", "ble_device" ) async def test_state( hass: HomeAssistant, config_entry: MockConfigEntry, snapshot: SnapshotAssertion, entity_registry: er.EntityRegistry, ) -> None: """Test the IronOS number platform states.""" config_entry.add_to_hass(hass) await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() assert config_entry.state is ConfigEntryState.LOADED await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id) @pytest.mark.usefixtures("entity_registry_enabled_by_default", "ble_device") async def test_set_value( hass: HomeAssistant, config_entry: MockConfigEntry, mock_pynecil: AsyncMock, ) -> None: """Test the IronOS number platform set value service.""" config_entry.add_to_hass(hass) await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() assert config_entry.state is ConfigEntryState.LOADED await hass.services.async_call( NUMBER_DOMAIN, SERVICE_SET_VALUE, service_data={ATTR_VALUE: 300}, target={ATTR_ENTITY_ID: "number.pinecil_setpoint_temperature"}, blocking=True, ) assert len(mock_pynecil.write.mock_calls) == 1 mock_pynecil.write.assert_called_once_with(CharSetting.SETPOINT_TEMP, 300) @pytest.mark.usefixtures("entity_registry_enabled_by_default", "ble_device") async def test_set_value_exception( hass: HomeAssistant, config_entry: MockConfigEntry, mock_pynecil: AsyncMock, ) -> None: """Test the IronOS number platform set value service with exception.""" config_entry.add_to_hass(hass) await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() assert config_entry.state is ConfigEntryState.LOADED mock_pynecil.write.side_effect = CommunicationError with pytest.raises( ServiceValidationError, match="Failed to submit setting to device, try again later", ): await hass.services.async_call( NUMBER_DOMAIN, SERVICE_SET_VALUE, service_data={ATTR_VALUE: 300}, target={ATTR_ENTITY_ID: "number.pinecil_setpoint_temperature"}, blocking=True, )