From 5316b9470500e14a23cf1c55a244993ba0805bf6 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Wed, 27 Mar 2024 14:36:31 +0100 Subject: [PATCH] Use `setup_test_component_platform` helper for alarm_control_panel entity component tests instead of `hass.components` (#114301) --- .../components/alarm_control_panel/common.py | 62 +++++++++- .../alarm_control_panel/conftest.py | 22 ++++ .../alarm_control_panel/test_device_action.py | 56 +++++---- .../test/alarm_control_panel.py | 112 ------------------ 4 files changed, 115 insertions(+), 137 deletions(-) create mode 100644 tests/components/alarm_control_panel/conftest.py delete mode 100644 tests/testing_config/custom_components/test/alarm_control_panel.py diff --git a/tests/components/alarm_control_panel/common.py b/tests/components/alarm_control_panel/common.py index 99f8a3d24bd..9ec419d8cf0 100644 --- a/tests/components/alarm_control_panel/common.py +++ b/tests/components/alarm_control_panel/common.py @@ -4,7 +4,11 @@ All containing methods are legacy helpers that should not be used by new components. Instead call the service directly. """ -from homeassistant.components.alarm_control_panel import DOMAIN +from homeassistant.components.alarm_control_panel import ( + DOMAIN, + AlarmControlPanelEntity, + AlarmControlPanelEntityFeature, +) from homeassistant.const import ( ATTR_CODE, ATTR_ENTITY_ID, @@ -16,8 +20,16 @@ from homeassistant.const import ( SERVICE_ALARM_ARM_VACATION, SERVICE_ALARM_DISARM, SERVICE_ALARM_TRIGGER, + STATE_ALARM_ARMED_AWAY, + STATE_ALARM_ARMED_HOME, + STATE_ALARM_ARMED_NIGHT, + STATE_ALARM_ARMED_VACATION, + STATE_ALARM_DISARMED, + STATE_ALARM_TRIGGERED, ) +from tests.common import MockEntity + async def async_alarm_disarm(hass, code=None, entity_id=ENTITY_MATCH_ALL): """Send the alarm the command for disarm.""" @@ -98,3 +110,51 @@ async def async_alarm_arm_custom_bypass(hass, code=None, entity_id=ENTITY_MATCH_ await hass.services.async_call( DOMAIN, SERVICE_ALARM_ARM_CUSTOM_BYPASS, data, blocking=True ) + + +class MockAlarm(MockEntity, AlarmControlPanelEntity): + """Mock Alarm control panel class.""" + + _attr_supported_features = ( + AlarmControlPanelEntityFeature.ARM_HOME + | AlarmControlPanelEntityFeature.ARM_AWAY + | AlarmControlPanelEntityFeature.ARM_NIGHT + | AlarmControlPanelEntityFeature.TRIGGER + | AlarmControlPanelEntityFeature.ARM_VACATION + ) + + @property + def code_arm_required(self): + """Whether the code is required for arm actions.""" + return self._handle("code_arm_required") + + def alarm_arm_away(self, code=None): + """Send arm away command.""" + self._attr_state = STATE_ALARM_ARMED_AWAY + self.schedule_update_ha_state() + + def alarm_arm_home(self, code=None): + """Send arm home command.""" + self._attr_state = STATE_ALARM_ARMED_HOME + self.schedule_update_ha_state() + + def alarm_arm_night(self, code=None): + """Send arm night command.""" + self._attr_state = STATE_ALARM_ARMED_NIGHT + self.schedule_update_ha_state() + + def alarm_arm_vacation(self, code=None): + """Send arm night command.""" + self._attr_state = STATE_ALARM_ARMED_VACATION + self.schedule_update_ha_state() + + def alarm_disarm(self, code=None): + """Send disarm command.""" + if code == "1234": + self._attr_state = STATE_ALARM_DISARMED + self.schedule_update_ha_state() + + def alarm_trigger(self, code=None): + """Send alarm trigger command.""" + self._attr_state = STATE_ALARM_TRIGGERED + self.schedule_update_ha_state() diff --git a/tests/components/alarm_control_panel/conftest.py b/tests/components/alarm_control_panel/conftest.py new file mode 100644 index 00000000000..cda3d81b26e --- /dev/null +++ b/tests/components/alarm_control_panel/conftest.py @@ -0,0 +1,22 @@ +"""Fixturs for Alarm Control Panel tests.""" + +import pytest + +from tests.components.alarm_control_panel.common import MockAlarm + + +@pytest.fixture +def mock_alarm_control_panel_entities() -> dict[str, MockAlarm]: + """Mock Alarm control panel class.""" + return { + "arm_code": MockAlarm( + name="Alarm arm code", + code_arm_required=True, + unique_id="unique_arm_code", + ), + "no_arm_code": MockAlarm( + name="Alarm no arm code", + code_arm_required=False, + unique_id="unique_no_arm_code", + ), + } diff --git a/tests/components/alarm_control_panel/test_device_action.py b/tests/components/alarm_control_panel/test_device_action.py index 81aa9c903ba..afcfa0a7a12 100644 --- a/tests/components/alarm_control_panel/test_device_action.py +++ b/tests/components/alarm_control_panel/test_device_action.py @@ -28,7 +28,9 @@ from tests.common import ( MockConfigEntry, async_get_device_automation_capabilities, async_get_device_automations, + setup_test_component_platform, ) +from tests.components.alarm_control_panel.common import MockAlarm @pytest.fixture(autouse=True, name="stub_blueprint_populate") @@ -223,11 +225,12 @@ async def test_get_action_capabilities( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, - enable_custom_integrations: None, + mock_alarm_control_panel_entities: dict[str, MockAlarm], ) -> None: """Test we get the expected capabilities from a sensor trigger.""" - platform = getattr(hass.components, f"test.{DOMAIN}") - platform.init() + setup_test_component_platform( + hass, DOMAIN, mock_alarm_control_panel_entities.values() + ) assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}}) await hass.async_block_till_done() @@ -240,7 +243,7 @@ async def test_get_action_capabilities( entity_registry.async_get_or_create( DOMAIN, "test", - platform.ENTITIES["no_arm_code"].unique_id, + mock_alarm_control_panel_entities["no_arm_code"].unique_id, device_id=device_entry.id, ) @@ -270,11 +273,12 @@ async def test_get_action_capabilities_legacy( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, - enable_custom_integrations: None, + mock_alarm_control_panel_entities: dict[str, MockAlarm], ) -> None: """Test we get the expected capabilities from a sensor trigger.""" - platform = getattr(hass.components, f"test.{DOMAIN}") - platform.init() + setup_test_component_platform( + hass, DOMAIN, mock_alarm_control_panel_entities.values() + ) assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}}) await hass.async_block_till_done() @@ -287,7 +291,7 @@ async def test_get_action_capabilities_legacy( entity_registry.async_get_or_create( DOMAIN, "test", - platform.ENTITIES["no_arm_code"].unique_id, + mock_alarm_control_panel_entities["no_arm_code"].unique_id, device_id=device_entry.id, ) @@ -318,11 +322,12 @@ async def test_get_action_capabilities_arm_code( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, - enable_custom_integrations: None, + mock_alarm_control_panel_entities: dict[str, MockAlarm], ) -> None: """Test we get the expected capabilities from a sensor trigger.""" - platform = getattr(hass.components, f"test.{DOMAIN}") - platform.init() + setup_test_component_platform( + hass, DOMAIN, mock_alarm_control_panel_entities.values() + ) assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}}) await hass.async_block_till_done() @@ -335,7 +340,7 @@ async def test_get_action_capabilities_arm_code( entity_registry.async_get_or_create( DOMAIN, "test", - platform.ENTITIES["arm_code"].unique_id, + mock_alarm_control_panel_entities["arm_code"].unique_id, device_id=device_entry.id, ) @@ -373,11 +378,12 @@ async def test_get_action_capabilities_arm_code_legacy( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, - enable_custom_integrations: None, + mock_alarm_control_panel_entities: dict[str, MockAlarm], ) -> None: """Test we get the expected capabilities from a sensor trigger.""" - platform = getattr(hass.components, f"test.{DOMAIN}") - platform.init() + setup_test_component_platform( + hass, DOMAIN, mock_alarm_control_panel_entities.values() + ) assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}}) await hass.async_block_till_done() @@ -390,7 +396,7 @@ async def test_get_action_capabilities_arm_code_legacy( entity_registry.async_get_or_create( DOMAIN, "test", - platform.ENTITIES["arm_code"].unique_id, + mock_alarm_control_panel_entities["arm_code"].unique_id, device_id=device_entry.id, ) @@ -429,11 +435,12 @@ async def test_action( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, - enable_custom_integrations: None, + mock_alarm_control_panel_entities: dict[str, MockAlarm], ) -> None: """Test for turn_on and turn_off actions.""" - platform = getattr(hass.components, f"test.{DOMAIN}") - platform.init() + setup_test_component_platform( + hass, DOMAIN, mock_alarm_control_panel_entities.values() + ) config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_hass(hass) @@ -444,7 +451,7 @@ async def test_action( entity_entry = entity_registry.async_get_or_create( DOMAIN, "test", - platform.ENTITIES["no_arm_code"].unique_id, + mock_alarm_control_panel_entities["no_arm_code"].unique_id, device_id=device_entry.id, ) @@ -560,11 +567,12 @@ async def test_action_legacy( hass: HomeAssistant, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, - enable_custom_integrations: None, + mock_alarm_control_panel_entities: dict[str, MockAlarm], ) -> None: """Test for turn_on and turn_off actions.""" - platform = getattr(hass.components, f"test.{DOMAIN}") - platform.init() + setup_test_component_platform( + hass, DOMAIN, mock_alarm_control_panel_entities.values() + ) config_entry = MockConfigEntry(domain="test", data={}) config_entry.add_to_hass(hass) @@ -575,7 +583,7 @@ async def test_action_legacy( entity_entry = entity_registry.async_get_or_create( DOMAIN, "test", - platform.ENTITIES["no_arm_code"].unique_id, + mock_alarm_control_panel_entities["no_arm_code"].unique_id, device_id=device_entry.id, ) diff --git a/tests/testing_config/custom_components/test/alarm_control_panel.py b/tests/testing_config/custom_components/test/alarm_control_panel.py deleted file mode 100644 index 204281af3d3..00000000000 --- a/tests/testing_config/custom_components/test/alarm_control_panel.py +++ /dev/null @@ -1,112 +0,0 @@ -"""Provide a mock alarm_control_panel platform. - -Call init before using it in your tests to ensure clean test data. -""" - -from homeassistant.components.alarm_control_panel import AlarmControlPanelEntity -from homeassistant.components.alarm_control_panel.const import ( - AlarmControlPanelEntityFeature, -) -from homeassistant.const import ( - STATE_ALARM_ARMED_AWAY, - STATE_ALARM_ARMED_HOME, - STATE_ALARM_ARMED_NIGHT, - STATE_ALARM_ARMED_VACATION, - STATE_ALARM_DISARMED, - STATE_ALARM_TRIGGERED, -) - -from tests.common import MockEntity - -ENTITIES = {} - - -def init(empty=False): - """Initialize the platform with entities.""" - global ENTITIES - - ENTITIES = ( - {} - if empty - else { - "arm_code": MockAlarm( - name="Alarm arm code", - code_arm_required=True, - unique_id="unique_arm_code", - ), - "no_arm_code": MockAlarm( - name="Alarm no arm code", - code_arm_required=False, - unique_id="unique_no_arm_code", - ), - } - ) - - -async def async_setup_platform( - hass, config, async_add_entities_callback, discovery_info=None -): - """Return mock entities.""" - async_add_entities_callback(list(ENTITIES.values())) - - -class MockAlarm(MockEntity, AlarmControlPanelEntity): - """Mock Alarm control panel class.""" - - def __init__(self, **values): - """Init the Mock Alarm Control Panel.""" - self._state = None - - MockEntity.__init__(self, **values) - - @property - def code_arm_required(self): - """Whether the code is required for arm actions.""" - return self._handle("code_arm_required") - - @property - def state(self): - """Return the state of the device.""" - return self._state - - @property - def supported_features(self) -> AlarmControlPanelEntityFeature: - """Return the list of supported features.""" - return ( - AlarmControlPanelEntityFeature.ARM_HOME - | AlarmControlPanelEntityFeature.ARM_AWAY - | AlarmControlPanelEntityFeature.ARM_NIGHT - | AlarmControlPanelEntityFeature.TRIGGER - | AlarmControlPanelEntityFeature.ARM_VACATION - ) - - def alarm_arm_away(self, code=None): - """Send arm away command.""" - self._state = STATE_ALARM_ARMED_AWAY - self.schedule_update_ha_state() - - def alarm_arm_home(self, code=None): - """Send arm home command.""" - self._state = STATE_ALARM_ARMED_HOME - self.schedule_update_ha_state() - - def alarm_arm_night(self, code=None): - """Send arm night command.""" - self._state = STATE_ALARM_ARMED_NIGHT - self.schedule_update_ha_state() - - def alarm_arm_vacation(self, code=None): - """Send arm night command.""" - self._state = STATE_ALARM_ARMED_VACATION - self.schedule_update_ha_state() - - def alarm_disarm(self, code=None): - """Send disarm command.""" - if code == "1234": - self._state = STATE_ALARM_DISARMED - self.schedule_update_ha_state() - - def alarm_trigger(self, code=None): - """Send alarm trigger command.""" - self._state = STATE_ALARM_TRIGGERED - self.schedule_update_ha_state()