diff --git a/.coveragerc b/.coveragerc index e7de89daffb..dcc51b83cc5 100644 --- a/.coveragerc +++ b/.coveragerc @@ -551,7 +551,6 @@ omit = homeassistant/components/homematic/switch.py homeassistant/components/homeworks/__init__.py homeassistant/components/homeworks/button.py - homeassistant/components/homeworks/light.py homeassistant/components/horizon/media_player.py homeassistant/components/hp_ilo/sensor.py homeassistant/components/huawei_lte/__init__.py diff --git a/tests/components/homeworks/snapshots/test_light.ambr b/tests/components/homeworks/snapshots/test_light.ambr new file mode 100644 index 00000000000..49f7f561bc0 --- /dev/null +++ b/tests/components/homeworks/snapshots/test_light.ambr @@ -0,0 +1,39 @@ +# serializer version: 1 +# name: test_light_attributes_state_update + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'brightness': None, + 'color_mode': None, + 'friendly_name': 'Foyer Sconces', + 'homeworks_address': '[02:08:01:01]', + 'supported_color_modes': list([ + , + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'light.foyer_sconces', + 'last_changed': , + 'last_updated': , + 'state': 'off', + }) +# --- +# name: test_light_attributes_state_update.1 + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'brightness': 127, + 'color_mode': , + 'friendly_name': 'Foyer Sconces', + 'homeworks_address': '[02:08:01:01]', + 'supported_color_modes': list([ + , + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'light.foyer_sconces', + 'last_changed': , + 'last_updated': , + 'state': 'on', + }) +# --- diff --git a/tests/components/homeworks/test_light.py b/tests/components/homeworks/test_light.py new file mode 100644 index 00000000000..dda88f2a784 --- /dev/null +++ b/tests/components/homeworks/test_light.py @@ -0,0 +1,124 @@ +"""Tests for the Lutron Homeworks Series 4 and 8 light.""" +from unittest.mock import ANY, MagicMock + +from pyhomeworks.pyhomeworks import HW_LIGHT_CHANGED +import pytest +from pytest_unordered import unordered +from syrupy.assertion import SnapshotAssertion + +from homeassistant.components.light import ATTR_BRIGHTNESS, DOMAIN as LIGHT_DOMAIN +from homeassistant.const import ( + ATTR_ENTITY_ID, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, + STATE_OFF, + STATE_ON, +) +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry + + +async def test_light_attributes_state_update( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_homeworks: MagicMock, + snapshot: SnapshotAssertion, +) -> None: + """Test Homeworks light state changes.""" + entity_id = "light.foyer_sconces" + mock_controller = MagicMock() + mock_homeworks.return_value = mock_controller + + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + mock_homeworks.assert_called_once_with("192.168.0.1", 1234, ANY) + hw_callback = mock_homeworks.mock_calls[0][1][2] + + assert len(mock_controller.request_dimmer_level.mock_calls) == 1 + assert mock_controller.request_dimmer_level.mock_calls[0][1] == ("[02:08:01:01]",) + + assert hass.states.async_entity_ids("light") == unordered([entity_id]) + + state = hass.states.get(entity_id) + assert state.state == STATE_OFF + assert state == snapshot + + hw_callback(HW_LIGHT_CHANGED, ["[02:08:01:01]", 50]) + await hass.async_block_till_done() + state = hass.states.get(entity_id) + assert state.state == STATE_ON + assert state == snapshot + + +async def test_light_service_calls( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_homeworks: MagicMock, +) -> None: + """Test Homeworks light service call.""" + entity_id = "light.foyer_sconces" + mock_controller = MagicMock() + mock_homeworks.return_value = mock_controller + + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert hass.states.async_entity_ids("light") == unordered([entity_id]) + + await hass.services.async_call( + LIGHT_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id}, blocking=True + ) + mock_controller.fade_dim.assert_called_with(0.0, 1.0, 0, "[02:08:01:01]") + + # The light's brightness is unknown, turning it on should set it to max + await hass.services.async_call( + LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id}, blocking=True + ) + mock_controller.fade_dim.assert_called_with(100.0, 1.0, 0, "[02:08:01:01]") + + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 127}, + blocking=True, + ) + mock_controller.fade_dim.assert_called_with( + pytest.approx(49.8, abs=0.1), 1.0, 0, "[02:08:01:01]" + ) + + +async def test_light_restore_brightness( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_homeworks: MagicMock, +) -> None: + """Test Homeworks light service call.""" + entity_id = "light.foyer_sconces" + mock_controller = MagicMock() + mock_homeworks.return_value = mock_controller + + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + mock_homeworks.assert_called_once_with("192.168.0.1", 1234, ANY) + hw_callback = mock_homeworks.mock_calls[0][1][2] + + assert hass.states.async_entity_ids("light") == unordered([entity_id]) + + hw_callback(HW_LIGHT_CHANGED, ["[02:08:01:01]", 50]) + await hass.async_block_till_done() + state = hass.states.get(entity_id) + assert state.state == STATE_ON + assert state.attributes[ATTR_BRIGHTNESS] == 127 + + await hass.services.async_call( + LIGHT_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id}, blocking=True + ) + mock_controller.fade_dim.assert_called_with( + pytest.approx(49.8, abs=0.1), 1.0, 0, "[02:08:01:01]" + )